mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 15:08:53 +00:00
ext/faad/gstfaad.c: Handle 'framed' field in caps; Port syncing for raw streams from 0.8 branch (for AAC+ radio strea...
Original commit message from CVS: * ext/faad/gstfaad.c: (gst_faad_setcaps), (gst_faad_chanpos_to_gst), (gst_faad_sync), (gst_faad_chain): Handle 'framed' field in caps; Port syncing for raw streams from 0.8 branch (for AAC+ radio streams) (#328722).
This commit is contained in:
parent
607d32dd1f
commit
b0ebf7d661
2 changed files with 109 additions and 15 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2006-01-27 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
|
* ext/faad/gstfaad.c: (gst_faad_setcaps),
|
||||||
|
(gst_faad_chanpos_to_gst), (gst_faad_sync), (gst_faad_chain):
|
||||||
|
Handle 'framed' field in caps; Port syncing for raw streams
|
||||||
|
from 0.8 branch (for AAC+ radio streams) (#328722).
|
||||||
|
|
||||||
2006-01-27 Jan Schmidt <thaytan@mad.scientist.com>
|
2006-01-27 Jan Schmidt <thaytan@mad.scientist.com>
|
||||||
|
|
||||||
* ext/sdl/sdlvideosink.c: (gst_sdlvideosink_supported),
|
* ext/sdl/sdlvideosink.c: (gst_sdlvideosink_supported),
|
||||||
|
|
|
@ -248,6 +248,9 @@ gst_faad_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
gst_buffer_unref (faad->tempbuf);
|
gst_buffer_unref (faad->tempbuf);
|
||||||
faad->tempbuf = NULL;
|
faad->tempbuf = NULL;
|
||||||
}
|
}
|
||||||
|
} else if ((value = gst_structure_get_value (str, "framed")) &&
|
||||||
|
g_value_get_boolean (value) == TRUE) {
|
||||||
|
faad->packetised = TRUE;
|
||||||
} else {
|
} else {
|
||||||
faad->init = FALSE;
|
faad->init = FALSE;
|
||||||
}
|
}
|
||||||
|
@ -356,15 +359,25 @@ gst_faad_chanpos_to_gst (guchar * fpos, guint num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unknown_channel) {
|
if (unknown_channel) {
|
||||||
if (num == 2) {
|
switch (num) {
|
||||||
GST_DEBUG ("FAAD reports unknown 2 channel mapping. Forcing to stereo");
|
case 1:{
|
||||||
pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
|
GST_DEBUG ("FAAD reports unknown 1 channel mapping. Forcing to mono");
|
||||||
pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
|
pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_MONO;
|
||||||
} else {
|
break;
|
||||||
GST_WARNING ("Unsupported FAAD channel position 0x%x encountered",
|
}
|
||||||
fpos[n]);
|
case 2:{
|
||||||
g_free (pos);
|
GST_DEBUG ("FAAD reports unknown 2 channel mapping. Forcing to stereo");
|
||||||
return NULL;
|
pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
|
||||||
|
pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
GST_WARNING ("Unsupported FAAD channel position 0x%x encountered",
|
||||||
|
fpos[n]);
|
||||||
|
g_free (pos);
|
||||||
|
pos = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -760,6 +773,68 @@ gst_faad_update_caps (GstFaad * faad, faacDecFrameInfo * info,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find syncpoint in ADTS/ADIF stream. Doesn't work for raw,
|
||||||
|
* packetized streams. Be careful when calling.
|
||||||
|
* Returns FALSE on no-sync, fills offset/length if one/two
|
||||||
|
* syncpoints are found, only returns TRUE when it finds two
|
||||||
|
* subsequent syncpoints (similar to mp3 typefinding in
|
||||||
|
* gst/typefind/) for ADTS because 12 bits isn't very reliable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_faad_sync (GstBuffer * buf, guint * off)
|
||||||
|
{
|
||||||
|
guint8 *data = GST_BUFFER_DATA (buf);
|
||||||
|
guint size = GST_BUFFER_SIZE (buf), n;
|
||||||
|
gint snc;
|
||||||
|
|
||||||
|
GST_DEBUG ("Finding syncpoint");
|
||||||
|
|
||||||
|
/* FIXME: for no-sync, we go over the same data for every new buffer.
|
||||||
|
* We should save the information somewhere. */
|
||||||
|
for (n = 0; n < size - 3; n++) {
|
||||||
|
snc = GST_READ_UINT16_BE (&data[n]);
|
||||||
|
if ((snc & 0xfff6) == 0xfff0) {
|
||||||
|
/* we have an ADTS syncpoint. Parse length and find
|
||||||
|
* next syncpoint. */
|
||||||
|
guint len;
|
||||||
|
|
||||||
|
GST_DEBUG ("Found one ADTS syncpoint at offset 0x%x, tracing next...", n);
|
||||||
|
|
||||||
|
if (size - n < 5) {
|
||||||
|
GST_DEBUG ("Not enough data to parse ADTS header");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*off = n;
|
||||||
|
len = ((data[n + 3] & 0x03) << 11) |
|
||||||
|
(data[n + 4] << 3) | ((data[n + 5] & 0xe0) >> 5);
|
||||||
|
if (n + len + 2 >= size) {
|
||||||
|
GST_DEBUG ("Next frame is not within reach");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
snc = GST_READ_UINT16_BE (&data[n + len]);
|
||||||
|
if ((snc & 0xfff6) == 0xfff0) {
|
||||||
|
GST_DEBUG ("Found ADTS syncpoint at offset 0x%x (framelen %u)", n, len);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG ("No next frame found... (should be at 0x%x)", n + len);
|
||||||
|
} else if (!memcmp (&data[n], "ADIF", 4)) {
|
||||||
|
/* we have an ADIF syncpoint. 4 bytes is enough. */
|
||||||
|
*off = n;
|
||||||
|
GST_DEBUG ("Found ADIF syncpoint at offset 0x%x", n);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG ("Found no syncpoint");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_faad_chain (GstPad * pad, GstBuffer * buffer)
|
gst_faad_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
|
@ -773,6 +848,7 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
faacDecFrameInfo info;
|
faacDecFrameInfo info;
|
||||||
void *out;
|
void *out;
|
||||||
gboolean run_loop = TRUE;
|
gboolean run_loop = TRUE;
|
||||||
|
guint sync_off;
|
||||||
|
|
||||||
faad = GST_FAAD (gst_pad_get_parent (pad));
|
faad = GST_FAAD (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
|
@ -794,22 +870,32 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
faad->tempbuf = NULL;
|
faad->tempbuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input_data = GST_BUFFER_DATA (buffer);
|
||||||
|
input_size = GST_BUFFER_SIZE (buffer);
|
||||||
|
if (!faad->packetised) {
|
||||||
|
if (!gst_faad_sync (buffer, &sync_off)) {
|
||||||
|
goto next;
|
||||||
|
} else {
|
||||||
|
input_data += sync_off;
|
||||||
|
input_size -= sync_off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* init if not already done during capsnego */
|
/* init if not already done during capsnego */
|
||||||
if (!faad->init) {
|
if (!faad->init) {
|
||||||
guint32 samplerate;
|
guint32 samplerate;
|
||||||
guchar channels;
|
guchar channels;
|
||||||
glong init_res;
|
glong init_res;
|
||||||
|
|
||||||
init_res = faacDecInit (faad->handle,
|
init_res = faacDecInit (faad->handle, input_data, input_size,
|
||||||
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), &samplerate,
|
&samplerate, &channels);
|
||||||
&channels);
|
|
||||||
if (init_res < 0) {
|
if (init_res < 0) {
|
||||||
GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
|
GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
|
||||||
("Failed to init decoder from stream"));
|
("Failed to init decoder from stream"));
|
||||||
gst_object_unref (faad);
|
gst_object_unref (faad);
|
||||||
return GST_FLOW_UNEXPECTED;
|
return GST_FLOW_UNEXPECTED;
|
||||||
}
|
}
|
||||||
skip_bytes = init_res;
|
skip_bytes = 0; /* init_res; */
|
||||||
faad->init = TRUE;
|
faad->init = TRUE;
|
||||||
|
|
||||||
/* make sure we create new caps below */
|
/* make sure we create new caps below */
|
||||||
|
@ -818,9 +904,8 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decode cycle */
|
/* decode cycle */
|
||||||
input_data = GST_BUFFER_DATA (buffer);
|
|
||||||
input_size = GST_BUFFER_SIZE (buffer);
|
|
||||||
info.bytesconsumed = input_size - skip_bytes;
|
info.bytesconsumed = input_size - skip_bytes;
|
||||||
|
info.error = 0;
|
||||||
|
|
||||||
if (!faad->packetised) {
|
if (!faad->packetised) {
|
||||||
/* We must check that ourselves for raw stream */
|
/* We must check that ourselves for raw stream */
|
||||||
|
@ -909,6 +994,8 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next:
|
||||||
|
|
||||||
/* Keep the leftovers in raw stream */
|
/* Keep the leftovers in raw stream */
|
||||||
if (input_size > 0 && !faad->packetised) {
|
if (input_size > 0 && !faad->packetised) {
|
||||||
if (input_size < GST_BUFFER_SIZE (buffer)) {
|
if (input_size < GST_BUFFER_SIZE (buffer)) {
|
||||||
|
|
Loading…
Reference in a new issue