mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 16:08:51 +00:00
I'm too lazy to comment this
Original commit message from CVS: Lots of LPCM support work from Martin. This fixes the mimetype being set and interprets sound stream properties better so it's just iedntified as audio/raw. Thanks go to Martin Soto <soto@informatik.uni-kl.de> - see #106875 for more info
This commit is contained in:
parent
2cf0ef34e1
commit
ab8278b082
2 changed files with 140 additions and 7 deletions
|
@ -122,8 +122,26 @@ GST_PAD_TEMPLATE_FACTORY (pcm_factory,
|
||||||
GST_PAD_SOMETIMES,
|
GST_PAD_SOMETIMES,
|
||||||
GST_CAPS_NEW (
|
GST_CAPS_NEW (
|
||||||
"mpeg_demux_pcm",
|
"mpeg_demux_pcm",
|
||||||
"audio/x-lpcm",
|
"audio/raw",
|
||||||
NULL
|
"format", GST_PROPS_STRING ("int"),
|
||||||
|
"law", GST_PROPS_INT (0),
|
||||||
|
"endianness", GST_PROPS_INT (G_BIG_ENDIAN),
|
||||||
|
"signed", GST_PROPS_BOOLEAN (TRUE),
|
||||||
|
"width", GST_PROPS_LIST (
|
||||||
|
GST_PROPS_INT (16),
|
||||||
|
GST_PROPS_INT (20),
|
||||||
|
GST_PROPS_INT (24)
|
||||||
|
),
|
||||||
|
"depth", GST_PROPS_LIST (
|
||||||
|
GST_PROPS_INT (16),
|
||||||
|
GST_PROPS_INT (20),
|
||||||
|
GST_PROPS_INT (24)
|
||||||
|
),
|
||||||
|
"rate", GST_PROPS_LIST (
|
||||||
|
GST_PROPS_INT (48000),
|
||||||
|
GST_PROPS_INT (96000)
|
||||||
|
),
|
||||||
|
"channels", GST_PROPS_INT_RANGE (1, 8)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -148,6 +166,9 @@ static gboolean gst_mpeg_demux_parse_pes (GstMPEGParse *mpeg_parse, GstBuffer
|
||||||
static void gst_mpeg_demux_send_data (GstMPEGParse *mpeg_parse,
|
static void gst_mpeg_demux_send_data (GstMPEGParse *mpeg_parse,
|
||||||
GstData *data, GstClockTime time);
|
GstData *data, GstClockTime time);
|
||||||
|
|
||||||
|
static void gst_mpeg_demux_lpcm_set_caps (GstPad *pad, guint8 sample_info);
|
||||||
|
static void gst_mpeg_demux_dvd_audio_clear (GstMPEGDemux *mpeg_demux, int channel);
|
||||||
|
|
||||||
static void gst_mpeg_demux_handle_discont (GstMPEGParse *mpeg_parse);
|
static void gst_mpeg_demux_handle_discont (GstMPEGParse *mpeg_parse);
|
||||||
static gboolean gst_mpeg_demux_handle_src_event (GstPad *pad, GstEvent *event);
|
static gboolean gst_mpeg_demux_handle_src_event (GstPad *pad, GstEvent *event);
|
||||||
|
|
||||||
|
@ -223,6 +244,9 @@ gst_mpeg_demux_init (GstMPEGDemux *mpeg_demux)
|
||||||
for (i=0;i<NUM_PRIVATE_1_STREAMS;i++) {
|
for (i=0;i<NUM_PRIVATE_1_STREAMS;i++) {
|
||||||
mpeg_demux->private_1_stream[i] = NULL;
|
mpeg_demux->private_1_stream[i] = NULL;
|
||||||
}
|
}
|
||||||
|
for (i=0;i<NUM_PCM_STREAMS;i++) {
|
||||||
|
mpeg_demux->pcm_stream[i] = NULL;
|
||||||
|
}
|
||||||
for (i=0;i<NUM_SUBTITLE_STREAMS;i++) {
|
for (i=0;i<NUM_SUBTITLE_STREAMS;i++) {
|
||||||
mpeg_demux->subtitle_stream[i] = NULL;
|
mpeg_demux->subtitle_stream[i] = NULL;
|
||||||
}
|
}
|
||||||
|
@ -265,7 +289,6 @@ gst_mpeg_demux_send_data (GstMPEGParse *mpeg_parse, GstData *data, GstClockTime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_mpeg_demux_handle_discont (GstMPEGParse *mpeg_parse)
|
gst_mpeg_demux_handle_discont (GstMPEGParse *mpeg_parse)
|
||||||
{
|
{
|
||||||
|
@ -788,6 +811,22 @@ gst_mpeg_demux_parse_pes (GstMPEGParse *mpeg_parse, GstBuffer *buffer)
|
||||||
GST_DEBUG (0, "we have a pcm_stream packet, track %d",
|
GST_DEBUG (0, "we have a pcm_stream packet, track %d",
|
||||||
ps_id_code - 0xA0);
|
ps_id_code - 0xA0);
|
||||||
outstream = &mpeg_demux->pcm_stream[ps_id_code - 0xA0];
|
outstream = &mpeg_demux->pcm_stream[ps_id_code - 0xA0];
|
||||||
|
|
||||||
|
/* Check for changes in the sample format. */
|
||||||
|
if (*outstream != NULL &&
|
||||||
|
basebuf[headerlen + 9] !=
|
||||||
|
mpeg_demux->lpcm_sample_info[ps_id_code - 0xA0]) {
|
||||||
|
/* Change the pad caps.*/
|
||||||
|
gst_mpeg_demux_lpcm_set_caps((*outstream)->pad, basebuf[headerlen + 9]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the sample info. */
|
||||||
|
mpeg_demux->lpcm_sample_info[ps_id_code - 0xA0] =
|
||||||
|
basebuf[headerlen + 9];
|
||||||
|
|
||||||
|
/* Get rid of the LPCM header. */
|
||||||
|
headerlen += 7;
|
||||||
|
datalen -= 7;
|
||||||
break;
|
break;
|
||||||
case 0x20 ... 0x2f:
|
case 0x20 ... 0x2f:
|
||||||
GST_DEBUG (0, "we have a subtitle_stream packet, track %d",
|
GST_DEBUG (0, "we have a subtitle_stream packet, track %d",
|
||||||
|
@ -838,10 +877,16 @@ gst_mpeg_demux_parse_pes (GstMPEGParse *mpeg_parse, GstBuffer *buffer)
|
||||||
case 0xBD:
|
case 0xBD:
|
||||||
switch (ps_id_code) {
|
switch (ps_id_code) {
|
||||||
case 0x80 ... 0x87:
|
case 0x80 ... 0x87:
|
||||||
name = g_strdup_printf ("private_stream_1.%d",ps_id_code - 0x80);
|
/* Erase any DVD audio pads. */
|
||||||
|
gst_mpeg_demux_dvd_audio_clear (mpeg_demux, ps_id_code - 0x80);
|
||||||
|
|
||||||
|
name = g_strdup_printf ("private_stream_1_%d",ps_id_code - 0x80);
|
||||||
newtemp = GST_PAD_TEMPLATE_GET (private1_factory);
|
newtemp = GST_PAD_TEMPLATE_GET (private1_factory);
|
||||||
break;
|
break;
|
||||||
case 0xA0 ... 0xA7:
|
case 0xA0 ... 0xA7:
|
||||||
|
/* Erase any DVD audio pads. */
|
||||||
|
gst_mpeg_demux_dvd_audio_clear (mpeg_demux, ps_id_code - 0xA0);
|
||||||
|
|
||||||
name = g_strdup_printf ("pcm_stream_%d", ps_id_code - 0xA0);
|
name = g_strdup_printf ("pcm_stream_%d", ps_id_code - 0xA0);
|
||||||
newtemp = GST_PAD_TEMPLATE_GET (pcm_factory);
|
newtemp = GST_PAD_TEMPLATE_GET (pcm_factory);
|
||||||
break;
|
break;
|
||||||
|
@ -883,9 +928,16 @@ gst_mpeg_demux_parse_pes (GstMPEGParse *mpeg_parse, GstBuffer *buffer)
|
||||||
|
|
||||||
/* create the pad and add it to self */
|
/* create the pad and add it to self */
|
||||||
*outpad = gst_pad_new_from_template (newtemp, name);
|
*outpad = gst_pad_new_from_template (newtemp, name);
|
||||||
caps = gst_pad_template_get_caps (newtemp);
|
if (ps_id_code < 0xA0 || ps_id_code > 0xA7) {
|
||||||
gst_pad_try_set_caps (*outpad, caps);
|
caps = gst_pad_template_get_caps (newtemp);
|
||||||
gst_caps_unref (caps);
|
gst_pad_try_set_caps (*outpad, caps);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gst_mpeg_demux_lpcm_set_caps(*outpad,
|
||||||
|
mpeg_demux->lpcm_sample_info[ps_id_code
|
||||||
|
- 0xA0]);
|
||||||
|
}
|
||||||
|
|
||||||
gst_pad_set_formats_function (*outpad, gst_mpeg_demux_get_src_formats);
|
gst_pad_set_formats_function (*outpad, gst_mpeg_demux_get_src_formats);
|
||||||
gst_pad_set_convert_function (*outpad, gst_mpeg_parse_convert_src);
|
gst_pad_set_convert_function (*outpad, gst_mpeg_parse_convert_src);
|
||||||
|
@ -947,6 +999,82 @@ gst_mpeg_demux_parse_pes (GstMPEGParse *mpeg_parse, GstBuffer *buffer)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the capabilities of the given pad based on the provided LPCM
|
||||||
|
* sample information.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
gst_mpeg_demux_lpcm_set_caps (GstPad *pad, guint8 sample_info)
|
||||||
|
{
|
||||||
|
gint width, rate, channels;
|
||||||
|
GstCaps *caps;
|
||||||
|
|
||||||
|
/* Determine the sample width. */
|
||||||
|
switch (sample_info & 0xC0) {
|
||||||
|
case 0x80:
|
||||||
|
width = 24;
|
||||||
|
break;
|
||||||
|
case 0x40:
|
||||||
|
width = 20;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
width = 16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine the rate. */
|
||||||
|
if (sample_info & 0x10) {
|
||||||
|
rate = 96000;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rate = 48000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine the number of channels. */
|
||||||
|
channels = (sample_info & 0x7) + 1;
|
||||||
|
|
||||||
|
caps = GST_CAPS_NEW (
|
||||||
|
"mpeg_demux_pcm",
|
||||||
|
"audio/raw",
|
||||||
|
"format", GST_PROPS_STRING ("int"),
|
||||||
|
"law", GST_PROPS_INT (0),
|
||||||
|
"endianness", GST_PROPS_INT (G_BIG_ENDIAN),
|
||||||
|
"signed", GST_PROPS_BOOLEAN (TRUE),
|
||||||
|
"width", GST_PROPS_INT (width),
|
||||||
|
"depth", GST_PROPS_INT (width),
|
||||||
|
"rate", GST_PROPS_INT (rate),
|
||||||
|
"channels", GST_PROPS_INT (channels)
|
||||||
|
);
|
||||||
|
gst_pad_try_set_caps (pad, caps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erase the DVD audio pad (if any) associated to the given channel.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
gst_mpeg_demux_dvd_audio_clear (GstMPEGDemux *mpeg_demux, int channel)
|
||||||
|
{
|
||||||
|
GstMPEGStream **stream = NULL;
|
||||||
|
|
||||||
|
if (mpeg_demux->private_1_stream[channel] != NULL) {
|
||||||
|
stream = &mpeg_demux->private_1_stream[channel];
|
||||||
|
}
|
||||||
|
else if (mpeg_demux->pcm_stream[channel] != NULL) {
|
||||||
|
stream = &mpeg_demux->pcm_stream[channel];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_pad_unlink ((*stream)->pad, gst_pad_get_peer((*stream)->pad));
|
||||||
|
gst_element_remove_pad (GST_ELEMENT (mpeg_demux), (*stream)->pad);
|
||||||
|
|
||||||
|
g_free (*stream);
|
||||||
|
*stream = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const GstFormat*
|
const GstFormat*
|
||||||
gst_mpeg_demux_get_src_formats (GstPad *pad)
|
gst_mpeg_demux_get_src_formats (GstPad *pad)
|
||||||
{
|
{
|
||||||
|
|
|
@ -89,6 +89,11 @@ struct _GstMPEGDemux {
|
||||||
GstMPEGStream *video_stream[NUM_VIDEO_STREAMS];
|
GstMPEGStream *video_stream[NUM_VIDEO_STREAMS];
|
||||||
GstMPEGStream *audio_stream[NUM_AUDIO_STREAMS];
|
GstMPEGStream *audio_stream[NUM_AUDIO_STREAMS];
|
||||||
|
|
||||||
|
/* The type of linear PCM samples associated to each channel. The
|
||||||
|
values are bit fields with the same format of the sample_info
|
||||||
|
field in the linear PCM header. */
|
||||||
|
guint8 lpcm_sample_info[NUM_PCM_STREAMS];
|
||||||
|
|
||||||
GstIndex *index;
|
GstIndex *index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue