Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

x264.c

00001 /*****************************************************************************
00002  * x264.c: h264 video encoder
00003  *****************************************************************************
00004  * Copyright (C) 2004 the VideoLAN team
00005  * $Id: x264.c 13388 2005-11-26 00:07:02Z dionoea $
00006  *
00007  * Authors: Laurent Aimar <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <vlc/vlc.h>
00028 #include <vlc/vout.h>
00029 #include <vlc/sout.h>
00030 #include <vlc/decoder.h>
00031 
00032 #include <x264.h>
00033 
00034 #define SOUT_CFG_PREFIX "sout-x264-"
00035 
00036 /*****************************************************************************
00037  * Module descriptor
00038  *****************************************************************************/
00039 static int  Open ( vlc_object_t * );
00040 static void Close( vlc_object_t * );
00041 
00042 #define QP_TEXT N_("Quantizer parameter")
00043 #define QP_LONGTEXT N_( \
00044     "This selects the quantizer to use (1 to 51). Lower values result in " \
00045     "better fidelity, but higher bitrates. 26 is a good default value." )
00046 
00047 #define QPMIN_TEXT N_("Minimum quantizer parameter")
00048 #define QPMIN_LONGTEXT N_( "Minimum quantizer, 15/35 seems to be a useful " \
00049     "range." )
00050 
00051 #define QPMAX_TEXT N_("Maximum quantizer parameter")
00052 #define QPMAX_LONGTEXT N_( "Maximum quantizer parameter." )
00053 
00054 #define CABAC_TEXT N_("Enable CABAC")
00055 #define CABAC_LONGTEXT N_( "Enable CABAC (Context-Adaptive Binary Arithmetic "\
00056     "Coding). Slightly slows down encoding and decoding, but should save " \
00057     "10-15% bitrate." )
00058 
00059 #define LOOPF_TEXT N_("Enable loop filter")
00060 #define LOOPF_LONGTEXT N_( "Use deblocking loop filter (increases quality).")
00061 
00062 #define ANALYSE_TEXT N_("Analyse mode")
00063 #define ANALYSE_LONGTEXT N_( "This selects the analysing mode.")
00064 
00065 #define TOLERANCE_TEXT N_("Bitrate tolerance")
00066 #define TOLERANCE_LONGTEXT N_( "Sets the allowed variance in average " \
00067     "bitrate.")
00068 
00069 #define VBV_MAXRATE_TEXT N_("Maximum local bitrate")
00070 #define VBV_MAXRATE_LONGTEXT N_( "Sets a maximum local bitrate in kbits/s.")
00071 
00072 #define VBV_BUFSIZE_TEXT N_("Averaging period for the maximum local bitrate")
00073 #define VBV_BUFSIZE_LONGTEXT N_( "Sets an averaging period for the maximum " \
00074     "local bitrate, in kbits/s.")
00075 
00076 #define VBV_INIT_TEXT N_("Initial buffer occupancy")
00077 #define VBV_INIT_LONGTEXT N_( "Sets the initial buffer occupancy as a " \
00078     "fraction of the buffer size.")
00079 
00080 #define KEYINT_TEXT N_("Sets maximum interval between IDR-frames")
00081 #define KEYINT_LONGTEXT N_( "Larger values save bits, thus improve quality "\
00082     "for a given bitrate, at the cost of seeking precision." )
00083 
00084 #define KEYINT_MIN_TEXT N_("Sets minimum interval between IDR-frames")
00085 #define KEYINT_MIN_LONGTEXT N_("In H.264, I-Frames do not necessarily bound " \
00086     "a closed GOP because it is allowable for a P-frame to be predicted from "\
00087     "more frames than just the one frame before it (also see frameref). " \
00088     "Therefore, I-frames are not necessarily seekable. " \
00089     "IDR-Frames restrict subsequent P-frames from referring to any frame " \
00090     "prior to the IDR-Frame. \n" \
00091     "If scenecuts appear within this interval, they are still encoded as " \
00092     "I-frames, but do not start a new GOP. Default value is keyint * 0.4." )
00093 
00094 #define BFRAMES_TEXT N_("B frames")
00095 #define BFRAMES_LONGTEXT N_( "Number of consecutive B-Frames between I and " \
00096     "P-frames." )
00097 
00098 #define BPYRAMID_TEXT N_("B pyramid")
00099 #define BPYRAMID_LONGTEXT N_( "Allows B-frames to be used as references for " \
00100     "predicting other frames." )
00101 
00102 #define FRAMEREF_TEXT N_("Number of previous frames used as predictors.")
00103 #define FRAMEREF_LONGTEXT N_( "This is effective in Anime, but seems to " \
00104     "make little difference in live-action source material. Some decoders " \
00105     "are unable to deal with large frameref values." )
00106 
00107 #define SCENE_TEXT N_("Scene-cut detection.")
00108 #define SCENE_LONGTEXT N_( "Controls how aggressively to insert extra " \
00109     "I-frames. With small values of scenecut, the codec often has to force " \
00110     "an I-frame when it would exceed keyint. " \
00111     "Good values of scenecut may find a better location for the I-frame. " \
00112     "Large values use more I-frames than necessary, thus wasting bits. " \
00113     "-1 disables scene-cut detection, so I-frames are be inserted only every "\
00114     "other keyint frames, which probably leads to ugly encoding artifacts." )
00115 
00116 #define SUBPEL_TEXT N_("Sub-pixel refinement quality.")
00117 #define SUBPEL_LONGTEXT N_( "This parameter controls quality versus speed " \
00118     "tradeoffs involved in the motion estimation decision process " \
00119     "(lower = quicker and higher = better quality)." )
00120 
00121 #define ME_TEXT N_("Motion estimation algorithm.")
00122 #define ME_LONGTEXT N_( "Selects the motion estimation algorithm: "\
00123     " dia - diamond (fastest) \n" \
00124     " hex - hexagon (default setting) \n" \
00125     " umh - uneven multi-hexagon (better but slower) \n" \
00126     " esa - exhaustive search (extremely slow, primarily for testing) " )
00127 
00128 #define MERANGE_TEXT N_("Motion estimation search range.")
00129 #define MERANGE_LONGTEXT N_( "Maximum distance to search for motion estimation, "\
00130     "measured from predicted position(s). Default of 16 is good for most footage, "\
00131     "high motion sequences may benefit from settings between 24-32." )
00132 
00133 #define NO_PSNR_TEXT N_("Disable PSNR calculation.")
00134 #define NO_PSNR_LONGTEXT N_( "This has no effect on actual encoding quality, "\
00135     "it just prevents the stats from being calculated (for speed)." )
00136 
00137 #define NO_B_ADAPT_TEXT N_("Disable adaptive B-frames.")
00138 #define NO_B_ADAPT_LONGTEXT N_( "If this is on, the specified number of consequtive B-frames "\
00139     "will always be used, except possibly before an I-frame. " )
00140 
00141 #define B_BIAS_TEXT N_("Bias the choice to use B-frames.")
00142 #define B_BIAS_LONGTEXT N_( "Positive values cause more= B-frames, negative values cause less B-frames. " )
00143 
00144 
00145 #if X264_BUILD >= 23
00146 static char *enc_me_list[] =
00147   { "", "dia", "hex", "umh", "esa" };
00148 static char *enc_me_list_text[] =
00149   { N_("default"), N_("dia"), N_("hex"), N_("umh"), N_("esa") };
00150 #endif
00151 
00152 static char *enc_analyse_list[] =
00153   { "", "all", "normal", "fast", "none" };
00154 static char *enc_analyse_list_text[] =
00155   { N_("default"), N_("all"), N_("slow"), N_("normal"),
00156     N_("fast"), N_("none") };
00157 
00158 vlc_module_begin();
00159     set_description( _("H264 encoder (using x264 library)"));
00160     set_capability( "encoder", 200 );
00161     set_callbacks( Open, Close );
00162     set_category( CAT_INPUT );
00163     set_subcategory( SUBCAT_INPUT_VCODEC );
00164 
00165     add_integer( SOUT_CFG_PREFIX "qp", 0, NULL, QP_TEXT, QP_LONGTEXT,
00166                  VLC_FALSE );
00167         change_integer_range( 0, 51 );
00168     add_integer( SOUT_CFG_PREFIX "qp-min", 10, NULL, QPMIN_TEXT,
00169                  QPMIN_LONGTEXT, VLC_FALSE );
00170         change_integer_range( 0, 51 );
00171     add_integer( SOUT_CFG_PREFIX "qp-max", 51, NULL, QPMAX_TEXT,
00172                  QPMAX_LONGTEXT, VLC_FALSE );
00173         change_integer_range( 0, 51 );
00174 
00175     add_bool( SOUT_CFG_PREFIX "cabac", 1, NULL, CABAC_TEXT, CABAC_LONGTEXT,
00176               VLC_FALSE );
00177 
00178     add_bool( SOUT_CFG_PREFIX "loopfilter", 1, NULL, LOOPF_TEXT,
00179               LOOPF_LONGTEXT, VLC_FALSE );
00180 
00181     add_string( SOUT_CFG_PREFIX "analyse", "", NULL, ANALYSE_TEXT,
00182                 ANALYSE_LONGTEXT, VLC_FALSE );
00183         change_string_list( enc_analyse_list, enc_analyse_list_text, 0 );
00184 
00185     add_float( SOUT_CFG_PREFIX "tolerance", 1.0, NULL, TOLERANCE_TEXT,
00186                TOLERANCE_LONGTEXT, VLC_FALSE );
00187         change_float_range( 0, 100 );
00188 
00189     add_integer( SOUT_CFG_PREFIX "vbv-maxrate", 0, NULL, VBV_MAXRATE_TEXT,
00190                  VBV_MAXRATE_LONGTEXT, VLC_FALSE );
00191 
00192     add_integer( SOUT_CFG_PREFIX "vbv-bufsize", 0, NULL, VBV_BUFSIZE_TEXT,
00193                  VBV_BUFSIZE_LONGTEXT, VLC_FALSE );
00194 
00195     add_float( SOUT_CFG_PREFIX "vbv-init", 0.9, NULL, VBV_INIT_TEXT,
00196                VBV_INIT_LONGTEXT, VLC_FALSE );
00197         change_float_range( 0, 1 );
00198 
00199     add_integer( SOUT_CFG_PREFIX "keyint", 250, NULL, KEYINT_TEXT,
00200                  KEYINT_LONGTEXT, VLC_FALSE );
00201 
00202     add_integer( SOUT_CFG_PREFIX "keyint-min", 0, NULL, KEYINT_MIN_TEXT,
00203                  KEYINT_MIN_LONGTEXT, VLC_FALSE );
00204 
00205     add_integer( SOUT_CFG_PREFIX "bframes", 0, NULL, BFRAMES_TEXT,
00206                  BFRAMES_LONGTEXT, VLC_FALSE );
00207         change_integer_range( 0, 16 );
00208 
00209     add_bool( SOUT_CFG_PREFIX "bpyramid", 0, NULL, BPYRAMID_TEXT,
00210               BPYRAMID_LONGTEXT, VLC_FALSE );
00211 
00212     add_integer( SOUT_CFG_PREFIX "frameref", 1, NULL, FRAMEREF_TEXT,
00213                  FRAMEREF_LONGTEXT, VLC_FALSE );
00214         change_integer_range( 1, 15 );
00215 
00216     add_integer( SOUT_CFG_PREFIX "scenecut", 40, NULL, SCENE_TEXT,
00217                  SCENE_LONGTEXT, VLC_FALSE );
00218         change_integer_range( -1, 100 );
00219 
00220 #if X264_BUILD >= 30
00221     add_integer( SOUT_CFG_PREFIX "subpel", 6, NULL, SUBPEL_TEXT,
00222                  SUBPEL_LONGTEXT, VLC_FALSE );
00223         change_integer_range( 1, 6 );
00224 #else
00225     add_integer( SOUT_CFG_PREFIX "subpel", 5, NULL, SUBPEL_TEXT,
00226                  SUBPEL_LONGTEXT, VLC_FALSE );
00227         change_integer_range( 1, 5 );
00228 #endif
00229 
00230 #if X264_BUILD >= 23
00231 /* r221 */    add_string( SOUT_CFG_PREFIX "me", "hex", NULL, ME_TEXT,
00232                 ME_LONGTEXT, VLC_FALSE );
00233         change_string_list( enc_me_list, enc_me_list_text, 0 );
00234 
00235 /* r221 */    add_integer( SOUT_CFG_PREFIX "merange", 16, NULL, MERANGE_TEXT,
00236                  MERANGE_LONGTEXT, VLC_FALSE );
00237         change_integer_range( 1, 64 );
00238 #endif
00239 
00240 /* r44 */    add_bool( SOUT_CFG_PREFIX "no-psnr", 0, NULL, NO_PSNR_TEXT,
00241               NO_PSNR_LONGTEXT, VLC_FALSE );
00242 
00243 #if X264_BUILD >= 0x0013
00244 /* r137 */    add_bool( SOUT_CFG_PREFIX "no-b-adapt", 0, NULL, NO_B_ADAPT_TEXT,
00245               NO_B_ADAPT_LONGTEXT, VLC_FALSE );
00246 
00247 /* r137 */    add_integer( SOUT_CFG_PREFIX "b-bias", 0, NULL, B_BIAS_TEXT,
00248                  B_BIAS_LONGTEXT, VLC_FALSE );
00249         change_integer_range( -100, 100 );
00250 #endif
00251 
00252 
00253 vlc_module_end();
00254 
00255 /*****************************************************************************
00256  * Local prototypes
00257  *****************************************************************************/
00258 static const char *ppsz_sout_options[] = {
00259     "qp", "qp-min", "qp-max", "cabac", "loopfilter", "analyse",
00260     "keyint", "keyint-min", "bframes", "bpyramid", "frameref", "scenecut",
00261     "subpel", "me", "merange", "no-psnr", "no-b-adapt", "b-bias", "tolerance", 
00262     "vbv-maxrate", "vbv-bufsize", "vbv-init", NULL
00263 };
00264 
00265 static block_t *Encode( encoder_t *, picture_t * );
00266 
00267 struct encoder_sys_t
00268 {
00269     x264_t          *h;
00270     x264_param_t    param;
00271 
00272     int             i_buffer;
00273     uint8_t         *p_buffer;
00274 
00275     mtime_t         i_last_ref_pts;
00276 };
00277 
00278 /*****************************************************************************
00279  * Open: probe the encoder
00280  *****************************************************************************/
00281 static int  Open ( vlc_object_t *p_this )
00282 {
00283     encoder_t     *p_enc = (encoder_t *)p_this;
00284     encoder_sys_t *p_sys;
00285     vlc_value_t    val;
00286     int i_qmin = 0, i_qmax = 0;
00287 
00288     if( p_enc->fmt_out.i_codec != VLC_FOURCC( 'h', '2', '6', '4' ) &&
00289         !p_enc->b_force )
00290     {
00291         return VLC_EGENERIC;
00292     }
00293 
00294 #if X264_BUILD < 37
00295     if( p_enc->fmt_in.video.i_width % 16 != 0 ||
00296         p_enc->fmt_in.video.i_height % 16!= 0 )
00297     {
00298         msg_Warn( p_enc, "size is not a multiple of 16 (%ix%i)",
00299                   p_enc->fmt_in.video.i_width, p_enc->fmt_in.video.i_height );
00300 
00301         if( p_enc->fmt_in.video.i_width < 16 ||
00302             p_enc->fmt_in.video.i_height < 16 )
00303         {
00304             msg_Err( p_enc, "video is too small to be cropped" );
00305             return VLC_EGENERIC;
00306         }
00307 
00308         msg_Warn( p_enc, "cropping video to %ix%i",
00309                   p_enc->fmt_in.video.i_width >> 4 << 4,
00310                   p_enc->fmt_in.video.i_height >> 4 << 4 );
00311     }
00312 #endif
00313 
00314     sout_CfgParse( p_enc, SOUT_CFG_PREFIX, ppsz_sout_options, p_enc->p_cfg );
00315 
00316     p_enc->fmt_out.i_codec = VLC_FOURCC( 'h', '2', '6', '4' );
00317     p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0');
00318 
00319     p_enc->pf_encode_video = Encode;
00320     p_enc->pf_encode_audio = NULL;
00321     p_enc->p_sys = p_sys = malloc( sizeof( encoder_sys_t ) );
00322     p_sys->i_last_ref_pts = 0;
00323 
00324     x264_param_default( &p_sys->param );
00325     p_sys->param.i_width  = p_enc->fmt_in.video.i_width;
00326     p_sys->param.i_height = p_enc->fmt_in.video.i_height;
00327 #if X264_BUILD < 37
00328     p_sys->param.i_width  = p_sys->param.i_width >> 4 << 4;
00329     p_sys->param.i_height = p_sys->param.i_height >> 4 << 4;
00330 #endif
00331 
00332     var_Get( p_enc, SOUT_CFG_PREFIX "qp-min", &val );
00333     if( val.i_int >= 1 && val.i_int <= 51 ) i_qmin = val.i_int;
00334     var_Get( p_enc, SOUT_CFG_PREFIX "qp-max", &val );
00335     if( val.i_int >= 1 && val.i_int <= 51 ) i_qmax = val.i_int;
00336 
00337     var_Get( p_enc, SOUT_CFG_PREFIX "qp", &val );
00338     if( val.i_int >= 1 && val.i_int <= 51 )
00339     {
00340         if( i_qmin > val.i_int ) i_qmin = val.i_int;
00341         if( i_qmax < val.i_int ) i_qmax = val.i_int;
00342 
00343 #if X264_BUILD >= 0x000a
00344         p_sys->param.rc.i_qp_constant = val.i_int;
00345         p_sys->param.rc.i_qp_min = i_qmin;
00346         p_sys->param.rc.i_qp_max = i_qmax;
00347 #else
00348         p_sys->param.i_qp_constant = val.i_int;
00349 #endif
00350     }
00351     else
00352     {
00353         /* No QP -> constant bitrate */
00354 #if X264_BUILD >= 0x000a
00355         p_sys->param.rc.b_cbr = 1;
00356         p_sys->param.rc.i_bitrate = p_enc->fmt_out.i_bitrate / 1000;
00357 
00358 #if X264_BUILD >= 24
00359         var_Get( p_enc, SOUT_CFG_PREFIX "tolerance", &val );
00360         p_sys->param.rc.f_rate_tolerance = val.f_float;
00361 
00362         var_Get( p_enc, SOUT_CFG_PREFIX "vbv-maxrate", &val );
00363         p_sys->param.rc.i_vbv_max_bitrate = val.i_int;
00364 
00365         var_Get( p_enc, SOUT_CFG_PREFIX "vbv-bufsize", &val );
00366         p_sys->param.rc.i_vbv_buffer_size = val.i_int;
00367         if( !val.i_int )
00368             p_sys->param.rc.i_vbv_buffer_size = p_sys->param.rc.i_bitrate;
00369 
00370         var_Get( p_enc, SOUT_CFG_PREFIX "vbv-init", &val );
00371         p_sys->param.rc.f_vbv_buffer_init = val.f_float;
00372 #else
00373         p_sys->param.rc.i_rc_buffer_size = p_sys->param.rc.i_bitrate;
00374         p_sys->param.rc.i_rc_init_buffer = p_sys->param.rc.i_bitrate / 4;
00375 #endif
00376 #endif
00377     }
00378 
00379     var_Get( p_enc, SOUT_CFG_PREFIX "cabac", &val );
00380     p_sys->param.b_cabac = val.b_bool;
00381 
00382     var_Get( p_enc, SOUT_CFG_PREFIX "loopfilter", &val );
00383     p_sys->param.b_deblocking_filter = val.b_bool;
00384 
00385     var_Get( p_enc, SOUT_CFG_PREFIX "keyint", &val );
00386 #if X264_BUILD >= 0x000e
00387     if( val.i_int > 0 ) p_sys->param.i_keyint_max = val.i_int;
00388     if( val.i_int > 0 ) p_sys->param.i_keyint_min = val.i_int * 0.4;
00389 #else
00390     if( val.i_int > 0 ) p_sys->param.i_iframe = val.i_int;
00391 #endif
00392 
00393     var_Get( p_enc, SOUT_CFG_PREFIX "keyint-min", &val );
00394 #if X264_BUILD >= 0x000e
00395     if( val.i_int > 0 ) p_sys->param.i_keyint_min = val.i_int;
00396 #else
00397     if( val.i_int > 0 ) p_sys->param.i_idrframe = val.i_int;
00398 #endif
00399 
00400     var_Get( p_enc, SOUT_CFG_PREFIX "bframes", &val );
00401     if( val.i_int >= 0 && val.i_int <= 16 ) p_sys->param.i_bframe = val.i_int;
00402 
00403 #if X264_BUILD >= 22
00404     var_Get( p_enc, SOUT_CFG_PREFIX "bpyramid", &val );
00405     p_sys->param.b_bframe_pyramid = val.b_bool;
00406 #endif
00407 
00408     var_Get( p_enc, SOUT_CFG_PREFIX "frameref", &val );
00409     if( val.i_int > 0 && val.i_int <= 15 )
00410         p_sys->param.i_frame_reference = val.i_int;
00411 
00412     var_Get( p_enc, SOUT_CFG_PREFIX "scenecut", &val );
00413 #if X264_BUILD >= 0x000b
00414     if( val.i_int >= -1 && val.i_int <= 100 )
00415         p_sys->param.i_scenecut_threshold = val.i_int;
00416 #endif
00417 
00418 #if X264_BUILD >= 22
00419     var_Get( p_enc, SOUT_CFG_PREFIX "subpel", &val );
00420 #if X264_BUILD >= 30
00421     if( val.i_int >= 1 && val.i_int <= 6 )
00422 #else
00423     if( val.i_int >= 1 && val.i_int <= 5 )
00424 #endif
00425         p_sys->param.analyse.i_subpel_refine = val.i_int;
00426 #endif
00427 
00428 #if X264_BUILD >= 23
00429     var_Get( p_enc, SOUT_CFG_PREFIX "me", &val );
00430     if( !strcmp( val.psz_string, "dia" ) )
00431     {
00432         p_sys->param.analyse.i_me_method = X264_ME_DIA;
00433     }
00434     else if( !strcmp( val.psz_string, "hex" ) )
00435     {
00436         p_sys->param.analyse.i_me_method = X264_ME_HEX;
00437     }
00438     else if( !strcmp( val.psz_string, "umh" ) )
00439     {
00440         p_sys->param.analyse.i_me_method = X264_ME_UMH;
00441     }
00442     else if( !strcmp( val.psz_string, "esa" ) )
00443     {
00444         p_sys->param.analyse.i_me_method = X264_ME_ESA;
00445     }
00446     if( val.psz_string ) free( val.psz_string );
00447 
00448     var_Get( p_enc, SOUT_CFG_PREFIX "merange", &val );
00449     if( val.i_int >= 1 && val.i_int <= 64 ) p_sys->param.analyse.i_me_range = val.i_int;
00450 #endif
00451 
00452     var_Get( p_enc, SOUT_CFG_PREFIX "no-psnr", &val );
00453     p_sys->param.analyse.b_psnr = ! val.b_bool;
00454 
00455 #if X264_BUILD >= 0x0013
00456     var_Get( p_enc, SOUT_CFG_PREFIX "no-b-adapt", &val );
00457     p_sys->param.b_bframe_adaptive = ! val.b_bool;
00458 
00459     var_Get( p_enc, SOUT_CFG_PREFIX "b-bias", &val );
00460     if( val.i_int >= -100 && val.i_int <= 100 )
00461         p_sys->param.i_bframe_bias = val.i_int;
00462 #endif
00463 
00464 #ifndef X264_ANALYSE_BSUB16x16
00465 #   define X264_ANALYSE_BSUB16x16 0
00466 #endif
00467     var_Get( p_enc, SOUT_CFG_PREFIX "analyse", &val );
00468     if( !strcmp( val.psz_string, "none" ) )
00469     {
00470         p_sys->param.analyse.inter = 0;
00471     }
00472     else if( !strcmp( val.psz_string, "fast" ) )
00473     {
00474         p_sys->param.analyse.inter = X264_ANALYSE_I4x4;
00475     }
00476     else if( !strcmp( val.psz_string, "normal" ) )
00477     {
00478         p_sys->param.analyse.inter =
00479             X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16;
00480     }
00481     else if( !strcmp( val.psz_string, "slow" ) )
00482     {
00483         p_sys->param.analyse.inter =
00484             X264_ANALYSE_I4x4 |
00485             X264_ANALYSE_PSUB16x16 | X264_ANALYSE_PSUB8x8 |
00486             X264_ANALYSE_BSUB16x16;
00487     }
00488     else if( !strcmp( val.psz_string, "all" ) )
00489     {
00490         p_sys->param.analyse.inter =
00491             X264_ANALYSE_I4x4 |
00492             X264_ANALYSE_PSUB16x16 | X264_ANALYSE_PSUB8x8 |
00493             X264_ANALYSE_BSUB16x16;
00494 #ifdef X264_ANALYSE_I8x8
00495         p_sys->param.analyse.inter |= X264_ANALYSE_I8x8;
00496         p_sys->param.analyse.b_transform_8x8 = 1;
00497 #endif
00498     }
00499     if( val.psz_string ) free( val.psz_string );
00500 
00501     if( p_enc->fmt_in.video.i_aspect > 0 )
00502     {
00503         int64_t i_num, i_den;
00504         int i_dst_num, i_dst_den;
00505 
00506         i_num = p_enc->fmt_in.video.i_aspect *
00507             (int64_t)p_enc->fmt_in.video.i_height;
00508         i_den = VOUT_ASPECT_FACTOR * p_enc->fmt_in.video.i_width;
00509         vlc_ureduce( &i_dst_num, &i_dst_den, i_num, i_den, 0 );
00510 
00511         p_sys->param.vui.i_sar_width = i_dst_num;
00512         p_sys->param.vui.i_sar_height = i_dst_den;
00513     }
00514     if( p_enc->fmt_in.video.i_frame_rate_base > 0 )
00515     {
00516         p_sys->param.i_fps_num = p_enc->fmt_in.video.i_frame_rate;
00517         p_sys->param.i_fps_den = p_enc->fmt_in.video.i_frame_rate_base;
00518     }
00519     if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMX) )
00520     {
00521         p_sys->param.cpu &= ~X264_CPU_MMX;
00522     }
00523     if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMXEXT) )
00524     {
00525         p_sys->param.cpu &= ~X264_CPU_MMXEXT;
00526     }
00527     if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_SSE) )
00528     {
00529         p_sys->param.cpu &= ~X264_CPU_SSE;
00530     }
00531     if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_SSE2) )
00532     {
00533         p_sys->param.cpu &= ~X264_CPU_SSE2;
00534     }
00535 
00536 #if X264_BUILD >= 29
00537     if( p_enc->i_threads >= 1 )
00538         p_sys->param.i_threads = p_enc->i_threads;
00539 #endif
00540 
00541     /* Open the encoder */
00542     p_sys->h = x264_encoder_open( &p_sys->param );
00543 
00544     /* alloc mem */
00545     p_sys->i_buffer = 4 * p_enc->fmt_in.video.i_width *
00546         p_enc->fmt_in.video.i_height + 1000;
00547     p_sys->p_buffer = malloc( p_sys->i_buffer );
00548 
00549     /* get the globals headers */
00550     p_enc->fmt_out.i_extra = 0;
00551     p_enc->fmt_out.p_extra = NULL;
00552 
00553 #if 0
00554     x264_encoder_headers( p_sys->h, &nal, &i_nal );
00555     for( i = 0; i < i_nal; i++ )
00556     {
00557         int i_size = p_sys->i_buffer;
00558 
00559         x264_nal_encode( p_sys->p_buffer, &i_size, 1, &nal[i] );
00560 
00561         p_enc->fmt_out.p_extra = realloc( p_enc->fmt_out.p_extra, p_enc->fmt_out.i_extra + i_size );
00562 
00563         memcpy( p_enc->fmt_out.p_extra + p_enc->fmt_out.i_extra,
00564                 p_sys->p_buffer, i_size );
00565 
00566         p_enc->fmt_out.i_extra += i_size;
00567     }
00568 #endif
00569 
00570     return VLC_SUCCESS;
00571 }
00572 
00573 /****************************************************************************
00574  * Encode:
00575  ****************************************************************************/
00576 static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
00577 {
00578     encoder_sys_t *p_sys = p_enc->p_sys;
00579     x264_picture_t pic;
00580     x264_nal_t *nal;
00581     block_t *p_block;
00582     int i_nal, i_out, i;
00583 
00584     /* init pic */
00585     memset( &pic, 0, sizeof( x264_picture_t ) );
00586     pic.i_pts = p_pict->date;
00587     pic.img.i_csp = X264_CSP_I420;
00588     pic.img.i_plane = p_pict->i_planes;
00589     for( i = 0; i < p_pict->i_planes; i++ )
00590     {
00591         pic.img.plane[i] = p_pict->p[i].p_pixels;
00592         pic.img.i_stride[i] = p_pict->p[i].i_pitch;
00593     }
00594 
00595 #if X264_BUILD >= 0x0013
00596     x264_encoder_encode( p_sys->h, &nal, &i_nal, &pic, &pic );
00597 #else
00598     x264_encoder_encode( p_sys->h, &nal, &i_nal, &pic );
00599 #endif
00600 
00601     if( !i_nal ) return NULL;
00602 
00603     for( i = 0, i_out = 0; i < i_nal; i++ )
00604     {
00605         int i_size = p_sys->i_buffer - i_out;
00606         x264_nal_encode( p_sys->p_buffer + i_out, &i_size, 1, &nal[i] );
00607 
00608         i_out += i_size;
00609     }
00610 
00611     p_block = block_New( p_enc, i_out );
00612     memcpy( p_block->p_buffer, p_sys->p_buffer, i_out );
00613 
00614     if( pic.i_type == X264_TYPE_IDR || pic.i_type == X264_TYPE_I )
00615         p_block->i_flags |= BLOCK_FLAG_TYPE_I;
00616     else if( pic.i_type == X264_TYPE_P )
00617         p_block->i_flags |= BLOCK_FLAG_TYPE_P;
00618     else if( pic.i_type == X264_TYPE_B )
00619         p_block->i_flags |= BLOCK_FLAG_TYPE_B;
00620 
00621     /* This isn't really valid for streams with B-frames */
00622     p_block->i_length = I64C(1000000) *
00623         p_enc->fmt_in.video.i_frame_rate_base /
00624             p_enc->fmt_in.video.i_frame_rate;
00625 
00626     p_block->i_dts = p_block->i_pts = pic.i_pts;
00627 
00628     if( p_sys->param.i_bframe > 0 )
00629     {
00630         if( p_block->i_flags & BLOCK_FLAG_TYPE_B )
00631         {
00632             p_block->i_dts = p_block->i_pts;
00633         }
00634         else
00635         {
00636             if( p_sys->i_last_ref_pts )
00637             {
00638                 p_block->i_dts = p_sys->i_last_ref_pts;
00639             }
00640             else
00641             {
00642                 /* Let's put something sensible */
00643                 p_block->i_dts = p_block->i_pts;
00644             }
00645 
00646             p_sys->i_last_ref_pts = p_block->i_pts;
00647         }
00648     }
00649 
00650     return p_block;
00651 }
00652 
00653 /*****************************************************************************
00654  * CloseEncoder: x264 encoder destruction
00655  *****************************************************************************/
00656 static void Close( vlc_object_t *p_this )
00657 {
00658     encoder_t     *p_enc = (encoder_t *)p_this;
00659     encoder_sys_t *p_sys = p_enc->p_sys;
00660 
00661     x264_encoder_close( p_sys->h );
00662     free( p_sys->p_buffer );
00663     free( p_sys );
00664 }

Generated on Tue Dec 20 10:14:30 2005 for vlc-0.8.4a by  doxygen 1.4.2