summaryrefslogtreecommitdiffstats
path: root/ext/faad
diff options
context:
space:
mode:
Diffstat (limited to 'ext/faad')
-rw-r--r--ext/faad/gstfaad.c45
-rw-r--r--ext/faad/gstfaad.h1
2 files changed, 40 insertions, 6 deletions
diff --git a/ext/faad/gstfaad.c b/ext/faad/gstfaad.c
index 5cac22ed..14fda859 100644
--- a/ext/faad/gstfaad.c
+++ b/ext/faad/gstfaad.c
@@ -282,11 +282,17 @@ gst_faad_sinkconnect (GstPad * pad, const GstCaps * caps)
const GValue *value;
GstBuffer *buf;
+ /* Assume raw stream */
+ faad->packetised = FALSE;
+
if ((value = gst_structure_get_value (str, "codec_data"))) {
gulong samplerate;
guchar channels;
+ /* We have codec data, means packetised stream */
+ faad->packetised = TRUE;
buf = g_value_get_boxed (value);
+
/* someone forgot that char can be unsigned when writing the API */
if ((gint8) faacDecInit2 (faad->handle, GST_BUFFER_DATA (buf),
GST_BUFFER_SIZE (buf), &samplerate, &channels) < 0)
@@ -540,12 +546,14 @@ static void
gst_faad_chain (GstPad * pad, GstData * data)
{
guint input_size;
+ guint skip_bytes = 0;
guchar *input_data;
GstFaad *faad = GST_FAAD (gst_pad_get_parent (pad));
GstBuffer *buf, *outbuf;
faacDecFrameInfo *info;
guint64 next_ts;
void *out;
+ gboolean run_loop = TRUE;
if (GST_IS_EVENT (data)) {
GstEvent *event = GST_EVENT (data);
@@ -579,12 +587,20 @@ gst_faad_chain (GstPad * pad, GstData * data)
if (!faad->init) {
gulong samplerate;
guchar channels;
+ glong init_res;
- faacDecInit (faad->handle,
+ init_res = faacDecInit (faad->handle,
GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf), &samplerate, &channels);
+ if (init_res < 0) {
+ GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
+ ("Failed to init decoder from stream"));
+ return;
+ }
+ skip_bytes = init_res;
faad->init = TRUE;
/* store for renegotiation later on */
+ /* FIXME: that's moot, info will get zeroed in DecDecode() */
info->samplerate = samplerate;
info->channels = channels;
} else {
@@ -595,9 +611,26 @@ gst_faad_chain (GstPad * pad, GstData * data)
/* decode cycle */
input_data = GST_BUFFER_DATA (buf);
input_size = GST_BUFFER_SIZE (buf);
- info->bytesconsumed = input_size;
- while (input_size >= FAAD_MIN_STREAMSIZE && info->bytesconsumed > 0) {
- out = faacDecDecode (faad->handle, info, input_data, input_size);
+ info->bytesconsumed = input_size - skip_bytes;
+
+ if (!faad->packetised) {
+ /* We must check that ourselves for raw stream */
+ run_loop = (input_size >= FAAD_MIN_STREAMSIZE);
+ }
+
+ while ((input_size > 0) && run_loop) {
+
+ if (faad->packetised) {
+ /* Only one packet per buffer, no matter how much is really consumed */
+ run_loop = FALSE;
+ } else {
+ if (input_size < FAAD_MIN_STREAMSIZE || info->bytesconsumed <= 0) {
+ break;
+ }
+ }
+
+ out = faacDecDecode (faad->handle, info, input_data + skip_bytes,
+ input_size - skip_bytes);
if (info->error) {
GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
("Failed to decode buffer: %s",
@@ -662,8 +695,8 @@ gst_faad_chain (GstPad * pad, GstData * data)
}
}
- /* Keep the leftovers */
- if (input_size > 0) {
+ /* Keep the leftovers in raw stream */
+ if (input_size > 0 && !faad->packetised) {
if (input_size < GST_BUFFER_SIZE (buf)) {
faad->tempbuf = gst_buffer_create_sub (buf,
GST_BUFFER_SIZE (buf) - input_size, input_size);
diff --git a/ext/faad/gstfaad.h b/ext/faad/gstfaad.h
index 2f048635..fa083aa4 100644
--- a/ext/faad/gstfaad.h
+++ b/ext/faad/gstfaad.h
@@ -57,6 +57,7 @@ typedef struct _GstFaad {
/* FAAD channel setup */
guchar *channel_positions;
gboolean need_channel_setup;
+ gboolean packetised; /* We must differentiate between raw and packetised streams */
} GstFaad;
typedef struct _GstFaadClass {