summaryrefslogtreecommitdiffstats
path: root/ext/faad
diff options
context:
space:
mode:
Diffstat (limited to 'ext/faad')
-rw-r--r--ext/faad/gstfaad.c83
-rw-r--r--ext/faad/gstfaad.h3
2 files changed, 50 insertions, 36 deletions
diff --git a/ext/faad/gstfaad.c b/ext/faad/gstfaad.c
index 9232bf82..97a17973 100644
--- a/ext/faad/gstfaad.c
+++ b/ext/faad/gstfaad.c
@@ -22,6 +22,7 @@
#endif
#include <string.h>
+#include <gst/audio/audio.h>
#include <gst/audio/multichannel.h>
#include "gstfaad.h"
@@ -135,6 +136,8 @@ gst_faad_base_init (GstFaadClass * klass)
gst_static_pad_template_get (&sink_template));
gst_element_class_set_details (element_class, &faad_details);
+
+ GST_DEBUG_CATEGORY_INIT (faad_debug, "faad", 0, "AAC decoding");
}
static void
@@ -144,9 +147,7 @@ gst_faad_class_init (GstFaadClass * klass)
parent_class = g_type_class_peek_parent (klass);
- gstelement_class->change_state = gst_faad_change_state;
-
- GST_DEBUG_CATEGORY_INIT (faad_debug, "faad", 0, "AAC decoding");
+ gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_faad_change_state);
}
static void
@@ -160,6 +161,7 @@ gst_faad_init (GstFaad * faad)
faad->channel_positions = NULL;
faad->init = FALSE;
faad->next_ts = 0;
+ faad->prev_ts = GST_CLOCK_TIME_NONE;
faad->bytes_in = 0;
faad->sum_dur_out = 0;
faad->packetised = FALSE;
@@ -168,16 +170,20 @@ gst_faad_init (GstFaad * faad)
gst_pad_new_from_template (gst_static_pad_template_get (&sink_template),
"sink");
gst_element_add_pad (GST_ELEMENT (faad), faad->sinkpad);
- gst_pad_set_event_function (faad->sinkpad, gst_faad_event);
- gst_pad_set_setcaps_function (faad->sinkpad, gst_faad_setcaps);
- gst_pad_set_chain_function (faad->sinkpad, gst_faad_chain);
+ gst_pad_set_event_function (faad->sinkpad,
+ GST_DEBUG_FUNCPTR (gst_faad_event));
+ gst_pad_set_setcaps_function (faad->sinkpad,
+ GST_DEBUG_FUNCPTR (gst_faad_setcaps));
+ gst_pad_set_chain_function (faad->sinkpad,
+ GST_DEBUG_FUNCPTR (gst_faad_chain));
faad->srcpad =
gst_pad_new_from_template (gst_static_pad_template_get (&src_template),
"src");
gst_element_add_pad (GST_ELEMENT (faad), faad->srcpad);
gst_pad_use_fixed_caps (faad->srcpad);
- gst_pad_set_getcaps_function (faad->srcpad, gst_faad_srcgetcaps);
+ gst_pad_set_getcaps_function (faad->srcpad,
+ GST_DEBUG_FUNCPTR (gst_faad_srcgetcaps));
}
static gboolean
@@ -380,7 +386,7 @@ gst_faad_sinkconnect (GstPad * pad, const GstCaps * caps)
static GstCaps *
gst_faad_srcgetcaps (GstPad * pad)
{
- GstFaad *faad = GST_FAAD (GST_OBJECT_PARENT (pad));
+ GstFaad *faad = GST_FAAD (gst_pad_get_parent (pad));
static GstAudioChannelPosition *supported_positions = NULL;
static gint num_supported_positions = LFE_CHANNEL - FRONT_CHANNEL_CENTER + 1;
GstCaps *templ;
@@ -485,7 +491,7 @@ gst_faad_srcgetcaps (GstPad * pad)
gst_audio_set_caps_channel_positions_list (caps,
supported_positions, num_supported_positions);
}
-
+ gst_object_unref (faad);
return caps;
}
@@ -494,6 +500,7 @@ gst_faad_srcgetcaps (GstPad * pad)
gst_audio_set_caps_channel_positions_list (templ,
supported_positions, num_supported_positions);
+ gst_object_unref (faad);
return templ;
}
@@ -611,18 +618,18 @@ gst_faad_event (GstPad * pad, GstEvent * event)
faad = GST_FAAD (gst_pad_get_parent (pad));
- GST_LOG ("handling event %d", GST_EVENT_TYPE (event));
+ GST_LOG ("Handling %s event", GST_EVENT_TYPE_NAME (event));
/* FIXME: we should probably handle FLUSH and also
* SEEK in the case where we are not in a container
* (when our newsegment was in BYTES) */
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
+ GST_STREAM_LOCK (pad);
if (faad->tempbuf != NULL) {
gst_buffer_unref (faad->tempbuf);
faad->tempbuf = NULL;
}
- GST_STREAM_LOCK (pad);
res = gst_pad_push_event (faad->srcpad, event);
GST_STREAM_UNLOCK (pad);
break;
@@ -672,18 +679,11 @@ gst_faad_event (GstPad * pad, GstEvent * event)
GST_STREAM_UNLOCK (pad);
break;
}
- case GST_EVENT_FLUSH_START:
- res = gst_pad_push_event (faad->srcpad, event);
- break;
default:
- GST_STREAM_LOCK (pad);
- res = gst_pad_push_event (faad->srcpad, event);
- GST_STREAM_UNLOCK (pad);
+ res = gst_pad_event_default (pad, event);
break;
}
-/* res = gst_pad_event_default (faad->sinkpad, event); */
-
return res;
}
@@ -740,14 +740,20 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
void *out;
gboolean run_loop = TRUE;
- faad = GST_FAAD (GST_OBJECT_PARENT (pad));
+ faad = GST_FAAD (gst_pad_get_parent (pad));
if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
- faad->next_ts = GST_BUFFER_TIMESTAMP (buffer);
- GST_DEBUG ("Timestamp on incoming buffer: %" GST_TIME_FORMAT,
+ /* some demuxers send multiple buffers in a row
+ * with the same timestamp (e.g. matroskademux) */
+ if (GST_BUFFER_TIMESTAMP (buffer) != faad->prev_ts) {
+ faad->next_ts = GST_BUFFER_TIMESTAMP (buffer);
+ faad->prev_ts = GST_BUFFER_TIMESTAMP (buffer);
+ }
+ GST_DEBUG ("Timestamp on incoming buffer: %" GST_TIME_FORMAT
+ ", next_ts: %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
GST_TIME_ARGS (faad->next_ts));
}
-
/* buffer + remaining data */
if (faad->tempbuf) {
buffer = gst_buffer_join (faad->tempbuf, buffer);
@@ -766,6 +772,7 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
if (init_res < 0) {
GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
("Failed to init decoder from stream"));
+ gst_object_unref (faad);
return GST_FLOW_UNEXPECTED;
}
skip_bytes = init_res;
@@ -838,22 +845,20 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
/* play decoded data */
if (info.samples > 0 && GST_PAD_PEER (faad->srcpad)) {
- GstFlowReturn r;
guint bufsize = info.samples * faad->bps;
+ guint num_samples = info.samples / faad->channels;
/* note: info.samples is total samples, not per channel */
- r = gst_pad_alloc_buffer (faad->srcpad, 0, bufsize, caps, &outbuf);
- if (r != GST_FLOW_OK) {
- GST_DEBUG ("Failed to allocate buffer");
- ret = r; //GST_FLOW_OK; /* CHECK: or return something else? */
+ ret = gst_pad_alloc_buffer (faad->srcpad, 0, bufsize, caps, &outbuf);
+ if (ret != GST_FLOW_OK)
goto out;
- }
memcpy (GST_BUFFER_DATA (outbuf), out, GST_BUFFER_SIZE (outbuf));
GST_BUFFER_OFFSET (outbuf) =
- (faad->next_ts * faad->samplerate) / GST_SECOND;
+ GST_CLOCK_TIME_TO_FRAMES (faad->next_ts, faad->samplerate);
GST_BUFFER_TIMESTAMP (outbuf) = faad->next_ts;
- GST_BUFFER_DURATION (outbuf) = (guint64) GST_SECOND *info.samples / (faad->samplerate * 2); ///////// over 2?
+ GST_BUFFER_DURATION (outbuf) =
+ GST_FRAMES_TO_CLOCK_TIME (num_samples, faad->samplerate);
faad->next_ts += GST_BUFFER_DURATION (outbuf);
faad->sum_dur_out += GST_BUFFER_DURATION (outbuf);
@@ -887,6 +892,7 @@ out:
gst_caps_unref (caps);
gst_buffer_unref (buffer);
+ gst_object_unref (faad);
return ret;
}
@@ -894,6 +900,7 @@ out:
static GstStateChangeReturn
gst_faad_change_state (GstElement * element, GstStateChange transition)
{
+ GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
GstFaad *faad = GST_FAAD (element);
switch (transition) {
@@ -913,6 +920,14 @@ gst_faad_change_state (GstElement * element, GstStateChange transition)
}
break;
}
+ default:
+ break;
+ }
+
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ switch (transition) {
case GST_STATE_CHANGE_PAUSED_TO_READY:
faad->samplerate = -1;
faad->channels = -1;
@@ -921,6 +936,7 @@ gst_faad_change_state (GstElement * element, GstStateChange transition)
g_free (faad->channel_positions);
faad->channel_positions = NULL;
faad->next_ts = 0;
+ faad->prev_ts = GST_CLOCK_TIME_NONE;
break;
case GST_STATE_CHANGE_READY_TO_NULL:
faacDecClose (faad->handle);
@@ -934,10 +950,7 @@ gst_faad_change_state (GstElement * element, GstStateChange transition)
break;
}
- if (GST_ELEMENT_CLASS (parent_class)->change_state)
- return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- return GST_STATE_CHANGE_SUCCESS;
+ return ret;
}
static gboolean
diff --git a/ext/faad/gstfaad.h b/ext/faad/gstfaad.h
index e9f0a3cb..419ce20d 100644
--- a/ext/faad/gstfaad.h
+++ b/ext/faad/gstfaad.h
@@ -57,7 +57,8 @@ typedef struct _GstFaad {
gboolean need_channel_setup;
gboolean packetised; /* We must differentiate between raw and packetised streams */
- guint64 next_ts; /* timestamp of next buffer */
+ gint64 prev_ts; /* timestamp of previous buffer */
+ gint64 next_ts; /* timestamp of next buffer */
guint64 bytes_in; /* bytes received */
guint64 sum_dur_out; /* sum of durations of decoded buffers we sent out */
} GstFaad;