* (http://www.bbc.co.uk/rd/projects/dirac/index.shtml)
* (http://diracvideo.org)
*****************************************************************************
- * Copyright (C) 2008 the VideoLAN team
- * $Id$
+ * Copyright (C) 2008-2011 the VideoLAN team
*
* Authors: Jonathan Rosser <jonathan.rosser@gmail.com>
* David Flynn <davidf at rd dot bbc.co.uk>
/*****************************************************************************
* Preamble
*****************************************************************************/
+
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_plugin.h>
-#include <vlc_codec.h>
-#include <vlc_sout.h>
+#include <vlc_codec.h> /* decoder_DeletePicture */
#include <schroedinger/schro.h>
#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")
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 sequenence 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 Ffilter"),
+};
+
+#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 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_callbacks( OpenDecoder, CloseDecoder )
add_shortcut( "schroedinger" )
+ /* encoder */
add_submodule()
set_section( N_("Encoding") , NULL )
set_description( N_("Dirac video encoder using libschroedinger") )
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, 0 );
- 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, 0 );
+
+ 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 );
- 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, 0 );
+
+ add_string( ENC_CFG_PREFIX ENC_MVPREC, NULL,
+ ENC_MVPREC_TEXT, ENC_MVPREC_LONGTEXT, false )
+ change_string_list( enc_mvprec_list, enc_mvprec_list, 0 );
+
+ /* 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, 0 );
+
+
+ /* 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, 0 );
+
+ /* 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, 0 );
+
+ 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, 0 );
+
+ 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, 0 );
+
+ 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, 0 );
+
+ 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, 0 );
+
+ /* 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, 0 );
vlc_module_end ()
+
/*****************************************************************************
* Local prototypes
*****************************************************************************/
*****************************************************************************/
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 */
};
/*****************************************************************************
static void ResetPTStlb( encoder_t *p_enc )
{
encoder_sys_t *p_sys = p_enc->p_sys;
- for( int i=0; i<SCHRO_PTS_TLB_SIZE; i++ )
+ for( int i = 0; i < SCHRO_PTS_TLB_SIZE; i++ )
{
p_sys->pts_tlb[i].b_empty = true;
}
{
encoder_sys_t *p_sys = p_enc->p_sys;
- for( int i=0; i<SCHRO_PTS_TLB_SIZE; i++ )
+ for( int i = 0; i<SCHRO_PTS_TLB_SIZE; i++ )
{
if( p_sys->pts_tlb[i].b_empty )
{
{
encoder_sys_t *p_sys = p_enc->p_sys;
- for( int i=0; i<SCHRO_PTS_TLB_SIZE; i++ )
+ for( int i = 0; i < SCHRO_PTS_TLB_SIZE; i++ )
{
if( !p_sys->pts_tlb[i].b_empty &&
p_sys->pts_tlb[i].u_pnum == 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;
}
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
encoder_sys_t *p_sys = p_enc->p_sys;
int i_tmp;
float f_tmp;
- bool b_tmp;
char *psz_tmp;
if( p_enc->fmt_out.i_codec != VLC_CODEC_DIRAC &&
config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
- int i_numopts = schro_encoder_get_n_settings();
-
- 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;
+ SCHRO_SET_ENUM(enc_rate_control_list, ENC_RATE_CONTROL, ENC_RATE_CONTROL_TEXT, "rate_control")
- 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 )
}
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;