00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 #include <xvid.h>
00027 #include <unistd.h>
00028 #include "common.h"
00029 #include "avcodec.h"
00030
00034 #define BUFFER_SIZE 1024
00035 #define BUFFER_REMAINING(x) (BUFFER_SIZE - strlen(x))
00036 #define BUFFER_CAT(x) (&((x)[strlen(x)]))
00037
00038
00039 #if HAVE_ALTIVEC==1
00040 extern int has_altivec(void);
00041 #endif
00042
00047 typedef struct xvid_context {
00048 void *encoder_handle;
00049 int xsize, ysize;
00050 int vop_flags;
00051 int vol_flags;
00052 int me_flags;
00053 int qscale;
00054 int quicktime_format;
00055 AVFrame encoded_picture;
00056 char *twopassbuffer;
00057 char *old_twopassbuffer;
00058 char *twopassfile;
00059 unsigned char *intra_matrix;
00060 unsigned char *inter_matrix;
00061 } xvid_context_t;
00062
00066 typedef struct xvid_ff_pass1 {
00067 int version;
00068 xvid_context_t *context;
00069 } xvid_ff_pass1_t;
00070
00071
00072 int xvid_strip_vol_header(AVCodecContext *avctx, unsigned char *frame, unsigned int header_len, unsigned int frame_len);
00073 int xvid_ff_2pass(void *ref, int opt, void *p1, void *p2);
00074 void xvid_correct_framerate(AVCodecContext *avctx);
00075
00084 int ff_xvid_encode_init(AVCodecContext *avctx) {
00085 int xerr, i;
00086 int xvid_flags = avctx->flags;
00087 xvid_context_t *x = avctx->priv_data;
00088 uint16_t *intra, *inter;
00089 int fd;
00090
00091 xvid_plugin_single_t single;
00092 xvid_ff_pass1_t rc2pass1;
00093 xvid_plugin_2pass2_t rc2pass2;
00094 xvid_gbl_init_t xvid_gbl_init;
00095 xvid_enc_create_t xvid_enc_create;
00096 xvid_enc_plugin_t plugins[7];
00097
00098
00099 x->vop_flags = XVID_VOP_HALFPEL;
00100 if( xvid_flags & CODEC_FLAG_4MV )
00101 x->vop_flags |= XVID_VOP_INTER4V;
00102 if( xvid_flags & CODEC_FLAG_TRELLIS_QUANT)
00103 x->vop_flags |= XVID_VOP_TRELLISQUANT;
00104 if( xvid_flags & CODEC_FLAG_AC_PRED )
00105 x->vop_flags |= XVID_VOP_HQACPRED;
00106 if( xvid_flags & CODEC_FLAG_GRAY )
00107 x->vop_flags |= XVID_VOP_GREYSCALE;
00108
00109
00110 x->me_flags = 0;
00111 switch( avctx->me_method ) {
00112 case ME_FULL:
00113 x->me_flags |= XVID_ME_EXTSEARCH16
00114 | XVID_ME_EXTSEARCH8;
00115
00116 case ME_EPZS:
00117 x->me_flags |= XVID_ME_ADVANCEDDIAMOND8
00118 | XVID_ME_HALFPELREFINE8
00119 | XVID_ME_CHROMA_PVOP
00120 | XVID_ME_CHROMA_BVOP;
00121
00122 case ME_LOG:
00123 case ME_PHODS:
00124 case ME_X1:
00125 x->me_flags |= XVID_ME_ADVANCEDDIAMOND16
00126 | XVID_ME_HALFPELREFINE16;
00127
00128 case ME_ZERO:
00129 default:
00130 break;
00131 }
00132
00133
00134 switch( avctx->mb_decision ) {
00135 case 2:
00136 x->vop_flags |= XVID_VOP_MODEDECISION_RD;
00137 x->me_flags |= XVID_ME_HALFPELREFINE8_RD
00138 | XVID_ME_QUARTERPELREFINE8_RD
00139 | XVID_ME_EXTSEARCH_RD
00140 | XVID_ME_CHECKPREDICTION_RD;
00141 case 1:
00142 if( !(x->vop_flags & XVID_VOP_MODEDECISION_RD) )
00143 x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD;
00144 x->me_flags |= XVID_ME_HALFPELREFINE16_RD
00145 | XVID_ME_QUARTERPELREFINE16_RD;
00146
00147 default:
00148 break;
00149 }
00150
00151
00152 x->vol_flags = 0;
00153 if( xvid_flags & CODEC_FLAG_GMC ) {
00154 x->vol_flags |= XVID_VOL_GMC;
00155 x->me_flags |= XVID_ME_GME_REFINE;
00156 }
00157 if( xvid_flags & CODEC_FLAG_QPEL ) {
00158 x->vol_flags |= XVID_VOL_QUARTERPEL;
00159 x->me_flags |= XVID_ME_QUARTERPELREFINE16;
00160 if( x->vop_flags & XVID_VOP_INTER4V )
00161 x->me_flags |= XVID_ME_QUARTERPELREFINE8;
00162 }
00163
00164 memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init));
00165 xvid_gbl_init.version = XVID_VERSION;
00166 xvid_gbl_init.debug = 0;
00167
00168 #ifdef ARCH_POWERPC
00169
00170 #if HAVE_ALTIVEC==1
00171 if( has_altivec() ) {
00172 xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC;
00173 } else
00174 #endif
00175 xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
00176 #else
00177
00178 xvid_gbl_init.cpu_flags = 0;
00179 #endif
00180
00181
00182 xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);
00183
00184
00185 memset(&xvid_enc_create, 0, sizeof(xvid_enc_create));
00186 xvid_enc_create.version = XVID_VERSION;
00187
00188
00189 xvid_enc_create.width = x->xsize = avctx->width;
00190 xvid_enc_create.height = x->ysize = avctx->height;
00191
00192
00193
00194
00195
00196 xvid_enc_create.zones = NULL;
00197 xvid_enc_create.num_zones = 0;
00198 xvid_enc_create.num_threads = 0;
00199
00200 xvid_enc_create.plugins = plugins;
00201 xvid_enc_create.num_plugins = 0;
00202
00203
00204 x->twopassbuffer = NULL;
00205 x->old_twopassbuffer = NULL;
00206 x->twopassfile = NULL;
00207
00208 if( xvid_flags & CODEC_FLAG_PASS1 ) {
00209 memset(&rc2pass1, 0, sizeof(xvid_ff_pass1_t));
00210 rc2pass1.version = XVID_VERSION;
00211 rc2pass1.context = x;
00212 x->twopassbuffer = av_malloc(BUFFER_SIZE);
00213 x->old_twopassbuffer = av_malloc(BUFFER_SIZE);
00214 if( x->twopassbuffer == NULL || x->old_twopassbuffer == NULL ) {
00215 av_log(avctx, AV_LOG_ERROR,
00216 "XviD: Cannot allocate 2-pass log buffers\n");
00217 return -1;
00218 }
00219 x->twopassbuffer[0] = x->old_twopassbuffer[0] = 0;
00220
00221 plugins[xvid_enc_create.num_plugins].func = xvid_ff_2pass;
00222 plugins[xvid_enc_create.num_plugins].param = &rc2pass1;
00223 xvid_enc_create.num_plugins++;
00224 } else if( xvid_flags & CODEC_FLAG_PASS2 ) {
00225 memset(&rc2pass2, 0, sizeof(xvid_plugin_2pass2_t));
00226 rc2pass2.version = XVID_VERSION;
00227 rc2pass2.bitrate = avctx->bit_rate;
00228
00229 x->twopassfile = av_malloc(BUFFER_SIZE);
00230 if( x->twopassfile == NULL ) {
00231 av_log(avctx, AV_LOG_ERROR,
00232 "XviD: Cannot allocate 2-pass buffer\n");
00233 return -1;
00234 }
00235 strcpy(x->twopassfile, "/tmp/xvidff.XXXXXX");
00236 fd = mkstemp(x->twopassfile);
00237 if(fd < 0){
00238 strcpy(x->twopassfile, "./xvidff.XXXXXX");
00239 fd = mkstemp(x->twopassfile);
00240 }
00241 if( fd == -1 ) {
00242 av_log(avctx, AV_LOG_ERROR,
00243 "XviD: Cannot write 2-pass pipe\n");
00244 return -1;
00245 }
00246
00247 if( avctx->stats_in == NULL ) {
00248 av_log(avctx, AV_LOG_ERROR,
00249 "XviD: No 2-pass information loaded for second pass\n");
00250 return -1;
00251 }
00252
00253 if( strlen(avctx->stats_in) >
00254 write(fd, avctx->stats_in, strlen(avctx->stats_in)) ) {
00255 close(fd);
00256 av_log(avctx, AV_LOG_ERROR,
00257 "XviD: Cannot write to 2-pass pipe\n");
00258 return -1;
00259 }
00260
00261 close(fd);
00262 rc2pass2.filename = x->twopassfile;
00263 plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2;
00264 plugins[xvid_enc_create.num_plugins].param = &rc2pass2;
00265 xvid_enc_create.num_plugins++;
00266 } else if( !(xvid_flags & CODEC_FLAG_QSCALE) ) {
00267
00268 memset(&single, 0, sizeof(xvid_plugin_single_t));
00269 single.version = XVID_VERSION;
00270 single.bitrate = avctx->bit_rate;
00271
00272 plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single;
00273 plugins[xvid_enc_create.num_plugins].param = &single;
00274 xvid_enc_create.num_plugins++;
00275 }
00276
00277
00278 if( 0.0 != avctx->lumi_masking ) {
00279 plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking;
00280 plugins[xvid_enc_create.num_plugins].param = NULL;
00281 xvid_enc_create.num_plugins++;
00282 }
00283
00284
00285 xvid_correct_framerate(avctx);
00286 xvid_enc_create.fincr = avctx->time_base.num;
00287 xvid_enc_create.fbase = avctx->time_base.den;
00288 if( avctx->gop_size > 0 )
00289 xvid_enc_create.max_key_interval = avctx->gop_size;
00290 else
00291 xvid_enc_create.max_key_interval = 240;
00292
00293
00294 if( xvid_flags & CODEC_FLAG_QSCALE ) x->qscale = 1;
00295 else x->qscale = 0;
00296
00297 xvid_enc_create.min_quant[0] = avctx->qmin;
00298 xvid_enc_create.min_quant[1] = avctx->qmin;
00299 xvid_enc_create.min_quant[2] = avctx->qmin;
00300 xvid_enc_create.max_quant[0] = avctx->qmax;
00301 xvid_enc_create.max_quant[1] = avctx->qmax;
00302 xvid_enc_create.max_quant[2] = avctx->qmax;
00303
00304
00305 x->intra_matrix = x->inter_matrix = NULL;
00306 if( avctx->mpeg_quant )
00307 x->vol_flags |= XVID_VOL_MPEGQUANT;
00308 if( (avctx->intra_matrix || avctx->inter_matrix) ) {
00309 x->vol_flags |= XVID_VOL_MPEGQUANT;
00310
00311 if( avctx->intra_matrix ) {
00312 intra = avctx->intra_matrix;
00313 x->intra_matrix = av_malloc(sizeof(unsigned char) * 64);
00314 } else
00315 intra = NULL;
00316 if( avctx->inter_matrix ) {
00317 inter = avctx->inter_matrix;
00318 x->inter_matrix = av_malloc(sizeof(unsigned char) * 64);
00319 } else
00320 inter = NULL;
00321
00322 for( i = 0; i < 64; i++ ) {
00323 if( intra )
00324 x->intra_matrix[i] = (unsigned char)intra[i];
00325 if( inter )
00326 x->inter_matrix[i] = (unsigned char)inter[i];
00327 }
00328 }
00329
00330
00331 xvid_enc_create.frame_drop_ratio = 0;
00332 xvid_enc_create.global = 0;
00333 if( xvid_flags & CODEC_FLAG_CLOSED_GOP )
00334 xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP;
00335
00336
00337 avctx->extradata = NULL;
00338 avctx->extradata_size = 0;
00339 if( xvid_flags & CODEC_FLAG_GLOBAL_HEADER ) {
00340
00341 x->quicktime_format = 1;
00342 avctx->codec_id = CODEC_ID_MPEG4;
00343 } else {
00344
00345 x->quicktime_format = 0;
00346 avctx->codec_tag = ff_get_fourcc("xvid");
00347 }
00348
00349
00350 xvid_enc_create.max_bframes = avctx->max_b_frames;
00351 xvid_enc_create.bquant_offset = avctx->b_quant_offset;
00352 xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor;
00353 if( avctx->max_b_frames > 0 && !x->quicktime_format ) xvid_enc_create.global |= XVID_GLOBAL_PACKED;
00354
00355
00356 xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
00357 if( xerr ) {
00358 av_log(avctx, AV_LOG_ERROR, "XviD: Could not create encoder reference\n");
00359 return -1;
00360 }
00361
00362 x->encoder_handle = xvid_enc_create.handle;
00363 avctx->coded_frame = &x->encoded_picture;
00364
00365 return 0;
00366 }
00367
00377 int ff_xvid_encode_frame(AVCodecContext *avctx,
00378 unsigned char *frame, int buf_size, void *data) {
00379 int xerr, i;
00380 char *tmp;
00381 xvid_context_t *x = avctx->priv_data;
00382 AVFrame *picture = data;
00383 AVFrame *p = &(x->encoded_picture);
00384
00385 xvid_enc_frame_t xvid_enc_frame;
00386 xvid_enc_stats_t xvid_enc_stats;
00387
00388
00389 memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame));
00390 xvid_enc_frame.version = XVID_VERSION;
00391 memset(&xvid_enc_stats, 0, sizeof(xvid_enc_stats));
00392 xvid_enc_stats.version = XVID_VERSION;
00393 *p = *picture;
00394
00395
00396 xvid_enc_frame.bitstream = frame;
00397 xvid_enc_frame.length = buf_size;
00398
00399
00400 if( avctx->pix_fmt != PIX_FMT_YUV420P ) {
00401 av_log(avctx, AV_LOG_ERROR, "XviD: Color spaces other than 420p not supported\n");
00402 return -1;
00403 }
00404
00405 xvid_enc_frame.input.csp = XVID_CSP_PLANAR;
00406
00407 for( i = 0; i < 4; i++ ) {
00408 xvid_enc_frame.input.plane[i] = picture->data[i];
00409 xvid_enc_frame.input.stride[i] = picture->linesize[i];
00410 }
00411
00412
00413 xvid_enc_frame.vop_flags = x->vop_flags;
00414 xvid_enc_frame.vol_flags = x->vol_flags;
00415 xvid_enc_frame.motion = x->me_flags;
00416 xvid_enc_frame.type = XVID_TYPE_AUTO;
00417
00418
00419 if( x->qscale ) xvid_enc_frame.quant = picture->quality / FF_QP2LAMBDA;
00420 else xvid_enc_frame.quant = 0;
00421
00422
00423 xvid_enc_frame.quant_intra_matrix = x->intra_matrix;
00424 xvid_enc_frame.quant_inter_matrix = x->inter_matrix;
00425
00426
00427 xerr = xvid_encore(x->encoder_handle, XVID_ENC_ENCODE,
00428 &xvid_enc_frame, &xvid_enc_stats);
00429
00430
00431 avctx->stats_out = NULL;
00432 if( x->twopassbuffer ) {
00433 tmp = x->old_twopassbuffer;
00434 x->old_twopassbuffer = x->twopassbuffer;
00435 x->twopassbuffer = tmp;
00436 x->twopassbuffer[0] = 0;
00437 if( x->old_twopassbuffer[0] != 0 ) {
00438 avctx->stats_out = x->old_twopassbuffer;
00439 }
00440 }
00441
00442 if( 0 <= xerr ) {
00443 p->quality = xvid_enc_stats.quant * FF_QP2LAMBDA;
00444 if( xvid_enc_stats.type == XVID_TYPE_PVOP )
00445 p->pict_type = FF_P_TYPE;
00446 else if( xvid_enc_stats.type == XVID_TYPE_BVOP )
00447 p->pict_type = FF_B_TYPE;
00448 else if( xvid_enc_stats.type == XVID_TYPE_SVOP )
00449 p->pict_type = FF_S_TYPE;
00450 else
00451 p->pict_type = FF_I_TYPE;
00452 if( xvid_enc_frame.out_flags & XVID_KEYFRAME ) {
00453 p->key_frame = 1;
00454 if( x->quicktime_format )
00455 return xvid_strip_vol_header(avctx, frame,
00456 xvid_enc_stats.hlength, xerr);
00457 } else
00458 p->key_frame = 0;
00459
00460 return xerr;
00461 } else {
00462 av_log(avctx, AV_LOG_ERROR, "XviD: Encoding Error Occurred: %i\n", xerr);
00463 return -1;
00464 }
00465 }
00466
00474 int ff_xvid_encode_close(AVCodecContext *avctx) {
00475 xvid_context_t *x = avctx->priv_data;
00476
00477 xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL);
00478
00479 if( avctx->extradata != NULL )
00480 av_free(avctx->extradata);
00481 if( x->twopassbuffer != NULL ) {
00482 av_free(x->twopassbuffer);
00483 av_free(x->old_twopassbuffer);
00484 }
00485 if( x->twopassfile != NULL )
00486 av_free(x->twopassfile);
00487 if( x->intra_matrix != NULL )
00488 av_free(x->intra_matrix);
00489 if( x->inter_matrix != NULL )
00490 av_free(x->inter_matrix);
00491
00492 return 0;
00493 }
00494
00508 int xvid_strip_vol_header(AVCodecContext *avctx,
00509 unsigned char *frame,
00510 unsigned int header_len,
00511 unsigned int frame_len) {
00512 int vo_len = 0, i;
00513
00514 for( i = 0; i < header_len - 3; i++ ) {
00515 if( frame[i] == 0x00 &&
00516 frame[i+1] == 0x00 &&
00517 frame[i+2] == 0x01 &&
00518 frame[i+3] == 0xB6 ) {
00519 vo_len = i;
00520 break;
00521 }
00522 }
00523
00524 if( vo_len > 0 ) {
00525
00526 if( avctx->extradata == NULL ) {
00527 avctx->extradata = av_malloc(vo_len);
00528 memcpy(avctx->extradata, frame, vo_len);
00529 avctx->extradata_size = vo_len;
00530 }
00531
00532
00533 memmove(frame, &(frame[vo_len]), frame_len - vo_len);
00534 return frame_len - vo_len;
00535 } else
00536 return frame_len;
00537 }
00538
00548 void xvid_correct_framerate(AVCodecContext *avctx) {
00549 int frate, fbase;
00550 int est_frate, est_fbase;
00551 int gcd;
00552 float est_fps, fps;
00553
00554 frate = avctx->time_base.den;
00555 fbase = avctx->time_base.num;
00556
00557 gcd = ff_gcd(frate, fbase);
00558 if( gcd > 1 ) {
00559 frate /= gcd;
00560 fbase /= gcd;
00561 }
00562
00563 if( frate <= 65000 && fbase <= 65000 ) {
00564 avctx->time_base.den = frate;
00565 avctx->time_base.num = fbase;
00566 return;
00567 }
00568
00569 fps = (float)frate / (float)fbase;
00570 est_fps = roundf(fps * 1000.0) / 1000.0;
00571
00572 est_frate = (int)est_fps;
00573 if( est_fps > (int)est_fps ) {
00574 est_frate = (est_frate + 1) * 1000;
00575 est_fbase = (int)roundf((float)est_frate / est_fps);
00576 } else
00577 est_fbase = 1;
00578
00579 gcd = ff_gcd(est_frate, est_fbase);
00580 if( gcd > 1 ) {
00581 est_frate /= gcd;
00582 est_fbase /= gcd;
00583 }
00584
00585 if( fbase > est_fbase ) {
00586 avctx->time_base.den = est_frate;
00587 avctx->time_base.num = est_fbase;
00588 av_log(avctx, AV_LOG_DEBUG,
00589 "XviD: framerate re-estimated: %.2f, %.3f%% correction\n",
00590 est_fps, (((est_fps - fps)/fps) * 100.0));
00591 } else {
00592 avctx->time_base.den = frate;
00593 avctx->time_base.num = fbase;
00594 }
00595 }
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00614 static int xvid_ff_2pass_create(xvid_plg_create_t * param,
00615 void ** handle) {
00616 xvid_ff_pass1_t *x = (xvid_ff_pass1_t *)param->param;
00617 char *log = x->context->twopassbuffer;
00618
00619
00620 if( log == NULL )
00621 return XVID_ERR_FAIL;
00622
00623
00624
00625 log[0] = 0;
00626 snprintf(log, BUFFER_REMAINING(log),
00627 "# ffmpeg 2-pass log file, using xvid codec\n");
00628 snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
00629 "# Do not modify. libxvidcore version: %d.%d.%d\n\n",
00630 XVID_VERSION_MAJOR(XVID_VERSION),
00631 XVID_VERSION_MINOR(XVID_VERSION),
00632 XVID_VERSION_PATCH(XVID_VERSION));
00633
00634 *handle = x->context;
00635 return 0;
00636 }
00637
00645 static int xvid_ff_2pass_destroy(xvid_context_t *ref,
00646 xvid_plg_destroy_t *param) {
00647
00648
00649 if( ref->twopassbuffer != NULL )
00650 ref->twopassbuffer[0] = 0;
00651 return 0;
00652 }
00653
00661 static int xvid_ff_2pass_before(xvid_context_t *ref,
00662 xvid_plg_data_t *param) {
00663 int motion_remove;
00664 int motion_replacements;
00665 int vop_remove;
00666
00667
00668 if( param->zone && param->zone->mode == XVID_ZONE_QUANT )
00669 return 0;
00670
00671
00672 param->quant = 2;
00673
00674
00675 motion_remove = ~XVID_ME_CHROMA_PVOP &
00676 ~XVID_ME_CHROMA_BVOP &
00677 ~XVID_ME_EXTSEARCH16 &
00678 ~XVID_ME_ADVANCEDDIAMOND16;
00679 motion_replacements = XVID_ME_FAST_MODEINTERPOLATE |
00680 XVID_ME_SKIP_DELTASEARCH |
00681 XVID_ME_FASTREFINE16 |
00682 XVID_ME_BFRAME_EARLYSTOP;
00683 vop_remove = ~XVID_VOP_MODEDECISION_RD &
00684 ~XVID_VOP_FAST_MODEDECISION_RD &
00685 ~XVID_VOP_TRELLISQUANT &
00686 ~XVID_VOP_INTER4V &
00687 ~XVID_VOP_HQACPRED;
00688
00689 param->vol_flags &= ~XVID_VOL_GMC;
00690 param->vop_flags &= vop_remove;
00691 param->motion_flags &= motion_remove;
00692 param->motion_flags |= motion_replacements;
00693
00694 return 0;
00695 }
00696
00704 static int xvid_ff_2pass_after(xvid_context_t *ref,
00705 xvid_plg_data_t *param) {
00706 char *log = ref->twopassbuffer;
00707 char *frame_types = " ipbs";
00708 char frame_type;
00709
00710
00711 if( log == NULL )
00712 return XVID_ERR_FAIL;
00713
00714
00715 if( param->type < 5 && param->type > 0 ) {
00716 frame_type = frame_types[param->type];
00717 } else {
00718 return XVID_ERR_FAIL;
00719 }
00720
00721 snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
00722 "%c %d %d %d %d %d %d\n",
00723 frame_type, param->stats.quant, param->stats.kblks, param->stats.mblks,
00724 param->stats.ublks, param->stats.length, param->stats.hlength);
00725
00726 return 0;
00727 }
00728
00740 int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2) {
00741 switch( cmd ) {
00742 case XVID_PLG_INFO:
00743 case XVID_PLG_FRAME:
00744 return 0;
00745
00746 case XVID_PLG_BEFORE:
00747 return xvid_ff_2pass_before(ref, p1);
00748
00749 case XVID_PLG_CREATE:
00750 return xvid_ff_2pass_create(p1, p2);
00751
00752 case XVID_PLG_AFTER:
00753 return xvid_ff_2pass_after(ref, p1);
00754
00755 case XVID_PLG_DESTROY:
00756 return xvid_ff_2pass_destroy(ref, p1);
00757
00758 default:
00759 return XVID_ERR_FAIL;
00760 }
00761 }
00762
00766 AVCodec xvid_encoder = {
00767 "xvid",
00768 CODEC_TYPE_VIDEO,
00769 CODEC_ID_XVID,
00770 sizeof(xvid_context_t),
00771 ff_xvid_encode_init,
00772 ff_xvid_encode_frame,
00773 ff_xvid_encode_close
00774 };