#include #include #include "transcode.h" #define MOD_NAME "export_qt.so" #define MOD_VERSION "v0.0.1 (11/07/01)" #define MOD_CODEC "(video) mjpeg | (audio) ima4" #define MOD_PRE qt #include "export_def.h" #include static int verbose_flag=TC_QUIET; static int capability_flag=TC_CAP_RGB|TC_CAP_PCM|TC_CAP_AC3|TC_CAP_AUD; static quicktime_t *qtfile = NULL; unsigned char** buffer; int16_t **audbuf; int w,h; int16_t* audbuf0; int16_t* audbuf1; /* ------------------------------------------------------------ * * open outputfile * * ------------------------------------------------------------*/ MOD_open { if (verbose & TC_DEBUG) fprintf(stderr,"[%s] OPEN\n",MOD_NAME); // I don't do anything here. if(param->flag == TC_VIDEO) return(0); if(param->flag == TC_AUDIO) return(0); return(TC_EXPORT_ERROR); } /* ------------------------------------------------------------ * * init codec * * ------------------------------------------------------------*/ MOD_init { int ret; if (verbose & TC_DEBUG) fprintf(stderr,"[%s] INIT\n",MOD_NAME); if(param->flag == TC_VIDEO) { //set the video params. I need to add checking. The height and // width both need to be integer mulitples of 16 // only supports mjpa and jpeg, this seems fine. if( (((float)vob->ex_v_width/16) != vob->ex_v_width/16) || (((float)vob->ex_v_height/16) != vob->ex_v_height/16) ){ fprintf(stderr,"[%s] Width and height must be multiples of 16.\n",MOD_NAME); fprintf(stderr,"[%s] Try the -j option.\n",MOD_NAME); return(TC_EXPORT_ERROR); } if(NULL == (qtfile = quicktime_open(vob->video_out_file, 0, 1)) ){ fprintf(stderr,"[%s] open error\n",MOD_NAME); return(TC_EXPORT_ERROR); } quicktime_set_video(qtfile, 1,vob->ex_v_width, vob->ex_v_height, (int)vob->fps,"mjpa"); if (!quicktime_supported_video(qtfile, 0)){ fprintf(stderr,"[%s] Codec unsupported.\n",MOD_NAME); return(TC_EXPORT_ERROR); } switch (vob->im_v_codec) { case CODEC_RGB: break; case CODEC_YUV: fprintf(stderr, "[%s] codec not supported\n", MOD_NAME); return(TC_EXPORT_ERROR); break; default: fprintf(stderr, "[%s] codec not supported\n", MOD_NAME); return(TC_EXPORT_ERROR); break; } //quicktime quality is 1-100, so 20,40,60,80,100 quicktime_set_jpeg(qtfile, 20 * vob->divxquality, 0); if(verbose & TC_DEBUG) { fprintf(stderr,"[%s] Quality %d\n",MOD_NAME,vob->divxquality*20); } // I need these later; w = vob->ex_v_width; h = vob->ex_v_height; // the quicktime buffer is a an array of pointers to video rows // here I allocate for that array buffer = malloc (sizeof(int) * vob->ex_v_height); return(0); } if(param->flag == TC_AUDIO){ // I only support 48khz, 2 chan, 16 bits, 24 fps. //fprintf(stderr,"[%s] %f fps %dchan %d bits %drate\n",MOD_NAME,vob->fps,vob->a_chan,vob->a_bits,vob->a_rate); if ( (vob->fps!=24) || (vob->a_chan!=2) || (vob->a_bits!=16) || (vob->a_rate!=48000)){ fprintf(stderr,"[%s] Only 24fps 48khz, 2 chan, 16 bits audio\n",MOD_NAME); return(TC_EXPORT_ERROR); } quicktime_set_audio(qtfile, 2, 48000, 16, "ima4"); if (!quicktime_supported_audio(qtfile, 0)){ fprintf(stderr,"[%s] Codec unsupported.\n",MOD_NAME); return(TC_EXPORT_ERROR); } // Quicktime expects one audio channel per buffer. It gets an array // of pointers to each audio channel // I need two audio buffers to un interleave the stereo audio audbuf = malloc (sizeof(int) * 16); audbuf0= (int16_t*)malloc(sizeof(int16_t)*2000); audbuf1= (int16_t*)malloc(sizeof(int16_t)*2000); return(0); } return(TC_EXPORT_ERROR); } /* ------------------------------------------------------------ * * encode and export frame * * ------------------------------------------------------------*/ MOD_encode { int iy; if (verbose & TC_DEBUG) fprintf(stderr,"[%s] ENCODE\n",MOD_NAME); if(param->flag == TC_VIDEO) { // point my buffer at the rows in the param buffer. for(iy=0;iybuffer+(iy*w*3); } if (quicktime_encode_video(qtfile, buffer, 0)){ fprintf(stderr, "[%s] Problem encoding quicktime:\n",MOD_NAME); return(TC_EXPORT_ERROR); } return(0); } if(param->flag == TC_AUDIO){ if (verbose & TC_DEBUG) fprintf(stderr,"[%s] audio buffer size %d\n\n",MOD_NAME,param->size); // Un-interleave the stereo buffer into 2 channels for(iy=0;iy<2000;iy++){ memcpy(&audbuf0[iy],param->buffer+iy*4, sizeof(int16_t)); memcpy(&audbuf1[iy],param->buffer+iy*4+2, sizeof(int16_t)); } //set my audio pointers to the two channels audbuf[0]=audbuf1; audbuf[1]=audbuf0; if ( (quicktime_encode_audio(qtfile, audbuf, NULL, 2000)!=0 )){ fprintf(stderr,"[%s] Trouble encoding audio.\n",MOD_NAME); return(TC_EXPORT_ERROR); } return(0); } return(TC_EXPORT_ERROR); } /* ------------------------------------------------------------ * * stop encoder * * ------------------------------------------------------------*/ MOD_stop { if (verbose & TC_DEBUG) fprintf(stderr,"[%s] STOP\n",MOD_NAME); if(param->flag == TC_VIDEO){ free(buffer); return(0); } if(param->flag == TC_AUDIO){ free(audbuf0); free(audbuf1); return(0); } return(TC_EXPORT_ERROR); } /* ------------------------------------------------------------ * * close outputfile * * ------------------------------------------------------------*/ MOD_close { if (verbose & TC_DEBUG) fprintf(stderr,"[%s] CLOSE\n",MOD_NAME); if(param->flag == TC_VIDEO){ quicktime_close(qtfile); qtfile=NULL; return(0); } if(param->flag == TC_AUDIO) return(0); return(TC_EXPORT_ERROR); }