dvdlpcmdec: Port to the new raw audio caps

This commit is contained in:
Sebastian Dröge 2012-01-04 15:26:56 +01:00
parent e3f1b21660
commit 7fea0ed2f5
2 changed files with 61 additions and 50 deletions

View File

@ -26,7 +26,7 @@
#include <string.h> #include <string.h>
#include "gstdvdlpcmdec.h" #include "gstdvdlpcmdec.h"
#include <gst/audio/multichannel.h> #include <gst/audio/audio.h>
GST_DEBUG_CATEGORY_STATIC (dvdlpcm_debug); GST_DEBUG_CATEGORY_STATIC (dvdlpcm_debug);
#define GST_CAT_DEFAULT dvdlpcm_debug #define GST_CAT_DEFAULT dvdlpcm_debug
@ -51,6 +51,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-raw, " GST_STATIC_CAPS ("audio/x-raw, "
"format = (string) { S16BE, S24BE }, " "format = (string) { S16BE, S24BE }, "
"layout = (string) interleaved, "
"rate = (int) { 32000, 44100, 48000, 96000 }, " "rate = (int) { 32000, 44100, 48000, 96000 }, "
"channels = (int) [ 1, 8 ]") "channels = (int) [ 1, 8 ]")
); );
@ -167,46 +168,31 @@ gst_dvdlpcmdec_init (GstDvdLpcmDec * dvdlpcmdec)
gst_dvdlpcm_reset (dvdlpcmdec); gst_dvdlpcm_reset (dvdlpcmdec);
} }
static GstAudioChannelPosition * static const GstAudioChannelPosition channel_positions[][8] = {
get_audio_channel_positions (GstDvdLpcmDec * dvdlpcmdec) {GST_AUDIO_CHANNEL_POSITION_MONO},
{ {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
gint n_channels = GST_AUDIO_INFO_CHANNELS (&dvdlpcmdec->info); GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
GstAudioChannelPosition *ret = g_new (GstAudioChannelPosition, n_channels); {GST_AUDIO_CHANNEL_POSITION_INVALID},
{GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
/* FIXME: The channel layouts for 5.1 and 7.1 are just guesses, I can't GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
* find any samples or confirmation */ GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
switch (n_channels) { GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT},
case 8: {GST_AUDIO_CHANNEL_POSITION_INVALID},
ret[7] = GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT; {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
ret[6] = GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT; GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
/* Fall through */ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
case 6: GST_AUDIO_CHANNEL_POSITION_LFE1, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
ret[5] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT; GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT},
ret[4] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT; {GST_AUDIO_CHANNEL_POSITION_INVALID},
ret[3] = GST_AUDIO_CHANNEL_POSITION_LFE; {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
ret[2] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER; GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
/* Fall through */ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
case 2: GST_AUDIO_CHANNEL_POSITION_LFE1, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
ret[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
ret[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
break; GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT},
case 4: {GST_AUDIO_CHANNEL_POSITION_INVALID}
ret[3] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT; };
ret[2] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
ret[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
ret[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
break;
case 1:
ret[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_MONO;
break;
default:
g_free (ret);
ret = NULL;
break;
}
return ret;
}
static void static void
gst_dvdlpcmdec_send_tags (GstDvdLpcmDec * dvdlpcmdec) gst_dvdlpcmdec_send_tags (GstDvdLpcmDec * dvdlpcmdec)
@ -231,17 +217,10 @@ gst_dvdlpcmdec_set_outcaps (GstDvdLpcmDec * dvdlpcmdec)
{ {
gboolean res = TRUE; gboolean res = TRUE;
GstCaps *src_caps; GstCaps *src_caps;
GstAudioChannelPosition *pos;
/* Build caps to set on the src pad, which we know from the incoming caps */ /* Build caps to set on the src pad, which we know from the incoming caps */
src_caps = gst_audio_info_to_caps (&dvdlpcmdec->info); src_caps = gst_audio_info_to_caps (&dvdlpcmdec->info);
pos = get_audio_channel_positions (dvdlpcmdec);
if (pos) {
gst_audio_set_channel_positions (gst_caps_get_structure (src_caps, 0), pos);
g_free (pos);
}
res = gst_pad_set_caps (dvdlpcmdec->srcpad, src_caps); res = gst_pad_set_caps (dvdlpcmdec->srcpad, src_caps);
if (res) { if (res) {
GST_DEBUG_OBJECT (dvdlpcmdec, "Successfully set output caps: %" GST_DEBUG_OBJECT (dvdlpcmdec, "Successfully set output caps: %"
@ -266,6 +245,7 @@ gst_dvdlpcmdec_setcaps (GstPad * pad, GstCaps * caps)
GstDvdLpcmDec *dvdlpcmdec; GstDvdLpcmDec *dvdlpcmdec;
GstAudioFormat format; GstAudioFormat format;
gint rate, channels, width; gint rate, channels, width;
const GstAudioChannelPosition *position;
g_return_val_if_fail (caps != NULL, FALSE); g_return_val_if_fail (caps != NULL, FALSE);
g_return_val_if_fail (pad != NULL, FALSE); g_return_val_if_fail (pad != NULL, FALSE);
@ -307,7 +287,20 @@ gst_dvdlpcmdec_setcaps (GstPad * pad, GstCaps * caps)
format = GST_AUDIO_FORMAT_UNKNOWN; format = GST_AUDIO_FORMAT_UNKNOWN;
break; break;
} }
gst_audio_info_set_format (&dvdlpcmdec->info, format, rate, channels);
gst_audio_info_set_format (&dvdlpcmdec->info, format, rate, channels, NULL);
if (channels < 9
&& channel_positions[channels - 1][0] !=
GST_AUDIO_CHANNEL_POSITION_INVALID) {
dvdlpcmdec->info.flags &= ~GST_AUDIO_FLAG_NONE_LAYOUT;
position = channel_positions[channels - 1];
dvdlpcmdec->lpcm_layout = position;
memcpy (dvdlpcmdec->info.position, position,
sizeof (GstAudioChannelPosition) * channels);
gst_audio_channel_positions_to_valid_order (dvdlpcmdec->info.position,
channels);
}
dvdlpcmdec->width = width; dvdlpcmdec->width = width;
res = gst_dvdlpcmdec_set_outcaps (dvdlpcmdec); res = gst_dvdlpcmdec_set_outcaps (dvdlpcmdec);
@ -413,7 +406,19 @@ parse_header (GstDvdLpcmDec * dec, guint32 header)
/* And, of course, the number of channels (up to 8) */ /* And, of course, the number of channels (up to 8) */
channels = ((header >> 8) & 0x7) + 1; channels = ((header >> 8) & 0x7) + 1;
gst_audio_info_set_format (&dec->info, format, rate, channels); gst_audio_info_set_format (&dec->info, format, rate, channels, NULL);
if (channels < 9
&& channel_positions[channels - 1][0] !=
GST_AUDIO_CHANNEL_POSITION_INVALID) {
const GstAudioChannelPosition *position;
dec->info.flags &= ~GST_AUDIO_FLAG_NONE_LAYOUT;
position = channel_positions[channels - 1];
dec->lpcm_layout = position;
memcpy (dec->info.position, position,
sizeof (GstAudioChannelPosition) * channels);
gst_audio_channel_positions_to_valid_order (dec->info.position, channels);
}
} }
static GstFlowReturn static GstFlowReturn
@ -716,6 +721,11 @@ gst_dvdlpcmdec_chain_raw (GstPad * pad, GstObject * parent, GstBuffer * buf)
update_timestamps (dvdlpcmdec, buf, samples); update_timestamps (dvdlpcmdec, buf, samples);
if (dvdlpcmdec->lpcm_layout)
gst_audio_buffer_reorder_channels (buf, dvdlpcmdec->info.finfo->format,
dvdlpcmdec->info.channels, dvdlpcmdec->lpcm_layout,
dvdlpcmdec->info.position);
ret = gst_pad_push (dvdlpcmdec->srcpad, buf); ret = gst_pad_push (dvdlpcmdec->srcpad, buf);
done: done:

View File

@ -48,6 +48,7 @@ struct _GstDvdLpcmDec {
guint32 header; guint32 header;
GstAudioInfo info; GstAudioInfo info;
const GstAudioChannelPosition *lpcm_layout;
gint width; gint width;
gint dynamic_range; gint dynamic_range;
gint emphasis; gint emphasis;