X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Fschroedinger.c;h=8178553be2e2fa4853949ba0dc03a5af155df7d0;hb=649ec7e50ce1927fde3449c77000d3dcad59fb7e;hp=16ddcf5d89fe1b8a3048b7075f79108e52404423;hpb=1c2a95b85ef3e984fd963e7fff6c1c03693b9255;p=vlc diff --git a/modules/codec/schroedinger.c b/modules/codec/schroedinger.c index 16ddcf5d89..8178553be2 100644 --- a/modules/codec/schroedinger.c +++ b/modules/codec/schroedinger.c @@ -3,31 +3,31 @@ * (http://www.bbc.co.uk/rd/projects/dirac/index.shtml) * (http://diracvideo.org) ***************************************************************************** - * Copyright (C) 2008 the VideoLAN team - * $Id$ + * Copyright (C) 2008-2011 VLC authors and VideoLAN * * Authors: Jonathan Rosser * David Flynn * Anuradha Suraparaju * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -36,8 +36,7 @@ #include #include -#include -#include +#include /* decoder_DeletePicture */ #include @@ -51,7 +50,7 @@ static void CloseEncoder ( vlc_object_t * ); #define ENC_CFG_PREFIX "sout-schro-" -#define ENC_CHROMAFMT "chroma_fmt" +#define ENC_CHROMAFMT "chroma-fmt" #define ENC_CHROMAFMT_TEXT N_("Chroma format") #define ENC_CHROMAFMT_LONGTEXT N_("Picking chroma format will force a " \ "conversion of the video into that format") @@ -60,83 +59,468 @@ static const char *const enc_chromafmt_list[] = static const char *const enc_chromafmt_list_text[] = { N_("4:2:0"), N_("4:2:2"), N_("4:4:4") }; +#define ENC_RATE_CONTROL "rate-control" +#define ENC_RATE_CONTROL_TEXT N_("Rate control method") +#define ENC_RATE_CONTROL_LONGTEXT N_("Method used to encode the video sequence") + +static const char *enc_rate_control_list[] = { + "constant_noise_threshold", + "constant_bitrate", + "low_delay", + "lossless", + "constant_lambda", + "constant_error", + "constant_quality" +}; + +static const char *enc_rate_control_list_text[] = { + N_("Constant noise threshold mode"), + N_("Constant bitrate mode (CBR)"), + N_("Low Delay mode"), + N_("Lossless mode"), + N_("Constant lambda mode"), + N_("Constant error mode"), + N_("Constant quality mode") +}; + +#define ENC_GOP_STRUCTURE "gop-structure" +#define ENC_GOP_STRUCTURE_TEXT N_("GOP structure") +#define ENC_GOP_STRUCTURE_LONGTEXT N_("GOP structure used to encode the video sequence") + +static const char *enc_gop_structure_list[] = { + "adaptive", + "intra_only", + "backref", + "chained_backref", + "biref", + "chained_biref" +}; + +static const char *enc_gop_structure_list_text[] = { + N_("No fixed gop structure. A picture can be intra or inter and refer to previous or future pictures."), + N_("I-frame only sequence"), + N_("Inter pictures refere to previous pictures only"), + N_("Inter pictures refere to previous pictures only"), + N_("Inter pictures can refer to previous or future pictures"), + N_("Inter pictures can refer to previous or future pictures") +}; + +#define ENC_QUALITY "quality" +#define ENC_QUALITY_TEXT N_("Constant quality factor") +#define ENC_QUALITY_LONGTEXT N_("Quality factor to use in constant quality mode") + +#define ENC_NOISE_THRESHOLD "noise-threshold" +#define ENC_NOISE_THRESHOLD_TEXT N_("Noise Threshold") +#define ENC_NOISE_THRESHOLD_LONGTEXT N_("Noise threshold to use in constant noise threshold mode") + +#define ENC_BITRATE "bitrate" +#define ENC_BITRATE_TEXT N_("CBR bitrate (kbps)") +#define ENC_BITRATE_LONGTEXT N_("Target bitrate in kbps when encoding in constant bitrate mode") + +#define ENC_MAX_BITRATE "max-bitrate" +#define ENC_MAX_BITRATE_TEXT N_("Maximum bitrate (kbps)") +#define ENC_MAX_BITRATE_LONGTEXT N_("Maximum bitrate in kbps when encoding in constant bitrate mode") -#define ENC_CODINGMODE "auto_coding_mode" -#define ENC_CODINGMODE_TEXT N_("Automate picture coding mode") -#define ENC_CODINGMODE_LONGTEXT N_("Use the input picture to determine how to" \ - " code it - interlaced or progressive") +#define ENC_MIN_BITRATE "min-bitrate" +#define ENC_MIN_BITRATE_TEXT N_("Minimum bitrate (kbps)") +#define ENC_MIN_BITRATE_LONGTEXT N_("Minimum bitrate in kbps when encoding in constant bitrate mode") -static const char **ppsz_enc_options = NULL; +#define ENC_AU_DISTANCE "gop-length" +#define ENC_AU_DISTANCE_TEXT N_("GOP length") +#define ENC_AU_DISTANCE_LONGTEXT N_("Number of pictures between successive sequence headers i.e. length of the group of pictures") + + +#define ENC_PREFILTER "filtering" +#define ENC_PREFILTER_TEXT N_("Prefilter") +#define ENC_PREFILTER_LONGTEXT N_("Enable adaptive prefiltering") + +static const char *enc_filtering_list[] = { + "none", + "center_weighted_median", + "gaussian", + "add_noise", + "adaptive_gaussian", + "lowpass" +}; + +static const char *enc_filtering_list_text[] = { + N_("No pre-filtering"), + N_("Centre Weighted Median"), + N_("Gaussian Low Pass Filter"), + N_("Add Noise"), + N_("Gaussian Adaptive Low Pass Filter"), + N_("Low Pass Filter"), +}; + +#define ENC_PREFILTER_STRENGTH "filter-value" +#define ENC_PREFILTER_STRENGTH_TEXT N_("Amount of prefiltering") +#define ENC_PREFILTER_STRENGTH_LONGTEXT N_("Higher value implies more prefiltering") + +#define ENC_CODINGMODE "coding-mode" +#define ENC_CODINGMODE_TEXT N_("Picture coding mode") +#define ENC_CODINGMODE_LONGTEXT N_("Field coding is where interlaced fields are coded" \ + " separately as opposed to a pseudo-progressive frame") +static const char *const enc_codingmode_list[] = + { "auto", "progressive", "field" }; +static const char *const enc_codingmode_list_text[] = + { N_("auto - let encoder decide based upon input (Best)"), + N_("force coding frame as single picture"), + N_("force coding frame as separate interlaced fields"), + }; + +/* advanced option only */ +#define ENC_MCBLK_SIZE "motion-block-size" +#define ENC_MCBLK_SIZE_TEXT N_("Size of motion compensation blocks") + +static const char *enc_block_size_list[] = { + "automatic", + "small", + "medium", + "large" +}; +static const char *const enc_block_size_list_text[] = + { N_("automatic - let encoder decide based upon input (Best)"), + N_("small - use small motion compensation blocks"), + N_("medium - use medium motion compensation blocks"), + N_("large - use large motion compensation blocks"), + }; + +/* advanced option only */ +#define ENC_MCBLK_OVERLAP "motion-block-overlap" +#define ENC_MCBLK_OVERLAP_TEXT N_("Overlap of motion compensation blocks") + +static const char *enc_block_overlap_list[] = { + "automatic", + "none", + "partial", + "full" +}; +static const char *const enc_block_overlap_list_text[] = + { N_("automatic - let encoder decide based upon input (Best)"), + N_("none - Motion compensation blocks do not overlap"), + N_("partial - Motion compensation blocks only partially overlap"), + N_("full - Motion compensation blocks fully overlap"), + }; + + +#define ENC_MVPREC "mv-precision" +#define ENC_MVPREC_TEXT N_("Motion Vector precision") +#define ENC_MVPREC_LONGTEXT N_("Motion Vector precision in pels") +static const char *const enc_mvprec_list[] = + { "1", "1/2", "1/4", "1/8" }; + +/* advanced option only */ +#define ENC_ME_COMBINED "me-combined" +#define ENC_ME_COMBINED_TEXT N_("Three component motion estimation") +#define ENC_ME_COMBINED_LONGTEXT N_("Use chroma as part of the motion estimation process") + +#define ENC_DWTINTRA "intra-wavelet" +#define ENC_DWTINTRA_TEXT N_("Intra picture DWT filter") + +#define ENC_DWTINTER "inter-wavelet" +#define ENC_DWTINTER_TEXT N_("Inter picture DWT filter") + +static const char *enc_wavelet_list[] = { + "desl_dubuc_9_7", + "le_gall_5_3", + "desl_dubuc_13_7", + "haar_0", + "haar_1", + "fidelity", + "daub_9_7" +}; + +static const char *enc_wavelet_list_text[] = { + "Deslauriers-Dubuc (9,7)", + "LeGall (5,3)", + "Deslauriers-Dubuc (13,7)", + "Haar with no shift", + "Haar with single shift per level", + "Fidelity filter", + "Daubechies (9,7) integer approximation" +}; + +#define ENC_DWTDEPTH "transform-depth" +#define ENC_DWTDEPTH_TEXT N_("Number of DWT iterations") +#define ENC_DWTDEPTH_LONGTEXT N_("Also known as DWT levels") + + +/* advanced option only */ +#define ENC_MULTIQUANT "enable-multiquant" +#define ENC_MULTIQUANT_TEXT N_("Enable multiple quantizers") +#define ENC_MULTIQUANT_LONGTEXT N_("Enable multiple quantizers per subband (one per codeblock)") + +/* advanced option only */ +#define ENC_NOAC "enable-noarith" +#define ENC_NOAC_TEXT N_("Disable arithmetic coding") +#define ENC_NOAC_LONGTEXT N_("Use variable length codes instead, useful for very high bitrates") + +/* visual modelling */ +/* advanced option only */ +#define ENC_PWT "perceptual-weighting" +#define ENC_PWT_TEXT N_("perceptual weighting method") + +static const char *enc_perceptual_weighting_list[] = { + "none", + "ccir959", + "moo", + "manos_sakrison" +}; + +/* advanced option only */ +#define ENC_PDIST "perceptual-distance" +#define ENC_PDIST_TEXT N_("perceptual distance") +#define ENC_PDIST_LONGTEXT N_("perceptual distance to calculate perceptual weight") + +/* advanced option only */ +#define ENC_HSLICES "horiz-slices" +#define ENC_HSLICES_TEXT N_("Horizontal slices per frame") +#define ENC_HSLICES_LONGTEXT N_("Number of horizontal slices per frame in low delay mode") + +/* advanced option only */ +#define ENC_VSLICES "vert-slices" +#define ENC_VSLICES_TEXT N_("Vertical slices per frame") +#define ENC_VSLICES_LONGTEXT N_("Number of vertical slices per frame in low delay mode") + +/* advanced option only */ +#define ENC_SCBLK_SIZE "codeblock-size" +#define ENC_SCBLK_SIZE_TEXT N_("Size of code blocks in each subband") + +static const char *enc_codeblock_size_list[] = { + "automatic", + "small", + "medium", + "large", + "full" +}; +static const char *const enc_codeblock_size_list_text[] = + { N_("automatic - let encoder decide based upon input (Best)"), + N_("small - use small code blocks"), + N_("medium - use medium sized code blocks"), + N_("large - use large code blocks"), + N_("full - One code block per subband"), + }; + +/* advanced option only */ +#define ENC_ME_HIERARCHICAL "enable-hierarchical-me" +#define ENC_ME_HIERARCHICAL_TEXT N_("Enable hierarchical Motion Estimation") + +/* advanced option only */ +#define ENC_ME_DOWNSAMPLE_LEVELS "downsample-levels" +#define ENC_ME_DOWNSAMPLE_LEVELS_TEXT N_("Number of levels of downsampling") +#define ENC_ME_DOWNSAMPLE_LEVELS_LONGTEXT N_("Number of levels of downsampling in hierarchical motion estimation mode") + +/* advanced option only */ +#define ENC_ME_GLOBAL_MOTION "enable-global-me" +#define ENC_ME_GLOBAL_MOTION_TEXT N_("Enable Global Motion Estimation") + +/* advanced option only */ +#define ENC_ME_PHASECORR "enable-phasecorr-me" +#define ENC_ME_PHASECORR_TEXT N_("Enable Phase Correlation Estimation") + +/* advanced option only */ +#define ENC_SCD "enable-scd" +#define ENC_SCD_TEXT N_("Enable Scene Change Detection") + +/* advanced option only */ +#define ENC_FORCE_PROFILE "force-profile" +#define ENC_FORCE_PROFILE_TEXT N_("Force Profile") + +static const char *enc_profile_list[] = { + "auto", + "vc2_low_delay", + "vc2_simple", + "vc2_main", + "main" +}; + +static const char *const enc_profile_list_text[] = + { N_("automatic - let encoder decide based upon input (Best)"), + N_("VC2 Low Delay Profile"), + N_("VC2 Simple Profile"), + N_("VC2 Main Profile"), + N_("Main Profile"), + }; + +static const char *const ppsz_enc_options[] = { + ENC_RATE_CONTROL, ENC_GOP_STRUCTURE, ENC_QUALITY, ENC_NOISE_THRESHOLD, ENC_BITRATE, + ENC_MIN_BITRATE, ENC_MAX_BITRATE, ENC_AU_DISTANCE, ENC_CHROMAFMT, + ENC_PREFILTER, ENC_PREFILTER_STRENGTH, ENC_CODINGMODE, ENC_MCBLK_SIZE, + ENC_MCBLK_OVERLAP, ENC_MVPREC, ENC_ME_COMBINED, ENC_DWTINTRA, ENC_DWTINTER, + ENC_DWTDEPTH, ENC_MULTIQUANT, ENC_NOAC, ENC_PWT, ENC_PDIST, ENC_HSLICES, + ENC_VSLICES, ENC_SCBLK_SIZE, ENC_ME_HIERARCHICAL, ENC_ME_DOWNSAMPLE_LEVELS, + ENC_ME_GLOBAL_MOTION, ENC_ME_PHASECORR, ENC_SCD, ENC_FORCE_PROFILE, + NULL +}; + + +/* Module declaration */ vlc_module_begin () set_category( CAT_INPUT ) set_subcategory( SUBCAT_INPUT_VCODEC ) - set_description( N_("Schroedinger video decoder") ) + set_shortname( "Schroedinger" ) + set_description( N_("Dirac video decoder using libschroedinger") ) set_capability( "decoder", 200 ) set_callbacks( OpenDecoder, CloseDecoder ) add_shortcut( "schroedinger" ) + /* encoder */ add_submodule() + set_section( N_("Encoding") , NULL ) set_description( N_("Dirac video encoder using libschroedinger") ) set_capability( "encoder", 110 ) set_callbacks( OpenEncoder, CloseEncoder ) add_shortcut( "schroedinger", "schro" ) - int i_numopts = schro_encoder_get_n_settings(); - /* Allocate for schro encoder options + chroma format + coding mode - + null */ - ppsz_enc_options = (const char **)malloc( sizeof( char * )*( i_numopts + 3 ) ); - if( unlikely( ppsz_enc_options == NULL ) ) - return VLC_ENOMEM; + add_string( ENC_CFG_PREFIX ENC_RATE_CONTROL, NULL, + ENC_RATE_CONTROL_TEXT, ENC_RATE_CONTROL_LONGTEXT, false ) + change_string_list( enc_rate_control_list, enc_rate_control_list_text ) - for( int i = 0; i < i_numopts; ++i ) { - const SchroEncoderSetting *p_setting = schro_encoder_get_setting_info( i ); - bool b_advanced = ( strlen( p_setting->name ) > 6 && !strncmp( p_setting->name, "magic_ ", 6 ) ); - char *p_cfg_setting_name = malloc( strlen( ENC_CFG_PREFIX ) + strlen( p_setting->name ) + 1 ); + add_float( ENC_CFG_PREFIX ENC_QUALITY, -1., + ENC_QUALITY_TEXT, ENC_QUALITY_LONGTEXT, false ) + change_float_range(-1., 10.); - if( unlikely( p_cfg_setting_name == NULL ) ) - return VLC_ENOMEM; + add_float( ENC_CFG_PREFIX ENC_NOISE_THRESHOLD, -1., + ENC_NOISE_THRESHOLD_TEXT, ENC_NOISE_THRESHOLD_LONGTEXT, false ) + change_float_range(-1., 100.); - strcpy( p_cfg_setting_name, ENC_CFG_PREFIX ); - strcat( p_cfg_setting_name, p_setting->name ); + add_integer( ENC_CFG_PREFIX ENC_BITRATE, -1, + ENC_BITRATE_TEXT, ENC_BITRATE_LONGTEXT, false ) + change_integer_range(-1, INT_MAX); - ppsz_enc_options[i] = strdup( p_setting->name ); - switch( p_setting->type ) { - case SCHRO_ENCODER_SETTING_TYPE_BOOLEAN: - add_bool( p_cfg_setting_name, p_setting->default_value, p_setting->name, p_setting->name, b_advanced ); - break; - case SCHRO_ENCODER_SETTING_TYPE_INT: - add_integer( p_cfg_setting_name, p_setting->default_value, p_setting->name, p_setting->name, b_advanced ); - change_integer_range( p_setting->min, p_setting->max ); - break; - case SCHRO_ENCODER_SETTING_TYPE_DOUBLE: - add_float( p_cfg_setting_name, p_setting->default_value, p_setting->name, p_setting->name, b_advanced ); - change_float_range( p_setting->min, p_setting->max ); - break; - case SCHRO_ENCODER_SETTING_TYPE_ENUM: - add_string( p_cfg_setting_name, p_setting->enum_list[(int)p_setting->default_value], p_setting->name, p_setting->name, b_advanced ); - vlc_config_set( p_config, VLC_CONFIG_LIST, (int)(p_setting->max-p_setting->min+1), p_setting->enum_list, p_setting->enum_list, 0 ); - break; - default: - break; - } - free( p_cfg_setting_name ); - } + add_integer( ENC_CFG_PREFIX ENC_MAX_BITRATE, -1, + ENC_MAX_BITRATE_TEXT, ENC_MAX_BITRATE_LONGTEXT, false ) + change_integer_range(-1, INT_MAX); + + add_integer( ENC_CFG_PREFIX ENC_MIN_BITRATE, -1, + ENC_MIN_BITRATE_TEXT, ENC_MIN_BITRATE_LONGTEXT, false ) + change_integer_range(-1, INT_MAX); + + add_string( ENC_CFG_PREFIX ENC_GOP_STRUCTURE, NULL, + ENC_GOP_STRUCTURE_TEXT, ENC_GOP_STRUCTURE_LONGTEXT, false ) + change_string_list( enc_gop_structure_list, enc_gop_structure_list_text ) + + add_integer( ENC_CFG_PREFIX ENC_AU_DISTANCE, -1, + ENC_AU_DISTANCE_TEXT, ENC_AU_DISTANCE_LONGTEXT, false ) + change_integer_range(-1, INT_MAX); - ppsz_enc_options[i_numopts] = strdup( ENC_CHROMAFMT ); add_string( ENC_CFG_PREFIX ENC_CHROMAFMT, "420", ENC_CHROMAFMT_TEXT, ENC_CHROMAFMT_LONGTEXT, false ) - change_string_list( enc_chromafmt_list, enc_chromafmt_list_text, 0 ); + change_string_list( enc_chromafmt_list, enc_chromafmt_list_text ) - ppsz_enc_options[i_numopts+1] = strdup( ENC_CODINGMODE ); - add_bool( ENC_CFG_PREFIX ENC_CODINGMODE, true, + add_string( ENC_CFG_PREFIX ENC_CODINGMODE, "auto", ENC_CODINGMODE_TEXT, ENC_CODINGMODE_LONGTEXT, false ) - - ppsz_enc_options[i_numopts+2] = NULL; - + change_string_list( enc_codingmode_list, enc_codingmode_list_text ) + + add_string( ENC_CFG_PREFIX ENC_MVPREC, NULL, + ENC_MVPREC_TEXT, ENC_MVPREC_LONGTEXT, false ) + change_string_list( enc_mvprec_list, enc_mvprec_list ) + + /* advanced option only */ + add_string( ENC_CFG_PREFIX ENC_MCBLK_SIZE, NULL, + ENC_MCBLK_SIZE_TEXT, ENC_MCBLK_SIZE_TEXT, true ) + change_string_list( enc_block_size_list, enc_block_size_list_text ) + + + /* advanced option only */ + add_string( ENC_CFG_PREFIX ENC_MCBLK_OVERLAP, NULL, + ENC_MCBLK_OVERLAP_TEXT, ENC_MCBLK_OVERLAP_TEXT, true ) + change_string_list( enc_block_overlap_list, enc_block_overlap_list_text ) + + /* advanced option only */ + add_integer( ENC_CFG_PREFIX ENC_ME_COMBINED, -1, + ENC_ME_COMBINED_TEXT, ENC_ME_COMBINED_LONGTEXT, true ) + change_integer_range(-1, 1 ); + + /* advanced option only */ + add_integer( ENC_CFG_PREFIX ENC_ME_HIERARCHICAL, -1, + ENC_ME_HIERARCHICAL_TEXT, ENC_ME_HIERARCHICAL_TEXT, true ) + change_integer_range(-1, 1 ); + + /* advanced option only */ + add_integer( ENC_CFG_PREFIX ENC_ME_DOWNSAMPLE_LEVELS, -1, + ENC_ME_DOWNSAMPLE_LEVELS_TEXT, ENC_ME_DOWNSAMPLE_LEVELS_LONGTEXT, true ) + change_integer_range(-1, 8 ); + + /* advanced option only */ + add_integer( ENC_CFG_PREFIX ENC_ME_GLOBAL_MOTION, -1, + ENC_ME_GLOBAL_MOTION_TEXT, ENC_ME_GLOBAL_MOTION_TEXT, true ) + change_integer_range(-1, 1 ); + + /* advanced option only */ + add_integer( ENC_CFG_PREFIX ENC_ME_PHASECORR, -1, + ENC_ME_PHASECORR_TEXT, ENC_ME_PHASECORR_TEXT, true ) + change_integer_range(-1, 1 ); + + add_string( ENC_CFG_PREFIX ENC_DWTINTRA, NULL, + ENC_DWTINTRA_TEXT, ENC_DWTINTRA_TEXT, false ) + change_string_list( enc_wavelet_list, enc_wavelet_list_text ) + + add_string( ENC_CFG_PREFIX ENC_DWTINTER, NULL, + ENC_DWTINTER_TEXT, ENC_DWTINTER_TEXT, false ) + change_string_list( enc_wavelet_list, enc_wavelet_list_text ) + + add_integer( ENC_CFG_PREFIX ENC_DWTDEPTH, -1, + ENC_DWTDEPTH_TEXT, ENC_DWTDEPTH_LONGTEXT, false ) + change_integer_range(-1, SCHRO_LIMIT_ENCODER_TRANSFORM_DEPTH ); + + /* advanced option only */ + add_integer( ENC_CFG_PREFIX ENC_MULTIQUANT, -1, + ENC_MULTIQUANT_TEXT, ENC_MULTIQUANT_LONGTEXT, true ) + change_integer_range(-1, 1 ); + + /* advanced option only */ + add_string( ENC_CFG_PREFIX ENC_SCBLK_SIZE, NULL, + ENC_SCBLK_SIZE_TEXT, ENC_SCBLK_SIZE_TEXT, true ) + change_string_list( enc_codeblock_size_list, enc_codeblock_size_list_text ) + + add_string( ENC_CFG_PREFIX ENC_PREFILTER, NULL, + ENC_PREFILTER_TEXT, ENC_PREFILTER_LONGTEXT, false ) + change_string_list( enc_filtering_list, enc_filtering_list_text ) + + add_float( ENC_CFG_PREFIX ENC_PREFILTER_STRENGTH, -1., + ENC_PREFILTER_STRENGTH_TEXT, ENC_PREFILTER_STRENGTH_LONGTEXT, false ) + change_float_range(-1., 100.0); + + /* advanced option only */ + add_integer( ENC_CFG_PREFIX ENC_SCD, -1, + ENC_SCD_TEXT, ENC_SCD_TEXT, true ) + change_integer_range(-1, 1 ); + + /* advanced option only */ + add_string( ENC_CFG_PREFIX ENC_PWT, NULL, + ENC_PWT_TEXT, ENC_PWT_TEXT, true ) + change_string_list( enc_perceptual_weighting_list, enc_perceptual_weighting_list ) + + /* advanced option only */ + add_float( ENC_CFG_PREFIX ENC_PDIST, -1, + ENC_PDIST_TEXT, ENC_PDIST_LONGTEXT, true ) + change_float_range(-1., 100.); + + /* advanced option only */ + add_integer( ENC_CFG_PREFIX ENC_NOAC, -1, + ENC_NOAC_TEXT, ENC_NOAC_LONGTEXT, true ) + change_integer_range(-1, 1 ); + + /* advanced option only */ + add_integer( ENC_CFG_PREFIX ENC_HSLICES, -1, + ENC_HSLICES_TEXT, ENC_HSLICES_LONGTEXT, true ) + change_integer_range(-1, INT_MAX ); + + /* advanced option only */ + add_integer( ENC_CFG_PREFIX ENC_VSLICES, -1, + ENC_VSLICES_TEXT, ENC_VSLICES_LONGTEXT, true ) + change_integer_range(-1, INT_MAX ); + + /* advanced option only */ + add_string( ENC_CFG_PREFIX ENC_FORCE_PROFILE, NULL, + ENC_FORCE_PROFILE_TEXT, ENC_FORCE_PROFILE_TEXT, true ) + change_string_list( enc_profile_list, enc_profile_list_text ) vlc_module_end () + /***************************************************************************** * Local prototypes *****************************************************************************/ @@ -218,7 +602,7 @@ static void SetVideoFormat( decoder_t *p_dec ) p_sys->p_format = schro_decoder_get_video_format(p_sys->p_schro); if( p_sys->p_format == NULL ) return; - p_sys->i_frame_pts_delta = INT64_C(1000000) + p_sys->i_frame_pts_delta = CLOCK_FREQ * p_sys->p_format->frame_rate_denominator / p_sys->p_format->frame_rate_numerator; @@ -489,9 +873,9 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pict ); *****************************************************************************/ struct picture_pts_t { - bool b_empty; /* entry is invalid */ - uint32_t u_pnum; /* dirac picture number */ mtime_t i_pts; /* associated pts */ + uint32_t u_pnum; /* dirac picture number */ + bool b_empty; /* entry is invalid */ }; /***************************************************************************** @@ -554,7 +938,7 @@ static struct static void ResetPTStlb( encoder_t *p_enc ) { encoder_sys_t *p_sys = p_enc->p_sys; - for( int i=0; ipts_tlb[i].b_empty = true; } @@ -568,7 +952,7 @@ static void StorePicturePTS( encoder_t *p_enc, uint32_t u_pnum, mtime_t i_pts ) { encoder_sys_t *p_sys = p_enc->p_sys; - for( int i=0; ipts_tlb[i].b_empty ) { @@ -590,7 +974,7 @@ static mtime_t GetPicturePTS( encoder_t *p_enc, uint32_t u_pnum ) { encoder_sys_t *p_sys = p_enc->p_sys; - for( int i=0; ipts_tlb[i].b_empty && p_sys->pts_tlb[i].u_pnum == u_pnum ) @@ -604,21 +988,18 @@ static mtime_t GetPicturePTS( encoder_t *p_enc, uint32_t u_pnum ) return 0; } -static inline bool SchroSetEnum( const encoder_t *p_enc, const SchroEncoderSetting *p_setting, const char *psz_value ) { +static inline bool SchroSetEnum( const encoder_t *p_enc, int i_list_size, const char *list[], + const char *psz_name, const char *psz_name_text, const char *psz_value) +{ encoder_sys_t *p_sys = p_enc->p_sys; - if( psz_value && p_setting && p_setting->type == SCHRO_ENCODER_SETTING_TYPE_ENUM ) { - int i_index = -1; - int i_list_size = p_setting->max - p_setting->min + 1; + if( list && psz_name_text && psz_name && psz_value ) { for( int i = 0; i < i_list_size; ++i ) { - if( strcmp( p_setting->enum_list[i], psz_value ) ) + if( strcmp( list[i], psz_value ) ) continue; - i_index = p_setting->min + i; - schro_encoder_setting_set_double( p_sys->p_schro, p_setting->name, i_index ); + schro_encoder_setting_set_double( p_sys->p_schro, psz_name, i ); return true; } - if( i_index == -1 ) { - msg_Err( p_enc, "Invalid %s: %s", p_setting->name, psz_value ); - } + msg_Err( p_enc, "Invalid %s: %s", psz_name_text, psz_value ); } return false; } @@ -650,6 +1031,28 @@ static bool SetEncChromaFormat( encoder_t *p_enc, uint32_t i_codec ) return true; } +#define SCHRO_SET_FLOAT(psz_name, pschro_name) \ + f_tmp = var_GetFloat( p_enc, ENC_CFG_PREFIX psz_name ); \ + if( f_tmp >= 0.0 ) \ + schro_encoder_setting_set_double( p_sys->p_schro, pschro_name, f_tmp ); + +#define SCHRO_SET_INTEGER(psz_name, pschro_name, ignore_val) \ + i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX psz_name ); \ + if( i_tmp > ignore_val ) \ + schro_encoder_setting_set_double( p_sys->p_schro, pschro_name, i_tmp ); + +#define SCHRO_SET_ENUM(list, psz_name, psz_name_text, pschro_name) \ + psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX psz_name ); \ + if( !psz_tmp ) \ + goto error; \ + else if ( *psz_tmp != '\0' ) { \ + int i_list_size = ARRAY_SIZE(list); \ + if( !SchroSetEnum( p_enc, i_list_size, list, pschro_name, psz_name_text, psz_tmp ) ) { \ + free( psz_tmp ); \ + goto error; \ + } \ + } \ + free( psz_tmp ); /***************************************************************************** * OpenEncoder: probe the encoder and return score @@ -657,10 +1060,9 @@ static bool SetEncChromaFormat( encoder_t *p_enc, uint32_t i_codec ) static int OpenEncoder( vlc_object_t *p_this ) { encoder_t *p_enc = (encoder_t *)p_this; - encoder_sys_t *p_sys = p_enc->p_sys; + encoder_sys_t *p_sys; int i_tmp; float f_tmp; - bool b_tmp; char *psz_tmp; if( p_enc->fmt_out.i_codec != VLC_CODEC_DIRAC && @@ -670,7 +1072,7 @@ static int OpenEncoder( vlc_object_t *p_this ) } if( !p_enc->fmt_in.video.i_frame_rate || !p_enc->fmt_in.video.i_frame_rate_base || - !p_enc->fmt_in.video.i_height || !p_enc->fmt_in.video.i_width ) + !p_enc->fmt_in.video.i_visible_height || !p_enc->fmt_in.video.i_visible_width ) { msg_Err( p_enc, "Framerate and picture dimensions must be non-zero" ); return VLC_EGENERIC; @@ -736,8 +1138,8 @@ static int OpenEncoder( vlc_object_t *p_this ) schro_video_format_set_std_video_format( p_sys->p_format, guessed_video_fmt ); /* constants set from the input video format */ - p_sys->p_format->width = p_enc->fmt_in.video.i_width; - p_sys->p_format->height = p_enc->fmt_in.video.i_height; + p_sys->p_format->width = p_enc->fmt_in.video.i_visible_width; + p_sys->p_format->height = p_enc->fmt_in.video.i_visible_height; p_sys->p_format->frame_rate_numerator = p_enc->fmt_in.video.i_frame_rate; p_sys->p_format->frame_rate_denominator = p_enc->fmt_in.video.i_frame_rate_base; unsigned u_asr_num, u_asr_den; @@ -749,53 +1151,9 @@ static int OpenEncoder( vlc_object_t *p_this ) config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg ); - int i_numopts = schro_encoder_get_n_settings(); + SCHRO_SET_ENUM(enc_rate_control_list, ENC_RATE_CONTROL, ENC_RATE_CONTROL_TEXT, "rate_control") - for( int i = 0; i < i_numopts; ++i ) { - const SchroEncoderSetting *p_setting = schro_encoder_get_setting_info( i ); - char *p_cfg_setting_name = malloc( strlen( ENC_CFG_PREFIX ) + strlen( p_setting->name ) + 1 ); - if( unlikely( p_cfg_setting_name == NULL ) ) - return VLC_ENOMEM; - - strcpy( p_cfg_setting_name, ENC_CFG_PREFIX ); - strcat( p_cfg_setting_name, p_setting->name ); - - switch( p_setting->type ) { - case SCHRO_ENCODER_SETTING_TYPE_BOOLEAN: - schro_encoder_setting_set_double ( p_sys->p_schro, p_setting->name, var_GetBool( p_enc, p_cfg_setting_name ) ); - break; - case SCHRO_ENCODER_SETTING_TYPE_INT: - i_tmp = var_GetInteger( p_enc, p_cfg_setting_name ); - schro_encoder_setting_set_double( p_sys->p_schro, p_setting->name, i_tmp ); - /* A kludge to set bitrate to the value in sout-transcode-vb */ - if( !strcmp( p_setting->name, "bitrate" ) ) { - if( i_tmp == p_setting->default_value ) - schro_encoder_setting_set_double( p_sys->p_schro, p_setting->name, p_enc->fmt_out.i_bitrate ); - p_enc->fmt_out.i_bitrate = schro_encoder_setting_get_double( p_sys->p_schro, p_setting->name ); - } - break; - case SCHRO_ENCODER_SETTING_TYPE_DOUBLE: - f_tmp = var_GetFloat( p_enc, p_cfg_setting_name ); - if( f_tmp >= 0.0 ) - schro_encoder_setting_set_double( p_sys->p_schro, p_setting->name, f_tmp ); - break; - case SCHRO_ENCODER_SETTING_TYPE_ENUM: - psz_tmp = var_GetString( p_enc, p_cfg_setting_name ); - if( !psz_tmp ) - goto error; - else if( *psz_tmp != '\0' ) { - if( !SchroSetEnum( p_enc, p_setting, psz_tmp ) ) { - free( psz_tmp ); - goto error; - } - } - free( psz_tmp ); - break; - default: - break; - } - free( p_cfg_setting_name ); - } + SCHRO_SET_ENUM(enc_gop_structure_list, ENC_GOP_STRUCTURE, ENC_GOP_STRUCTURE_TEXT, "gop_structure") psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_CHROMAFMT ); if( !psz_tmp ) @@ -820,12 +1178,116 @@ static int OpenEncoder( vlc_object_t *p_this ) } free( psz_tmp ); + SCHRO_SET_FLOAT(ENC_QUALITY, "quality") - b_tmp = var_GetBool( p_enc, ENC_CFG_PREFIX ENC_CODINGMODE ); - if( b_tmp == true ) - p_sys->b_auto_field_coding = true; + SCHRO_SET_FLOAT(ENC_NOISE_THRESHOLD, "noise_threshold") + + /* use bitrate from sout-transcode-vb in kbps */ + i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_BITRATE ); + if( i_tmp > -1 ) + schro_encoder_setting_set_double( p_sys->p_schro, "bitrate", i_tmp * 1000 ); else + schro_encoder_setting_set_double( p_sys->p_schro, "bitrate", p_enc->fmt_out.i_bitrate ); + + p_enc->fmt_out.i_bitrate = schro_encoder_setting_get_double( p_sys->p_schro, "bitrate" ); + + i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MIN_BITRATE ); + if( i_tmp > -1 ) + schro_encoder_setting_set_double( p_sys->p_schro, "min_bitrate", i_tmp * 1000 ); + + i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MAX_BITRATE ); + if( i_tmp > -1 ) + schro_encoder_setting_set_double( p_sys->p_schro, "max_bitrate", i_tmp * 1000 ); + + SCHRO_SET_INTEGER(ENC_AU_DISTANCE, "au_distance", -1) + + SCHRO_SET_ENUM(enc_filtering_list, ENC_PREFILTER, ENC_PREFILTER_TEXT, "filtering") + + SCHRO_SET_FLOAT(ENC_PREFILTER_STRENGTH, "filter_value") + + + psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_CODINGMODE ); + if( !psz_tmp ) + goto error; + else if( !strcmp( psz_tmp, "auto" ) ) { + p_sys->b_auto_field_coding = true; + } + else if( !strcmp( psz_tmp, "progressive" ) ) { + p_sys->b_auto_field_coding = false; + schro_encoder_setting_set_double( p_sys->p_schro, "interlaced_coding", false); + } + else if( !strcmp( psz_tmp, "field" ) ) { p_sys->b_auto_field_coding = false; + schro_encoder_setting_set_double( p_sys->p_schro, "interlaced_coding", true); + } + else { + msg_Err( p_enc, "Invalid codingmode: %s", psz_tmp ); + free( psz_tmp ); + goto error; + } + free( psz_tmp ); + + SCHRO_SET_ENUM(enc_block_size_list, ENC_MCBLK_SIZE, ENC_MCBLK_SIZE_TEXT, "motion_block_size") + + SCHRO_SET_ENUM(enc_block_overlap_list, ENC_MCBLK_OVERLAP, ENC_MCBLK_OVERLAP_TEXT, "motion_block_overlap") + + psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_MVPREC ); + if( !psz_tmp ) + goto error; + else if( *psz_tmp != '\0') { + if( !strcmp( psz_tmp, "1" ) ) { + schro_encoder_setting_set_double( p_sys->p_schro, "mv_precision", 0 ); + } + else if( !strcmp( psz_tmp, "1/2" ) ) { + schro_encoder_setting_set_double( p_sys->p_schro, "mv_precision", 1 ); + } + else if( !strcmp( psz_tmp, "1/4" ) ) { + schro_encoder_setting_set_double( p_sys->p_schro, "mv_precision", 2 ); + } + else if( !strcmp( psz_tmp, "1/8" ) ) { + schro_encoder_setting_set_double( p_sys->p_schro, "mv_precision", 3 ); + } + else { + msg_Err( p_enc, "Invalid mv_precision: %s", psz_tmp ); + free( psz_tmp ); + goto error; + } + } + free( psz_tmp ); + + SCHRO_SET_INTEGER(ENC_ME_COMBINED, "enable_chroma_me", -1) + + SCHRO_SET_ENUM(enc_wavelet_list, ENC_DWTINTRA, ENC_DWTINTRA_TEXT, "intra_wavelet") + + SCHRO_SET_ENUM(enc_wavelet_list, ENC_DWTINTER, ENC_DWTINTER_TEXT, "inter_wavelet") + + SCHRO_SET_INTEGER(ENC_DWTDEPTH, "transform_depth", -1) + + SCHRO_SET_INTEGER(ENC_MULTIQUANT, "enable_multiquant", -1) + + SCHRO_SET_INTEGER(ENC_NOAC, "enable_noarith", -1) + + SCHRO_SET_ENUM(enc_perceptual_weighting_list, ENC_PWT, ENC_PWT_TEXT, "perceptual_weighting") + + SCHRO_SET_FLOAT(ENC_PDIST, "perceptual_distance") + + SCHRO_SET_INTEGER(ENC_HSLICES, "horiz_slices", -1) + + SCHRO_SET_INTEGER(ENC_VSLICES, "vert_slices", -1) + + SCHRO_SET_ENUM(enc_codeblock_size_list, ENC_SCBLK_SIZE, ENC_SCBLK_SIZE_TEXT, "codeblock_size") + + SCHRO_SET_INTEGER(ENC_ME_HIERARCHICAL, "enable_hierarchical_estimation", -1) + + SCHRO_SET_INTEGER(ENC_ME_DOWNSAMPLE_LEVELS, "downsample_levels", 1) + + SCHRO_SET_INTEGER(ENC_ME_GLOBAL_MOTION, "enable_global_motion", -1) + + SCHRO_SET_INTEGER(ENC_ME_PHASECORR, "enable_phasecorr_estimation", -1) + + SCHRO_SET_INTEGER(ENC_SCD, "enable_scene_change_detection", -1) + + SCHRO_SET_ENUM(enc_profile_list, ENC_FORCE_PROFILE, ENC_FORCE_PROFILE_TEXT, "force_profile") p_sys->started = 0; @@ -1021,7 +1483,7 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pic ) /* store dts in a queue, so that they appear in order in * coded order */ - p_block = block_New( p_enc, 1 ); + p_block = block_Alloc( 1 ); if( !p_block ) return NULL; p_block->i_dts = p_pic->date - p_sys->i_pts_offset; @@ -1035,7 +1497,7 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pic ) StorePicturePTS( p_enc, p_sys->i_input_picnum, p_pic->date + p_sys->i_field_time ); p_sys->i_input_picnum++; - p_block = block_New( p_enc, 1 ); + p_block = block_Alloc( 1 ); if( !p_block ) return NULL; p_block->i_dts = p_pic->date - p_sys->i_pts_offset + p_sys->i_field_time; @@ -1065,7 +1527,7 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pic ) uint32_t u_pic_num; int i_presentation_frame; p_enc_buf = schro_encoder_pull( p_sys->p_schro, &i_presentation_frame ); - p_block = block_New( p_enc, p_enc_buf->length ); + p_block = block_Alloc( p_enc_buf->length ); if( !p_block ) return NULL; @@ -1091,7 +1553,7 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pic ) return NULL; memcpy( p_enc->fmt_out.p_extra, p_block->p_buffer, len ); memcpy( (uint8_t*)p_enc->fmt_out.p_extra + len, eos, sizeof( eos ) ); - SetDWBE( (uint8_t*)p_enc->fmt_out.p_extra + len + 10, len ); + SetDWBE( (uint8_t*)p_enc->fmt_out.p_extra + len + sizeof(eos) - 4, len ); p_enc->fmt_out.i_extra = len + sizeof( eos ); } }