00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #include <xvid.h>
00029 #include <unistd.h>
00030 #include "avcodec.h"
00031 #include "libavutil/cpu.h"
00032 #include "libavutil/intreadwrite.h"
00033 #include "libavutil/mathematics.h"
00034 #include "libxvid_internal.h"
00035 #if !HAVE_MKSTEMP
00036 #include <fcntl.h>
00037 #endif
00038
00042 #define BUFFER_SIZE 1024
00043 #define BUFFER_REMAINING(x) (BUFFER_SIZE - strlen(x))
00044 #define BUFFER_CAT(x) (&((x)[strlen(x)]))
00045
00050 struct xvid_context {
00051 void *encoder_handle;
00052 int xsize;
00053 int ysize;
00054 int vop_flags;
00055 int vol_flags;
00056 int me_flags;
00057 int qscale;
00058 int quicktime_format;
00059 AVFrame encoded_picture;
00060 char *twopassbuffer;
00061 char *old_twopassbuffer;
00062 char *twopassfile;
00063 unsigned char *intra_matrix;
00064 unsigned char *inter_matrix;
00065 };
00066
00070 struct xvid_ff_pass1 {
00071 int version;
00072 struct xvid_context *context;
00073 };
00074
00075
00076 int xvid_strip_vol_header(AVCodecContext *avctx, unsigned char *frame, unsigned int header_len, unsigned int frame_len);
00077 int xvid_ff_2pass(void *ref, int opt, void *p1, void *p2);
00078 void xvid_correct_framerate(AVCodecContext *avctx);
00079
00080
00081
00082
00083
00084
00085 int ff_tempfile(const char *prefix, char **filename) {
00086 int fd=-1;
00087 #if !HAVE_MKSTEMP
00088 *filename = tempnam(".", prefix);
00089 #else
00090 size_t len = strlen(prefix) + 12;
00091 *filename = av_malloc(len);
00092 #endif
00093
00094 if (*filename == NULL) {
00095 av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n");
00096 return -1;
00097 }
00098 #if !HAVE_MKSTEMP
00099 fd = open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444);
00100 #else
00101 snprintf(*filename, len, "/tmp/%sXXXXXX", prefix);
00102 fd = mkstemp(*filename);
00103 if (fd < 0) {
00104 snprintf(*filename, len, "./%sXXXXXX", prefix);
00105 fd = mkstemp(*filename);
00106 }
00107 #endif
00108
00109 if (fd < 0) {
00110 av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename);
00111 return -1;
00112 }
00113 return fd;
00114 }
00115
00116 #if CONFIG_LIBXVID_ENCODER
00117
00126 static av_cold int xvid_encode_init(AVCodecContext *avctx) {
00127 int xerr, i;
00128 int xvid_flags = avctx->flags;
00129 struct xvid_context *x = avctx->priv_data;
00130 uint16_t *intra, *inter;
00131 int fd;
00132
00133 xvid_plugin_single_t single;
00134 struct xvid_ff_pass1 rc2pass1;
00135 xvid_plugin_2pass2_t rc2pass2;
00136 xvid_gbl_init_t xvid_gbl_init;
00137 xvid_enc_create_t xvid_enc_create;
00138 xvid_enc_plugin_t plugins[7];
00139
00140
00141 x->vop_flags = XVID_VOP_HALFPEL;
00142 if( xvid_flags & CODEC_FLAG_4MV )
00143 x->vop_flags |= XVID_VOP_INTER4V;
00144 if( avctx->trellis
00145 )
00146 x->vop_flags |= XVID_VOP_TRELLISQUANT;
00147 if( xvid_flags & CODEC_FLAG_AC_PRED )
00148 x->vop_flags |= XVID_VOP_HQACPRED;
00149 if( xvid_flags & CODEC_FLAG_GRAY )
00150 x->vop_flags |= XVID_VOP_GREYSCALE;
00151
00152
00153 x->me_flags = 0;
00154 switch( avctx->me_method ) {
00155 case ME_FULL:
00156 x->me_flags |= XVID_ME_EXTSEARCH16
00157 | XVID_ME_EXTSEARCH8;
00158
00159 case ME_EPZS:
00160 x->me_flags |= XVID_ME_ADVANCEDDIAMOND8
00161 | XVID_ME_HALFPELREFINE8
00162 | XVID_ME_CHROMA_PVOP
00163 | XVID_ME_CHROMA_BVOP;
00164
00165 case ME_LOG:
00166 case ME_PHODS:
00167 case ME_X1:
00168 x->me_flags |= XVID_ME_ADVANCEDDIAMOND16
00169 | XVID_ME_HALFPELREFINE16;
00170
00171 case ME_ZERO:
00172 default:
00173 break;
00174 }
00175
00176
00177 switch( avctx->mb_decision ) {
00178 case 2:
00179 x->vop_flags |= XVID_VOP_MODEDECISION_RD;
00180 x->me_flags |= XVID_ME_HALFPELREFINE8_RD
00181 | XVID_ME_QUARTERPELREFINE8_RD
00182 | XVID_ME_EXTSEARCH_RD
00183 | XVID_ME_CHECKPREDICTION_RD;
00184 case 1:
00185 if( !(x->vop_flags & XVID_VOP_MODEDECISION_RD) )
00186 x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD;
00187 x->me_flags |= XVID_ME_HALFPELREFINE16_RD
00188 | XVID_ME_QUARTERPELREFINE16_RD;
00189
00190 default:
00191 break;
00192 }
00193
00194
00195 x->vol_flags = 0;
00196 if( xvid_flags & CODEC_FLAG_GMC ) {
00197 x->vol_flags |= XVID_VOL_GMC;
00198 x->me_flags |= XVID_ME_GME_REFINE;
00199 }
00200 if( xvid_flags & CODEC_FLAG_QPEL ) {
00201 x->vol_flags |= XVID_VOL_QUARTERPEL;
00202 x->me_flags |= XVID_ME_QUARTERPELREFINE16;
00203 if( x->vop_flags & XVID_VOP_INTER4V )
00204 x->me_flags |= XVID_ME_QUARTERPELREFINE8;
00205 }
00206
00207 memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init));
00208 xvid_gbl_init.version = XVID_VERSION;
00209 xvid_gbl_init.debug = 0;
00210
00211 #if ARCH_PPC
00212
00213 #if HAVE_ALTIVEC
00214 if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
00215 xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC;
00216 } else
00217 #endif
00218 xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
00219 #else
00220
00221 xvid_gbl_init.cpu_flags = 0;
00222 #endif
00223
00224
00225 xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);
00226
00227
00228 memset(&xvid_enc_create, 0, sizeof(xvid_enc_create));
00229 xvid_enc_create.version = XVID_VERSION;
00230
00231
00232 xvid_enc_create.width = x->xsize = avctx->width;
00233 xvid_enc_create.height = x->ysize = avctx->height;
00234
00235
00236
00237
00238
00239 xvid_enc_create.zones = NULL;
00240 xvid_enc_create.num_zones = 0;
00241
00242 xvid_enc_create.num_threads = avctx->thread_count;
00243
00244 xvid_enc_create.plugins = plugins;
00245 xvid_enc_create.num_plugins = 0;
00246
00247
00248 x->twopassbuffer = NULL;
00249 x->old_twopassbuffer = NULL;
00250 x->twopassfile = NULL;
00251
00252 if( xvid_flags & CODEC_FLAG_PASS1 ) {
00253 memset(&rc2pass1, 0, sizeof(struct xvid_ff_pass1));
00254 rc2pass1.version = XVID_VERSION;
00255 rc2pass1.context = x;
00256 x->twopassbuffer = av_malloc(BUFFER_SIZE);
00257 x->old_twopassbuffer = av_malloc(BUFFER_SIZE);
00258 if( x->twopassbuffer == NULL || x->old_twopassbuffer == NULL ) {
00259 av_log(avctx, AV_LOG_ERROR,
00260 "Xvid: Cannot allocate 2-pass log buffers\n");
00261 return -1;
00262 }
00263 x->twopassbuffer[0] = x->old_twopassbuffer[0] = 0;
00264
00265 plugins[xvid_enc_create.num_plugins].func = xvid_ff_2pass;
00266 plugins[xvid_enc_create.num_plugins].param = &rc2pass1;
00267 xvid_enc_create.num_plugins++;
00268 } else if( xvid_flags & CODEC_FLAG_PASS2 ) {
00269 memset(&rc2pass2, 0, sizeof(xvid_plugin_2pass2_t));
00270 rc2pass2.version = XVID_VERSION;
00271 rc2pass2.bitrate = avctx->bit_rate;
00272
00273 fd = ff_tempfile("xvidff.", &(x->twopassfile));
00274 if( fd == -1 ) {
00275 av_log(avctx, AV_LOG_ERROR,
00276 "Xvid: Cannot write 2-pass pipe\n");
00277 return -1;
00278 }
00279
00280 if( avctx->stats_in == NULL ) {
00281 av_log(avctx, AV_LOG_ERROR,
00282 "Xvid: No 2-pass information loaded for second pass\n");
00283 return -1;
00284 }
00285
00286 if( strlen(avctx->stats_in) >
00287 write(fd, avctx->stats_in, strlen(avctx->stats_in)) ) {
00288 close(fd);
00289 av_log(avctx, AV_LOG_ERROR,
00290 "Xvid: Cannot write to 2-pass pipe\n");
00291 return -1;
00292 }
00293
00294 close(fd);
00295 rc2pass2.filename = x->twopassfile;
00296 plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2;
00297 plugins[xvid_enc_create.num_plugins].param = &rc2pass2;
00298 xvid_enc_create.num_plugins++;
00299 } else if( !(xvid_flags & CODEC_FLAG_QSCALE) ) {
00300
00301 memset(&single, 0, sizeof(xvid_plugin_single_t));
00302 single.version = XVID_VERSION;
00303 single.bitrate = avctx->bit_rate;
00304
00305 plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single;
00306 plugins[xvid_enc_create.num_plugins].param = &single;
00307 xvid_enc_create.num_plugins++;
00308 }
00309
00310
00311 if( 0.0 != avctx->lumi_masking ) {
00312 plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking;
00313 plugins[xvid_enc_create.num_plugins].param = NULL;
00314 xvid_enc_create.num_plugins++;
00315 }
00316
00317
00318 xvid_correct_framerate(avctx);
00319 xvid_enc_create.fincr = avctx->time_base.num;
00320 xvid_enc_create.fbase = avctx->time_base.den;
00321 if( avctx->gop_size > 0 )
00322 xvid_enc_create.max_key_interval = avctx->gop_size;
00323 else
00324 xvid_enc_create.max_key_interval = 240;
00325
00326
00327 if( xvid_flags & CODEC_FLAG_QSCALE ) x->qscale = 1;
00328 else x->qscale = 0;
00329
00330 xvid_enc_create.min_quant[0] = avctx->qmin;
00331 xvid_enc_create.min_quant[1] = avctx->qmin;
00332 xvid_enc_create.min_quant[2] = avctx->qmin;
00333 xvid_enc_create.max_quant[0] = avctx->qmax;
00334 xvid_enc_create.max_quant[1] = avctx->qmax;
00335 xvid_enc_create.max_quant[2] = avctx->qmax;
00336
00337
00338 x->intra_matrix = x->inter_matrix = NULL;
00339 if( avctx->mpeg_quant )
00340 x->vol_flags |= XVID_VOL_MPEGQUANT;
00341 if( (avctx->intra_matrix || avctx->inter_matrix) ) {
00342 x->vol_flags |= XVID_VOL_MPEGQUANT;
00343
00344 if( avctx->intra_matrix ) {
00345 intra = avctx->intra_matrix;
00346 x->intra_matrix = av_malloc(sizeof(unsigned char) * 64);
00347 } else
00348 intra = NULL;
00349 if( avctx->inter_matrix ) {
00350 inter = avctx->inter_matrix;
00351 x->inter_matrix = av_malloc(sizeof(unsigned char) * 64);
00352 } else
00353 inter = NULL;
00354
00355 for( i = 0; i < 64; i++ ) {
00356 if( intra )
00357 x->intra_matrix[i] = (unsigned char)intra[i];
00358 if( inter )
00359 x->inter_matrix[i] = (unsigned char)inter[i];
00360 }
00361 }
00362
00363
00364 xvid_enc_create.frame_drop_ratio = 0;
00365 xvid_enc_create.global = 0;
00366 if( xvid_flags & CODEC_FLAG_CLOSED_GOP )
00367 xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP;
00368
00369
00370 avctx->extradata = NULL;
00371 avctx->extradata_size = 0;
00372 if( xvid_flags & CODEC_FLAG_GLOBAL_HEADER ) {
00373
00374 x->quicktime_format = 1;
00375 avctx->codec_id = CODEC_ID_MPEG4;
00376 } else {
00377
00378 x->quicktime_format = 0;
00379 if(!avctx->codec_tag)
00380 avctx->codec_tag = AV_RL32("xvid");
00381 }
00382
00383
00384 xvid_enc_create.max_bframes = avctx->max_b_frames;
00385 xvid_enc_create.bquant_offset = 100 * avctx->b_quant_offset;
00386 xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor;
00387 if( avctx->max_b_frames > 0 && !x->quicktime_format ) xvid_enc_create.global |= XVID_GLOBAL_PACKED;
00388
00389
00390 xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
00391 if( xerr ) {
00392 av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n");
00393 return -1;
00394 }
00395
00396 x->encoder_handle = xvid_enc_create.handle;
00397 avctx->coded_frame = &x->encoded_picture;
00398
00399 return 0;
00400 }
00401
00411 static int xvid_encode_frame(AVCodecContext *avctx,
00412 unsigned char *frame, int buf_size, void *data) {
00413 int xerr, i;
00414 char *tmp;
00415 struct xvid_context *x = avctx->priv_data;
00416 AVFrame *picture = data;
00417 AVFrame *p = &(x->encoded_picture);
00418
00419 xvid_enc_frame_t xvid_enc_frame;
00420 xvid_enc_stats_t xvid_enc_stats;
00421
00422
00423 memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame));
00424 xvid_enc_frame.version = XVID_VERSION;
00425 memset(&xvid_enc_stats, 0, sizeof(xvid_enc_stats));
00426 xvid_enc_stats.version = XVID_VERSION;
00427 *p = *picture;
00428
00429
00430 xvid_enc_frame.bitstream = frame;
00431 xvid_enc_frame.length = buf_size;
00432
00433
00434 if( avctx->pix_fmt != PIX_FMT_YUV420P ) {
00435 av_log(avctx, AV_LOG_ERROR, "Xvid: Color spaces other than 420p not supported\n");
00436 return -1;
00437 }
00438
00439 xvid_enc_frame.input.csp = XVID_CSP_PLANAR;
00440
00441 for( i = 0; i < 4; i++ ) {
00442 xvid_enc_frame.input.plane[i] = picture->data[i];
00443 xvid_enc_frame.input.stride[i] = picture->linesize[i];
00444 }
00445
00446
00447 xvid_enc_frame.vop_flags = x->vop_flags;
00448 xvid_enc_frame.vol_flags = x->vol_flags;
00449 xvid_enc_frame.motion = x->me_flags;
00450 xvid_enc_frame.type =
00451 picture->pict_type == AV_PICTURE_TYPE_I ? XVID_TYPE_IVOP :
00452 picture->pict_type == AV_PICTURE_TYPE_P ? XVID_TYPE_PVOP :
00453 picture->pict_type == AV_PICTURE_TYPE_B ? XVID_TYPE_BVOP :
00454 XVID_TYPE_AUTO;
00455
00456
00457 if (avctx->sample_aspect_ratio.num < 0 || avctx->sample_aspect_ratio.num > 255 ||
00458 avctx->sample_aspect_ratio.den < 0 || avctx->sample_aspect_ratio.den > 255) {
00459 av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i\n",
00460 avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den);
00461 return -1;
00462 }
00463 xvid_enc_frame.par = XVID_PAR_EXT;
00464 xvid_enc_frame.par_width = avctx->sample_aspect_ratio.num;
00465 xvid_enc_frame.par_height = avctx->sample_aspect_ratio.den;
00466
00467
00468 if( x->qscale ) xvid_enc_frame.quant = picture->quality / FF_QP2LAMBDA;
00469 else xvid_enc_frame.quant = 0;
00470
00471
00472 xvid_enc_frame.quant_intra_matrix = x->intra_matrix;
00473 xvid_enc_frame.quant_inter_matrix = x->inter_matrix;
00474
00475
00476 xerr = xvid_encore(x->encoder_handle, XVID_ENC_ENCODE,
00477 &xvid_enc_frame, &xvid_enc_stats);
00478
00479
00480 avctx->stats_out = NULL;
00481 if( x->twopassbuffer ) {
00482 tmp = x->old_twopassbuffer;
00483 x->old_twopassbuffer = x->twopassbuffer;
00484 x->twopassbuffer = tmp;
00485 x->twopassbuffer[0] = 0;
00486 if( x->old_twopassbuffer[0] != 0 ) {
00487 avctx->stats_out = x->old_twopassbuffer;
00488 }
00489 }
00490
00491 if( 0 <= xerr ) {
00492 p->quality = xvid_enc_stats.quant * FF_QP2LAMBDA;
00493 if( xvid_enc_stats.type == XVID_TYPE_PVOP )
00494 p->pict_type = AV_PICTURE_TYPE_P;
00495 else if( xvid_enc_stats.type == XVID_TYPE_BVOP )
00496 p->pict_type = AV_PICTURE_TYPE_B;
00497 else if( xvid_enc_stats.type == XVID_TYPE_SVOP )
00498 p->pict_type = AV_PICTURE_TYPE_S;
00499 else
00500 p->pict_type = AV_PICTURE_TYPE_I;
00501 if( xvid_enc_frame.out_flags & XVID_KEYFRAME ) {
00502 p->key_frame = 1;
00503 if( x->quicktime_format )
00504 return xvid_strip_vol_header(avctx, frame,
00505 xvid_enc_stats.hlength, xerr);
00506 } else
00507 p->key_frame = 0;
00508
00509 return xerr;
00510 } else {
00511 av_log(avctx, AV_LOG_ERROR, "Xvid: Encoding Error Occurred: %i\n", xerr);
00512 return -1;
00513 }
00514 }
00515
00523 static av_cold int xvid_encode_close(AVCodecContext *avctx) {
00524 struct xvid_context *x = avctx->priv_data;
00525
00526 xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL);
00527
00528 av_freep(&avctx->extradata);
00529 if( x->twopassbuffer != NULL ) {
00530 av_free(x->twopassbuffer);
00531 av_free(x->old_twopassbuffer);
00532 avctx->stats_out = NULL;
00533 }
00534 av_free(x->twopassfile);
00535 av_free(x->intra_matrix);
00536 av_free(x->inter_matrix);
00537
00538 return 0;
00539 }
00540
00554 int xvid_strip_vol_header(AVCodecContext *avctx,
00555 unsigned char *frame,
00556 unsigned int header_len,
00557 unsigned int frame_len) {
00558 int vo_len = 0, i;
00559
00560 for( i = 0; i < header_len - 3; i++ ) {
00561 if( frame[i] == 0x00 &&
00562 frame[i+1] == 0x00 &&
00563 frame[i+2] == 0x01 &&
00564 frame[i+3] == 0xB6 ) {
00565 vo_len = i;
00566 break;
00567 }
00568 }
00569
00570 if( vo_len > 0 ) {
00571
00572 if( avctx->extradata == NULL ) {
00573 avctx->extradata = av_malloc(vo_len);
00574 memcpy(avctx->extradata, frame, vo_len);
00575 avctx->extradata_size = vo_len;
00576 }
00577
00578
00579 memmove(frame, &(frame[vo_len]), frame_len - vo_len);
00580 return frame_len - vo_len;
00581 } else
00582 return frame_len;
00583 }
00584
00594 void xvid_correct_framerate(AVCodecContext *avctx) {
00595 int frate, fbase;
00596 int est_frate, est_fbase;
00597 int gcd;
00598 float est_fps, fps;
00599
00600 frate = avctx->time_base.den;
00601 fbase = avctx->time_base.num;
00602
00603 gcd = av_gcd(frate, fbase);
00604 if( gcd > 1 ) {
00605 frate /= gcd;
00606 fbase /= gcd;
00607 }
00608
00609 if( frate <= 65000 && fbase <= 65000 ) {
00610 avctx->time_base.den = frate;
00611 avctx->time_base.num = fbase;
00612 return;
00613 }
00614
00615 fps = (float)frate / (float)fbase;
00616 est_fps = roundf(fps * 1000.0) / 1000.0;
00617
00618 est_frate = (int)est_fps;
00619 if( est_fps > (int)est_fps ) {
00620 est_frate = (est_frate + 1) * 1000;
00621 est_fbase = (int)roundf((float)est_frate / est_fps);
00622 } else
00623 est_fbase = 1;
00624
00625 gcd = av_gcd(est_frate, est_fbase);
00626 if( gcd > 1 ) {
00627 est_frate /= gcd;
00628 est_fbase /= gcd;
00629 }
00630
00631 if( fbase > est_fbase ) {
00632 avctx->time_base.den = est_frate;
00633 avctx->time_base.num = est_fbase;
00634 av_log(avctx, AV_LOG_DEBUG,
00635 "Xvid: framerate re-estimated: %.2f, %.3f%% correction\n",
00636 est_fps, (((est_fps - fps)/fps) * 100.0));
00637 } else {
00638 avctx->time_base.den = frate;
00639 avctx->time_base.num = fbase;
00640 }
00641 }
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00660 static int xvid_ff_2pass_create(xvid_plg_create_t * param,
00661 void ** handle) {
00662 struct xvid_ff_pass1 *x = (struct xvid_ff_pass1 *)param->param;
00663 char *log = x->context->twopassbuffer;
00664
00665
00666 if( log == NULL )
00667 return XVID_ERR_FAIL;
00668
00669
00670
00671 log[0] = 0;
00672 snprintf(log, BUFFER_REMAINING(log),
00673 "# ffmpeg 2-pass log file, using xvid codec\n");
00674 snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
00675 "# Do not modify. libxvidcore version: %d.%d.%d\n\n",
00676 XVID_VERSION_MAJOR(XVID_VERSION),
00677 XVID_VERSION_MINOR(XVID_VERSION),
00678 XVID_VERSION_PATCH(XVID_VERSION));
00679
00680 *handle = x->context;
00681 return 0;
00682 }
00683
00691 static int xvid_ff_2pass_destroy(struct xvid_context *ref,
00692 xvid_plg_destroy_t *param) {
00693
00694
00695 if( ref->twopassbuffer != NULL )
00696 ref->twopassbuffer[0] = 0;
00697 return 0;
00698 }
00699
00707 static int xvid_ff_2pass_before(struct xvid_context *ref,
00708 xvid_plg_data_t *param) {
00709 int motion_remove;
00710 int motion_replacements;
00711 int vop_remove;
00712
00713
00714 if( param->zone && param->zone->mode == XVID_ZONE_QUANT )
00715 return 0;
00716
00717
00718 param->quant = 2;
00719
00720
00721 motion_remove = ~XVID_ME_CHROMA_PVOP &
00722 ~XVID_ME_CHROMA_BVOP &
00723 ~XVID_ME_EXTSEARCH16 &
00724 ~XVID_ME_ADVANCEDDIAMOND16;
00725 motion_replacements = XVID_ME_FAST_MODEINTERPOLATE |
00726 XVID_ME_SKIP_DELTASEARCH |
00727 XVID_ME_FASTREFINE16 |
00728 XVID_ME_BFRAME_EARLYSTOP;
00729 vop_remove = ~XVID_VOP_MODEDECISION_RD &
00730 ~XVID_VOP_FAST_MODEDECISION_RD &
00731 ~XVID_VOP_TRELLISQUANT &
00732 ~XVID_VOP_INTER4V &
00733 ~XVID_VOP_HQACPRED;
00734
00735 param->vol_flags &= ~XVID_VOL_GMC;
00736 param->vop_flags &= vop_remove;
00737 param->motion_flags &= motion_remove;
00738 param->motion_flags |= motion_replacements;
00739
00740 return 0;
00741 }
00742
00750 static int xvid_ff_2pass_after(struct xvid_context *ref,
00751 xvid_plg_data_t *param) {
00752 char *log = ref->twopassbuffer;
00753 char *frame_types = " ipbs";
00754 char frame_type;
00755
00756
00757 if( log == NULL )
00758 return XVID_ERR_FAIL;
00759
00760
00761 if( param->type < 5 && param->type > 0 ) {
00762 frame_type = frame_types[param->type];
00763 } else {
00764 return XVID_ERR_FAIL;
00765 }
00766
00767 snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
00768 "%c %d %d %d %d %d %d\n",
00769 frame_type, param->stats.quant, param->stats.kblks, param->stats.mblks,
00770 param->stats.ublks, param->stats.length, param->stats.hlength);
00771
00772 return 0;
00773 }
00774
00786 int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2) {
00787 switch( cmd ) {
00788 case XVID_PLG_INFO:
00789 case XVID_PLG_FRAME:
00790 return 0;
00791
00792 case XVID_PLG_BEFORE:
00793 return xvid_ff_2pass_before(ref, p1);
00794
00795 case XVID_PLG_CREATE:
00796 return xvid_ff_2pass_create(p1, p2);
00797
00798 case XVID_PLG_AFTER:
00799 return xvid_ff_2pass_after(ref, p1);
00800
00801 case XVID_PLG_DESTROY:
00802 return xvid_ff_2pass_destroy(ref, p1);
00803
00804 default:
00805 return XVID_ERR_FAIL;
00806 }
00807 }
00808
00812 AVCodec ff_libxvid_encoder = {
00813 "libxvid",
00814 AVMEDIA_TYPE_VIDEO,
00815 CODEC_ID_MPEG4,
00816 sizeof(struct xvid_context),
00817 xvid_encode_init,
00818 xvid_encode_frame,
00819 xvid_encode_close,
00820 .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
00821 .long_name= NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"),
00822 };
00823
00824 #endif