Libav
|
00001 /* 00002 * Interface to xvidcore for mpeg4 encoding 00003 * Copyright (c) 2004 Adam Thayer <krevnik@comcast.net> 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00028 #include <xvid.h> 00029 #include <unistd.h> 00030 #include "avcodec.h" 00031 #include "libavutil/intreadwrite.h" 00032 #include "libxvid_internal.h" 00033 00037 #define BUFFER_SIZE 1024 00038 #define BUFFER_REMAINING(x) (BUFFER_SIZE - strlen(x)) 00039 #define BUFFER_CAT(x) (&((x)[strlen(x)])) 00040 00041 /* For PPC Use */ 00042 int has_altivec(void); 00043 00048 struct xvid_context { 00049 void *encoder_handle; 00050 int xsize, ysize; 00051 int vop_flags; 00052 int vol_flags; 00053 int me_flags; 00054 int qscale; 00055 int quicktime_format; 00056 AVFrame encoded_picture; 00057 char *twopassbuffer; 00058 char *old_twopassbuffer; 00059 char *twopassfile; 00060 unsigned char *intra_matrix; 00061 unsigned char *inter_matrix; 00062 }; 00063 00067 struct xvid_ff_pass1 { 00068 int version; 00069 struct xvid_context *context; 00070 }; 00071 00072 /* Prototypes - See function implementation for details */ 00073 int xvid_strip_vol_header(AVCodecContext *avctx, unsigned char *frame, unsigned int header_len, unsigned int frame_len); 00074 int xvid_ff_2pass(void *ref, int opt, void *p1, void *p2); 00075 void xvid_correct_framerate(AVCodecContext *avctx); 00076 00085 static av_cold int xvid_encode_init(AVCodecContext *avctx) { 00086 int xerr, i; 00087 int xvid_flags = avctx->flags; 00088 struct xvid_context *x = avctx->priv_data; 00089 uint16_t *intra, *inter; 00090 int fd; 00091 00092 xvid_plugin_single_t single; 00093 struct xvid_ff_pass1 rc2pass1; 00094 xvid_plugin_2pass2_t rc2pass2; 00095 xvid_gbl_init_t xvid_gbl_init; 00096 xvid_enc_create_t xvid_enc_create; 00097 xvid_enc_plugin_t plugins[7]; 00098 00099 /* Bring in VOP flags from ffmpeg command-line */ 00100 x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */ 00101 if( xvid_flags & CODEC_FLAG_4MV ) 00102 x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */ 00103 if( avctx->trellis 00104 ) 00105 x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */ 00106 if( xvid_flags & CODEC_FLAG_AC_PRED ) 00107 x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 */ 00108 if( xvid_flags & CODEC_FLAG_GRAY ) 00109 x->vop_flags |= XVID_VOP_GREYSCALE; 00110 00111 /* Decide which ME quality setting to use */ 00112 x->me_flags = 0; 00113 switch( avctx->me_method ) { 00114 case ME_FULL: /* Quality 6 */ 00115 x->me_flags |= XVID_ME_EXTSEARCH16 00116 | XVID_ME_EXTSEARCH8; 00117 00118 case ME_EPZS: /* Quality 4 */ 00119 x->me_flags |= XVID_ME_ADVANCEDDIAMOND8 00120 | XVID_ME_HALFPELREFINE8 00121 | XVID_ME_CHROMA_PVOP 00122 | XVID_ME_CHROMA_BVOP; 00123 00124 case ME_LOG: /* Quality 2 */ 00125 case ME_PHODS: 00126 case ME_X1: 00127 x->me_flags |= XVID_ME_ADVANCEDDIAMOND16 00128 | XVID_ME_HALFPELREFINE16; 00129 00130 case ME_ZERO: /* Quality 0 */ 00131 default: 00132 break; 00133 } 00134 00135 /* Decide how we should decide blocks */ 00136 switch( avctx->mb_decision ) { 00137 case 2: 00138 x->vop_flags |= XVID_VOP_MODEDECISION_RD; 00139 x->me_flags |= XVID_ME_HALFPELREFINE8_RD 00140 | XVID_ME_QUARTERPELREFINE8_RD 00141 | XVID_ME_EXTSEARCH_RD 00142 | XVID_ME_CHECKPREDICTION_RD; 00143 case 1: 00144 if( !(x->vop_flags & XVID_VOP_MODEDECISION_RD) ) 00145 x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD; 00146 x->me_flags |= XVID_ME_HALFPELREFINE16_RD 00147 | XVID_ME_QUARTERPELREFINE16_RD; 00148 00149 default: 00150 break; 00151 } 00152 00153 /* Bring in VOL flags from ffmpeg command-line */ 00154 x->vol_flags = 0; 00155 if( xvid_flags & CODEC_FLAG_GMC ) { 00156 x->vol_flags |= XVID_VOL_GMC; 00157 x->me_flags |= XVID_ME_GME_REFINE; 00158 } 00159 if( xvid_flags & CODEC_FLAG_QPEL ) { 00160 x->vol_flags |= XVID_VOL_QUARTERPEL; 00161 x->me_flags |= XVID_ME_QUARTERPELREFINE16; 00162 if( x->vop_flags & XVID_VOP_INTER4V ) 00163 x->me_flags |= XVID_ME_QUARTERPELREFINE8; 00164 } 00165 00166 memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init)); 00167 xvid_gbl_init.version = XVID_VERSION; 00168 xvid_gbl_init.debug = 0; 00169 00170 #if ARCH_PPC 00171 /* Xvid's PPC support is borked, use libavcodec to detect */ 00172 #if HAVE_ALTIVEC 00173 if( has_altivec() ) { 00174 xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC; 00175 } else 00176 #endif 00177 xvid_gbl_init.cpu_flags = XVID_CPU_FORCE; 00178 #else 00179 /* Xvid can detect on x86 */ 00180 xvid_gbl_init.cpu_flags = 0; 00181 #endif 00182 00183 /* Initialize */ 00184 xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL); 00185 00186 /* Create the encoder reference */ 00187 memset(&xvid_enc_create, 0, sizeof(xvid_enc_create)); 00188 xvid_enc_create.version = XVID_VERSION; 00189 00190 /* Store the desired frame size */ 00191 xvid_enc_create.width = x->xsize = avctx->width; 00192 xvid_enc_create.height = x->ysize = avctx->height; 00193 00194 /* Xvid can determine the proper profile to use */ 00195 /* xvid_enc_create.profile = XVID_PROFILE_S_L3; */ 00196 00197 /* We don't use zones */ 00198 xvid_enc_create.zones = NULL; 00199 xvid_enc_create.num_zones = 0; 00200 00201 xvid_enc_create.num_threads = avctx->thread_count; 00202 00203 xvid_enc_create.plugins = plugins; 00204 xvid_enc_create.num_plugins = 0; 00205 00206 /* Initialize Buffers */ 00207 x->twopassbuffer = NULL; 00208 x->old_twopassbuffer = NULL; 00209 x->twopassfile = NULL; 00210 00211 if( xvid_flags & CODEC_FLAG_PASS1 ) { 00212 memset(&rc2pass1, 0, sizeof(struct xvid_ff_pass1)); 00213 rc2pass1.version = XVID_VERSION; 00214 rc2pass1.context = x; 00215 x->twopassbuffer = av_malloc(BUFFER_SIZE); 00216 x->old_twopassbuffer = av_malloc(BUFFER_SIZE); 00217 if( x->twopassbuffer == NULL || x->old_twopassbuffer == NULL ) { 00218 av_log(avctx, AV_LOG_ERROR, 00219 "Xvid: Cannot allocate 2-pass log buffers\n"); 00220 return -1; 00221 } 00222 x->twopassbuffer[0] = x->old_twopassbuffer[0] = 0; 00223 00224 plugins[xvid_enc_create.num_plugins].func = xvid_ff_2pass; 00225 plugins[xvid_enc_create.num_plugins].param = &rc2pass1; 00226 xvid_enc_create.num_plugins++; 00227 } else if( xvid_flags & CODEC_FLAG_PASS2 ) { 00228 memset(&rc2pass2, 0, sizeof(xvid_plugin_2pass2_t)); 00229 rc2pass2.version = XVID_VERSION; 00230 rc2pass2.bitrate = avctx->bit_rate; 00231 00232 fd = av_tempfile("xvidff.", &(x->twopassfile)); 00233 if( fd == -1 ) { 00234 av_log(avctx, AV_LOG_ERROR, 00235 "Xvid: Cannot write 2-pass pipe\n"); 00236 return -1; 00237 } 00238 00239 if( avctx->stats_in == NULL ) { 00240 av_log(avctx, AV_LOG_ERROR, 00241 "Xvid: No 2-pass information loaded for second pass\n"); 00242 return -1; 00243 } 00244 00245 if( strlen(avctx->stats_in) > 00246 write(fd, avctx->stats_in, strlen(avctx->stats_in)) ) { 00247 close(fd); 00248 av_log(avctx, AV_LOG_ERROR, 00249 "Xvid: Cannot write to 2-pass pipe\n"); 00250 return -1; 00251 } 00252 00253 close(fd); 00254 rc2pass2.filename = x->twopassfile; 00255 plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2; 00256 plugins[xvid_enc_create.num_plugins].param = &rc2pass2; 00257 xvid_enc_create.num_plugins++; 00258 } else if( !(xvid_flags & CODEC_FLAG_QSCALE) ) { 00259 /* Single Pass Bitrate Control! */ 00260 memset(&single, 0, sizeof(xvid_plugin_single_t)); 00261 single.version = XVID_VERSION; 00262 single.bitrate = avctx->bit_rate; 00263 00264 plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single; 00265 plugins[xvid_enc_create.num_plugins].param = &single; 00266 xvid_enc_create.num_plugins++; 00267 } 00268 00269 /* Luminance Masking */ 00270 if( 0.0 != avctx->lumi_masking ) { 00271 plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking; 00272 plugins[xvid_enc_create.num_plugins].param = NULL; 00273 xvid_enc_create.num_plugins++; 00274 } 00275 00276 /* Frame Rate and Key Frames */ 00277 xvid_correct_framerate(avctx); 00278 xvid_enc_create.fincr = avctx->time_base.num; 00279 xvid_enc_create.fbase = avctx->time_base.den; 00280 if( avctx->gop_size > 0 ) 00281 xvid_enc_create.max_key_interval = avctx->gop_size; 00282 else 00283 xvid_enc_create.max_key_interval = 240; /* Xvid's best default */ 00284 00285 /* Quants */ 00286 if( xvid_flags & CODEC_FLAG_QSCALE ) x->qscale = 1; 00287 else x->qscale = 0; 00288 00289 xvid_enc_create.min_quant[0] = avctx->qmin; 00290 xvid_enc_create.min_quant[1] = avctx->qmin; 00291 xvid_enc_create.min_quant[2] = avctx->qmin; 00292 xvid_enc_create.max_quant[0] = avctx->qmax; 00293 xvid_enc_create.max_quant[1] = avctx->qmax; 00294 xvid_enc_create.max_quant[2] = avctx->qmax; 00295 00296 /* Quant Matrices */ 00297 x->intra_matrix = x->inter_matrix = NULL; 00298 if( avctx->mpeg_quant ) 00299 x->vol_flags |= XVID_VOL_MPEGQUANT; 00300 if( (avctx->intra_matrix || avctx->inter_matrix) ) { 00301 x->vol_flags |= XVID_VOL_MPEGQUANT; 00302 00303 if( avctx->intra_matrix ) { 00304 intra = avctx->intra_matrix; 00305 x->intra_matrix = av_malloc(sizeof(unsigned char) * 64); 00306 } else 00307 intra = NULL; 00308 if( avctx->inter_matrix ) { 00309 inter = avctx->inter_matrix; 00310 x->inter_matrix = av_malloc(sizeof(unsigned char) * 64); 00311 } else 00312 inter = NULL; 00313 00314 for( i = 0; i < 64; i++ ) { 00315 if( intra ) 00316 x->intra_matrix[i] = (unsigned char)intra[i]; 00317 if( inter ) 00318 x->inter_matrix[i] = (unsigned char)inter[i]; 00319 } 00320 } 00321 00322 /* Misc Settings */ 00323 xvid_enc_create.frame_drop_ratio = 0; 00324 xvid_enc_create.global = 0; 00325 if( xvid_flags & CODEC_FLAG_CLOSED_GOP ) 00326 xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP; 00327 00328 /* Determines which codec mode we are operating in */ 00329 avctx->extradata = NULL; 00330 avctx->extradata_size = 0; 00331 if( xvid_flags & CODEC_FLAG_GLOBAL_HEADER ) { 00332 /* In this case, we are claiming to be MPEG4 */ 00333 x->quicktime_format = 1; 00334 avctx->codec_id = CODEC_ID_MPEG4; 00335 } else { 00336 /* We are claiming to be Xvid */ 00337 x->quicktime_format = 0; 00338 if(!avctx->codec_tag) 00339 avctx->codec_tag = AV_RL32("xvid"); 00340 } 00341 00342 /* Bframes */ 00343 xvid_enc_create.max_bframes = avctx->max_b_frames; 00344 xvid_enc_create.bquant_offset = 100 * avctx->b_quant_offset; 00345 xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor; 00346 if( avctx->max_b_frames > 0 && !x->quicktime_format ) xvid_enc_create.global |= XVID_GLOBAL_PACKED; 00347 00348 /* Create encoder context */ 00349 xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); 00350 if( xerr ) { 00351 av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n"); 00352 return -1; 00353 } 00354 00355 x->encoder_handle = xvid_enc_create.handle; 00356 avctx->coded_frame = &x->encoded_picture; 00357 00358 return 0; 00359 } 00360 00370 static int xvid_encode_frame(AVCodecContext *avctx, 00371 unsigned char *frame, int buf_size, void *data) { 00372 int xerr, i; 00373 char *tmp; 00374 struct xvid_context *x = avctx->priv_data; 00375 AVFrame *picture = data; 00376 AVFrame *p = &(x->encoded_picture); 00377 00378 xvid_enc_frame_t xvid_enc_frame; 00379 xvid_enc_stats_t xvid_enc_stats; 00380 00381 /* Start setting up the frame */ 00382 memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame)); 00383 xvid_enc_frame.version = XVID_VERSION; 00384 memset(&xvid_enc_stats, 0, sizeof(xvid_enc_stats)); 00385 xvid_enc_stats.version = XVID_VERSION; 00386 *p = *picture; 00387 00388 /* Let Xvid know where to put the frame. */ 00389 xvid_enc_frame.bitstream = frame; 00390 xvid_enc_frame.length = buf_size; 00391 00392 /* Initialize input image fields */ 00393 if( avctx->pix_fmt != PIX_FMT_YUV420P ) { 00394 av_log(avctx, AV_LOG_ERROR, "Xvid: Color spaces other than 420p not supported\n"); 00395 return -1; 00396 } 00397 00398 xvid_enc_frame.input.csp = XVID_CSP_PLANAR; /* YUV420P */ 00399 00400 for( i = 0; i < 4; i++ ) { 00401 xvid_enc_frame.input.plane[i] = picture->data[i]; 00402 xvid_enc_frame.input.stride[i] = picture->linesize[i]; 00403 } 00404 00405 /* Encoder Flags */ 00406 xvid_enc_frame.vop_flags = x->vop_flags; 00407 xvid_enc_frame.vol_flags = x->vol_flags; 00408 xvid_enc_frame.motion = x->me_flags; 00409 xvid_enc_frame.type = XVID_TYPE_AUTO; 00410 00411 /* Pixel aspect ratio setting */ 00412 if (avctx->sample_aspect_ratio.num < 1 || avctx->sample_aspect_ratio.num > 255 || 00413 avctx->sample_aspect_ratio.den < 1 || avctx->sample_aspect_ratio.den > 255) { 00414 av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i\n", 00415 avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den); 00416 return -1; 00417 } 00418 xvid_enc_frame.par = XVID_PAR_EXT; 00419 xvid_enc_frame.par_width = avctx->sample_aspect_ratio.num; 00420 xvid_enc_frame.par_height = avctx->sample_aspect_ratio.den; 00421 00422 /* Quant Setting */ 00423 if( x->qscale ) xvid_enc_frame.quant = picture->quality / FF_QP2LAMBDA; 00424 else xvid_enc_frame.quant = 0; 00425 00426 /* Matrices */ 00427 xvid_enc_frame.quant_intra_matrix = x->intra_matrix; 00428 xvid_enc_frame.quant_inter_matrix = x->inter_matrix; 00429 00430 /* Encode */ 00431 xerr = xvid_encore(x->encoder_handle, XVID_ENC_ENCODE, 00432 &xvid_enc_frame, &xvid_enc_stats); 00433 00434 /* Two-pass log buffer swapping */ 00435 avctx->stats_out = NULL; 00436 if( x->twopassbuffer ) { 00437 tmp = x->old_twopassbuffer; 00438 x->old_twopassbuffer = x->twopassbuffer; 00439 x->twopassbuffer = tmp; 00440 x->twopassbuffer[0] = 0; 00441 if( x->old_twopassbuffer[0] != 0 ) { 00442 avctx->stats_out = x->old_twopassbuffer; 00443 } 00444 } 00445 00446 if( 0 <= xerr ) { 00447 p->quality = xvid_enc_stats.quant * FF_QP2LAMBDA; 00448 if( xvid_enc_stats.type == XVID_TYPE_PVOP ) 00449 p->pict_type = FF_P_TYPE; 00450 else if( xvid_enc_stats.type == XVID_TYPE_BVOP ) 00451 p->pict_type = FF_B_TYPE; 00452 else if( xvid_enc_stats.type == XVID_TYPE_SVOP ) 00453 p->pict_type = FF_S_TYPE; 00454 else 00455 p->pict_type = FF_I_TYPE; 00456 if( xvid_enc_frame.out_flags & XVID_KEYFRAME ) { 00457 p->key_frame = 1; 00458 if( x->quicktime_format ) 00459 return xvid_strip_vol_header(avctx, frame, 00460 xvid_enc_stats.hlength, xerr); 00461 } else 00462 p->key_frame = 0; 00463 00464 return xerr; 00465 } else { 00466 av_log(avctx, AV_LOG_ERROR, "Xvid: Encoding Error Occurred: %i\n", xerr); 00467 return -1; 00468 } 00469 } 00470 00478 static av_cold int xvid_encode_close(AVCodecContext *avctx) { 00479 struct xvid_context *x = avctx->priv_data; 00480 00481 xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); 00482 00483 if( avctx->extradata != NULL ) 00484 av_freep(&avctx->extradata); 00485 if( x->twopassbuffer != NULL ) { 00486 av_free(x->twopassbuffer); 00487 av_free(x->old_twopassbuffer); 00488 } 00489 if( x->twopassfile != NULL ) 00490 av_free(x->twopassfile); 00491 if( x->intra_matrix != NULL ) 00492 av_free(x->intra_matrix); 00493 if( x->inter_matrix != NULL ) 00494 av_free(x->inter_matrix); 00495 00496 return 0; 00497 } 00498 00512 int xvid_strip_vol_header(AVCodecContext *avctx, 00513 unsigned char *frame, 00514 unsigned int header_len, 00515 unsigned int frame_len) { 00516 int vo_len = 0, i; 00517 00518 for( i = 0; i < header_len - 3; i++ ) { 00519 if( frame[i] == 0x00 && 00520 frame[i+1] == 0x00 && 00521 frame[i+2] == 0x01 && 00522 frame[i+3] == 0xB6 ) { 00523 vo_len = i; 00524 break; 00525 } 00526 } 00527 00528 if( vo_len > 0 ) { 00529 /* We need to store the header, so extract it */ 00530 if( avctx->extradata == NULL ) { 00531 avctx->extradata = av_malloc(vo_len); 00532 memcpy(avctx->extradata, frame, vo_len); 00533 avctx->extradata_size = vo_len; 00534 } 00535 /* Less dangerous now, memmove properly copies the two 00536 chunks of overlapping data */ 00537 memmove(frame, &(frame[vo_len]), frame_len - vo_len); 00538 return frame_len - vo_len; 00539 } else 00540 return frame_len; 00541 } 00542 00552 void xvid_correct_framerate(AVCodecContext *avctx) { 00553 int frate, fbase; 00554 int est_frate, est_fbase; 00555 int gcd; 00556 float est_fps, fps; 00557 00558 frate = avctx->time_base.den; 00559 fbase = avctx->time_base.num; 00560 00561 gcd = av_gcd(frate, fbase); 00562 if( gcd > 1 ) { 00563 frate /= gcd; 00564 fbase /= gcd; 00565 } 00566 00567 if( frate <= 65000 && fbase <= 65000 ) { 00568 avctx->time_base.den = frate; 00569 avctx->time_base.num = fbase; 00570 return; 00571 } 00572 00573 fps = (float)frate / (float)fbase; 00574 est_fps = roundf(fps * 1000.0) / 1000.0; 00575 00576 est_frate = (int)est_fps; 00577 if( est_fps > (int)est_fps ) { 00578 est_frate = (est_frate + 1) * 1000; 00579 est_fbase = (int)roundf((float)est_frate / est_fps); 00580 } else 00581 est_fbase = 1; 00582 00583 gcd = av_gcd(est_frate, est_fbase); 00584 if( gcd > 1 ) { 00585 est_frate /= gcd; 00586 est_fbase /= gcd; 00587 } 00588 00589 if( fbase > est_fbase ) { 00590 avctx->time_base.den = est_frate; 00591 avctx->time_base.num = est_fbase; 00592 av_log(avctx, AV_LOG_DEBUG, 00593 "Xvid: framerate re-estimated: %.2f, %.3f%% correction\n", 00594 est_fps, (((est_fps - fps)/fps) * 100.0)); 00595 } else { 00596 avctx->time_base.den = frate; 00597 avctx->time_base.num = fbase; 00598 } 00599 } 00600 00601 /* 00602 * Xvid 2-Pass Kludge Section 00603 * 00604 * Xvid's default 2-pass doesn't allow us to create data as we need to, so 00605 * this section spends time replacing the first pass plugin so we can write 00606 * statistic information as libavcodec requests in. We have another kludge 00607 * that allows us to pass data to the second pass in Xvid without a custom 00608 * rate-control plugin. 00609 */ 00610 00618 static int xvid_ff_2pass_create(xvid_plg_create_t * param, 00619 void ** handle) { 00620 struct xvid_ff_pass1 *x = (struct xvid_ff_pass1 *)param->param; 00621 char *log = x->context->twopassbuffer; 00622 00623 /* Do a quick bounds check */ 00624 if( log == NULL ) 00625 return XVID_ERR_FAIL; 00626 00627 /* We use snprintf() */ 00628 /* This is because we can safely prevent a buffer overflow */ 00629 log[0] = 0; 00630 snprintf(log, BUFFER_REMAINING(log), 00631 "# ffmpeg 2-pass log file, using xvid codec\n"); 00632 snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log), 00633 "# Do not modify. libxvidcore version: %d.%d.%d\n\n", 00634 XVID_VERSION_MAJOR(XVID_VERSION), 00635 XVID_VERSION_MINOR(XVID_VERSION), 00636 XVID_VERSION_PATCH(XVID_VERSION)); 00637 00638 *handle = x->context; 00639 return 0; 00640 } 00641 00649 static int xvid_ff_2pass_destroy(struct xvid_context *ref, 00650 xvid_plg_destroy_t *param) { 00651 /* Currently cannot think of anything to do on destruction */ 00652 /* Still, the framework should be here for reference/use */ 00653 if( ref->twopassbuffer != NULL ) 00654 ref->twopassbuffer[0] = 0; 00655 return 0; 00656 } 00657 00665 static int xvid_ff_2pass_before(struct xvid_context *ref, 00666 xvid_plg_data_t *param) { 00667 int motion_remove; 00668 int motion_replacements; 00669 int vop_remove; 00670 00671 /* Nothing to do here, result is changed too much */ 00672 if( param->zone && param->zone->mode == XVID_ZONE_QUANT ) 00673 return 0; 00674 00675 /* We can implement a 'turbo' first pass mode here */ 00676 param->quant = 2; 00677 00678 /* Init values */ 00679 motion_remove = ~XVID_ME_CHROMA_PVOP & 00680 ~XVID_ME_CHROMA_BVOP & 00681 ~XVID_ME_EXTSEARCH16 & 00682 ~XVID_ME_ADVANCEDDIAMOND16; 00683 motion_replacements = XVID_ME_FAST_MODEINTERPOLATE | 00684 XVID_ME_SKIP_DELTASEARCH | 00685 XVID_ME_FASTREFINE16 | 00686 XVID_ME_BFRAME_EARLYSTOP; 00687 vop_remove = ~XVID_VOP_MODEDECISION_RD & 00688 ~XVID_VOP_FAST_MODEDECISION_RD & 00689 ~XVID_VOP_TRELLISQUANT & 00690 ~XVID_VOP_INTER4V & 00691 ~XVID_VOP_HQACPRED; 00692 00693 param->vol_flags &= ~XVID_VOL_GMC; 00694 param->vop_flags &= vop_remove; 00695 param->motion_flags &= motion_remove; 00696 param->motion_flags |= motion_replacements; 00697 00698 return 0; 00699 } 00700 00708 static int xvid_ff_2pass_after(struct xvid_context *ref, 00709 xvid_plg_data_t *param) { 00710 char *log = ref->twopassbuffer; 00711 char *frame_types = " ipbs"; 00712 char frame_type; 00713 00714 /* Quick bounds check */ 00715 if( log == NULL ) 00716 return XVID_ERR_FAIL; 00717 00718 /* Convert the type given to us into a character */ 00719 if( param->type < 5 && param->type > 0 ) { 00720 frame_type = frame_types[param->type]; 00721 } else { 00722 return XVID_ERR_FAIL; 00723 } 00724 00725 snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log), 00726 "%c %d %d %d %d %d %d\n", 00727 frame_type, param->stats.quant, param->stats.kblks, param->stats.mblks, 00728 param->stats.ublks, param->stats.length, param->stats.hlength); 00729 00730 return 0; 00731 } 00732 00744 int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2) { 00745 switch( cmd ) { 00746 case XVID_PLG_INFO: 00747 case XVID_PLG_FRAME: 00748 return 0; 00749 00750 case XVID_PLG_BEFORE: 00751 return xvid_ff_2pass_before(ref, p1); 00752 00753 case XVID_PLG_CREATE: 00754 return xvid_ff_2pass_create(p1, p2); 00755 00756 case XVID_PLG_AFTER: 00757 return xvid_ff_2pass_after(ref, p1); 00758 00759 case XVID_PLG_DESTROY: 00760 return xvid_ff_2pass_destroy(ref, p1); 00761 00762 default: 00763 return XVID_ERR_FAIL; 00764 } 00765 } 00766 00770 AVCodec libxvid_encoder = { 00771 "libxvid", 00772 AVMEDIA_TYPE_VIDEO, 00773 CODEC_ID_MPEG4, 00774 sizeof(struct xvid_context), 00775 xvid_encode_init, 00776 xvid_encode_frame, 00777 xvid_encode_close, 00778 .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, 00779 .long_name= NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"), 00780 };