summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/alsa/gstalsa.c52
-rw-r--r--ext/alsa/gstalsa.h4
-rw-r--r--ext/alsa/gstalsasink.c12
-rw-r--r--ext/alsa/gstalsasrc.c12
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 */