diff --git a/gst-libs/gst/audio/audio-channel-mixer.c b/gst-libs/gst/audio/audio-channel-mixer.c index 7e1e950ad1..d6407119d7 100644 --- a/gst-libs/gst/audio/audio-channel-mixer.c +++ b/gst-libs/gst/audio/audio-channel-mixer.c @@ -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); diff --git a/gst-libs/gst/audio/audio-converter.c b/gst-libs/gst/audio/audio-converter.c index 36bca569a7..b8f20152cb 100644 --- a/gst-libs/gst/audio/audio-converter.c +++ b/gst-libs/gst/audio/audio-converter.c @@ -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, diff --git a/gst/audioconvert/gstaudioconvert.c b/gst/audioconvert/gstaudioconvert.c index 27a85af44c..fa3d024095 100644 --- a/gst/audioconvert/gstaudioconvert.c +++ b/gst/audioconvert/gstaudioconvert.c @@ -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: diff --git a/gst/audioconvert/gstaudioconvert.h b/gst/audioconvert/gstaudioconvert.h index d4ae33843a..3efbfe08aa 100644 --- a/gst/audioconvert/gstaudioconvert.h +++ b/gst/audioconvert/gstaudioconvert.h @@ -48,6 +48,7 @@ struct _GstAudioConvert GstAudioDitherMethod dither; GstAudioNoiseShapingMethod ns; GValue mix_matrix; + gboolean mix_matrix_was_set; GstAudioInfo in_info; GstAudioInfo out_info;