00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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 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 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 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 add_bool( SOUT_CFG_PREFIX "no-b-adapt", 0, NULL, NO_B_ADAPT_TEXT,
00245 NO_B_ADAPT_LONGTEXT, VLC_FALSE );
00246
00247 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
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
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
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
00542 p_sys->h = x264_encoder_open( &p_sys->param );
00543
00544
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
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
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
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
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
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
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 }