From 2fc75efdce287a791521bd4c68fbd2a2d6bf5293 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 20 Dec 2011 11:44:27 +0100 Subject: [PATCH] alsa: Port to the new multichannel caps --- ext/alsa/gstalsa.c | 125 +++++++++++++++++++++++++++++++++++-------------- ext/alsa/gstalsa.h | 5 ++ ext/alsa/gstalsasink.c | 4 ++ ext/alsa/gstalsasrc.c | 4 ++ 4 files changed, 104 insertions(+), 34 deletions(-) diff --git a/ext/alsa/gstalsa.c b/ext/alsa/gstalsa.c index 2a2410a..8da665b 100644 --- a/ext/alsa/gstalsa.c +++ b/ext/alsa/gstalsa.c @@ -204,26 +204,23 @@ get_channel_free_structure (const GstStructure * in_structure) return s; } +#define ONE_64 G_GUINT64_CONSTANT (1) +#define CHANNEL_MASK_STEREO ((ONE_64<= 2) { s = get_channel_free_structure (in_structure); - gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL); + gst_structure_set (s, "channels", G_TYPE_INT, 2, "channel-mask", + GST_TYPE_BITMASK, CHANNEL_MASK_STEREO, NULL); + gst_caps_append_structure (caps, s); + s = get_channel_free_structure (in_structure); + gst_structure_set (s, "channels", G_TYPE_INT, 1, NULL); gst_caps_append_structure (caps, s); } @@ -245,41 +247,44 @@ caps_add_channel_configuration (GstCaps * caps, * alsa might work around that/fix it somehow. Can we tell alsa * what our channel layout is like? */ if (max_chans >= 3 && min_chans <= 3) { - GstAudioChannelPosition pos_21[3] = { - GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, - GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, - GST_AUDIO_CHANNEL_POSITION_LFE - }; - s = get_channel_free_structure (in_structure); - gst_structure_set (s, "channels", G_TYPE_INT, 3, NULL); - gst_audio_set_channel_positions (s, pos_21); + gst_structure_set (s, "channels", G_TYPE_INT, 3, "channel-mask", + GST_TYPE_BITMASK, CHANNEL_MASK_2_1, NULL); gst_caps_append_structure (caps, s); } /* everything else (4, 6, 8 channels) needs a channel layout */ for (c = MAX (4, min_chans); c <= 8; c += 2) { if (max_chans >= c) { + guint64 channel_mask; + s = get_channel_free_structure (in_structure); - gst_structure_set (s, "channels", G_TYPE_INT, c, NULL); - gst_audio_set_channel_positions (s, pos); + switch (c) { + case 4: + channel_mask = CHANNEL_MASK_4_0; + break; + case 6: + channel_mask = CHANNEL_MASK_5_1; + break; + case 8: + channel_mask = CHANNEL_MASK_7_1; + break; + default: + g_assert_not_reached (); + break; + } + gst_structure_set (s, "channels", G_TYPE_INT, c, "channel-mask", + GST_TYPE_BITMASK, channel_mask, NULL); gst_caps_append_structure (caps, s); } } + /* NONE layouts for everything else */ for (c = MAX (9, min_chans); c <= max_chans; ++c) { - GstAudioChannelPosition *ch_layout; - guint i; - - ch_layout = g_new (GstAudioChannelPosition, c); - for (i = 0; i < c; ++i) { - ch_layout[i] = GST_AUDIO_CHANNEL_POSITION_NONE; - } s = get_channel_free_structure (in_structure); - gst_structure_set (s, "channels", G_TYPE_INT, c, NULL); - gst_audio_set_channel_positions (s, ch_layout); + gst_structure_set (s, "channels", G_TYPE_INT, c, "channel-mask", + GST_TYPE_BITMASK, G_GUINT64_CONSTANT (0), NULL); gst_caps_append_structure (caps, s); - g_free (ch_layout); } } @@ -599,3 +604,55 @@ gst_alsa_find_device_name (GstObject * obj, const gchar * device, return ret; } + +/* ALSA channel positions */ +const GstAudioChannelPosition alsa_position[][8] = { + { + GST_AUDIO_CHANNEL_POSITION_MONO}, + { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, + { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1}, + { + 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_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID}, + { + 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_LFE1}, + { + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID}, + { + 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_LFE1, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT} +}; diff --git a/ext/alsa/gstalsa.h b/ext/alsa/gstalsa.h index 92466d2..ee813ae 100644 --- a/ext/alsa/gstalsa.h +++ b/ext/alsa/gstalsa.h @@ -31,6 +31,7 @@ #include #include #include +#include #define GST_CHECK_ALSA_VERSION(major,minor,micro) \ (SND_LIB_MAJOR > (major) || \ @@ -56,5 +57,9 @@ gchar * gst_alsa_find_card_name (GstObject * obj, const gchar * devcard, snd_pcm_stream_t stream); +void gst_alsa_add_channel_reorder_map (GstObject * obj, + GstCaps * caps); + +extern const GstAudioChannelPosition alsa_position[][8]; #endif /* __GST_ALSA_H__ */ diff --git a/ext/alsa/gstalsasink.c b/ext/alsa/gstalsasink.c index 090114a..7ae9e51 100644 --- a/ext/alsa/gstalsasink.c +++ b/ext/alsa/gstalsasink.c @@ -713,6 +713,10 @@ alsasink_parse_spec (GstAlsaSink * alsa, GstAudioRingBufferSpec * spec) alsa->period_time = spec->latency_time; alsa->access = SND_PCM_ACCESS_RW_INTERLEAVED; + if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9) + gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SINK + (alsa)->ringbuffer, alsa_position[alsa->channels - 1]); + return TRUE; /* ERRORS */ diff --git a/ext/alsa/gstalsasrc.c b/ext/alsa/gstalsasrc.c index 223cf64..2d21c88 100644 --- a/ext/alsa/gstalsasrc.c +++ b/ext/alsa/gstalsasrc.c @@ -642,6 +642,10 @@ alsasrc_parse_spec (GstAlsaSrc * alsa, GstAudioRingBufferSpec * spec) alsa->period_time = spec->latency_time; alsa->access = SND_PCM_ACCESS_RW_INTERLEAVED; + if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9) + gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SRC + (alsa)->ringbuffer, alsa_position[alsa->channels - 1]); + return TRUE; /* ERRORS */ -- 2.7.4