mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-15 22:01:27 +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",
|
"type": "GstAudioDitherMethod",
|
||||||
"writable": true
|
"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": {
|
"mix-matrix": {
|
||||||
"blurb": "Transformation matrix for input/output channels",
|
"blurb": "Transformation matrix for input/output channels",
|
||||||
"conditionally-available": false,
|
"conditionally-available": false,
|
||||||
|
|
|
@ -263,7 +263,6 @@ audio_chain_get_samples (AudioChain * chain, gsize * avail)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
static guint
|
static guint
|
||||||
get_opt_uint (GstAudioConverter * convert, const gchar * opt, guint def)
|
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;
|
res = def;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
get_opt_enum (GstAudioConverter * convert, const gchar * opt, GType type,
|
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_RESAMPLER_METHOD GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL
|
||||||
#define DEFAULT_OPT_DITHER_METHOD GST_AUDIO_DITHER_NONE
|
#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_NOISE_SHAPING_METHOD GST_AUDIO_NOISE_SHAPING_NONE
|
||||||
#define DEFAULT_OPT_QUANTIZATION 1
|
#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, \
|
#define GET_OPT_DITHER_METHOD(c) get_opt_enum(c, \
|
||||||
GST_AUDIO_CONVERTER_OPT_DITHER_METHOD, GST_TYPE_AUDIO_DITHER_METHOD, \
|
GST_AUDIO_CONVERTER_OPT_DITHER_METHOD, GST_TYPE_AUDIO_DITHER_METHOD, \
|
||||||
DEFAULT_OPT_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, \
|
#define GET_OPT_NOISE_SHAPING_METHOD(c) get_opt_enum(c, \
|
||||||
GST_AUDIO_CONVERTER_OPT_NOISE_SHAPING_METHOD, GST_TYPE_AUDIO_NOISE_SHAPING_METHOD, \
|
GST_AUDIO_CONVERTER_OPT_NOISE_SHAPING_METHOD, GST_TYPE_AUDIO_NOISE_SHAPING_METHOD, \
|
||||||
DEFAULT_OPT_NOISE_SHAPING_METHOD)
|
DEFAULT_OPT_NOISE_SHAPING_METHOD)
|
||||||
|
@ -951,9 +952,11 @@ chain_quantize (GstAudioConverter * convert, AudioChain * prev)
|
||||||
gint in_depth, out_depth;
|
gint in_depth, out_depth;
|
||||||
gboolean in_int, out_int;
|
gboolean in_int, out_int;
|
||||||
GstAudioDitherMethod dither;
|
GstAudioDitherMethod dither;
|
||||||
|
guint dither_threshold;
|
||||||
GstAudioNoiseShapingMethod ns;
|
GstAudioNoiseShapingMethod ns;
|
||||||
|
|
||||||
dither = GET_OPT_DITHER_METHOD (convert);
|
dither = GET_OPT_DITHER_METHOD (convert);
|
||||||
|
dither_threshold = GET_OPT_DITHER_THRESHOLD (convert);
|
||||||
ns = GET_OPT_NOISE_SHAPING_METHOD (convert);
|
ns = GET_OPT_NOISE_SHAPING_METHOD (convert);
|
||||||
|
|
||||||
cur_finfo = gst_audio_format_get_info (convert->current_format);
|
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.
|
* 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
|
* Also don't dither or apply noise shaping if target depth is larger than
|
||||||
* source depth. */
|
* 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;
|
dither = GST_AUDIO_DITHER_NONE;
|
||||||
ns = GST_AUDIO_NOISE_SHAPING_NONE;
|
ns = GST_AUDIO_NOISE_SHAPING_NONE;
|
||||||
GST_INFO ("using no dither and noise shaping");
|
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"
|
#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:
|
* GstAudioConverterFlags:
|
||||||
* @GST_AUDIO_CONVERTER_FLAG_NONE: no flag
|
* @GST_AUDIO_CONVERTER_FLAG_NONE: no flag
|
||||||
|
|
|
@ -157,6 +157,7 @@ enum
|
||||||
PROP_DITHERING,
|
PROP_DITHERING,
|
||||||
PROP_NOISE_SHAPING,
|
PROP_NOISE_SHAPING,
|
||||||
PROP_MIX_MATRIX,
|
PROP_MIX_MATRIX,
|
||||||
|
PROP_DITHERING_THRESHOLD
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEBUG_INIT \
|
#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),
|
||||||
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_element_class_add_static_pad_template (element_class,
|
||||||
&gst_audio_convert_src_template);
|
&gst_audio_convert_src_template);
|
||||||
gst_element_class_add_static_pad_template (element_class,
|
gst_element_class_add_static_pad_template (element_class,
|
||||||
|
@ -260,6 +273,7 @@ static void
|
||||||
gst_audio_convert_init (GstAudioConvert * this)
|
gst_audio_convert_init (GstAudioConvert * this)
|
||||||
{
|
{
|
||||||
this->dither = GST_AUDIO_DITHER_TPDF;
|
this->dither = GST_AUDIO_DITHER_TPDF;
|
||||||
|
this->dither_threshold = 20;
|
||||||
this->ns = GST_AUDIO_NOISE_SHAPING_NONE;
|
this->ns = GST_AUDIO_NOISE_SHAPING_NONE;
|
||||||
g_value_init (&this->mix_matrix, GST_TYPE_ARRAY);
|
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",
|
config = gst_structure_new ("GstAudioConverterConfig",
|
||||||
GST_AUDIO_CONVERTER_OPT_DITHER_METHOD, GST_TYPE_AUDIO_DITHER_METHOD,
|
GST_AUDIO_CONVERTER_OPT_DITHER_METHOD, GST_TYPE_AUDIO_DITHER_METHOD,
|
||||||
this->dither,
|
this->dither,
|
||||||
|
GST_AUDIO_CONVERTER_OPT_DITHER_THRESHOLD, G_TYPE_UINT,
|
||||||
|
this->dither_threshold,
|
||||||
GST_AUDIO_CONVERTER_OPT_NOISE_SHAPING_METHOD,
|
GST_AUDIO_CONVERTER_OPT_NOISE_SHAPING_METHOD,
|
||||||
GST_TYPE_AUDIO_NOISE_SHAPING_METHOD, this->ns, NULL);
|
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:
|
case PROP_NOISE_SHAPING:
|
||||||
this->ns = g_value_get_enum (value);
|
this->ns = g_value_get_enum (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_DITHERING_THRESHOLD:
|
||||||
|
this->dither_threshold = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
case PROP_MIX_MATRIX:
|
case PROP_MIX_MATRIX:
|
||||||
if (!gst_value_array_get_size (value)) {
|
if (!gst_value_array_get_size (value)) {
|
||||||
this->mix_matrix_is_set = FALSE;
|
this->mix_matrix_is_set = FALSE;
|
||||||
|
@ -1014,6 +1033,9 @@ gst_audio_convert_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_NOISE_SHAPING:
|
case PROP_NOISE_SHAPING:
|
||||||
g_value_set_enum (value, this->ns);
|
g_value_set_enum (value, this->ns);
|
||||||
break;
|
break;
|
||||||
|
case PROP_DITHERING_THRESHOLD:
|
||||||
|
g_value_set_uint (value, this->dither_threshold);
|
||||||
|
break;
|
||||||
case PROP_MIX_MATRIX:
|
case PROP_MIX_MATRIX:
|
||||||
if (this->mix_matrix_is_set)
|
if (this->mix_matrix_is_set)
|
||||||
g_value_copy (&this->mix_matrix, value);
|
g_value_copy (&this->mix_matrix, value);
|
||||||
|
|
|
@ -41,6 +41,7 @@ struct _GstAudioConvert
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
GstAudioDitherMethod dither;
|
GstAudioDitherMethod dither;
|
||||||
|
guint dither_threshold;
|
||||||
GstAudioNoiseShapingMethod ns;
|
GstAudioNoiseShapingMethod ns;
|
||||||
GValue mix_matrix;
|
GValue mix_matrix;
|
||||||
gboolean mix_matrix_is_set;
|
gboolean mix_matrix_is_set;
|
||||||
|
|
Loading…
Reference in a new issue