summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--ext/faac/gstfaac.c28
-rw-r--r--ext/faac/gstfaac.h3
3 files changed, 37 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 8c76c3a0..181a05d4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-08-29 Edward Hervey <edward.hervey@collabora.co.uk>
+
+ * ext/faac/gstfaac.c: (gst_faac_init), (gst_faac_sink_event),
+ (gst_faac_chain), (gst_faac_change_state):
+ * ext/faac/gstfaac.h:
+ Add code for calculating proper timestamp/duration for the trailing
+ encoded buffers that faac will output when receiving EOS.
+
2008-08-29 Sebastian Dröge <sebastian.droege@collabora.co.uk>
* configure.ac:
diff --git a/ext/faac/gstfaac.c b/ext/faac/gstfaac.c
index eae5849e..fb62b336 100644
--- a/ext/faac/gstfaac.c
+++ b/ext/faac/gstfaac.c
@@ -250,6 +250,7 @@ gst_faac_init (GstFaac * faac)
faac->cache = NULL;
faac->cache_time = GST_CLOCK_TIME_NONE;
faac->cache_duration = 0;
+ faac->next_ts = GST_CLOCK_TIME_NONE;
faac->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
gst_pad_set_chain_function (faac->sinkpad,
@@ -459,17 +460,27 @@ gst_faac_sink_event (GstPad * pad, GstEvent * event)
ret = TRUE;
/* flush first */
+ GST_DEBUG ("Pushing out remaining buffers because of EOS");
while (ret) {
if (gst_pad_alloc_buffer_and_set_caps (faac->srcpad,
GST_BUFFER_OFFSET_NONE, faac->bytes,
GST_PAD_CAPS (faac->srcpad), &outbuf) == GST_FLOW_OK) {
gint ret_size;
+ GST_DEBUG ("next_ts %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (faac->next_ts));
+
if ((ret_size = faacEncEncode (faac->handle, NULL, 0,
GST_BUFFER_DATA (outbuf), faac->bytes)) > 0) {
GST_BUFFER_SIZE (outbuf) = ret_size;
- GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
- GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
+ GST_BUFFER_TIMESTAMP (outbuf) = faac->next_ts;
+ /* faac seems to always consume a fixed number of input samples,
+ * therefore extrapolate the duration from that value and the incoming
+ * bitrate */
+ GST_BUFFER_DURATION (outbuf) = gst_util_uint64_scale (faac->samples,
+ GST_SECOND, faac->channels * faac->samplerate);
+ if (GST_CLOCK_TIME_IS_VALID (faac->next_ts))
+ faac->next_ts += GST_BUFFER_DURATION (outbuf);
gst_pad_push (faac->srcpad, outbuf);
} else {
gst_buffer_unref (outbuf);
@@ -513,6 +524,10 @@ gst_faac_chain (GstPad * pad, GstBuffer * inbuf)
goto nego_failed;
}
+ GST_DEBUG ("Got buffer time:%" GST_TIME_FORMAT " duration:%" GST_TIME_FORMAT,
+ GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (inbuf)),
+ GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)));
+
size = GST_BUFFER_SIZE (inbuf);
in_size = size;
if (faac->cache)
@@ -600,6 +615,14 @@ gst_faac_chain (GstPad * pad, GstBuffer * inbuf)
GST_BUFFER_DURATION (outbuf) += faac->cache_duration;
faac->cache_duration = 0;
}
+ /* Store the value of the next expected timestamp to output
+ * This is required in order to output the trailing encoded packets
+ * at EOS with proper timestamps and duration. */
+ faac->next_ts =
+ GST_BUFFER_TIMESTAMP (outbuf) + GST_BUFFER_DURATION (outbuf);
+ GST_DEBUG ("Pushing out buffer time:%" GST_TIME_FORMAT " duration:%"
+ GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
+ GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
result = gst_pad_push (faac->srcpad, outbuf);
} else {
/* FIXME: what I'm doing here isn't fully correct, but there
@@ -745,6 +768,7 @@ gst_faac_change_state (GstElement * element, GstStateChange transition)
faac->cache_duration = 0;
faac->samplerate = -1;
faac->channels = -1;
+ faac->next_ts = GST_CLOCK_TIME_NONE;
GST_OBJECT_UNLOCK (faac);
break;
}
diff --git a/ext/faac/gstfaac.h b/ext/faac/gstfaac.h
index d69d4d4c..88a3e34b 100644
--- a/ext/faac/gstfaac.h
+++ b/ext/faac/gstfaac.h
@@ -62,6 +62,9 @@ typedef struct _GstFaac {
/* cache of the input */
GstBuffer *cache;
guint64 cache_time, cache_duration;
+
+ /* Expected timestamp of the next buffer to output */
+ GstClockTime next_ts;
} GstFaac;
typedef struct _GstFaacClass {