ext/faac/gstfaac.*: Add code for calculating proper timestamp/duration for the traili...
authorEdward Hervey <bilboed@bilboed.com>
Fri, 29 Aug 2008 11:36:41 +0000 (11:36 +0000)
committerEdward Hervey <bilboed@bilboed.com>
Fri, 29 Aug 2008 11:36:41 +0000 (11:36 +0000)
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.

ChangeLog
ext/faac/gstfaac.c
ext/faac/gstfaac.h

index 8c76c3a..181a05d 100644 (file)
--- 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:
index eae5849..fb62b33 100644 (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;
     }
index d69d4d4..88a3e34 100644 (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 {