X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Fx264.c;h=68df693b7a7904076ff6d6117b4539b7762cb17d;hb=56220f86120b3d7b7d8c7b2957befede19f669b6;hp=de3ac8d26f00d9f8e04a76de02ef58090f552dcd;hpb=edfb6e4ad2f508bf92f05b39e13378072bf9777e;p=vlc diff --git a/modules/codec/x264.c b/modules/codec/x264.c index de3ac8d26f..68df693b7a 100644 --- a/modules/codec/x264.c +++ b/modules/codec/x264.c @@ -29,6 +29,7 @@ # include "config.h" #endif +#define VLC_MODULE_LICENSE VLC_LICENSE_GPL_2_PLUS #include #include #include @@ -40,13 +41,21 @@ #ifdef PTW32_STATIC_LIB #include #endif +#ifdef MODULE_NAME_IS_x262 +#include +#else #include +#endif #include #ifdef MODULE_NAME_IS_x26410b #define SOUT_CFG_PREFIX "sout-x26410b-" -#else +#endif +#ifdef MODULE_NAME_IS_x262 +#define SOUT_CFG_PREFIX "sout-x262-" +#endif +#ifdef MODULE_NAME_IS_x264 #define SOUT_CFG_PREFIX "sout-x264-" #endif @@ -122,6 +131,10 @@ static void x264_log( void *, int i_level, const char *psz, va_list ); " - normal: Non-strict (not Blu-ray compatible)\n"\ ) +#define FULLRANGE_TEXT N_("Use fullrange instead of TV colorrange") +#define FULLRANGE_LONGTEXT N_("TV-range is usually used colorrange, defining this to true " \ + "will enable libx264 to use full colorrange on encoding") + #define CABAC_TEXT N_("CABAC") #define CABAC_LONGTEXT N_( "CABAC (Context-Adaptive Binary Arithmetic "\ "Coding). Slightly slows down encoding and decoding, but should save " \ @@ -267,7 +280,7 @@ static void x264_log( void *, int i_level, const char *psz, va_list ); "(p4x4 requires p8x8. i8x8 requires 8x8dct).") #define DIRECT_PRED_TEXT N_("Direct MV prediction mode") -#define DIRECT_PRED_LONGTEXT N_( "Direct MV prediction mode.") +#define DIRECT_PRED_LONGTEXT DIRECT_PRED_TEXT #define DIRECT_PRED_SIZE_TEXT N_("Direct prediction size") #define DIRECT_PRED_SIZE_LONGTEXT N_( "Direct prediction size: "\ @@ -317,7 +330,6 @@ static void x264_log( void *, int i_level, const char *psz, va_list ); "tradeoffs involved in the motion estimation decision process " \ "(lower = quicker and higher = better quality). Range 1 to 9." ) -#define B_RDO_TEXT N_("RD based mode decision for B-frames") #define B_RDO_LONGTEXT N_( "RD based mode decision for B-frames. This " \ "requires subme 6 (or higher).") @@ -330,7 +342,6 @@ static void x264_log( void *, int i_level, const char *psz, va_list ); #define CHROMA_ME_LONGTEXT N_( "Chroma ME for subpel and mode decision in " \ "P-frames.") -#define BIME_TEXT N_("Jointly optimize both MVs in B-frames") #define BIME_LONGTEXT N_( "Joint bidirectional motion refinement.") #define TRANSFORM_8X8DCT_TEXT N_("Adaptive spatial transform size") @@ -424,24 +435,29 @@ static const char *const bpyramid_list[] = static const char *const enc_analyse_list[] = { "none", "fast", "normal", "slow", "all" }; static const char *const enc_analyse_list_text[] = - { N_("none"), N_("fast"), N_("normal"), N_("slow"), N_("all") }; + { N_("None"), N_("Fast"), N_("Normal"), N_("Slow"), N_("All") }; static const char *const direct_pred_list[] = { "none", "spatial", "temporal", "auto" }; static const char *const direct_pred_list_text[] = - { N_("none"), N_("spatial"), N_("temporal"), N_("auto") }; + { N_("None"), N_("Spatial"), N_("Temporal"), N_("Auto") }; -static const int const framepacking_list[] = +static const int framepacking_list[] = { -1, 0, 1, 2, 3, 4, 5 }; static const char *const framepacking_list_text[] = { "", N_("checkerboard"), N_("column alternation"), N_("row alternation"), N_("side by side"), N_("top bottom"), N_("frame alternation") }; vlc_module_begin () #ifdef MODULE_NAME_IS_x26410b - set_description( N_("H.264/MPEG4 AVC encoder (x264 10-bit)")) + set_description( N_("H.264/MPEG-4 Part 10/AVC encoder (x264 10-bit)")) set_capability( "encoder", 0 ) -#else - set_description( N_("H.264/MPEG4 AVC encoder (x264)")) +#endif +#ifdef MODULE_NAME_IS_x262 + set_description( N_("H.262/MPEG-2 encoder (x262)")) + set_capability( "encoder", 0 ) +#endif +#ifdef MODULE_NAME_IS_x264 + set_description( N_("H.264/MPEG-4 Part 10/AVC encoder (x264)")) set_capability( "encoder", 200 ) #endif set_callbacks( Open, Close ) @@ -459,7 +475,7 @@ vlc_module_begin () #if X264_BUILD >= 102 && X264_BUILD <= 114 add_string( SOUT_CFG_PREFIX "opengop", "none", OPENGOP_TEXT, OPENGOP_LONGTEXT, true ) - change_string_list( x264_open_gop_names, x264_open_gop_names, 0 ); + change_string_list( x264_open_gop_names, x264_open_gop_names ) #elif X264_BUILD > 114 add_bool( SOUT_CFG_PREFIX "opengop", false, OPENGOP_TEXT, OPENGOP_LONGTEXT, true ) @@ -492,11 +508,14 @@ vlc_module_begin () add_string( SOUT_CFG_PREFIX "bpyramid", "none", BPYRAMID_TEXT, BPYRAMID_LONGTEXT, true ) #endif - change_string_list( bpyramid_list, bpyramid_list, 0 ); + change_string_list( bpyramid_list, bpyramid_list ) add_bool( SOUT_CFG_PREFIX "cabac", true, CABAC_TEXT, CABAC_LONGTEXT, true ) + add_bool( SOUT_CFG_PREFIX "fullrange", false, FULLRANGE_TEXT, FULLRANGE_LONGTEXT, + true ) + add_integer( SOUT_CFG_PREFIX "ref", 3, REF_TEXT, REF_LONGTEXT, true ) change_integer_range( 1, 16 ) @@ -517,7 +536,10 @@ vlc_module_begin () add_string( SOUT_CFG_PREFIX "profile", "high", PROFILE_TEXT, PROFILE_LONGTEXT, false ) - change_string_list( x264_profile_names, x264_profile_names, 0 ); + vlc_config_set (VLC_CONFIG_LIST, + (sizeof(x264_profile_names) / sizeof (char*)) - 1, + x264_profile_names, x264_profile_names); + add_bool( SOUT_CFG_PREFIX "interlaced", false, INTERLACED_TEXT, INTERLACED_LONGTEXT, true ) @@ -534,7 +556,9 @@ vlc_module_begin () #if X264_BUILD >= 89 add_string( SOUT_CFG_PREFIX "hrd", "none", HRD_TEXT, HRD_TEXT, true ) - change_string_list( x264_nal_hrd_names, x264_nal_hrd_names, 0 ); + vlc_config_set (VLC_CONFIG_LIST, + (sizeof(x264_nal_hrd_names) / sizeof (char*)) - 1, + x264_nal_hrd_names, x264_nal_hrd_names); #endif @@ -610,11 +634,11 @@ vlc_module_begin () /* x264 partitions = none (default). set at least "normal" mode. */ add_string( SOUT_CFG_PREFIX "partitions", "normal", ANALYSE_TEXT, ANALYSE_LONGTEXT, true ) - change_string_list( enc_analyse_list, enc_analyse_list_text, 0 ); + change_string_list( enc_analyse_list, enc_analyse_list_text ) add_string( SOUT_CFG_PREFIX "direct", "spatial", DIRECT_PRED_TEXT, DIRECT_PRED_LONGTEXT, true ) - change_string_list( direct_pred_list, direct_pred_list_text, 0 ); + change_string_list( direct_pred_list, direct_pred_list_text ) add_integer( SOUT_CFG_PREFIX "direct-8x8", 1, DIRECT_PRED_SIZE_TEXT, DIRECT_PRED_SIZE_LONGTEXT, true ) @@ -629,7 +653,7 @@ vlc_module_begin () add_string( SOUT_CFG_PREFIX "me", "hex", ME_TEXT, ME_LONGTEXT, true ) - change_string_list( enc_me_list, enc_me_list_text, 0 ); + change_string_list( enc_me_list, enc_me_list_text ) add_integer( SOUT_CFG_PREFIX "merange", 16, MERANGE_TEXT, MERANGE_LONGTEXT, true ) @@ -720,9 +744,13 @@ vlc_module_begin () STATS_LONGTEXT, true ) add_string( SOUT_CFG_PREFIX "preset", NULL , PRESET_TEXT , PRESET_TEXT, false ) - change_string_list( x264_preset_names, x264_preset_names, 0 ); + vlc_config_set (VLC_CONFIG_LIST, + (sizeof(x264_preset_names) / sizeof (char*)) - 1, + x264_preset_names, x264_preset_names); add_string( SOUT_CFG_PREFIX "tune", NULL , TUNE_TEXT, TUNE_TEXT, false ) - change_string_list( x264_tune_names, x264_tune_names, 0 ); + vlc_config_set (VLC_CONFIG_LIST, + (sizeof(x264_tune_names) / sizeof (char*)) - 1, + x264_tune_names, x264_tune_names); add_string( SOUT_CFG_PREFIX "options", NULL, X264_OPTIONS_TEXT, X264_OPTIONS_LONGTEXT, true ) @@ -747,6 +775,7 @@ static const char *const ppsz_sout_options[] = { "aq-mode", "aq-strength", "psy-rd", "psy", "profile", "lookahead", "slices", "slice-max-size", "slice-max-mbs", "intra-refresh", "mbtree", "hrd", "tune","preset", "opengop", "bluray-compat", "frame-packing", "options", + "fullrange", NULL }; @@ -782,24 +811,38 @@ static int Open ( vlc_object_t *p_this ) int i_qmin = 0, i_qmax = 0; x264_nal_t *nal; int i, i_nal; + bool fullrange = false; +#ifdef MODULE_NAME_IS_x262 + if( p_enc->fmt_out.i_codec != VLC_CODEC_MP2V && +#else if( p_enc->fmt_out.i_codec != VLC_CODEC_H264 && +#endif !p_enc->b_force ) { return VLC_EGENERIC; } /* X264_POINTVER or X264_VERSION are not available */ +#ifdef MODULE_NAME_IS_x262 + msg_Dbg ( p_enc, "version x262 0.%d.X", X264_BUILD ); +#else msg_Dbg ( p_enc, "version x264 0.%d.X", X264_BUILD ); +#endif config_ChainParse( p_enc, SOUT_CFG_PREFIX, ppsz_sout_options, p_enc->p_cfg ); p_enc->fmt_out.i_cat = VIDEO_ES; +#ifdef MODULE_NAME_IS_x262 + p_enc->fmt_out.i_codec = VLC_CODEC_MP2V; +#else p_enc->fmt_out.i_codec = VLC_CODEC_H264; +#endif p_enc->p_sys = p_sys = malloc( sizeof( encoder_sys_t ) ); if( !p_sys ) return VLC_ENOMEM; - p_enc->fmt_in.i_codec = VLC_CODEC_I420; + fullrange = var_GetBool( p_enc, SOUT_CFG_PREFIX "fullrange" ); + p_enc->fmt_in.i_codec = fullrange ? VLC_CODEC_J420 : VLC_CODEC_I420; p_sys->i_colorspace = X264_CSP_I420; #if X264_BUILD >= 118 char *psz_profile = var_GetString( p_enc, SOUT_CFG_PREFIX "profile" ); @@ -807,45 +850,46 @@ static int Open ( vlc_object_t *p_this ) { const int mask = x264_bit_depth > 8 ? X264_CSP_HIGH_DEPTH : 0; -#ifdef MODULE_NAME_IS_x26410b + +# ifdef MODULE_NAME_IS_x26410b if( mask == 0) { msg_Err( p_enc, "Only high bith depth encoding supported, bit depth:%d", x264_bit_depth); return VLC_EGENERIC; } -#endif +# endif if( !strcmp( psz_profile, "high10" ) ) { - p_enc->fmt_in.i_codec = mask ? VLC_CODEC_I420_10L : VLC_CODEC_I420; + p_enc->fmt_in.i_codec = mask ? VLC_CODEC_I420_10L : fullrange ? VLC_CODEC_J420 : VLC_CODEC_I420; p_sys->i_colorspace = X264_CSP_I420 | mask; } else if( !strcmp( psz_profile, "high422" ) ) { - p_enc->fmt_in.i_codec = mask ? VLC_CODEC_I422_10L : VLC_CODEC_I422; + p_enc->fmt_in.i_codec = mask ? VLC_CODEC_I422_10L : fullrange ? VLC_CODEC_J422 : VLC_CODEC_I422; p_sys->i_colorspace = X264_CSP_I422 | mask; } else if( !strcmp( psz_profile, "high444" ) ) { - p_enc->fmt_in.i_codec = mask ? VLC_CODEC_I444_10L : VLC_CODEC_I444; + p_enc->fmt_in.i_codec = mask ? VLC_CODEC_I444_10L : fullrange ? VLC_CODEC_J444 : VLC_CODEC_I444; p_sys->i_colorspace = X264_CSP_I444 | mask; } -#ifdef MODULE_NAME_IS_x26410b +# ifdef MODULE_NAME_IS_x26410b else { msg_Err( p_enc, "Only high-profiles and 10-bit are supported"); return VLC_EGENERIC; } -#endif +# endif } -#ifdef MODULE_NAME_IS_x26410b +# ifdef MODULE_NAME_IS_x26410b else { msg_Err( p_enc, "Only high-profiles and 10-bit are supported"); return VLC_EGENERIC; } -#endif +# endif free( psz_profile ); #endif //X264_BUILD @@ -856,7 +900,6 @@ static int Open ( vlc_object_t *p_this ) p_sys->i_sei_size = 0; p_sys->p_sei = NULL; - x264_param_default( &p_sys->param ); char *psz_preset = var_GetString( p_enc, SOUT_CFG_PREFIX "preset" ); char *psz_tune = var_GetString( p_enc, SOUT_CFG_PREFIX "tune" ); if( *psz_preset == '\0' ) @@ -864,12 +907,20 @@ static int Open ( vlc_object_t *p_this ) free(psz_preset); psz_preset = NULL; } +#ifdef MODULE_NAME_IS_x262 + p_sys->param.b_mpeg2 = true; + x264_param_default_mpeg2( &p_sys->param ); + x264_param_default_preset_mpeg2( &p_sys->param, psz_preset, psz_tune ); +#else + x264_param_default( &p_sys->param ); x264_param_default_preset( &p_sys->param, psz_preset, psz_tune ); +#endif free( psz_preset ); free( psz_tune ); p_sys->param.i_csp = p_sys->i_colorspace; - p_sys->param.i_width = p_enc->fmt_in.video.i_width; - p_sys->param.i_height = p_enc->fmt_in.video.i_height; + p_sys->param.i_width = p_enc->fmt_in.video.i_visible_width; + p_sys->param.i_height = p_enc->fmt_in.video.i_visible_height; + p_sys->param.vui.b_fullrange = fullrange; if( fabs(var_GetFloat( p_enc, SOUT_CFG_PREFIX "qcomp" ) - 0.60) > 0.005 ) p_sys->param.rc.f_qcompress = var_GetFloat( p_enc, SOUT_CFG_PREFIX "qcomp" ); @@ -930,6 +981,8 @@ static int Open ( vlc_object_t *p_this ) /* max bitrate = average bitrate -> CBR */ p_sys->param.rc.i_vbv_max_bitrate = var_GetInteger( p_enc, SOUT_CFG_PREFIX "vbv-maxrate" ); + if( p_sys->param.rc.i_vbv_max_bitrate && p_sys->param.rc.i_rc_method != X264_RC_ABR ) + p_enc->fmt_out.i_bitrate = p_sys->param.rc.i_vbv_max_bitrate * 1000; if( !var_GetBool( p_enc, SOUT_CFG_PREFIX "mbtree" ) ) @@ -1098,8 +1151,8 @@ static int Open ( vlc_object_t *p_this ) { p_sys->param.analyse.i_me_method = X264_ME_TESA; } - free( psz_val ); } + free( psz_val ); i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "merange" ); if( i_val >= 0 && i_val <= 64 && i_val != 16 ) @@ -1237,8 +1290,8 @@ static int Open ( vlc_object_t *p_this ) p_sys->param.i_fps_num = p_enc->fmt_in.video.i_frame_rate; p_sys->param.i_fps_den = p_enc->fmt_in.video.i_frame_rate_base; p_sys->param.i_timebase_num = 1; - p_sys->param.i_timebase_den = INT64_C(1000000); - p_sys->param.b_vfr_input = 1; + p_sys->param.i_timebase_den = CLOCK_FREQ; + p_sys->param.b_vfr_input = 0; } /* Check slice-options */ @@ -1255,7 +1308,7 @@ static int Open ( vlc_object_t *p_this ) /* Check if user has given some profile (baseline,main,high) to limit * settings, and apply those*/ psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "profile" ); - if( psz_val ) + if( psz_val && *psz_val ) x264_param_apply_profile( &p_sys->param, psz_val ); free( psz_val ); @@ -1415,12 +1468,11 @@ static void x264_log( void *data, int i_level, const char *psz, va_list args) i_level = VLC_MSG_INFO; break; case X264_LOG_DEBUG: - i_level = VLC_MSG_DBG; default: i_level = VLC_MSG_DBG; } - msg_GenericVa( p_enc, i_level, MODULE_STRING, psz, args ); + msg_GenericVa( p_enc, i_level, psz, args ); }; /**************************************************************************** @@ -1464,7 +1516,7 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pict ) for( i = 0; i < i_nal; i++ ) i_out += nal[i].i_payload; - p_block = block_New( p_enc, i_out + p_sys->i_sei_size ); + p_block = block_Alloc( i_out + p_sys->i_sei_size ); if( !p_block ) return NULL; unsigned int i_offset = 0; @@ -1484,13 +1536,13 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pict ) p_block->i_flags |= BLOCK_FLAG_TYPE_I; else if( pic.i_type == X264_TYPE_P || pic.i_type == X264_TYPE_I ) p_block->i_flags |= BLOCK_FLAG_TYPE_P; - else if( pic.i_type == X264_TYPE_B ) + else if( IS_X264_TYPE_B( pic.i_type ) ) p_block->i_flags |= BLOCK_FLAG_TYPE_B; else p_block->i_flags |= BLOCK_FLAG_TYPE_PB; /* This isn't really valid for streams with B-frames */ - p_block->i_length = INT64_C(1000000) * + p_block->i_length = CLOCK_FREQ * p_enc->fmt_in.video.i_frame_rate_base / p_enc->fmt_in.video.i_frame_rate; @@ -1512,10 +1564,11 @@ static void Close( vlc_object_t *p_this ) free( p_sys->psz_stat_name ); free( p_sys->p_sei ); - msg_Dbg( p_enc, "framecount still in libx264 buffer: %d", x264_encoder_delayed_frames( p_sys->h ) ); - if( p_sys->h ) + { + msg_Dbg( p_enc, "framecount still in libx264 buffer: %d", x264_encoder_delayed_frames( p_sys->h ) ); x264_encoder_close( p_sys->h ); + } #ifdef PTW32_STATIC_LIB vlc_mutex_lock( &pthread_win32_mutex );