audioconvert: Fix regression when using a mix matrix

This fixes regression introduced by commit da3a1011. When a mix matrix
is set, we still want to set the default channel-mask on output caps.

Fixes: #4579

Co-authored-by: Sebastian Dröge <sebastian@centricular.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9487>
This commit is contained in:
Xavier Claessens 2025-08-03 16:31:32 -04:00 committed by GStreamer Marge Bot
parent a9f803247f
commit 24356c099a
2 changed files with 60 additions and 5 deletions

View File

@ -1456,7 +1456,11 @@ gst_audio_convert_fixate_channels (GstBaseTransform * base, GstStructure * ins,
* channel position array or something else that's not a list; we assume
* the input if half-way sane and don't try to fall back on other list items
* if the first one is something unexpected or non-channel-pos-array-y */
if (n_bits_set (out_mask) >= out_chans) {
if (has_out_mask && out_mask == 0) {
gst_structure_set_static_str (outs, "channel-mask", GST_TYPE_BITMASK,
out_mask, NULL);
return;
} else if (n_bits_set (out_mask) >= out_chans) {
intersection = find_suitable_mask (out_mask, out_chans);
gst_structure_set_static_str (outs, "channel-mask", GST_TYPE_BITMASK,
intersection, NULL);
@ -1464,11 +1468,10 @@ gst_audio_convert_fixate_channels (GstBaseTransform * base, GstStructure * ins,
} else if (this->mix_matrix_is_set) {
/* Assume the matrix matches the number of in/out channels. This will be
* validated when creating the converter. */
return;
} else {
/* what now?! Just ignore what we're given and use default positions */
GST_WARNING_OBJECT (base, "invalid or unexpected channel-positions");
}
/* what now?! Just ignore what we're given and use default positions */
GST_WARNING_OBJECT (base, "invalid or unexpected channel-positions");
}
/* missing or invalid output layout and we can't use the input layout for

View File

@ -2365,6 +2365,57 @@ GST_START_TEST (test_dynamic_mix_matrix)
GST_END_TEST;
/* Regression test for https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4579 */
GST_START_TEST (test_mix_matrix_sets_channel_masks)
{
GstCaps *incaps = gst_caps_from_string ("audio/x-raw, "
"format = (string) S16LE, "
"layout = (string) interleaved, "
"channel-mask = (bitmask) 0, "
"rate = (int) 44100, " "channels = (int) 2 ");
GstCaps *outcaps = gst_caps_from_string ("audio/x-raw,channels = (int) 8");
/* Create 2:8 mix matrix */
GValue mix_matrix = G_VALUE_INIT;
g_value_init (&mix_matrix, GST_TYPE_ARRAY);
for (int i = 0; i < 8; i++) {
GValue row = G_VALUE_INIT;
g_value_init (&row, GST_TYPE_ARRAY);
for (int j = 0; j < 2; j++) {
GValue value = G_VALUE_INIT;
g_value_init (&value, G_TYPE_FLOAT);
g_value_set_float (&value, (i == j) ? 1.0 : 0.0);
gst_value_array_append_value (&row, &value);
g_value_unset (&value);
}
gst_value_array_append_value (&mix_matrix, &row);
g_value_unset (&row);
}
GstElement *audioconvert = setup_audioconvert (outcaps, TRUE, &mix_matrix);
fail_unless (gst_element_set_state (audioconvert,
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
"could not set to playing");
gst_check_setup_events (mysrcpad, audioconvert, incaps, GST_FORMAT_TIME);
/* Pushing a buffer should work */
GstBuffer *outbuffer = NULL;
GstBuffer *buffer = gst_buffer_new_and_alloc (1 * 2 * 2);
fail_unless_equals_int (gst_pad_push (mysrcpad, buffer), GST_FLOW_OK);
fail_unless (g_list_length (buffers) == 1);
fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
fail_unless_equals_int (gst_buffer_get_size (outbuffer), 1 * 2 * 8);
buffers = g_list_remove (buffers, outbuffer);
gst_buffer_unref (outbuffer);
/* cleanup */
cleanup_audioconvert (audioconvert);
gst_caps_unref (incaps);
gst_caps_unref (outcaps);
g_value_unset (&mix_matrix);
}
GST_END_TEST;
static Suite *
audioconvert_suite (void)
{
@ -2391,6 +2442,7 @@ audioconvert_suite (void)
tcase_add_test (tc_chain, test_layout_conv_fixate_caps);
tcase_add_test (tc_chain, test_96_channels_conversion);
tcase_add_test (tc_chain, test_dynamic_mix_matrix);
tcase_add_test (tc_chain, test_mix_matrix_sets_channel_masks);
return s;
}