mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-08 16:35:40 +00:00
audioconvert: Add dithering-threshold property
By default, no dithering is applied if the target bit depth is above 20 bits. This new property allows to apply dithering nonetheless in these cases. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1730>
This commit is contained in:
parent
e10bd02e1d
commit
3941eb7dbd
5 changed files with 54 additions and 3 deletions
|
@ -813,6 +813,20 @@
|
|||
"type": "GstAudioDitherMethod",
|
||||
"writable": true
|
||||
},
|
||||
"dithering-threshold": {
|
||||
"blurb": "Threshold for the output bit depth at/below which to apply dithering.",
|
||||
"conditionally-available": false,
|
||||
"construct": false,
|
||||
"construct-only": false,
|
||||
"controllable": false,
|
||||
"default": "20",
|
||||
"max": "32",
|
||||
"min": "0",
|
||||
"mutable": "null",
|
||||
"readable": true,
|
||||
"type": "guint",
|
||||
"writable": true
|
||||
},
|
||||
"mix-matrix": {
|
||||
"blurb": "Transformation matrix for input/output channels",
|
||||
"conditionally-available": false,
|
||||
|
|
|
@ -263,7 +263,6 @@ audio_chain_get_samples (AudioChain * chain, gsize * avail)
|
|||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
static guint
|
||||
get_opt_uint (GstAudioConverter * convert, const gchar * opt, guint def)
|
||||
{
|
||||
|
@ -272,7 +271,6 @@ get_opt_uint (GstAudioConverter * convert, const gchar * opt, guint def)
|
|||
res = def;
|
||||
return res;
|
||||
}
|
||||
*/
|
||||
|
||||
static gint
|
||||
get_opt_enum (GstAudioConverter * convert, const gchar * opt, GType type,
|
||||
|
@ -292,6 +290,7 @@ get_opt_value (GstAudioConverter * convert, const gchar * opt)
|
|||
|
||||
#define DEFAULT_OPT_RESAMPLER_METHOD GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL
|
||||
#define DEFAULT_OPT_DITHER_METHOD GST_AUDIO_DITHER_NONE
|
||||
#define DEFAULT_OPT_DITHER_THRESHOLD 20
|
||||
#define DEFAULT_OPT_NOISE_SHAPING_METHOD GST_AUDIO_NOISE_SHAPING_NONE
|
||||
#define DEFAULT_OPT_QUANTIZATION 1
|
||||
|
||||
|
@ -301,6 +300,8 @@ get_opt_value (GstAudioConverter * convert, const gchar * opt)
|
|||
#define GET_OPT_DITHER_METHOD(c) get_opt_enum(c, \
|
||||
GST_AUDIO_CONVERTER_OPT_DITHER_METHOD, GST_TYPE_AUDIO_DITHER_METHOD, \
|
||||
DEFAULT_OPT_DITHER_METHOD)
|
||||
#define GET_OPT_DITHER_THRESHOLD(c) get_opt_uint(c, \
|
||||
GST_AUDIO_CONVERTER_OPT_DITHER_THRESHOLD, DEFAULT_OPT_DITHER_THRESHOLD)
|
||||
#define GET_OPT_NOISE_SHAPING_METHOD(c) get_opt_enum(c, \
|
||||
GST_AUDIO_CONVERTER_OPT_NOISE_SHAPING_METHOD, GST_TYPE_AUDIO_NOISE_SHAPING_METHOD, \
|
||||
DEFAULT_OPT_NOISE_SHAPING_METHOD)
|
||||
|
@ -951,9 +952,11 @@ chain_quantize (GstAudioConverter * convert, AudioChain * prev)
|
|||
gint in_depth, out_depth;
|
||||
gboolean in_int, out_int;
|
||||
GstAudioDitherMethod dither;
|
||||
guint dither_threshold;
|
||||
GstAudioNoiseShapingMethod ns;
|
||||
|
||||
dither = GET_OPT_DITHER_METHOD (convert);
|
||||
dither_threshold = GET_OPT_DITHER_THRESHOLD (convert);
|
||||
ns = GET_OPT_NOISE_SHAPING_METHOD (convert);
|
||||
|
||||
cur_finfo = gst_audio_format_get_info (convert->current_format);
|
||||
|
@ -969,7 +972,7 @@ chain_quantize (GstAudioConverter * convert, AudioChain * prev)
|
|||
* as DA converters only can do a SNR up to 20 bits in reality.
|
||||
* Also don't dither or apply noise shaping if target depth is larger than
|
||||
* source depth. */
|
||||
if (out_depth > 20 || (in_int && out_depth >= in_depth)) {
|
||||
if (out_depth > dither_threshold || (in_int && out_depth >= in_depth)) {
|
||||
dither = GST_AUDIO_DITHER_NONE;
|
||||
ns = GST_AUDIO_NOISE_SHAPING_NONE;
|
||||
GST_INFO ("using no dither and noise shaping");
|
||||
|
|
|
@ -106,6 +106,17 @@ typedef struct _GstAudioConverter GstAudioConverter;
|
|||
*/
|
||||
#define GST_AUDIO_CONVERTER_OPT_MIX_MATRIX "GstAudioConverter.mix-matrix"
|
||||
|
||||
/**
|
||||
* GST_AUDIO_CONVERTER_OPT_DITHER_THRESHOLD:
|
||||
*
|
||||
* Threshold for the output bit depth at/below which to apply dithering.
|
||||
*
|
||||
* Default is 20 bit.
|
||||
*
|
||||
* Since: 1.22
|
||||
*/
|
||||
#define GST_AUDIO_CONVERTER_OPT_DITHER_THRESHOLD "GstAudioConverter.dither-threshold"
|
||||
|
||||
/**
|
||||
* GstAudioConverterFlags:
|
||||
* @GST_AUDIO_CONVERTER_FLAG_NONE: no flag
|
||||
|
|
|
@ -157,6 +157,7 @@ enum
|
|||
PROP_DITHERING,
|
||||
PROP_NOISE_SHAPING,
|
||||
PROP_MIX_MATRIX,
|
||||
PROP_DITHERING_THRESHOLD
|
||||
};
|
||||
|
||||
#define DEBUG_INIT \
|
||||
|
@ -224,6 +225,18 @@ gst_audio_convert_class_init (GstAudioConvertClass * klass)
|
|||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GstAudioConvert:dithering-threshold:
|
||||
*
|
||||
* Threshold for the output bit depth at/below which to apply dithering.
|
||||
*
|
||||
* Since: 1.22
|
||||
*/
|
||||
g_object_class_install_property (gobject_class, PROP_DITHERING_THRESHOLD,
|
||||
g_param_spec_uint ("dithering-threshold", "Dithering Threshold",
|
||||
"Threshold for the output bit depth at/below which to apply dithering.",
|
||||
0, 32, 20, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gst_element_class_add_static_pad_template (element_class,
|
||||
&gst_audio_convert_src_template);
|
||||
gst_element_class_add_static_pad_template (element_class,
|
||||
|
@ -260,6 +273,7 @@ static void
|
|||
gst_audio_convert_init (GstAudioConvert * this)
|
||||
{
|
||||
this->dither = GST_AUDIO_DITHER_TPDF;
|
||||
this->dither_threshold = 20;
|
||||
this->ns = GST_AUDIO_NOISE_SHAPING_NONE;
|
||||
g_value_init (&this->mix_matrix, GST_TYPE_ARRAY);
|
||||
|
||||
|
@ -765,6 +779,8 @@ gst_audio_convert_set_caps (GstBaseTransform * base, GstCaps * incaps,
|
|||
config = gst_structure_new ("GstAudioConverterConfig",
|
||||
GST_AUDIO_CONVERTER_OPT_DITHER_METHOD, GST_TYPE_AUDIO_DITHER_METHOD,
|
||||
this->dither,
|
||||
GST_AUDIO_CONVERTER_OPT_DITHER_THRESHOLD, G_TYPE_UINT,
|
||||
this->dither_threshold,
|
||||
GST_AUDIO_CONVERTER_OPT_NOISE_SHAPING_METHOD,
|
||||
GST_TYPE_AUDIO_NOISE_SHAPING_METHOD, this->ns, NULL);
|
||||
|
||||
|
@ -978,6 +994,9 @@ gst_audio_convert_set_property (GObject * object, guint prop_id,
|
|||
case PROP_NOISE_SHAPING:
|
||||
this->ns = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_DITHERING_THRESHOLD:
|
||||
this->dither_threshold = g_value_get_uint (value);
|
||||
break;
|
||||
case PROP_MIX_MATRIX:
|
||||
if (!gst_value_array_get_size (value)) {
|
||||
this->mix_matrix_is_set = FALSE;
|
||||
|
@ -1014,6 +1033,9 @@ gst_audio_convert_get_property (GObject * object, guint prop_id,
|
|||
case PROP_NOISE_SHAPING:
|
||||
g_value_set_enum (value, this->ns);
|
||||
break;
|
||||
case PROP_DITHERING_THRESHOLD:
|
||||
g_value_set_uint (value, this->dither_threshold);
|
||||
break;
|
||||
case PROP_MIX_MATRIX:
|
||||
if (this->mix_matrix_is_set)
|
||||
g_value_copy (&this->mix_matrix, value);
|
||||
|
|
|
@ -41,6 +41,7 @@ struct _GstAudioConvert
|
|||
|
||||
/* properties */
|
||||
GstAudioDitherMethod dither;
|
||||
guint dither_threshold;
|
||||
GstAudioNoiseShapingMethod ns;
|
||||
GValue mix_matrix;
|
||||
gboolean mix_matrix_is_set;
|
||||
|
|
Loading…
Reference in a new issue