From 6bcf03574e4a49b01894046b4db25a34272bb561 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 29 Aug 2008 11:36:41 +0000 Subject: ext/faac/gstfaac.*: Add code for calculating proper timestamp/duration for the trailing encoded buffers that faac wil... Original commit message from CVS: * 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. --- ext/faac/gstfaac.c | 28 ++++++++++++++++++++++++++-- ext/faac/gstfaac.h | 3 +++ 2 files changed, 29 insertions(+), 2 deletions(-) (limited to 'ext/faac') 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 { -- cgit v1.2.1