mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
dcaparse: Add depth and endianness to the caps
Some decoders can only handle specific endianness or a fixed depth and this allows better negotiation. Fixes bug #644208.
This commit is contained in:
parent
0276663d0c
commit
48e8c093dc
2 changed files with 32 additions and 11 deletions
|
@ -57,8 +57,12 @@ GST_DEBUG_CATEGORY_STATIC (dca_parse_debug);
|
||||||
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
|
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS ("audio/x-dts, framed = (boolean) true, "
|
GST_STATIC_CAPS ("audio/x-dts,"
|
||||||
" channels = (int) [ 1, 8 ], rate = (int) [ 8000, 192000 ]"));
|
" framed = (boolean) true,"
|
||||||
|
" channels = (int) [ 1, 8 ],"
|
||||||
|
" rate = (int) [ 8000, 192000 ],"
|
||||||
|
" depth = (int) { 14, 16 },"
|
||||||
|
" endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }"));
|
||||||
|
|
||||||
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
|
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
|
@ -114,6 +118,8 @@ gst_dca_parse_reset (GstDcaParse * dcaparse)
|
||||||
{
|
{
|
||||||
dcaparse->channels = -1;
|
dcaparse->channels = -1;
|
||||||
dcaparse->rate = -1;
|
dcaparse->rate = -1;
|
||||||
|
dcaparse->depth = -1;
|
||||||
|
dcaparse->endianness = -1;
|
||||||
dcaparse->last_sync = 0;
|
dcaparse->last_sync = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +160,8 @@ gst_dca_parse_stop (GstBaseParse * parse)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_dca_parse_parse_header (GstDcaParse * dcaparse,
|
gst_dca_parse_parse_header (GstDcaParse * dcaparse,
|
||||||
const GstByteReader * reader, guint * frame_size,
|
const GstByteReader * reader, guint * frame_size,
|
||||||
guint * sample_rate, guint * channels, guint * samples)
|
guint * sample_rate, guint * channels, guint * depth,
|
||||||
|
gint * endianness, guint * samples)
|
||||||
{
|
{
|
||||||
static const int sample_rates[16] = { 0, 8000, 16000, 32000, 0, 0, 11025,
|
static const int sample_rates[16] = { 0, 8000, 16000, 32000, 0, 0, 11025,
|
||||||
22050, 44100, 0, 0, 12000, 24000, 48000, 96000, 192000
|
22050, 44100, 0, 0, 12000, 24000, 48000, 96000, 192000
|
||||||
|
@ -229,6 +236,12 @@ gst_dca_parse_parse_header (GstDcaParse * dcaparse,
|
||||||
else
|
else
|
||||||
*channels = 0;
|
*channels = 0;
|
||||||
|
|
||||||
|
if (depth)
|
||||||
|
*depth = (marker == 0x1FFFE800 || marker == 0xFF1F00E8) ? 14 : 16;
|
||||||
|
if (endianness)
|
||||||
|
*endianness = (marker == 0xFE7F0180 || marker == 0xFF1F00E8) ?
|
||||||
|
G_LITTLE_ENDIAN : G_BIG_ENDIAN;
|
||||||
|
|
||||||
*samples = num_blocks * samples_per_block;
|
*samples = num_blocks * samples_per_block;
|
||||||
|
|
||||||
GST_TRACE_OBJECT (dcaparse, "frame size %u, channels %u, rate %u, samples %u",
|
GST_TRACE_OBJECT (dcaparse, "frame size %u, channels %u, rate %u, samples %u",
|
||||||
|
@ -331,8 +344,8 @@ gst_dca_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make sure the values in the frame header look sane */
|
/* make sure the values in the frame header look sane */
|
||||||
if (!gst_dca_parse_parse_header (dcaparse, &r, &size, &rate, &chans,
|
if (!gst_dca_parse_parse_header (dcaparse, &r, &size, &rate, &chans, NULL,
|
||||||
&samples)) {
|
NULL, &samples)) {
|
||||||
*skipsize = 4;
|
*skipsize = 4;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -356,7 +369,8 @@ gst_dca_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
gst_byte_reader_init_from_buffer (&r, buf);
|
gst_byte_reader_init_from_buffer (&r, buf);
|
||||||
gst_byte_reader_skip_unchecked (&r, size);
|
gst_byte_reader_skip_unchecked (&r, size);
|
||||||
|
|
||||||
if (!gst_dca_parse_parse_header (dcaparse, &r, &s2, &r2, &c2, &n2)) {
|
if (!gst_dca_parse_parse_header (dcaparse, &r, &s2, &r2, &c2, NULL, NULL,
|
||||||
|
&n2)) {
|
||||||
GST_DEBUG_OBJECT (dcaparse, "didn't find second syncword");
|
GST_DEBUG_OBJECT (dcaparse, "didn't find second syncword");
|
||||||
*skipsize = 4;
|
*skipsize = 4;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -383,24 +397,29 @@ gst_dca_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
GstDcaParse *dcaparse = GST_DCA_PARSE (parse);
|
GstDcaParse *dcaparse = GST_DCA_PARSE (parse);
|
||||||
GstBuffer *buf = frame->buffer;
|
GstBuffer *buf = frame->buffer;
|
||||||
GstByteReader r = GST_BYTE_READER_INIT_FROM_BUFFER (buf);
|
GstByteReader r = GST_BYTE_READER_INIT_FROM_BUFFER (buf);
|
||||||
guint size, rate, chans, samples;
|
guint size, rate, chans, depth, samples;
|
||||||
|
gint endianness;
|
||||||
|
|
||||||
if (!gst_dca_parse_parse_header (dcaparse, &r, &size, &rate, &chans,
|
if (!gst_dca_parse_parse_header (dcaparse, &r, &size, &rate, &chans, &depth,
|
||||||
&samples))
|
&endianness, &samples))
|
||||||
goto broken_header;
|
goto broken_header;
|
||||||
|
|
||||||
if (G_UNLIKELY (dcaparse->rate != rate || dcaparse->channels != chans)) {
|
if (G_UNLIKELY (dcaparse->rate != rate || dcaparse->channels != chans
|
||||||
|
|| dcaparse->depth != depth || dcaparse->endianness != endianness)) {
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
|
||||||
caps = gst_caps_new_simple ("audio/x-dts",
|
caps = gst_caps_new_simple ("audio/x-dts",
|
||||||
"framed", G_TYPE_BOOLEAN, TRUE,
|
"framed", G_TYPE_BOOLEAN, TRUE,
|
||||||
"rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, chans, NULL);
|
"rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, chans,
|
||||||
|
"endianness", G_TYPE_INT, endianness, "depth", G_TYPE_INT, depth, NULL);
|
||||||
gst_buffer_set_caps (buf, caps);
|
gst_buffer_set_caps (buf, caps);
|
||||||
gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps);
|
gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps);
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
dcaparse->rate = rate;
|
dcaparse->rate = rate;
|
||||||
dcaparse->channels = chans;
|
dcaparse->channels = chans;
|
||||||
|
dcaparse->depth = depth;
|
||||||
|
dcaparse->endianness = endianness;
|
||||||
|
|
||||||
gst_base_parse_set_frame_props (parse, rate, samples, 0, 0);
|
gst_base_parse_set_frame_props (parse, rate, samples, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,8 @@ struct _GstDcaParse {
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
gint rate;
|
gint rate;
|
||||||
gint channels;
|
gint channels;
|
||||||
|
gint depth;
|
||||||
|
gint endianness;
|
||||||
|
|
||||||
guint32 last_sync;
|
guint32 last_sync;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue