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:
parent
ba10061a5a
commit
6bcf03574e
@ -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>
|
2008-08-29 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
|
||||||
* configure.ac:
|
* configure.ac:
|
||||||
|
@ -250,6 +250,7 @@ gst_faac_init (GstFaac * faac)
|
|||||||
faac->cache = NULL;
|
faac->cache = NULL;
|
||||||
faac->cache_time = GST_CLOCK_TIME_NONE;
|
faac->cache_time = GST_CLOCK_TIME_NONE;
|
||||||
faac->cache_duration = 0;
|
faac->cache_duration = 0;
|
||||||
|
faac->next_ts = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
faac->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
|
faac->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
|
||||||
gst_pad_set_chain_function (faac->sinkpad,
|
gst_pad_set_chain_function (faac->sinkpad,
|
||||||
@ -459,17 +460,27 @@ gst_faac_sink_event (GstPad * pad, GstEvent * event)
|
|||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
/* flush first */
|
/* flush first */
|
||||||
|
GST_DEBUG ("Pushing out remaining buffers because of EOS");
|
||||||
while (ret) {
|
while (ret) {
|
||||||
if (gst_pad_alloc_buffer_and_set_caps (faac->srcpad,
|
if (gst_pad_alloc_buffer_and_set_caps (faac->srcpad,
|
||||||
GST_BUFFER_OFFSET_NONE, faac->bytes,
|
GST_BUFFER_OFFSET_NONE, faac->bytes,
|
||||||
GST_PAD_CAPS (faac->srcpad), &outbuf) == GST_FLOW_OK) {
|
GST_PAD_CAPS (faac->srcpad), &outbuf) == GST_FLOW_OK) {
|
||||||
gint ret_size;
|
gint ret_size;
|
||||||
|
|
||||||
|
GST_DEBUG ("next_ts %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (faac->next_ts));
|
||||||
|
|
||||||
if ((ret_size = faacEncEncode (faac->handle, NULL, 0,
|
if ((ret_size = faacEncEncode (faac->handle, NULL, 0,
|
||||||
GST_BUFFER_DATA (outbuf), faac->bytes)) > 0) {
|
GST_BUFFER_DATA (outbuf), faac->bytes)) > 0) {
|
||||||
GST_BUFFER_SIZE (outbuf) = ret_size;
|
GST_BUFFER_SIZE (outbuf) = ret_size;
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
|
GST_BUFFER_TIMESTAMP (outbuf) = faac->next_ts;
|
||||||
GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
|
/* 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);
|
gst_pad_push (faac->srcpad, outbuf);
|
||||||
} else {
|
} else {
|
||||||
gst_buffer_unref (outbuf);
|
gst_buffer_unref (outbuf);
|
||||||
@ -513,6 +524,10 @@ gst_faac_chain (GstPad * pad, GstBuffer * inbuf)
|
|||||||
goto nego_failed;
|
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);
|
size = GST_BUFFER_SIZE (inbuf);
|
||||||
in_size = size;
|
in_size = size;
|
||||||
if (faac->cache)
|
if (faac->cache)
|
||||||
@ -600,6 +615,14 @@ gst_faac_chain (GstPad * pad, GstBuffer * inbuf)
|
|||||||
GST_BUFFER_DURATION (outbuf) += faac->cache_duration;
|
GST_BUFFER_DURATION (outbuf) += faac->cache_duration;
|
||||||
faac->cache_duration = 0;
|
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);
|
result = gst_pad_push (faac->srcpad, outbuf);
|
||||||
} else {
|
} else {
|
||||||
/* FIXME: what I'm doing here isn't fully correct, but there
|
/* 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->cache_duration = 0;
|
||||||
faac->samplerate = -1;
|
faac->samplerate = -1;
|
||||||
faac->channels = -1;
|
faac->channels = -1;
|
||||||
|
faac->next_ts = GST_CLOCK_TIME_NONE;
|
||||||
GST_OBJECT_UNLOCK (faac);
|
GST_OBJECT_UNLOCK (faac);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,9 @@ typedef struct _GstFaac {
|
|||||||
/* cache of the input */
|
/* cache of the input */
|
||||||
GstBuffer *cache;
|
GstBuffer *cache;
|
||||||
guint64 cache_time, cache_duration;
|
guint64 cache_time, cache_duration;
|
||||||
|
|
||||||
|
/* Expected timestamp of the next buffer to output */
|
||||||
|
GstClockTime next_ts;
|
||||||
} GstFaac;
|
} GstFaac;
|
||||||
|
|
||||||
typedef struct _GstFaacClass {
|
typedef struct _GstFaacClass {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user