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.
This commit is contained in:
Edward Hervey 2008-08-29 11:36:41 +00:00
parent ba10061a5a
commit 6bcf03574e
3 changed files with 37 additions and 2 deletions

View file

@ -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:

View file

@ -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;
}

View file

@ -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 {