diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/alsa/gstalsa.c | 52 | ||||
-rw-r--r-- | ext/alsa/gstalsa.h | 4 | ||||
-rw-r--r-- | ext/alsa/gstalsasink.c | 12 | ||||
-rw-r--r-- | ext/alsa/gstalsasrc.c | 12 |
4 files changed, 80 insertions, 0 deletions
diff --git a/ext/alsa/gstalsa.c b/ext/alsa/gstalsa.c index 0828110d33..d702a23a1e 100644 --- a/ext/alsa/gstalsa.c +++ b/ext/alsa/gstalsa.c @@ -707,3 +707,55 @@ const GstAudioChannelPosition alsa_position[][8] = { GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT} }; + +#ifdef SND_CHMAP_API_VERSION +/* +1 is to make zero as holes */ +#define ITEM(x, y) \ + [SND_CHMAP_ ## x] = GST_AUDIO_CHANNEL_POSITION_ ## y + 1 + +static GstAudioChannelPosition gst_pos[SND_CHMAP_LAST + 1] = { + ITEM(MONO, MONO), + ITEM(FL, FRONT_LEFT), + ITEM(FR, FRONT_RIGHT), + ITEM(FC, FRONT_CENTER), + ITEM(RL, REAR_LEFT), + ITEM(RR, REAR_RIGHT), + ITEM(RC, REAR_CENTER), + ITEM(LFE, LFE1), + ITEM(SL, SIDE_LEFT), + ITEM(SR, SIDE_RIGHT), + ITEM(FLC, FRONT_LEFT_OF_CENTER), + ITEM(FRC, FRONT_RIGHT_OF_CENTER), + ITEM(FLW, WIDE_LEFT), + ITEM(FRW, WIDE_RIGHT), + ITEM(TC, TOP_CENTER), + ITEM(TFL, TOP_FRONT_LEFT), + ITEM(TFR, TOP_FRONT_RIGHT), + ITEM(TFC, TOP_FRONT_CENTER), + ITEM(TRL, TOP_REAR_LEFT), + ITEM(TRR, TOP_REAR_RIGHT), + ITEM(TRC, TOP_REAR_CENTER), + ITEM(LLFE, LFE1), + ITEM(RLFE, LFE2), + ITEM(BC, BOTTOM_FRONT_CENTER), + ITEM(BLC, BOTTOM_FRONT_LEFT), + ITEM(BRC, BOTTOM_FRONT_LEFT), +}; +#undef ITEM + +gboolean alsa_chmap_to_channel_positions (const snd_pcm_chmap_t *chmap, + GstAudioChannelPosition *pos) +{ + int c; + + for (c = 0; c < chmap->channels; c++) { + if (chmap->pos[c] > SND_CHMAP_LAST) + return FALSE; + pos[c] = gst_pos[chmap->pos[c]]; + if (!pos[c]) + return FALSE; + pos[c]--; + } + return TRUE; +} +#endif /* SND_CHMAP_API_VERSION */ diff --git a/ext/alsa/gstalsa.h b/ext/alsa/gstalsa.h index b9000ded39..8026619d4c 100644 --- a/ext/alsa/gstalsa.h +++ b/ext/alsa/gstalsa.h @@ -71,5 +71,9 @@ void gst_alsa_add_channel_reorder_map (GstObject * obj, GstCaps * caps); extern const GstAudioChannelPosition alsa_position[][8]; +#ifdef SND_CHMAP_API_VERSION +gboolean alsa_chmap_to_channel_positions (const snd_pcm_chmap_t *chmap, + GstAudioChannelPosition *pos); +#endif #endif /* __GST_ALSA_H__ */ diff --git a/ext/alsa/gstalsasink.c b/ext/alsa/gstalsasink.c index 19dbd8bde6..38957499ca 100644 --- a/ext/alsa/gstalsasink.c +++ b/ext/alsa/gstalsasink.c @@ -896,6 +896,18 @@ gst_alsasink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec) snd_output_close (out_buf); } +#ifdef SND_CHMAP_API_VERSION + if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9) { + snd_pcm_chmap_t *chmap = snd_pcm_get_chmap (alsa->handle); + if (chmap && chmap->channels == alsa->channels) { + GstAudioChannelPosition pos[8]; + if (alsa_chmap_to_channel_positions (chmap, pos)) + gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SINK (alsa)->ringbuffer, pos); + } + free (chmap); + } +#endif /* SND_CHMAP_API_VERSION */ + return TRUE; /* ERRORS */ diff --git a/ext/alsa/gstalsasrc.c b/ext/alsa/gstalsasrc.c index fa4b5556bc..741f9f9fa2 100644 --- a/ext/alsa/gstalsasrc.c +++ b/ext/alsa/gstalsasrc.c @@ -783,6 +783,18 @@ gst_alsasrc_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec) snd_output_close (out_buf); } +#ifdef SND_CHMAP_API_VERSION + if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9) { + snd_pcm_chmap_t *chmap = snd_pcm_get_chmap (alsa->handle); + if (chmap && chmap->channels == alsa->channels) { + GstAudioChannelPosition pos[8]; + if (alsa_chmap_to_channel_positions (chmap, pos)) + gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SRC (alsa)->ringbuffer, pos); + } + free (chmap); + } +#endif /* SND_CHMAP_API_VERSION */ + return TRUE; /* ERRORS */ |