audioconvert: allow empty mix matrix

When an empty mix matrix is passed, audio-channel-mixer
will now generate a (potentially truncated) identity matrix,
this replicates the behaviour of audiomixmatrix in first-channels
mode.

https://bugzilla.gnome.org/show_bug.cgi?id=788833
This commit is contained in:
Mathieu Duponchelle 2017-10-11 18:03:20 +02:00
parent 464d10f5c2
commit d4db88772b
4 changed files with 22 additions and 10 deletions

View file

@ -796,8 +796,8 @@ gst_audio_channel_mixer_mix_double (GstAudioChannelMixer * mix,
* @in_channels: number of input channels
* @out_channels: number of output channels
* @matrix: (transfer full) (nullable): channel conversion matrix, m[@in_channels][@out_channels].
* If identity matrix, passthrough applies. If %NULL, @in_channels must be
* equal to @out_channels, in which case an identity matrix is generated.
* If identity matrix, passthrough applies. If %NULL, a (potentially truncated)
* identity matrix is generated.
*
* Create a new channel mixer object for the given parameters.
*
@ -820,14 +820,13 @@ gst_audio_channel_mixer_new_with_matrix (GstAudioChannelMixerFlags flags,
|| format == GST_AUDIO_FORMAT_F64, NULL);
g_return_val_if_fail (in_channels > 0 && in_channels < 64, NULL);
g_return_val_if_fail (out_channels > 0 && out_channels < 64, NULL);
g_return_val_if_fail (matrix != NULL || in_channels == out_channels, NULL);
mix = g_slice_new0 (GstAudioChannelMixer);
mix->in_channels = in_channels;
mix->out_channels = out_channels;
if (!matrix) {
/* Generate identity matrix */
/* Generate (potentially truncated) identity matrix */
gint i, j;
mix->matrix = g_new0 (gfloat *, in_channels);

View file

@ -637,6 +637,10 @@ check_mix_matrix (guint in_channels, guint out_channels, const GValue * value)
{
guint i, j;
/* audio-channel-mixer will generate an identity matrix */
if (gst_value_array_get_size (value) == 0)
return TRUE;
if (gst_value_array_get_size (value) != out_channels) {
GST_ERROR ("Invalid mix matrix size, should be %d", out_channels);
goto fail;
@ -704,8 +708,11 @@ chain_mix (GstAudioConverter * convert, AudioChain * prev)
convert->current_channels = out->channels;
if (opt_matrix) {
gfloat **matrix =
mix_matrix_from_g_value (in->channels, out->channels, opt_matrix);
gfloat **matrix = NULL;
if (gst_value_array_get_size (opt_matrix))
matrix =
mix_matrix_from_g_value (in->channels, out->channels, opt_matrix);
convert->mix =
gst_audio_channel_mixer_new_with_matrix (0, format, in->channels,

View file

@ -72,6 +72,9 @@
* |[
* gst-launch-1.0 audiotestsrc ! audio/x-raw, channels=4 ! audioconvert mix-matrix="<<(float)1.0, (float)0.0, (float)0.0, (float)0.0>, <(float)0.0, (float)1.0, (float)0.0, (float)0.0>>" ! audio/x-raw,channels=2 ! autoaudiosink
* ]|
*
* > If an empty mix matrix is specified, a (potentially truncated)
* > identity matrix will be generated.
*/
/*
@ -300,7 +303,7 @@ remove_channels_from_structure (GstCapsFeatures * features, GstStructure * s,
/* Only remove the channels and channel-mask for non-NONE layouts,
* or if a mix matrix was manually specified */
if (gst_value_array_get_size (&this->mix_matrix) ||
if (this->mix_matrix_was_set ||
!gst_structure_get (s, "channel-mask", GST_TYPE_BITMASK, &mask, NULL) ||
(mask != 0 || (gst_structure_get_int (s, "channels", &channels)
&& channels == 1))) {
@ -733,7 +736,7 @@ gst_audio_convert_set_caps (GstBaseTransform * base, GstCaps * incaps,
GST_AUDIO_CONVERTER_OPT_NOISE_SHAPING_METHOD,
GST_TYPE_AUDIO_NOISE_SHAPING_METHOD, this->ns, NULL);
if (gst_value_array_get_size (&this->mix_matrix))
if (this->mix_matrix_was_set)
gst_structure_set_value (config, GST_AUDIO_CONVERTER_OPT_MIX_MATRIX,
&this->mix_matrix);
@ -933,7 +936,8 @@ gst_audio_convert_set_property (GObject * object, guint prop_id,
break;
case PROP_MIX_MATRIX:
if (!gst_value_array_get_size (value)) {
g_warning ("Empty mix matrix");
g_value_copy (value, &this->mix_matrix);
this->mix_matrix_was_set = TRUE;
} else {
const GValue *first_row = gst_value_array_get_value (value, 0);
@ -942,6 +946,7 @@ gst_audio_convert_set_property (GObject * object, guint prop_id,
g_value_unset (&this->mix_matrix);
g_value_copy (value, &this->mix_matrix);
this->mix_matrix_was_set = TRUE;
} else {
g_warning ("Empty mix matrix's first row");
}
@ -967,7 +972,7 @@ gst_audio_convert_get_property (GObject * object, guint prop_id,
g_value_set_enum (value, this->ns);
break;
case PROP_MIX_MATRIX:
if (gst_value_array_get_size (&this->mix_matrix))
if (this->mix_matrix_was_set)
g_value_copy (&this->mix_matrix, value);
break;
default:

View file

@ -48,6 +48,7 @@ struct _GstAudioConvert
GstAudioDitherMethod dither;
GstAudioNoiseShapingMethod ns;
GValue mix_matrix;
gboolean mix_matrix_was_set;
GstAudioInfo in_info;
GstAudioInfo out_info;