From 31b677599aec996f0b2155e282389500510ac6a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 29 May 2008 07:02:50 +0000 Subject: [PATCH] ext/vorbis/: Add sane defaults for the 7 and 8 channel layouts as those are undefined in the Vorbis spec. Use NONE ch... Original commit message from CVS: * ext/vorbis/vorbisdec.c: (vorbis_handle_identification_packet): * ext/vorbis/vorbisenc.c: (gst_vorbis_enc_generate_sink_caps): Add sane defaults for the 7 and 8 channel layouts as those are undefined in the Vorbis spec. Use NONE channel layouts when decoding more than 8 channels instead of erroring out. Fixes bug #535356. --- ChangeLog | 8 ++++++ ext/vorbis/vorbisdec.c | 58 ++++++++++++++++++++++++++++++++++-------- ext/vorbis/vorbisenc.c | 25 +++++++++++++++--- 3 files changed, 78 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 130b4606ac..6e6aa23cae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-05-29 Sebastian Dröge + + * ext/vorbis/vorbisdec.c: (vorbis_handle_identification_packet): + * ext/vorbis/vorbisenc.c: (gst_vorbis_enc_generate_sink_caps): + Add sane defaults for the 7 and 8 channel layouts as those are + undefined in the Vorbis spec. Use NONE channel layouts when decoding + more than 8 channels instead of erroring out. Fixes bug #535356. + 2008-05-28 Wim Taymans * docs/plugins/Makefile.am: diff --git a/ext/vorbis/vorbisdec.c b/ext/vorbis/vorbisdec.c index 0cc1ee03cd..e0a0375e89 100644 --- a/ext/vorbis/vorbisdec.c +++ b/ext/vorbis/vorbisdec.c @@ -618,8 +618,49 @@ vorbis_handle_identification_packet (GstVorbisDec * vd) pos = pos6; break; } - default: - goto channel_count_error; + /* FIXME: for >6 channels the layout is not defined by the Vorbis + * spec. These are the gstreamer "defaults" for 7/8 channels and + * NONE layouts for more channels + */ + case 7:{ + static const GstAudioChannelPosition pos7[] = { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }; + pos = pos7; + } + case 8:{ + static const GstAudioChannelPosition pos8[] = { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }; + + pos = pos8; + } + default:{ + gint i; + GstAudioChannelPosition *posn = + g_new (GstAudioChannelPosition, vd->vi.channels); + + GST_ELEMENT_WARNING (GST_ELEMENT (vd), STREAM, DECODE, + (NULL), ("Using NONE channel layout for more than 8 channels")); + + for (i = 0; i < vd->vi.channels; i++) + posn[i] = GST_AUDIO_CHANNEL_POSITION_NONE; + + pos = posn; + } } caps = gst_caps_new_simple ("audio/x-raw-float", @@ -630,18 +671,15 @@ vorbis_handle_identification_packet (GstVorbisDec * vd) if (pos) { gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos); } + + if (vd->vi.channels > 8) { + g_free ((GstAudioChannelPosition *) pos); + } + gst_pad_set_caps (vd->srcpad, caps); gst_caps_unref (caps); return GST_FLOW_OK; - - /* ERROR */ -channel_count_error: - { - GST_ELEMENT_ERROR (vd, STREAM, NOT_IMPLEMENTED, (NULL), - ("Unsupported channel count %d", vd->vi.channels)); - return GST_FLOW_ERROR; - } } static GstFlowReturn diff --git a/ext/vorbis/vorbisenc.c b/ext/vorbis/vorbisenc.c index 0e6cf94d5f..5c594f7ce5 100644 --- a/ext/vorbis/vorbisenc.c +++ b/ext/vorbis/vorbisenc.c @@ -241,7 +241,7 @@ gst_vorbis_enc_dispose (GObject * object) G_OBJECT_CLASS (parent_class)->dispose (object); } -static const GstAudioChannelPosition vorbischannelpositions[][6] = { +static const GstAudioChannelPosition vorbischannelpositions[][8] = { { /* Mono */ GST_AUDIO_CHANNEL_POSITION_FRONT_MONO}, { /* Stereo */ @@ -272,6 +272,25 @@ static const GstAudioChannelPosition vorbischannelpositions[][6] = { GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, GST_AUDIO_CHANNEL_POSITION_LFE, }, + { /* Not defined by spec, GStreamer default */ + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + { /* Not defined by spec, GStreamer default */ + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, }; static GstCaps * gst_vorbis_enc_generate_sink_caps (void) @@ -291,7 +310,7 @@ gst_vorbis_enc_generate_sink_caps (void) "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32, NULL)); - for (i = 3; i <= 6; i++) { + for (i = 3; i <= 8; i++) { GValue chanpos = { 0 }; GValue pos = { 0 }; GstStructure *structure; @@ -317,7 +336,7 @@ gst_vorbis_enc_generate_sink_caps (void) gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw-float", "rate", GST_TYPE_INT_RANGE, 1, 200000, - "channels", GST_TYPE_INT_RANGE, 7, 256, + "channels", GST_TYPE_INT_RANGE, 9, 256, "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32, NULL));