libavcodec/libxvidff.c
Go to the documentation of this file.
00001 /*
00002  * Interface to xvidcore for mpeg4 encoding
00003  * Copyright (c) 2004 Adam Thayer <krevnik@comcast.net>
00004  *
00005  * This file is part of Libav.
00006  *
00007  * Libav 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  * Libav 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 Libav; 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/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 /* Prototypes - See function implementation for details */
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 /* Wrapper to work around the lack of mkstemp() on mingw.
00081  * Also, tries to create file in /tmp first, if possible.
00082  * *prefix can be a character constant; *filename will be allocated internally.
00083  * @return file descriptor of opened file (or -1 on error)
00084  * and opened file name in **filename. */
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; /* room for "/tmp/" and "XXXXXX\0" */
00091     *filename = av_malloc(len);
00092 #endif
00093     /* -----common section-----*/
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     /* -----common section-----*/
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; /* success */
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     /* Bring in VOP flags from avconv command-line */
00141     x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */
00142     if( xvid_flags & CODEC_FLAG_4MV )
00143         x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */
00144     if( avctx->trellis
00145         )
00146         x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */
00147     if( xvid_flags & CODEC_FLAG_AC_PRED )
00148         x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 */
00149     if( xvid_flags & CODEC_FLAG_GRAY )
00150         x->vop_flags |= XVID_VOP_GREYSCALE;
00151 
00152     /* Decide which ME quality setting to use */
00153     x->me_flags = 0;
00154     switch( avctx->me_method ) {
00155        case ME_FULL:   /* Quality 6 */
00156            x->me_flags |=  XVID_ME_EXTSEARCH16
00157                        |   XVID_ME_EXTSEARCH8;
00158 
00159        case ME_EPZS:   /* Quality 4 */
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:    /* Quality 2 */
00166        case ME_PHODS:
00167        case ME_X1:
00168            x->me_flags |=  XVID_ME_ADVANCEDDIAMOND16
00169                        |   XVID_ME_HALFPELREFINE16;
00170 
00171        case ME_ZERO:   /* Quality 0 */
00172        default:
00173            break;
00174     }
00175 
00176     /* Decide how we should decide blocks */
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     /* Bring in VOL flags from avconv command-line */
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     /* Xvid's PPC support is borked, use libavcodec to detect */
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     /* Xvid can detect on x86 */
00221     xvid_gbl_init.cpu_flags = 0;
00222 #endif
00223 
00224     /* Initialize */
00225     xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);
00226 
00227     /* Create the encoder reference */
00228     memset(&xvid_enc_create, 0, sizeof(xvid_enc_create));
00229     xvid_enc_create.version = XVID_VERSION;
00230 
00231     /* Store the desired frame size */
00232     xvid_enc_create.width = x->xsize = avctx->width;
00233     xvid_enc_create.height = x->ysize = avctx->height;
00234 
00235     /* Xvid can determine the proper profile to use */
00236     /* xvid_enc_create.profile = XVID_PROFILE_S_L3; */
00237 
00238     /* We don't use zones */
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     /* Initialize Buffers */
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         /* Single Pass Bitrate Control! */
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     /* Luminance Masking */
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     /* Frame Rate and Key Frames */
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; /* Xvid's best default */
00325 
00326     /* Quants */
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     /* Quant Matrices */
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     /* Misc Settings */
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     /* Determines which codec mode we are operating in */
00370     avctx->extradata = NULL;
00371     avctx->extradata_size = 0;
00372     if( xvid_flags & CODEC_FLAG_GLOBAL_HEADER ) {
00373         /* In this case, we are claiming to be MPEG4 */
00374         x->quicktime_format = 1;
00375         avctx->codec_id = CODEC_ID_MPEG4;
00376     } else {
00377         /* We are claiming to be Xvid */
00378         x->quicktime_format = 0;
00379         if(!avctx->codec_tag)
00380             avctx->codec_tag = AV_RL32("xvid");
00381     }
00382 
00383     /* Bframes */
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     /* Create encoder context */
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     /* Start setting up the frame */
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     /* Let Xvid know where to put the frame. */
00430     xvid_enc_frame.bitstream = frame;
00431     xvid_enc_frame.length = buf_size;
00432 
00433     /* Initialize input image fields */
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; /* YUV420P */
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     /* Encoder Flags */
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     /* Pixel aspect ratio setting */
00457     if (avctx->sample_aspect_ratio.num < 1 || avctx->sample_aspect_ratio.num > 255 ||
00458         avctx->sample_aspect_ratio.den < 1 || 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     /* Quant Setting */
00468     if( x->qscale ) xvid_enc_frame.quant = picture->quality / FF_QP2LAMBDA;
00469     else xvid_enc_frame.quant = 0;
00470 
00471     /* Matrices */
00472     xvid_enc_frame.quant_intra_matrix = x->intra_matrix;
00473     xvid_enc_frame.quant_inter_matrix = x->inter_matrix;
00474 
00475     /* Encode */
00476     xerr = xvid_encore(x->encoder_handle, XVID_ENC_ENCODE,
00477         &xvid_enc_frame, &xvid_enc_stats);
00478 
00479     /* Two-pass log buffer swapping */
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     }
00533     av_free(x->twopassfile);
00534     av_free(x->intra_matrix);
00535     av_free(x->inter_matrix);
00536 
00537     return 0;
00538 }
00539 
00553 int xvid_strip_vol_header(AVCodecContext *avctx,
00554                   unsigned char *frame,
00555                   unsigned int header_len,
00556                   unsigned int frame_len) {
00557     int vo_len = 0, i;
00558 
00559     for( i = 0; i < header_len - 3; i++ ) {
00560         if( frame[i] == 0x00 &&
00561             frame[i+1] == 0x00 &&
00562             frame[i+2] == 0x01 &&
00563             frame[i+3] == 0xB6 ) {
00564             vo_len = i;
00565             break;
00566         }
00567     }
00568 
00569     if( vo_len > 0 ) {
00570         /* We need to store the header, so extract it */
00571         if( avctx->extradata == NULL ) {
00572             avctx->extradata = av_malloc(vo_len);
00573             memcpy(avctx->extradata, frame, vo_len);
00574             avctx->extradata_size = vo_len;
00575         }
00576         /* Less dangerous now, memmove properly copies the two
00577            chunks of overlapping data */
00578         memmove(frame, &frame[vo_len], frame_len - vo_len);
00579         return frame_len - vo_len;
00580     } else
00581         return frame_len;
00582 }
00583 
00593 void xvid_correct_framerate(AVCodecContext *avctx) {
00594     int frate, fbase;
00595     int est_frate, est_fbase;
00596     int gcd;
00597     float est_fps, fps;
00598 
00599     frate = avctx->time_base.den;
00600     fbase = avctx->time_base.num;
00601 
00602     gcd = av_gcd(frate, fbase);
00603     if( gcd > 1 ) {
00604         frate /= gcd;
00605         fbase /= gcd;
00606     }
00607 
00608     if( frate <= 65000 && fbase <= 65000 ) {
00609         avctx->time_base.den = frate;
00610         avctx->time_base.num = fbase;
00611         return;
00612     }
00613 
00614     fps = (float)frate / (float)fbase;
00615     est_fps = roundf(fps * 1000.0) / 1000.0;
00616 
00617     est_frate = (int)est_fps;
00618     if( est_fps > (int)est_fps ) {
00619         est_frate = (est_frate + 1) * 1000;
00620         est_fbase = (int)roundf((float)est_frate / est_fps);
00621     } else
00622         est_fbase = 1;
00623 
00624     gcd = av_gcd(est_frate, est_fbase);
00625     if( gcd > 1 ) {
00626         est_frate /= gcd;
00627         est_fbase /= gcd;
00628     }
00629 
00630     if( fbase > est_fbase ) {
00631         avctx->time_base.den = est_frate;
00632         avctx->time_base.num = est_fbase;
00633         av_log(avctx, AV_LOG_DEBUG,
00634             "Xvid: framerate re-estimated: %.2f, %.3f%% correction\n",
00635             est_fps, (((est_fps - fps)/fps) * 100.0));
00636     } else {
00637         avctx->time_base.den = frate;
00638         avctx->time_base.num = fbase;
00639     }
00640 }
00641 
00642 /*
00643  * Xvid 2-Pass Kludge Section
00644  *
00645  * Xvid's default 2-pass doesn't allow us to create data as we need to, so
00646  * this section spends time replacing the first pass plugin so we can write
00647  * statistic information as libavcodec requests in. We have another kludge
00648  * that allows us to pass data to the second pass in Xvid without a custom
00649  * rate-control plugin.
00650  */
00651 
00659 static int xvid_ff_2pass_create(xvid_plg_create_t * param,
00660                                 void ** handle) {
00661     struct xvid_ff_pass1 *x = (struct xvid_ff_pass1 *)param->param;
00662     char *log = x->context->twopassbuffer;
00663 
00664     /* Do a quick bounds check */
00665     if( log == NULL )
00666         return XVID_ERR_FAIL;
00667 
00668     /* We use snprintf() */
00669     /* This is because we can safely prevent a buffer overflow */
00670     log[0] = 0;
00671     snprintf(log, BUFFER_REMAINING(log),
00672         "# avconv 2-pass log file, using xvid codec\n");
00673     snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
00674         "# Do not modify. libxvidcore version: %d.%d.%d\n\n",
00675         XVID_VERSION_MAJOR(XVID_VERSION),
00676         XVID_VERSION_MINOR(XVID_VERSION),
00677         XVID_VERSION_PATCH(XVID_VERSION));
00678 
00679     *handle = x->context;
00680     return 0;
00681 }
00682 
00690 static int xvid_ff_2pass_destroy(struct xvid_context *ref,
00691                                 xvid_plg_destroy_t *param) {
00692     /* Currently cannot think of anything to do on destruction */
00693     /* Still, the framework should be here for reference/use */
00694     if( ref->twopassbuffer != NULL )
00695         ref->twopassbuffer[0] = 0;
00696     return 0;
00697 }
00698 
00706 static int xvid_ff_2pass_before(struct xvid_context *ref,
00707                                 xvid_plg_data_t *param) {
00708     int motion_remove;
00709     int motion_replacements;
00710     int vop_remove;
00711 
00712     /* Nothing to do here, result is changed too much */
00713     if( param->zone && param->zone->mode == XVID_ZONE_QUANT )
00714         return 0;
00715 
00716     /* We can implement a 'turbo' first pass mode here */
00717     param->quant = 2;
00718 
00719     /* Init values */
00720     motion_remove = ~XVID_ME_CHROMA_PVOP &
00721                     ~XVID_ME_CHROMA_BVOP &
00722                     ~XVID_ME_EXTSEARCH16 &
00723                     ~XVID_ME_ADVANCEDDIAMOND16;
00724     motion_replacements = XVID_ME_FAST_MODEINTERPOLATE |
00725                           XVID_ME_SKIP_DELTASEARCH |
00726                           XVID_ME_FASTREFINE16 |
00727                           XVID_ME_BFRAME_EARLYSTOP;
00728     vop_remove = ~XVID_VOP_MODEDECISION_RD &
00729                  ~XVID_VOP_FAST_MODEDECISION_RD &
00730                  ~XVID_VOP_TRELLISQUANT &
00731                  ~XVID_VOP_INTER4V &
00732                  ~XVID_VOP_HQACPRED;
00733 
00734     param->vol_flags &= ~XVID_VOL_GMC;
00735     param->vop_flags &= vop_remove;
00736     param->motion_flags &= motion_remove;
00737     param->motion_flags |= motion_replacements;
00738 
00739     return 0;
00740 }
00741 
00749 static int xvid_ff_2pass_after(struct xvid_context *ref,
00750                                 xvid_plg_data_t *param) {
00751     char *log = ref->twopassbuffer;
00752     const char *frame_types = " ipbs";
00753     char frame_type;
00754 
00755     /* Quick bounds check */
00756     if( log == NULL )
00757         return XVID_ERR_FAIL;
00758 
00759     /* Convert the type given to us into a character */
00760     if( param->type < 5 && param->type > 0 ) {
00761         frame_type = frame_types[param->type];
00762     } else {
00763         return XVID_ERR_FAIL;
00764     }
00765 
00766     snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
00767         "%c %d %d %d %d %d %d\n",
00768         frame_type, param->stats.quant, param->stats.kblks, param->stats.mblks,
00769         param->stats.ublks, param->stats.length, param->stats.hlength);
00770 
00771     return 0;
00772 }
00773 
00785 int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2) {
00786     switch( cmd ) {
00787         case XVID_PLG_INFO:
00788         case XVID_PLG_FRAME:
00789             return 0;
00790 
00791         case XVID_PLG_BEFORE:
00792             return xvid_ff_2pass_before(ref, p1);
00793 
00794         case XVID_PLG_CREATE:
00795             return xvid_ff_2pass_create(p1, p2);
00796 
00797         case XVID_PLG_AFTER:
00798             return xvid_ff_2pass_after(ref, p1);
00799 
00800         case XVID_PLG_DESTROY:
00801             return xvid_ff_2pass_destroy(ref, p1);
00802 
00803         default:
00804             return XVID_ERR_FAIL;
00805     }
00806 }
00807 
00811 AVCodec ff_libxvid_encoder = {
00812     .name           = "libxvid",
00813     .type           = AVMEDIA_TYPE_VIDEO,
00814     .id             = CODEC_ID_MPEG4,
00815     .priv_data_size = sizeof(struct xvid_context),
00816     .init           = xvid_encode_init,
00817     .encode         = xvid_encode_frame,
00818     .close          = xvid_encode_close,
00819     .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
00820     .long_name= NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"),
00821 };
00822 
00823 #endif /* CONFIG_LIBXVID_ENCODER */