• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

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 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/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 ffmpeg 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 ffmpeg 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 < 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     /* 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         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         /* We need to store the header, so extract it */
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         /* Less dangerous now, memmove properly copies the two
00578            chunks of overlapping data */
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  * Xvid 2-Pass Kludge Section
00645  *
00646  * Xvid's default 2-pass doesn't allow us to create data as we need to, so
00647  * this section spends time replacing the first pass plugin so we can write
00648  * statistic information as libavcodec requests in. We have another kludge
00649  * that allows us to pass data to the second pass in Xvid without a custom
00650  * rate-control plugin.
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     /* Do a quick bounds check */
00666     if( log == NULL )
00667         return XVID_ERR_FAIL;
00668 
00669     /* We use snprintf() */
00670     /* This is because we can safely prevent a buffer overflow */
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     /* Currently cannot think of anything to do on destruction */
00694     /* Still, the framework should be here for reference/use */
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     /* Nothing to do here, result is changed too much */
00714     if( param->zone && param->zone->mode == XVID_ZONE_QUANT )
00715         return 0;
00716 
00717     /* We can implement a 'turbo' first pass mode here */
00718     param->quant = 2;
00719 
00720     /* Init values */
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     /* Quick bounds check */
00757     if( log == NULL )
00758         return XVID_ERR_FAIL;
00759 
00760     /* Convert the type given to us into a character */
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 /* CONFIG_LIBXVID_ENCODER */

Generated on Wed Apr 11 2012 07:31:33 for FFmpeg by  doxygen 1.7.1