opusenc: Add support for encoding >8 channels and unknown/unpositioned layouts

This was kind of implemented before but missing a few pieces to actually
work correctly.

These configurations are mapped to channel mapping family 255.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4180>
This commit is contained in:
Sebastian Dröge 2023-03-15 19:30:53 +02:00 committed by GStreamer Marge Bot
parent 0be233a446
commit 7e63427827
2 changed files with 29 additions and 24 deletions

View file

@ -8160,7 +8160,7 @@
"long-name": "Opus audio encoder",
"pad-templates": {
"sink": {
"caps": "audio/x-raw:\n format: S16LE\n layout: interleaved\n rate: 48000\n channels: [ 1, 8 ]\naudio/x-raw:\n format: S16LE\n layout: interleaved\n rate: { (int)8000, (int)12000, (int)16000, (int)24000 }\n channels: [ 1, 8 ]\n",
"caps": "audio/x-raw:\n format: S16LE\n layout: interleaved\n rate: 48000\n channels: [ 1, 255 ]\naudio/x-raw:\n format: S16LE\n layout: interleaved\n rate: { (int)8000, (int)12000, (int)16000, (int)24000 }\n channels: [ 1, 255 ]\n",
"direction": "sink",
"presence": "always"
},

View file

@ -174,12 +174,12 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
"format = (string) " FORMAT_STR ", "
"layout = (string) interleaved, "
"rate = (int) 48000, "
"channels = (int) [ 1, 8 ]; "
"channels = (int) [ 1, 255 ]; "
"audio/x-raw, "
"format = (string) " FORMAT_STR ", "
"layout = (string) interleaved, "
"rate = (int) { 8000, 12000, 16000, 24000 }, "
"channels = (int) [ 1, 8 ] ")
"channels = (int) [ 1, 255 ] ")
);
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
@ -594,13 +594,8 @@ gst_opus_enc_setup_channel_mappings (GstOpusEnc * enc,
/* Find where they map in Vorbis order */
c0v = gst_opus_enc_find_channel_position_in_vorbis_order (enc, p0);
c1v = gst_opus_enc_find_channel_position_in_vorbis_order (enc, p1);
if (c0v < 0 || c1v < 0) {
GST_WARNING_OBJECT (enc,
"Cannot map channel positions to Vorbis order, using unknown mapping");
enc->channel_mapping_family = 255;
enc->n_stereo_streams = 0;
return;
}
if (c0v < 0 || c1v < 0)
goto unpositioned;
enc->encoding_channel_mapping[mapped] = c0;
enc->encoding_channel_mapping[mapped + 1] = c1;
@ -624,7 +619,7 @@ gst_opus_enc_setup_channel_mappings (GstOpusEnc * enc,
gst_opus_channel_names[position]);
cv = gst_opus_enc_find_channel_position_in_vorbis_order (enc, position);
if (cv < 0)
g_assert_not_reached ();
goto unpositioned;
enc->encoding_channel_mapping[mapped] = n;
enc->decoding_channel_mapping[cv] = mapped;
mapped++;
@ -647,7 +642,8 @@ gst_opus_enc_setup_channel_mappings (GstOpusEnc * enc,
return;
}
/* More than 8 channels, if future mappings are added for those */
unpositioned:
/* More than 8 channels or unsupported positions, if future mappings are added for those */
/* For other cases, we use undefined, with the default trivial mapping
and all mono streams */
@ -656,9 +652,21 @@ gst_opus_enc_setup_channel_mappings (GstOpusEnc * enc,
else
GST_INFO_OBJECT (enc, "Unpositioned mapping, all channels mono");
gst_opus_enc_setup_trivial_mapping (enc, enc->encoding_channel_mapping);
gst_opus_enc_setup_trivial_mapping (enc, enc->decoding_channel_mapping);
enc->channel_mapping_family = 255;
enc->n_stereo_streams = 0;
#ifndef GST_DISABLE_GST_DEBUG
GST_INFO_OBJECT (enc,
"Mapping tables built: %d channels, %d stereo streams", enc->n_channels,
enc->n_stereo_streams);
gst_opus_common_log_channel_mapping_table (GST_ELEMENT (enc), opusenc_debug,
"Encoding mapping table", enc->n_channels, enc->encoding_channel_mapping);
gst_opus_common_log_channel_mapping_table (GST_ELEMENT (enc), opusenc_debug,
"Decoding mapping table", enc->n_channels, enc->decoding_channel_mapping);
#endif
#undef MAPS
}
@ -884,20 +892,17 @@ gst_opus_enc_get_sink_template_caps (void)
gst_structure_set (s, "channels", G_TYPE_INT, i, "channel-mask",
GST_TYPE_BITMASK, channel_mask, NULL);
gst_caps_append_structure (caps, s);
/* We also allow unpositioned channels, input will be
* treated as a set of individual mono channels */
s = gst_structure_copy (s2);
gst_structure_set (s, "channels", G_TYPE_INT, i, "channel-mask",
GST_TYPE_BITMASK, G_GUINT64_CONSTANT (0), NULL);
gst_caps_append_structure (caps, s);
s = gst_structure_copy (s1);
gst_structure_set (s, "channels", G_TYPE_INT, i, "channel-mask",
GST_TYPE_BITMASK, G_GUINT64_CONSTANT (0), NULL);
gst_caps_append_structure (caps, s);
}
/* Everything else and unpositioned */
s = gst_structure_copy (s1);
gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 255, NULL);
gst_caps_append_structure (caps, s);
s = gst_structure_copy (s2);
gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 255, NULL);
gst_caps_append_structure (caps, s);
gst_structure_free (s1);
gst_structure_free (s2);