diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | ext/faac/gstfaac.c | 28 | ||||
-rw-r--r-- | ext/faac/gstfaac.h | 3 |
3 files changed, 37 insertions, 2 deletions
@@ -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 { |