From 9c605059008375ecc0023492e196de951a5879ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 20 Dec 2011 12:08:53 +0100 Subject: [PATCH] vorbis: Port to the new multichannel caps --- ext/vorbis/gstvorbiscommon.c | 74 ++++++++++++++++++++++++++++++++++-- ext/vorbis/gstvorbiscommon.h | 7 +++- ext/vorbis/gstvorbisdec.c | 25 ++++++------ ext/vorbis/gstvorbisdeclib.c | 8 ++-- ext/vorbis/gstvorbisenc.c | 46 +++++++++++----------- 5 files changed, 118 insertions(+), 42 deletions(-) diff --git a/ext/vorbis/gstvorbiscommon.c b/ext/vorbis/gstvorbiscommon.c index c4dd408d3a..81348819f9 100644 --- a/ext/vorbis/gstvorbiscommon.c +++ b/ext/vorbis/gstvorbiscommon.c @@ -26,7 +26,7 @@ /* http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9 */ const GstAudioChannelPosition gst_vorbis_channel_positions[][8] = { { /* Mono */ - GST_AUDIO_CHANNEL_POSITION_FRONT_MONO}, + GST_AUDIO_CHANNEL_POSITION_MONO}, { /* Stereo */ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, @@ -53,7 +53,7 @@ const GstAudioChannelPosition gst_vorbis_channel_positions[][8] = { GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, - GST_AUDIO_CHANNEL_POSITION_LFE, + GST_AUDIO_CHANNEL_POSITION_LFE1, }, { /* 6.1 Surround, in Vorbis spec since 2010-01-13 */ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, @@ -62,7 +62,7 @@ const GstAudioChannelPosition gst_vorbis_channel_positions[][8] = { GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, - GST_AUDIO_CHANNEL_POSITION_LFE}, + GST_AUDIO_CHANNEL_POSITION_LFE1}, { /* 7.1 Surround, in Vorbis spec since 2010-01-13 */ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, @@ -71,5 +71,71 @@ const GstAudioChannelPosition gst_vorbis_channel_positions[][8] = { GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, - GST_AUDIO_CHANNEL_POSITION_LFE}, + GST_AUDIO_CHANNEL_POSITION_LFE1}, }; + +const GstAudioChannelPosition gst_vorbis_default_channel_positions[][8] = { + { /* Mono */ + GST_AUDIO_CHANNEL_POSITION_MONO}, + { /* Stereo */ + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, + { /* Stereo + Centre */ + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, + { /* Quadraphonic */ + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + }, + { /* Stereo + Centre + rear stereo */ + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + }, + { /* Full 5.1 Surround */ + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + }, + { /* 6.1 Surround, in Vorbis spec since 2010-01-13 */ + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, + { /* 7.1 Surround, in Vorbis spec since 2010-01-13 */ + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, +}; + +#ifndef USE_TREMOLO +/* gst[i] = vorbis[reorder_map[i]] */ +const gint gst_vorbis_reorder_map[][8] = { + {0}, + {0, 1}, + {0, 2, 1}, + {0, 1, 2, 3}, + {0, 2, 1, 3, 4}, + {0, 2, 1, 4, 5, 3}, + {0, 2, 1, 5, 6, 4, 3}, + {0, 2, 1, 6, 7, 4, 5, 3} +}; +#endif diff --git a/ext/vorbis/gstvorbiscommon.h b/ext/vorbis/gstvorbiscommon.h index 563b8f717d..64386a9d7b 100644 --- a/ext/vorbis/gstvorbiscommon.h +++ b/ext/vorbis/gstvorbiscommon.h @@ -21,8 +21,13 @@ #define __GST_VORBIS_COMMON_H__ #include -#include +#include extern const GstAudioChannelPosition gst_vorbis_channel_positions[][8]; +extern const GstAudioChannelPosition gst_vorbis_default_channel_positions[][8]; + +#ifndef USE_TREMOLO +extern const gint gst_vorbis_reorder_map[][8]; +#endif #endif /* __GST_VORBIS_COMMON_H__ */ diff --git a/ext/vorbis/gstvorbisdec.c b/ext/vorbis/gstvorbisdec.c index 8a596607c8..1683f457f9 100644 --- a/ext/vorbis/gstvorbisdec.c +++ b/ext/vorbis/gstvorbisdec.c @@ -44,7 +44,6 @@ #include #include #include -#include #include "gstvorbiscommon.h" @@ -230,14 +229,9 @@ vorbis_handle_identification_packet (GstVorbisDec * vd) GstCaps *caps; GstAudioInfo info; - gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate, - vd->vi.channels); - switch (info.channels) { case 1: case 2: - /* nothing */ - break; case 3: case 4: case 5: @@ -246,20 +240,22 @@ vorbis_handle_identification_packet (GstVorbisDec * vd) case 8: { const GstAudioChannelPosition *pos; - gint i; - pos = gst_vorbis_channel_positions[info.channels - 1]; - for (i = 0; i < info.channels; i++) - info.position[i] = pos[i]; + pos = gst_vorbis_default_channel_positions[info.channels - 1]; + gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate, + vd->vi.channels, pos); break; } default:{ + GstAudioChannelPosition position[64]; gint i, max_pos = MAX (info.channels, 64); GST_ELEMENT_WARNING (vd, STREAM, DECODE, (NULL), ("Using NONE channel layout for more than 8 channels")); for (i = 0; i < max_pos; i++) - info.position[i] = GST_AUDIO_CHANNEL_POSITION_NONE; + position[i] = GST_AUDIO_CHANNEL_POSITION_NONE; + gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate, + vd->vi.channels, position); break; } } @@ -577,7 +573,12 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet, #endif goto wrong_samples; -#ifndef USE_TREMOLO +#ifdef USE_TREMOLO + if (vd->info.channels < 9) + gst_audio_reorder_channels (data, size, GST_VORBIS_AUDIO_FORMAT, + vd->info.channels, gst_vorbis_channel_positions[vd->info.channels - 1], + gst_vorbis_default_channel_positions[vd->info.channels - 1]); +#else /* copy samples in buffer */ vd->copy_samples ((vorbis_sample_t *) data, pcm, sample_count, vd->info.channels); diff --git a/ext/vorbis/gstvorbisdeclib.c b/ext/vorbis/gstvorbisdeclib.c index 66a2ee39fc..a28ba375a7 100644 --- a/ext/vorbis/gstvorbisdeclib.c +++ b/ext/vorbis/gstvorbisdeclib.c @@ -28,6 +28,7 @@ #include #include "gstvorbisdeclib.h" +#include "gstvorbiscommon.h" #ifndef TREMOR /* These samples can be outside of the float -1.0 -- 1.0 range, this @@ -65,7 +66,8 @@ copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples, gint i; for (i = 0; i < channels; i++) { - memcpy (out, in[i], samples * sizeof (float)); + memcpy (out, in[gst_vorbis_reorder_map[channels - 1][i]], + samples * sizeof (float)); out += samples; } #else @@ -73,7 +75,7 @@ copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples, for (j = 0; j < samples; j++) { for (i = 0; i < channels; i++) { - *out++ = in[i][j]; + *out++ = in[gst_vorbis_reorder_map[channels - 1][i]][j]; } } #endif @@ -165,7 +167,7 @@ copy_samples_16 (vorbis_sample_t * _out, vorbis_sample_t ** _in, guint samples, for (j = 0; j < samples; j++) { for (i = 0; i < channels; i++) { - *out++ = CLIP_TO_15 (in[i][j] >> 9); + *out++ = CLIP_TO_15 (in[gst_vorbis_reorder_map[channels - 1][i]][j] >> 9); } } } diff --git a/ext/vorbis/gstvorbisenc.c b/ext/vorbis/gstvorbisenc.c index c699d5f0e6..518b6041fa 100644 --- a/ext/vorbis/gstvorbisenc.c +++ b/ext/vorbis/gstvorbisenc.c @@ -50,7 +50,6 @@ #include #include -#include #include #include "gstvorbisenc.h" @@ -264,30 +263,19 @@ gst_vorbis_enc_generate_sink_caps (void) "rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, 1, NULL)); - gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw", - "format", G_TYPE_STRING, GST_AUDIO_NE (F32), - "rate", GST_TYPE_INT_RANGE, 1, 200000, - "channels", G_TYPE_INT, 2, NULL)); - - for (i = 3; i <= 8; i++) { - GValue chanpos = { 0 }; - GValue pos = { 0 }; + for (i = 2; i <= 8; i++) { GstStructure *structure; - - g_value_init (&chanpos, GST_TYPE_ARRAY); - g_value_init (&pos, GST_TYPE_AUDIO_CHANNEL_POSITION); + guint64 channel_mask = 0; + const GstAudioChannelPosition *pos = gst_vorbis_channel_positions[i - 1]; for (c = 0; c < i; c++) { - g_value_set_enum (&pos, gst_vorbis_channel_positions[i - 1][c]); - gst_value_array_append_value (&chanpos, &pos); + channel_mask |= pos[i]; } - g_value_unset (&pos); structure = gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING, GST_AUDIO_NE (F32), - "rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i, NULL); - gst_structure_set_value (structure, "channel-positions", &chanpos); - g_value_unset (&chanpos); + "rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i, + "channel-mask", GST_TYPE_BITMASK, channel_mask, NULL); gst_caps_append_structure (caps, structure); } @@ -295,7 +283,8 @@ gst_vorbis_enc_generate_sink_caps (void) gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING, GST_AUDIO_NE (F32), "rate", GST_TYPE_INT_RANGE, 1, 200000, - "channels", GST_TYPE_INT_RANGE, 9, 255, NULL)); + "channels", GST_TYPE_INT_RANGE, 9, 255, + "channel-mask", GST_TYPE_BITMASK, G_GUINT64_CONSTANT (0), NULL)); return caps; } @@ -765,9 +754,22 @@ gst_vorbis_enc_handle_frame (GstAudioEncoder * enc, GstBuffer * buffer) vorbis_buffer = vorbis_analysis_buffer (&vorbisenc->vd, size); /* deinterleave samples, write the buffer data */ - for (i = 0; i < size; i++) { - for (j = 0; j < vorbisenc->channels; j++) { - vorbis_buffer[j][i] = *ptr++; + if (vorbisenc->channels < 2 || vorbisenc->channels > 8) { + for (i = 0; i < size; i++) { + for (j = 0; j < vorbisenc->channels; j++) { + vorbis_buffer[j][i] = *ptr++; + } + } + } else { + gint i, j; + + /* Reorder */ + for (i = 0; i < size; i++) { + for (j = 0; j < vorbisenc->channels; j++) { + vorbis_buffer[gst_vorbis_reorder_map[vorbisenc->channels - 1][j]][i] = + ptr[j]; + } + ptr += vorbisenc->channels; } }