[gst-cvs] gst-plugins-bad: faad: drain sync pending frames when appropriate

Mark Nauwelaerts mnauw at kemper.freedesktop.org
Thu Feb 11 13:37:14 PST 2010


Module: gst-plugins-bad
Branch: master
Commit: 83f1b71613a07b98e2b68dc24b6f17e55214f5c6
URL:    http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/commit/?id=83f1b71613a07b98e2b68dc24b6f17e55214f5c6

Author: Mark Nauwelaerts <mark.nauwelaerts at collabora.co.uk>
Date:   Wed Feb 10 23:29:23 2010 +0100

faad: drain sync pending frames when appropriate

---

 ext/faad/gstfaad.c |   48 +++++++++++++++++++++++++++++++++---------------
 1 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/ext/faad/gstfaad.c b/ext/faad/gstfaad.c
index 614bee8..bee468e 100644
--- a/ext/faad/gstfaad.c
+++ b/ext/faad/gstfaad.c
@@ -544,6 +544,9 @@ gst_faad_drain (GstFaad * faad)
     /* if we have some queued frames for reverse playback, flush
      * them now */
     ret = flush_queued (faad);
+  } else {
+    /* squeeze any possible remaining frames that are pending sync */
+    gst_faad_chain (faad->sinkpad, NULL);
   }
   return ret;
 }
@@ -898,7 +901,8 @@ gst_faad_update_caps (GstFaad * faad, faacDecFrameInfo * info)
  * gst/typefind/) for ADTS because 12 bits isn't very reliable.
  */
 static gboolean
-gst_faad_sync (GstFaad * faad, guint8 * data, guint size, guint * off)
+gst_faad_sync (GstFaad * faad, guint8 * data, guint size, gboolean next,
+    guint * off)
 {
   guint n = 0;
   gint snc;
@@ -928,8 +932,16 @@ gst_faad_sync (GstFaad * faad, guint8 * data, guint size, guint * off)
       len = ((data[n + 3] & 0x03) << 11) |
           (data[n + 4] << 3) | ((data[n + 5] & 0xe0) >> 5);
       if (n + len + 2 >= size) {
-        GST_LOG_OBJECT (faad, "Next frame is not within reach");
-        break;
+        GST_LOG_OBJECT (faad, "Frame size %d, next frame is not within reach",
+            len);
+        if (next) {
+          break;
+        } else if (n + len <= size) {
+          GST_LOG_OBJECT (faad, "but have complete frame and no next frame; "
+              "accept ADTS syncpoint at offset 0x%x (framelen %u)", n, len);
+          ret = TRUE;
+          break;
+        }
       }
 
       snc = GST_READ_UINT16_BE (&data[n + len]);
@@ -994,22 +1006,28 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
   gboolean run_loop = TRUE;
   guint sync_off;
   GstClockTime ts;
+  gboolean next;
 
   faad = GST_FAAD (gst_pad_get_parent (pad));
 
-  GST_LOG_OBJECT (faad, "buffer of size %d with ts: %" GST_TIME_FORMAT
-      ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buffer),
-      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
-      GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
+  if (G_LIKELY (buffer)) {
+    GST_LOG_OBJECT (faad, "buffer of size %d with ts: %" GST_TIME_FORMAT
+        ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buffer),
+        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
+        GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
 
-  if (GST_BUFFER_IS_DISCONT (buffer)) {
-    gst_faad_drain (faad);
-    gst_faad_reset_stream_state (faad);
-    faad->discont = TRUE;
-  }
+    if (GST_BUFFER_IS_DISCONT (buffer)) {
+      gst_faad_drain (faad);
+      gst_faad_reset_stream_state (faad);
+      faad->discont = TRUE;
+    }
 
-  gst_adapter_push (faad->adapter, buffer);
-  buffer = NULL;
+    gst_adapter_push (faad->adapter, buffer);
+    buffer = NULL;
+    next = TRUE;
+  } else {
+    next = FALSE;
+  }
 
   ts = gst_adapter_prev_timestamp (faad->adapter, NULL);
   if (GST_CLOCK_TIME_IS_VALID (ts) && (ts != faad->prev_ts))
@@ -1024,7 +1042,7 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
   input_data = (guchar *) gst_adapter_peek (faad->adapter, available);
 
   if (!faad->packetised) {
-    if (!gst_faad_sync (faad, input_data, input_size, &sync_off)) {
+    if (!gst_faad_sync (faad, input_data, input_size, next, &sync_off)) {
       faad->sync_flush += sync_off;
       input_size -= sync_off;
       if (faad->sync_flush > FAAD_MAX_SYNC)





More information about the Gstreamer-commits mailing list