xvidff.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:26k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * Interface to xvidcore for mpeg4 encoding
  3.  * Copyright (c) 2004 Adam Thayer <krevnik@comcast.net>
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19.  
  20. /**
  21.  * @file xvidmpeg4.c
  22.  * Interface to xvidcore for MPEG-4 compliant encoding.
  23.  * @author Adam Thayer (krevnik@comcast.net)
  24.  */
  25.  
  26. #include <xvid.h>
  27. #include <unistd.h>
  28. #include "common.h"
  29. #include "avcodec.h"
  30. #ifdef CONFIG_WIN32
  31. #include <fcntl.h>
  32. #endif
  33. /**
  34.  * Buffer management macros.
  35.  */
  36. #define BUFFER_SIZE                 1024
  37. #define BUFFER_REMAINING(x)         (BUFFER_SIZE - strlen(x))
  38. #define BUFFER_CAT(x)               (&((x)[strlen(x)]))
  39. /* For PPC Use */
  40. #if HAVE_ALTIVEC==1
  41. extern int has_altivec(void);
  42. #endif
  43. /**
  44.  * Structure for the private XviD context.
  45.  * This stores all the private context for the codec.
  46.  */
  47. typedef struct xvid_context {
  48.     void *encoder_handle;          /** Handle for XviD Encoder */
  49.     int xsize, ysize;              /** Frame size */
  50.     int vop_flags;                 /** VOP flags for XviD Encoder */
  51.     int vol_flags;                 /** VOL flags for XviD Encoder */
  52.     int me_flags;                  /** Motion Estimation flags */
  53.     int qscale;                    /** Do we use constant scale? */
  54.     int quicktime_format;          /** Are we in a QT-based format? */
  55.     AVFrame encoded_picture;       /** Encoded frame information */
  56.     char *twopassbuffer;           /** Character buffer for two-pass */
  57.     char *old_twopassbuffer;       /** Old character buffer (two-pass) */
  58.     char *twopassfile;             /** second pass temp file name */
  59.     unsigned char *intra_matrix;   /** P-Frame Quant Matrix */
  60.     unsigned char *inter_matrix;   /** I-Frame Quant Matrix */
  61. } xvid_context_t;
  62.  
  63. /**
  64.  * Structure for the private first-pass plugin.
  65.  */
  66. typedef struct xvid_ff_pass1 {
  67.     int     version;                /** XviD version */
  68.     xvid_context_t *context;        /** Pointer to private context */
  69. } xvid_ff_pass1_t;
  70. /* Prototypes - See function implementation for details */
  71. int xvid_strip_vol_header(AVCodecContext *avctx, unsigned char *frame, unsigned int header_len, unsigned int frame_len);
  72. int xvid_ff_2pass(void *ref, int opt, void *p1, void *p2);
  73. void xvid_correct_framerate(AVCodecContext *avctx); 
  74.  
  75. /** 
  76.  * Creates the private context for the encoder.
  77.  * All buffers are allocated, settings are loaded from the user,
  78.  * and the encoder context created.
  79.  *
  80.  * @param avctx AVCodecContext pointer to context
  81.  * @return Returns 0 on success, -1 on failure
  82.  */ 
  83. int ff_xvid_encode_init(AVCodecContext *avctx)  {
  84.     int xerr, i;
  85.     int xvid_flags = avctx->flags;
  86.     xvid_context_t *x = avctx->priv_data;
  87.     uint16_t *intra, *inter;
  88.     int fd;
  89.     
  90.     xvid_plugin_single_t single;
  91.     xvid_ff_pass1_t rc2pass1;
  92.     xvid_plugin_2pass2_t rc2pass2;
  93.     xvid_gbl_init_t xvid_gbl_init;
  94.     xvid_enc_create_t xvid_enc_create;
  95.     xvid_enc_plugin_t plugins[7];
  96.     /* Bring in VOP flags from ffmpeg command-line */
  97.     x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */
  98.     if( xvid_flags & CODEC_FLAG_4MV ) 
  99.         x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */
  100.     if( xvid_flags & CODEC_FLAG_TRELLIS_QUANT) 
  101.         x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */
  102.     if( xvid_flags & CODEC_FLAG_AC_PRED ) 
  103.         x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 */
  104.     if( xvid_flags & CODEC_FLAG_GRAY )
  105.         x->vop_flags |= XVID_VOP_GREYSCALE;
  106.     
  107.     /* Decide which ME quality setting to use */
  108.     x->me_flags = 0;
  109.     switch( avctx->me_method ) {
  110.        case ME_FULL:   /* Quality 6 */
  111.            x->me_flags |=  XVID_ME_EXTSEARCH16
  112.                        |   XVID_ME_EXTSEARCH8;
  113.                        
  114.        case ME_EPZS:   /* Quality 4 */
  115.            x->me_flags |=  XVID_ME_ADVANCEDDIAMOND8
  116.                        |   XVID_ME_HALFPELREFINE8
  117.                        |   XVID_ME_CHROMA_PVOP
  118.                        |   XVID_ME_CHROMA_BVOP;
  119.            
  120.        case ME_LOG:    /* Quality 2 */
  121.        case ME_PHODS:
  122.        case ME_X1:
  123.            x->me_flags |=  XVID_ME_ADVANCEDDIAMOND16
  124.                        |   XVID_ME_HALFPELREFINE16;
  125.        
  126.        case ME_ZERO:   /* Quality 0 */
  127.        default:
  128.            break;
  129.     }
  130.     
  131.     /* Decide how we should decide blocks */
  132.     switch( avctx->mb_decision ) {
  133.        case 2:
  134.            x->vop_flags |= XVID_VOP_MODEDECISION_RD;
  135.            x->me_flags |=  XVID_ME_HALFPELREFINE8_RD
  136.                        |   XVID_ME_QUARTERPELREFINE8_RD
  137.                        |   XVID_ME_EXTSEARCH_RD
  138.                        |   XVID_ME_CHECKPREDICTION_RD;  
  139.        case 1:
  140.            if( !(x->vop_flags & XVID_VOP_MODEDECISION_RD) )
  141.                x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD;
  142.            x->me_flags |=  XVID_ME_HALFPELREFINE16_RD
  143.                        |   XVID_ME_QUARTERPELREFINE16_RD;
  144.            
  145.        default:
  146.            break;
  147.     }
  148.     
  149.     /* Bring in VOL flags from ffmpeg command-line */
  150.     x->vol_flags = 0;
  151.     if( xvid_flags & CODEC_FLAG_GMC ) { 
  152.         x->vol_flags |= XVID_VOL_GMC; 
  153.         x->me_flags |= XVID_ME_GME_REFINE; 
  154.     }
  155.     if( xvid_flags & CODEC_FLAG_QPEL ) { 
  156.         x->vol_flags |= XVID_VOL_QUARTERPEL;
  157.         x->me_flags |= XVID_ME_QUARTERPELREFINE16;
  158.         if( x->vop_flags & XVID_VOP_INTER4V )
  159.             x->me_flags |= XVID_ME_QUARTERPELREFINE8;
  160.     }
  161.     memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init));
  162.     xvid_gbl_init.version = XVID_VERSION;
  163.     xvid_gbl_init.debug = 0;
  164.     
  165. #ifdef ARCH_POWERPC
  166.     /* XviD's PPC support is borked, use libavcodec to detect */
  167. #if HAVE_ALTIVEC==1
  168.     if( has_altivec() ) {
  169.         xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC;
  170.     } else
  171. #endif
  172.         xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;    
  173. #else
  174.     /* XviD can detect on x86 */
  175.     xvid_gbl_init.cpu_flags = 0;
  176. #endif
  177.     
  178.     /* Initialize */
  179.     xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);
  180.     /* Create the encoder reference */
  181.     memset(&xvid_enc_create, 0, sizeof(xvid_enc_create));
  182.     xvid_enc_create.version = XVID_VERSION;
  183.     
  184.     /* Store the desired frame size */
  185.     xvid_enc_create.width = x->xsize = avctx->width;
  186.     xvid_enc_create.height = x->ysize = avctx->height;
  187.     /* XviD can determine the proper profile to use */
  188.     /* xvid_enc_create.profile = XVID_PROFILE_S_L3; */
  189.     
  190.     /* We don't use zones or threads */
  191.     xvid_enc_create.zones = NULL;
  192.     xvid_enc_create.num_zones = 0;
  193.     xvid_enc_create.num_threads = 0;
  194.     
  195.     xvid_enc_create.plugins = plugins;
  196.     xvid_enc_create.num_plugins = 0;
  197.     
  198.     /* Initialize Buffers */
  199.     x->twopassbuffer = NULL;
  200.     x->old_twopassbuffer = NULL;
  201.     x->twopassfile = NULL;
  202.     
  203.     if( xvid_flags & CODEC_FLAG_PASS1 ) {
  204.         memset(&rc2pass1, 0, sizeof(xvid_ff_pass1_t));
  205.         rc2pass1.version = XVID_VERSION;
  206.         rc2pass1.context = x;
  207.         x->twopassbuffer = av_malloc(BUFFER_SIZE);
  208.         x->old_twopassbuffer = av_malloc(BUFFER_SIZE);
  209.         if( x->twopassbuffer == NULL || x->old_twopassbuffer == NULL ) {
  210.             av_log(avctx, AV_LOG_ERROR,
  211.                 "XviD: Cannot allocate 2-pass log buffersn");
  212.             return -1;
  213.         }
  214.         x->twopassbuffer[0] = x->old_twopassbuffer[0] = 0;
  215.         
  216.         plugins[xvid_enc_create.num_plugins].func = xvid_ff_2pass;
  217.         plugins[xvid_enc_create.num_plugins].param = &rc2pass1;
  218.         xvid_enc_create.num_plugins++;
  219.     } else if( xvid_flags & CODEC_FLAG_PASS2 ) {
  220.         memset(&rc2pass2, 0, sizeof(xvid_plugin_2pass2_t));
  221.         rc2pass2.version = XVID_VERSION;
  222.         rc2pass2.bitrate = avctx->bit_rate;
  223.         
  224. #ifdef CONFIG_WIN32 /* Ugly work around */
  225.         {
  226.            char *tempname;
  227.            tempname = tempnam(".", "xvidff");
  228.             fd = -1;
  229.             if( tempname &&
  230.                 (fd = open(tempname, _O_RDWR | _O_BINARY)) != -1 ) {
  231.                 x->twopassfile = av_strdup(tempname);
  232. #undef free
  233.                 free(tempname);
  234. #define free please_use_av_free
  235.                 if( x->twopassfile == NULL ) {
  236.                     av_log(avctx, AV_LOG_ERROR,
  237.                         "XviD: Cannot allocate 2-pass buffern");
  238.                     return -1;
  239.                 }
  240.             }
  241.        }
  242. #else
  243.         x->twopassfile = av_malloc(BUFFER_SIZE);
  244.         if( x->twopassfile == NULL ) {
  245.             av_log(avctx, AV_LOG_ERROR,
  246.                 "XviD: Cannot allocate 2-pass buffern");
  247.             return -1;
  248.         }
  249.         strcpy(x->twopassfile, "/tmp/xvidff.XXXXXX");
  250.         fd = mkstemp(x->twopassfile);
  251.         if(fd < 0){
  252.             strcpy(x->twopassfile, "./xvidff.XXXXXX");
  253.             fd = mkstemp(x->twopassfile);
  254.         }
  255. #endif
  256.         if( fd == -1 ) {
  257.             av_log(avctx, AV_LOG_ERROR,
  258.                 "XviD: Cannot write 2-pass pipen");
  259.             return -1;
  260.         }
  261.         
  262.         if( avctx->stats_in == NULL ) {
  263.             av_log(avctx, AV_LOG_ERROR,
  264.                 "XviD: No 2-pass information loaded for second passn");
  265.             return -1;
  266.         }
  267.         
  268.         if( strlen(avctx->stats_in) > 
  269.               write(fd, avctx->stats_in, strlen(avctx->stats_in)) ) {
  270.             close(fd);
  271.             av_log(avctx, AV_LOG_ERROR,
  272.                 "XviD: Cannot write to 2-pass pipen");
  273.             return -1;
  274.         }
  275.         
  276.         close(fd);
  277.         rc2pass2.filename = x->twopassfile;
  278.         plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2;
  279.         plugins[xvid_enc_create.num_plugins].param = &rc2pass2;
  280.         xvid_enc_create.num_plugins++;
  281.     } else if( !(xvid_flags & CODEC_FLAG_QSCALE) ) {
  282.         /* Single Pass Bitrate Control! */
  283.         memset(&single, 0, sizeof(xvid_plugin_single_t));
  284.         single.version = XVID_VERSION;
  285.         single.bitrate = avctx->bit_rate;
  286.         
  287.         plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single;
  288.         plugins[xvid_enc_create.num_plugins].param = &single;
  289.         xvid_enc_create.num_plugins++;
  290.     }
  291.     /* Luminance Masking */
  292.     if( 0.0 != avctx->lumi_masking ) {
  293.         plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking;
  294.         plugins[xvid_enc_create.num_plugins].param = NULL;
  295.         xvid_enc_create.num_plugins++;
  296.     }
  297.     /* Frame Rate and Key Frames */
  298.     xvid_correct_framerate(avctx);
  299.     xvid_enc_create.fincr = avctx->time_base.num;
  300.     xvid_enc_create.fbase = avctx->time_base.den;
  301.     if( avctx->gop_size > 0 )
  302.         xvid_enc_create.max_key_interval = avctx->gop_size;
  303.     else
  304.         xvid_enc_create.max_key_interval = 240; /* XviD's best default */
  305.     /* Quants */
  306.     if( xvid_flags & CODEC_FLAG_QSCALE ) x->qscale = 1; 
  307.     else x->qscale = 0;
  308.     
  309.     xvid_enc_create.min_quant[0] = avctx->qmin;
  310.     xvid_enc_create.min_quant[1] = avctx->qmin;
  311.     xvid_enc_create.min_quant[2] = avctx->qmin;
  312.     xvid_enc_create.max_quant[0] = avctx->qmax;
  313.     xvid_enc_create.max_quant[1] = avctx->qmax;
  314.     xvid_enc_create.max_quant[2] = avctx->qmax;
  315.     
  316.     /* Quant Matrices */
  317.     x->intra_matrix = x->inter_matrix = NULL;
  318.     if( avctx->mpeg_quant )
  319.        x->vol_flags |= XVID_VOL_MPEGQUANT;
  320.     if( (avctx->intra_matrix || avctx->inter_matrix) ) {
  321.        x->vol_flags |= XVID_VOL_MPEGQUANT;
  322.        
  323.        if( avctx->intra_matrix ) {
  324.            intra = avctx->intra_matrix;
  325.            x->intra_matrix = av_malloc(sizeof(unsigned char) * 64);
  326.        } else 
  327.            intra = NULL;
  328.        if( avctx->inter_matrix ) {
  329.            inter = avctx->inter_matrix;
  330.            x->inter_matrix = av_malloc(sizeof(unsigned char) * 64);
  331.        } else   
  332.            inter = NULL;
  333.            
  334.        for( i = 0; i < 64; i++ ) {
  335.            if( intra )
  336.                x->intra_matrix[i] = (unsigned char)intra[i];
  337.            if( inter )
  338.                x->inter_matrix[i] = (unsigned char)inter[i];
  339.        }
  340.     }
  341.     
  342.     /* Misc Settings */
  343.     xvid_enc_create.frame_drop_ratio = 0;
  344.     xvid_enc_create.global = 0;
  345.     if( xvid_flags & CODEC_FLAG_CLOSED_GOP ) 
  346.         xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP;
  347.     /* Determines which codec mode we are operating in */
  348.     avctx->extradata = NULL;
  349.     avctx->extradata_size = 0;
  350.     if( xvid_flags & CODEC_FLAG_GLOBAL_HEADER ) {
  351.         /* In this case, we are claiming to be MPEG4 */
  352.         x->quicktime_format = 1;
  353.         avctx->codec_id = CODEC_ID_MPEG4;
  354.     } else {
  355.         /* We are claiming to be XviD */
  356.         x->quicktime_format = 0;
  357.         avctx->codec_tag = ff_get_fourcc("xvid");
  358.     }    
  359.     
  360.     /* Bframes */
  361.     xvid_enc_create.max_bframes = avctx->max_b_frames;
  362.     xvid_enc_create.bquant_offset = avctx->b_quant_offset;
  363.     xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor;
  364.     if( avctx->max_b_frames > 0  && !x->quicktime_format ) xvid_enc_create.global |= XVID_GLOBAL_PACKED;
  365.     
  366.     /* Create encoder context */
  367.     xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
  368.     if( xerr ) {
  369.         av_log(avctx, AV_LOG_ERROR, "XviD: Could not create encoder referencen");
  370.         return -1;
  371.     }
  372.     
  373.     x->encoder_handle = xvid_enc_create.handle;
  374.     avctx->coded_frame = &x->encoded_picture;
  375.     return 0;
  376. }
  377. /** 
  378.  * Encodes a single frame.
  379.  *
  380.  * @param avctx AVCodecContext pointer to context
  381.  * @param frame Pointer to encoded frame buffer
  382.  * @param buf_size Size of encoded frame buffer
  383.  * @param data Pointer to AVFrame of unencoded frame
  384.  * @return Returns 0 on success, -1 on failure
  385.  */
  386. int ff_xvid_encode_frame(AVCodecContext *avctx,
  387.                          unsigned char *frame, int buf_size, void *data) {
  388.     int xerr, i;
  389.     char *tmp;
  390.     xvid_context_t *x = avctx->priv_data;
  391.     AVFrame *picture = data;
  392.     AVFrame *p = &(x->encoded_picture);
  393.     
  394.     xvid_enc_frame_t xvid_enc_frame;
  395.     xvid_enc_stats_t xvid_enc_stats;
  396.     
  397.     /* Start setting up the frame */
  398.     memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame));
  399.     xvid_enc_frame.version = XVID_VERSION;
  400.     memset(&xvid_enc_stats, 0, sizeof(xvid_enc_stats));
  401.     xvid_enc_stats.version = XVID_VERSION;
  402.     *p = *picture;    
  403.     /* Let XviD know where to put the frame. */
  404.     xvid_enc_frame.bitstream = frame;
  405.     xvid_enc_frame.length = buf_size;
  406.     
  407.     /* Initialize input image fields */
  408.     if( avctx->pix_fmt != PIX_FMT_YUV420P ) {
  409.         av_log(avctx, AV_LOG_ERROR, "XviD: Color spaces other than 420p not supportedn");
  410.         return -1;
  411.     }
  412.     
  413.     xvid_enc_frame.input.csp = XVID_CSP_PLANAR; /* YUV420P */
  414.     for( i = 0; i < 4; i++ ) {
  415.         xvid_enc_frame.input.plane[i] = picture->data[i];
  416.         xvid_enc_frame.input.stride[i] = picture->linesize[i];
  417.     }
  418.     /* Encoder Flags */
  419.     xvid_enc_frame.vop_flags = x->vop_flags;
  420.     xvid_enc_frame.vol_flags = x->vol_flags;
  421.     xvid_enc_frame.motion = x->me_flags;
  422.     xvid_enc_frame.type = XVID_TYPE_AUTO;
  423.     
  424.     /* Quant Setting */
  425.     if( x->qscale ) xvid_enc_frame.quant = picture->quality / FF_QP2LAMBDA;
  426.     else xvid_enc_frame.quant = 0;
  427.     
  428.     /* Matrices */
  429.     xvid_enc_frame.quant_intra_matrix = x->intra_matrix;
  430.     xvid_enc_frame.quant_inter_matrix = x->inter_matrix;
  431.     /* Encode */
  432.     xerr = xvid_encore(x->encoder_handle, XVID_ENC_ENCODE, 
  433.         &xvid_enc_frame, &xvid_enc_stats);
  434.     /* Two-pass log buffer swapping */
  435.     avctx->stats_out = NULL;
  436.     if( x->twopassbuffer ) {
  437.         tmp = x->old_twopassbuffer;
  438.         x->old_twopassbuffer = x->twopassbuffer;
  439.         x->twopassbuffer = tmp;
  440.         x->twopassbuffer[0] = 0;
  441.         if( x->old_twopassbuffer[0] != 0 ) {
  442.             avctx->stats_out = x->old_twopassbuffer;
  443.         }
  444.     } 
  445.                          
  446.     if( 0 <= xerr ) {
  447.         p->quality = xvid_enc_stats.quant * FF_QP2LAMBDA;
  448.         if( xvid_enc_stats.type == XVID_TYPE_PVOP )
  449.             p->pict_type = FF_P_TYPE;
  450.         else if( xvid_enc_stats.type == XVID_TYPE_BVOP )
  451.             p->pict_type = FF_B_TYPE;
  452.         else if( xvid_enc_stats.type == XVID_TYPE_SVOP )
  453.             p->pict_type = FF_S_TYPE;
  454.         else
  455.             p->pict_type = FF_I_TYPE;
  456.         if( xvid_enc_frame.out_flags & XVID_KEYFRAME ) {
  457.             p->key_frame = 1;
  458.             if( x->quicktime_format )
  459.                 return xvid_strip_vol_header(avctx, frame, 
  460.                     xvid_enc_stats.hlength, xerr);
  461.          } else 
  462.             p->key_frame = 0;
  463.         return xerr;
  464.     } else {
  465.         av_log(avctx, AV_LOG_ERROR, "XviD: Encoding Error Occurred: %in", xerr);
  466.         return -1;
  467.     }
  468. }
  469. /** 
  470.  * Destroys the private context for the encoder.
  471.  * All buffers are freed, and the XviD encoder context is destroyed.
  472.  *
  473.  * @param avctx AVCodecContext pointer to context
  474.  * @return Returns 0, success guaranteed
  475.  */
  476. int ff_xvid_encode_close(AVCodecContext *avctx) {
  477.     xvid_context_t *x = avctx->priv_data;
  478.     
  479.     xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL);
  480.     if( avctx->extradata != NULL )
  481.         av_free(avctx->extradata);
  482.     if( x->twopassbuffer != NULL ) {
  483.         av_free(x->twopassbuffer);
  484.         av_free(x->old_twopassbuffer);
  485.     }
  486.     if( x->twopassfile != NULL )
  487.         av_free(x->twopassfile);
  488.     if( x->intra_matrix != NULL )
  489.         av_free(x->intra_matrix);
  490.     if( x->inter_matrix != NULL )
  491.         av_free(x->inter_matrix);
  492.     return 0;
  493. }
  494. /** 
  495.  * Routine to create a global VO/VOL header for MP4 container.
  496.  * What we do here is extract the header from the XviD bitstream
  497.  * as it is encoded. We also strip the repeated headers from the
  498.  * bitstream when a global header is requested for MPEG-4 ISO
  499.  * compliance.
  500.  *
  501.  * @param avctx AVCodecContext pointer to context
  502.  * @param frame Pointer to encoded frame data
  503.  * @param header_len Length of header to search
  504.  * @param frame_len Length of encoded frame data
  505.  * @return Returns new length of frame data
  506.  */
  507. int xvid_strip_vol_header(AVCodecContext *avctx, 
  508.                   unsigned char *frame, 
  509.                   unsigned int header_len,
  510.                   unsigned int frame_len) {
  511.     int vo_len = 0, i;
  512.     for( i = 0; i < header_len - 3; i++ ) {
  513.         if( frame[i] == 0x00 && 
  514.             frame[i+1] == 0x00 &&
  515.             frame[i+2] == 0x01 &&
  516.             frame[i+3] == 0xB6 ) {
  517.             vo_len = i;
  518.             break;
  519.         } 
  520.     }
  521.     
  522.     if( vo_len > 0 ) {
  523.         /* We need to store the header, so extract it */
  524.         if( avctx->extradata == NULL ) {
  525.             avctx->extradata = av_malloc(vo_len);
  526.             memcpy(avctx->extradata, frame, vo_len);
  527.             avctx->extradata_size = vo_len;
  528.         }
  529.         /* Less dangerous now, memmove properly copies the two
  530.            chunks of overlapping data */
  531.         memmove(frame, &(frame[vo_len]), frame_len - vo_len);
  532.         return frame_len - vo_len;
  533.     } else
  534.         return frame_len;
  535. }
  536. /**
  537.  * Routine to correct a possibly erroneous framerate being fed to us.
  538.  * XviD currently chokes on framerates where the ticks per frame is 
  539.  * extremely large. This function works to correct problems in this area
  540.  * by estimating a new framerate and taking the simpler fraction of 
  541.  * the two presented.
  542.  *
  543.  * @param avctx Context that contains the framerate to correct.
  544.  */
  545. void xvid_correct_framerate(AVCodecContext *avctx) {
  546.     int frate, fbase;
  547.     int est_frate, est_fbase;
  548.     int gcd;
  549.     float est_fps, fps;
  550.     
  551.     frate = avctx->time_base.den;
  552.     fbase = avctx->time_base.num;
  553.     
  554.     gcd = ff_gcd(frate, fbase);
  555.     if( gcd > 1 ) {
  556.         frate /= gcd;
  557.         fbase /= gcd;
  558.     }
  559.     
  560.     if( frate <= 65000 && fbase <= 65000 ) {
  561.         avctx->time_base.den = frate;
  562.         avctx->time_base.num = fbase;
  563.         return;
  564.     }
  565.     
  566.     fps = (float)frate / (float)fbase;
  567.     est_fps = roundf(fps * 1000.0) / 1000.0;
  568.     est_frate = (int)est_fps;
  569.     if( est_fps > (int)est_fps ) {
  570.         est_frate = (est_frate + 1) * 1000;
  571.         est_fbase = (int)roundf((float)est_frate / est_fps);        
  572.     } else
  573.         est_fbase = 1;
  574.     gcd = ff_gcd(est_frate, est_fbase);
  575.     if( gcd > 1 ) {
  576.         est_frate /= gcd;
  577.         est_fbase /= gcd;
  578.     }    
  579.     
  580.     if( fbase > est_fbase ) {
  581.         avctx->time_base.den = est_frate;
  582.         avctx->time_base.num = est_fbase;
  583.         av_log(avctx, AV_LOG_DEBUG, 
  584.             "XviD: framerate re-estimated: %.2f, %.3f%% correctionn",
  585.             est_fps, (((est_fps - fps)/fps) * 100.0));
  586.     } else {
  587.         avctx->time_base.den = frate;
  588.         avctx->time_base.num = fbase;
  589.     }
  590. }
  591. /*
  592.  * XviD 2-Pass Kludge Section
  593.  *
  594.  * XviD's default 2-pass doesn't allow us to create data as we need to, so
  595.  * this section spends time replacing the first pass plugin so we can write
  596.  * statistic information as libavcodec requests in. We have another kludge
  597.  * that allows us to pass data to the second pass in XviD without a custom
  598.  * rate-control plugin.
  599.  */
  600. /**
  601.  * Initializes the two-pass plugin and context.
  602.  *
  603.  * @param param Input construction parameter structure
  604.  * @param handle Private context handle
  605.  * @return Returns XVID_ERR_xxxx on failure, or 0 on success.
  606.  */
  607. static int xvid_ff_2pass_create(xvid_plg_create_t * param,
  608.                                 void ** handle) {
  609.     xvid_ff_pass1_t *x = (xvid_ff_pass1_t *)param->param;
  610.     char *log = x->context->twopassbuffer;
  611.     
  612.     /* Do a quick bounds check */
  613.     if( log == NULL )
  614.         return XVID_ERR_FAIL;
  615.     
  616.     /* We use snprintf() */
  617.     /* This is because we can safely prevent a buffer overflow */
  618.     log[0] = 0;
  619.     snprintf(log, BUFFER_REMAINING(log),
  620.         "# ffmpeg 2-pass log file, using xvid codecn");
  621.     snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
  622.         "# Do not modify. libxvidcore version: %d.%d.%dnn",
  623.         XVID_VERSION_MAJOR(XVID_VERSION),
  624.         XVID_VERSION_MINOR(XVID_VERSION),
  625.         XVID_VERSION_PATCH(XVID_VERSION));
  626.     
  627.     *handle = x->context;
  628.     return 0;                                
  629. }
  630. /**
  631.  * Destroys the two-pass plugin context.
  632.  *
  633.  * @param ref Context pointer for the plugin
  634.  * @param param Destrooy context
  635.  * @return Returns 0, success guaranteed
  636.  */
  637. static int xvid_ff_2pass_destroy(xvid_context_t *ref, 
  638.                                 xvid_plg_destroy_t *param) {
  639.     /* Currently cannot think of anything to do on destruction */
  640.     /* Still, the framework should be here for reference/use */
  641.     if( ref->twopassbuffer != NULL )
  642.         ref->twopassbuffer[0] = 0;
  643.     return 0;
  644. }
  645. /**
  646.  * Enables fast encode mode during the first pass.
  647.  *
  648.  * @param ref Context pointer for the plugin
  649.  * @param param Frame data
  650.  * @return Returns 0, success guaranteed
  651.  */
  652. static int xvid_ff_2pass_before(xvid_context_t *ref,
  653.                                 xvid_plg_data_t *param) {
  654.     int motion_remove;
  655.     int motion_replacements;                            
  656.     int vop_remove;
  657.                  
  658.     /* Nothing to do here, result is changed too much */  
  659.     if( param->zone && param->zone->mode == XVID_ZONE_QUANT )
  660.         return 0;             
  661.     
  662.     /* We can implement a 'turbo' first pass mode here */      
  663.     param->quant = 2;      
  664.     
  665.     /* Init values */
  666.     motion_remove = ~XVID_ME_CHROMA_PVOP &
  667.                     ~XVID_ME_CHROMA_BVOP &
  668.                     ~XVID_ME_EXTSEARCH16 &
  669.                     ~XVID_ME_ADVANCEDDIAMOND16;
  670.     motion_replacements = XVID_ME_FAST_MODEINTERPOLATE |
  671.                           XVID_ME_SKIP_DELTASEARCH |
  672.                           XVID_ME_FASTREFINE16 |
  673.                           XVID_ME_BFRAME_EARLYSTOP;
  674.     vop_remove = ~XVID_VOP_MODEDECISION_RD &
  675.                  ~XVID_VOP_FAST_MODEDECISION_RD &
  676.                  ~XVID_VOP_TRELLISQUANT &
  677.                  ~XVID_VOP_INTER4V &
  678.                  ~XVID_VOP_HQACPRED;
  679.                  
  680.     param->vol_flags &= ~XVID_VOL_GMC;
  681.     param->vop_flags &= vop_remove;
  682.     param->motion_flags &= motion_remove;
  683.     param->motion_flags |= motion_replacements;                      
  684.     
  685.     return 0;                                
  686. }
  687. /**
  688.  * Captures statistic data and writes it during first pass.
  689.  *
  690.  * @param ref Context pointer for the plugin
  691.  * @param param Statistic data
  692.  * @return Returns XVID_ERR_xxxx on failure, or 0 on success
  693.  */
  694. static int xvid_ff_2pass_after(xvid_context_t *ref,
  695.                                 xvid_plg_data_t *param) {
  696.     char *log = ref->twopassbuffer;
  697.     char *frame_types = " ipbs";
  698.     char frame_type;
  699.     
  700.     /* Quick bounds check */
  701.     if( log == NULL )
  702.         return XVID_ERR_FAIL;
  703.     
  704.     /* Convert the type given to us into a character */
  705.     if( param->type < 5 && param->type > 0 ) {
  706.         frame_type = frame_types[param->type];
  707.     } else {
  708.         return XVID_ERR_FAIL;
  709.     }
  710.     
  711.     snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
  712.         "%c %d %d %d %d %d %dn",
  713.         frame_type, param->stats.quant, param->stats.kblks, param->stats.mblks, 
  714.         param->stats.ublks, param->stats.length, param->stats.hlength);
  715.     
  716.     return 0;
  717. }
  718. /**
  719.  * Dispatch function for our custom plugin.
  720.  * This handles the dispatch for the XviD plugin. It passes data
  721.  * on to other functions for actual processing.
  722.  *
  723.  * @param ref Context pointer for the plugin
  724.  * @param cmd The task given for us to complete
  725.  * @param p1 First parameter (varies)
  726.  * @param p2 Second parameter (varies)
  727.  * @return Returns XVID_ERR_xxxx on failure, or 0 on success
  728.  */
  729. int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2) {
  730.     switch( cmd ) {
  731.         case XVID_PLG_INFO:
  732.         case XVID_PLG_FRAME:
  733.             return 0;
  734.         case XVID_PLG_BEFORE:
  735.             return xvid_ff_2pass_before(ref, p1);
  736.             
  737.         case XVID_PLG_CREATE:
  738.             return xvid_ff_2pass_create(p1, p2);
  739.         
  740.         case XVID_PLG_AFTER:
  741.             return xvid_ff_2pass_after(ref, p1);
  742.             
  743.         case XVID_PLG_DESTROY:
  744.             return xvid_ff_2pass_destroy(ref, p1);
  745.                     
  746.         default:
  747.             return XVID_ERR_FAIL;
  748.     }
  749. }
  750. /**
  751.  * XviD codec definition for libavcodec.
  752.  */
  753. AVCodec xvid_encoder = {
  754.     "xvid",
  755.     CODEC_TYPE_VIDEO,
  756.     CODEC_ID_XVID,
  757.     sizeof(xvid_context_t),
  758.     ff_xvid_encode_init,
  759.     ff_xvid_encode_frame,
  760.     ff_xvid_encode_close
  761. };