mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-19 00:43:44 +00:00
ext/faad/gstfaad.*: Allow playback of raw (unframed) MPEG AAC files (#148993).
Original commit message from CVS: Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net> * ext/faad/gstfaad.c: (gst_faad_init), (gst_faad_sinkconnect), (gst_faad_chain), (gst_faad_change_state): * ext/faad/gstfaad.h: Allow playback of raw (unframed) MPEG AAC files (#148993).
This commit is contained in:
parent
060ae9b59b
commit
cebbba83a9
3 changed files with 93 additions and 34 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2004-10-01 Sebastien Cote <sc5@hermes.usherb.ca>
|
||||||
|
|
||||||
|
Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
|
||||||
|
* ext/faad/gstfaad.c: (gst_faad_init), (gst_faad_sinkconnect),
|
||||||
|
(gst_faad_chain), (gst_faad_change_state):
|
||||||
|
* ext/faad/gstfaad.h:
|
||||||
|
Allow playback of raw (unframed) MPEG AAC files (#148993).
|
||||||
|
|
||||||
2004-10-01 Sebastien Cote <sc5@hermes.usherb.ca>
|
2004-10-01 Sebastien Cote <sc5@hermes.usherb.ca>
|
||||||
|
|
||||||
Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
|
|
@ -124,6 +124,7 @@ gst_faad_init (GstFaad * faad)
|
||||||
faad->handle = NULL;
|
faad->handle = NULL;
|
||||||
faad->samplerate = -1;
|
faad->samplerate = -1;
|
||||||
faad->channels = -1;
|
faad->channels = -1;
|
||||||
|
faad->tempbuf = NULL;
|
||||||
|
|
||||||
GST_FLAG_SET (faad, GST_ELEMENT_EVENT_AWARE);
|
GST_FLAG_SET (faad, GST_ELEMENT_EVENT_AWARE);
|
||||||
|
|
||||||
|
@ -152,7 +153,6 @@ gst_faad_sinkconnect (GstPad * pad, const GstCaps * caps)
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
|
|
||||||
if ((value = gst_structure_get_value (str, "codec_data"))) {
|
if ((value = gst_structure_get_value (str, "codec_data"))) {
|
||||||
GstPadLinkReturn ret;
|
|
||||||
gulong samplerate;
|
gulong samplerate;
|
||||||
guchar channels;
|
guchar channels;
|
||||||
|
|
||||||
|
@ -165,11 +165,12 @@ gst_faad_sinkconnect (GstPad * pad, const GstCaps * caps)
|
||||||
faad->samplerate = samplerate;
|
faad->samplerate = samplerate;
|
||||||
faad->channels = channels;
|
faad->channels = channels;
|
||||||
|
|
||||||
ret = gst_pad_renegotiate (faad->srcpad);
|
if (faad->tempbuf) {
|
||||||
if (ret == GST_PAD_LINK_DELAYED)
|
gst_buffer_unref (faad->tempbuf);
|
||||||
ret = GST_PAD_LINK_OK;
|
faad->tempbuf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return GST_PAD_LINK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if there's no decoderspecificdata, it's all fine. We cannot know
|
/* if there's no decoderspecificdata, it's all fine. We cannot know
|
||||||
|
@ -326,6 +327,8 @@ gst_faad_srcconnect (GstPad * pad, const GstCaps * caps)
|
||||||
static void
|
static void
|
||||||
gst_faad_chain (GstPad * pad, GstData * data)
|
gst_faad_chain (GstPad * pad, GstData * data)
|
||||||
{
|
{
|
||||||
|
guint input_size;
|
||||||
|
guchar *input_data;
|
||||||
GstFaad *faad = GST_FAAD (gst_pad_get_parent (pad));
|
GstFaad *faad = GST_FAAD (gst_pad_get_parent (pad));
|
||||||
GstBuffer *buf, *outbuf;
|
GstBuffer *buf, *outbuf;
|
||||||
faacDecFrameInfo info;
|
faacDecFrameInfo info;
|
||||||
|
@ -336,6 +339,20 @@ gst_faad_chain (GstPad * pad, GstData * data)
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
|
if (faad->tempbuf != NULL) {
|
||||||
|
/* Try to decode the remaining data */
|
||||||
|
out = faacDecDecode (faad->handle, &info,
|
||||||
|
GST_BUFFER_DATA (faad->tempbuf), GST_BUFFER_SIZE (faad->tempbuf));
|
||||||
|
gst_buffer_unref (faad->tempbuf);
|
||||||
|
faad->tempbuf = NULL;
|
||||||
|
if (out && !info.error && info.samples > 0) {
|
||||||
|
outbuf = gst_buffer_new_and_alloc (info.samples * faad->bps);
|
||||||
|
/* ugh */
|
||||||
|
memcpy (GST_BUFFER_DATA (outbuf), out, GST_BUFFER_SIZE (outbuf));
|
||||||
|
|
||||||
|
gst_pad_push (faad->srcpad, GST_DATA (outbuf));
|
||||||
|
}
|
||||||
|
}
|
||||||
gst_element_set_eos (GST_ELEMENT (faad));
|
gst_element_set_eos (GST_ELEMENT (faad));
|
||||||
gst_pad_push (faad->srcpad, data);
|
gst_pad_push (faad->srcpad, data);
|
||||||
return;
|
return;
|
||||||
|
@ -356,6 +373,7 @@ gst_faad_chain (GstPad * pad, GstData * data)
|
||||||
GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf), &samplerate, &channels);
|
GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf), &samplerate, &channels);
|
||||||
faad->samplerate = samplerate;
|
faad->samplerate = samplerate;
|
||||||
faad->channels = channels;
|
faad->channels = channels;
|
||||||
|
|
||||||
ret = gst_pad_renegotiate (faad->srcpad);
|
ret = gst_pad_renegotiate (faad->srcpad);
|
||||||
if (GST_PAD_LINK_FAILED (ret)) {
|
if (GST_PAD_LINK_FAILED (ret)) {
|
||||||
GST_ELEMENT_ERROR (faad, CORE, NEGOTIATION, (NULL), (NULL));
|
GST_ELEMENT_ERROR (faad, CORE, NEGOTIATION, (NULL), (NULL));
|
||||||
|
@ -364,42 +382,66 @@ gst_faad_chain (GstPad * pad, GstData * data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out = faacDecDecode (faad->handle, &info,
|
/* Use the leftovers */
|
||||||
GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
|
if (faad->tempbuf) {
|
||||||
if (info.error) {
|
buf = gst_buffer_join (faad->tempbuf, buf);
|
||||||
GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
|
faad->tempbuf = NULL;
|
||||||
("Failed to decode buffer: %s", faacDecGetErrorMessage (info.error)));
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.samplerate != faad->samplerate || info.channels != faad->channels) {
|
input_data = GST_BUFFER_DATA (buf);
|
||||||
GstPadLinkReturn ret;
|
input_size = GST_BUFFER_SIZE (buf);
|
||||||
|
info.bytesconsumed = input_size;
|
||||||
|
while (input_size > (faad->channels * FAAD_MIN_STREAMSIZE)
|
||||||
|
&& info.bytesconsumed > 0) {
|
||||||
|
out = faacDecDecode (faad->handle, &info, input_data, input_size);
|
||||||
|
if (info.error) {
|
||||||
|
GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
|
||||||
|
("Failed to decode buffer: %s", faacDecGetErrorMessage (info.error)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
faad->samplerate = info.samplerate;
|
input_size -= info.bytesconsumed;
|
||||||
faad->channels = info.channels;
|
input_data += info.bytesconsumed;
|
||||||
ret = gst_pad_renegotiate (faad->srcpad);
|
|
||||||
if (GST_PAD_LINK_FAILED (ret)) {
|
if (out) {
|
||||||
GST_ELEMENT_ERROR (faad, CORE, NEGOTIATION, (NULL), (NULL));
|
|
||||||
gst_buffer_unref (buf);
|
if (info.samplerate != faad->samplerate
|
||||||
return;
|
|| info.channels != faad->channels) {
|
||||||
|
GstPadLinkReturn ret;
|
||||||
|
|
||||||
|
faad->samplerate = info.samplerate;
|
||||||
|
faad->channels = info.channels;
|
||||||
|
ret = gst_pad_renegotiate (faad->srcpad);
|
||||||
|
if (GST_PAD_LINK_FAILED (ret)) {
|
||||||
|
GST_ELEMENT_ERROR (faad, CORE, NEGOTIATION, (NULL), (NULL));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.samples > 0) {
|
||||||
|
outbuf = gst_buffer_new_and_alloc (info.samples * faad->bps);
|
||||||
|
/* ugh */
|
||||||
|
memcpy (GST_BUFFER_DATA (outbuf), out, GST_BUFFER_SIZE (outbuf));
|
||||||
|
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
|
||||||
|
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
|
||||||
|
|
||||||
|
gst_pad_push (faad->srcpad, GST_DATA (outbuf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Keep the leftovers */
|
||||||
|
if (input_size > 0) {
|
||||||
|
if (input_size < GST_BUFFER_SIZE (buf))
|
||||||
|
faad->tempbuf = gst_buffer_create_sub (buf,
|
||||||
|
GST_BUFFER_SIZE (buf) - input_size, input_size);
|
||||||
|
else {
|
||||||
|
faad->tempbuf = buf;
|
||||||
|
gst_buffer_ref (buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.samples == 0) {
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: did it handle the whole buffer? */
|
|
||||||
outbuf = gst_buffer_new_and_alloc (info.samples * faad->bps);
|
|
||||||
/* ugh */
|
|
||||||
memcpy (GST_BUFFER_DATA (outbuf), out, GST_BUFFER_SIZE (outbuf));
|
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
|
|
||||||
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
|
|
||||||
|
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
gst_pad_push (faad->srcpad, GST_DATA (outbuf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstElementStateReturn
|
static GstElementStateReturn
|
||||||
|
@ -416,6 +458,7 @@ gst_faad_change_state (GstElement * element)
|
||||||
|
|
||||||
conf = faacDecGetCurrentConfiguration (faad->handle);
|
conf = faacDecGetCurrentConfiguration (faad->handle);
|
||||||
conf->defObjectType = LC;
|
conf->defObjectType = LC;
|
||||||
|
conf->dontUpSampleImplicitSBR = 1;
|
||||||
faacDecSetConfiguration (faad->handle, conf);
|
faacDecSetConfiguration (faad->handle, conf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -426,6 +469,10 @@ gst_faad_change_state (GstElement * element)
|
||||||
case GST_STATE_READY_TO_NULL:
|
case GST_STATE_READY_TO_NULL:
|
||||||
faacDecClose (faad->handle);
|
faacDecClose (faad->handle);
|
||||||
faad->handle = NULL;
|
faad->handle = NULL;
|
||||||
|
if (faad->tempbuf) {
|
||||||
|
gst_buffer_unref (faad->tempbuf);
|
||||||
|
faad->tempbuf = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -47,6 +47,9 @@ typedef struct _GstFaad {
|
||||||
channels,
|
channels,
|
||||||
bps;
|
bps;
|
||||||
|
|
||||||
|
/* used to keep input leftovers */
|
||||||
|
GstBuffer *tempbuf;
|
||||||
|
|
||||||
/* FAAD object */
|
/* FAAD object */
|
||||||
faacDecHandle handle;
|
faacDecHandle handle;
|
||||||
} GstFaad;
|
} GstFaad;
|
||||||
|
|
Loading…
Reference in a new issue