gst/base/gstbasesink.*: Some tweaks, only EOS and a buffer complete a preroll.
authorWim Taymans <wim.taymans@gmail.com>
Thu, 30 Jun 2005 12:14:47 +0000 (12:14 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Thu, 30 Jun 2005 12:14:47 +0000 (12:14 +0000)
Original commit message from CVS:
* gst/base/gstbasesink.c: (gst_base_sink_preroll_queue_empty),
(gst_base_sink_preroll_queue_flush), (gst_base_sink_handle_object),
(gst_base_sink_change_state):
* gst/base/gstbasesink.h:
Some tweaks, only EOS and a buffer complete a preroll.

ChangeLog
common
gst/base/gstbasesink.c
gst/base/gstbasesink.h
libs/gst/base/gstbasesink.c
libs/gst/base/gstbasesink.h

index 900d034..6e7caa8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2005-06-30  Wim Taymans  <wim@fluendo.com>
+
+       * gst/base/gstbasesink.c: (gst_base_sink_preroll_queue_empty),
+       (gst_base_sink_preroll_queue_flush), (gst_base_sink_handle_object),
+       (gst_base_sink_change_state):
+       * gst/base/gstbasesink.h:
+       Some tweaks, only EOS and a buffer complete a preroll.
+
 2005-06-30  Andy Wingo  <wingo@pobox.com>
 
        * gst/gstghostpad.c (gst_ghost_pad_do_activate_push): Proxy
diff --git a/common b/common
index 2826306..4ca96ae 160000 (submodule)
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit 2826306411790bf8aa9298922aa59b126897431f
+Subproject commit 4ca96aedcf2be0b3dcf31fce732aed1da21b8850
index be4c2bb..f0aa9f8 100644 (file)
@@ -380,12 +380,28 @@ gst_base_sink_preroll_queue_empty (GstBaseSink * basesink, GstPad * pad)
   if (q) {
     GST_DEBUG ("emptying queue");
     while ((obj = g_queue_pop_head (q))) {
+      gboolean is_buffer;
+
+      is_buffer = GST_IS_BUFFER (obj);
+      if (is_buffer) {
+        basesink->preroll_queued--;
+        basesink->buffers_queued--;
+      } else {
+        switch (GST_EVENT_TYPE (obj)) {
+          case GST_EVENT_EOS:
+            basesink->preroll_queued--;
+            break;
+          default:
+            break;
+        }
+        basesink->events_queued--;
+      }
       /* we release the preroll lock while pushing so that we
        * can still flush it while blocking on the clock or
        * inside the element. */
       GST_PREROLL_UNLOCK (pad);
 
-      if (GST_IS_BUFFER (obj)) {
+      if (is_buffer) {
         GST_DEBUG ("poped buffer %p", obj);
         ret = gst_base_sink_handle_buffer (basesink, GST_BUFFER (obj));
       } else {
@@ -417,6 +433,9 @@ gst_base_sink_preroll_queue_flush (GstBaseSink * basesink, GstPad * pad)
   }
   /* we can't have EOS anymore now */
   basesink->eos = FALSE;
+  basesink->preroll_queued = 0;
+  basesink->buffers_queued = 0;
+  basesink->events_queued = 0;
   /* and signal any waiters now */
   GST_PREROLL_SIGNAL (pad);
 }
@@ -432,22 +451,34 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
 
   GST_PREROLL_LOCK (pad);
   /* push object on the queue */
-  GST_DEBUG ("push on queue %p %p", basesink, obj);
+  GST_DEBUG ("push on queue %p", basesink, obj);
   g_queue_push_tail (basesink->preroll_queue, obj);
 
   have_event = GST_IS_EVENT (obj);
-
-  if (have_event && GST_EVENT_TYPE (obj) == GST_EVENT_EOS) {
-    basesink->eos = TRUE;
+  if (have_event) {
+    switch (GST_EVENT_TYPE (obj)) {
+      case GST_EVENT_EOS:
+        basesink->preroll_queued++;
+        basesink->eos = TRUE;
+        break;
+      default:
+        break;
+    }
+    basesink->events_queued++;
+  } else {
+    basesink->preroll_queued++;
+    basesink->buffers_queued++;
   }
+  GST_DEBUG ("now %d preroll, %d buffers, %d events on queue",
+      basesink->preroll_queued,
+      basesink->buffers_queued, basesink->events_queued);
 
   /* check if we are prerolling */
   if (!basesink->need_preroll)
     goto no_preroll;
 
-  length = basesink->preroll_queue->length;
-  /* this is the first object we queued */
-  if (length == 1) {
+  /* there is a buffer queued */
+  if (basesink->buffers_queued == 1) {
     GST_DEBUG ("do preroll %p", obj);
 
     /* if it's a buffer, we need to call the preroll method */
@@ -459,46 +490,50 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
         bclass->preroll (basesink, GST_BUFFER (obj));
     }
   }
-  /* we are prerolling */
-  GST_DEBUG ("finish preroll %p >", basesink);
-  basesink->have_preroll = TRUE;
-  GST_PREROLL_UNLOCK (pad);
+  length = basesink->preroll_queued;
+  GST_DEBUG ("prerolled length %d", length);
 
-  /* have to release STREAM_LOCK as we cannot take the STATE_LOCK
-   * inside the STREAM_LOCK */
-  t = GST_STREAM_UNLOCK_FULL (pad);
-  GST_DEBUG ("released stream lock %d times", t);
-  if (t == 0) {
-    GST_WARNING ("STREAM_LOCK should have been locked !!");
-    g_warning ("STREAM_LOCK should have been locked !!");
-  }
+  if (length == 1) {
+    basesink->have_preroll = TRUE;
+    /* we are prerolling */
+    GST_PREROLL_UNLOCK (pad);
 
-  /* now we commit our state */
-  GST_STATE_LOCK (basesink);
-  GST_DEBUG ("commit state %p >", basesink);
-  gst_element_commit_state (GST_ELEMENT (basesink));
-  GST_STATE_UNLOCK (basesink);
+    /* have to release STREAM_LOCK as we cannot take the STATE_LOCK
+     * inside the STREAM_LOCK */
+    t = GST_STREAM_UNLOCK_FULL (pad);
+    GST_DEBUG ("released stream lock %d times", t);
+    if (t == 0) {
+      GST_WARNING ("STREAM_LOCK should have been locked !!");
+      g_warning ("STREAM_LOCK should have been locked !!");
+    }
 
-  /* reacquire stream lock, pad could be flushing now */
-  /* FIXME in glib, if t==0, the lock is still taken... hmmm */
-  if (t > 0)
-    GST_STREAM_LOCK_FULL (pad, t);
+    /* now we commit our state */
+    GST_STATE_LOCK (basesink);
+    GST_DEBUG ("commit state %p >", basesink);
+    gst_element_commit_state (GST_ELEMENT (basesink));
+    GST_STATE_UNLOCK (basesink);
 
-  /* and wait if needed */
-  GST_PREROLL_LOCK (pad);
+    /* reacquire stream lock, pad could be flushing now */
+    /* FIXME in glib, if t==0, the lock is still taken... hmmm */
+    if (t > 0)
+      GST_STREAM_LOCK_FULL (pad, t);
 
-  GST_LOCK (pad);
-  if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
-    goto flushing;
-  GST_UNLOCK (pad);
+    /* and wait if needed */
+    GST_PREROLL_LOCK (pad);
 
-  /* it is possible that the application set the state to PLAYING
-   * now in which case we don't need to block anymore. */
-  if (!basesink->need_preroll)
-    goto no_preroll;
+    GST_LOCK (pad);
+    if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
+      goto flushing;
+    GST_UNLOCK (pad);
+
+    /* it is possible that the application set the state to PLAYING
+     * now in which case we don't need to block anymore. */
+    if (!basesink->need_preroll)
+      goto no_preroll;
+
+    length = basesink->preroll_queued;
+  }
 
-  length = basesink->preroll_queue->length;
-  GST_DEBUG ("prerolled length %d", length);
   /* see if we need to block now. We cannot block on events, only
    * on buffers, the reason is that events can be sent from the
    * application thread and we don't want to block there. */
index ceeb2ea..e0d0f8a 100644 (file)
@@ -54,6 +54,9 @@ struct _GstBaseSink {
   /*< protected >*/ /* with PREROLL_LOCK */
   GQueue       *preroll_queue;
   gint          preroll_queue_max_len;
+  gint          preroll_queued;
+  gint          buffers_queued;
+  gint          events_queued;
 
   guint64       offset;
   gboolean      has_loop;
index be4c2bb..f0aa9f8 100644 (file)
@@ -380,12 +380,28 @@ gst_base_sink_preroll_queue_empty (GstBaseSink * basesink, GstPad * pad)
   if (q) {
     GST_DEBUG ("emptying queue");
     while ((obj = g_queue_pop_head (q))) {
+      gboolean is_buffer;
+
+      is_buffer = GST_IS_BUFFER (obj);
+      if (is_buffer) {
+        basesink->preroll_queued--;
+        basesink->buffers_queued--;
+      } else {
+        switch (GST_EVENT_TYPE (obj)) {
+          case GST_EVENT_EOS:
+            basesink->preroll_queued--;
+            break;
+          default:
+            break;
+        }
+        basesink->events_queued--;
+      }
       /* we release the preroll lock while pushing so that we
        * can still flush it while blocking on the clock or
        * inside the element. */
       GST_PREROLL_UNLOCK (pad);
 
-      if (GST_IS_BUFFER (obj)) {
+      if (is_buffer) {
         GST_DEBUG ("poped buffer %p", obj);
         ret = gst_base_sink_handle_buffer (basesink, GST_BUFFER (obj));
       } else {
@@ -417,6 +433,9 @@ gst_base_sink_preroll_queue_flush (GstBaseSink * basesink, GstPad * pad)
   }
   /* we can't have EOS anymore now */
   basesink->eos = FALSE;
+  basesink->preroll_queued = 0;
+  basesink->buffers_queued = 0;
+  basesink->events_queued = 0;
   /* and signal any waiters now */
   GST_PREROLL_SIGNAL (pad);
 }
@@ -432,22 +451,34 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
 
   GST_PREROLL_LOCK (pad);
   /* push object on the queue */
-  GST_DEBUG ("push on queue %p %p", basesink, obj);
+  GST_DEBUG ("push on queue %p", basesink, obj);
   g_queue_push_tail (basesink->preroll_queue, obj);
 
   have_event = GST_IS_EVENT (obj);
-
-  if (have_event && GST_EVENT_TYPE (obj) == GST_EVENT_EOS) {
-    basesink->eos = TRUE;
+  if (have_event) {
+    switch (GST_EVENT_TYPE (obj)) {
+      case GST_EVENT_EOS:
+        basesink->preroll_queued++;
+        basesink->eos = TRUE;
+        break;
+      default:
+        break;
+    }
+    basesink->events_queued++;
+  } else {
+    basesink->preroll_queued++;
+    basesink->buffers_queued++;
   }
+  GST_DEBUG ("now %d preroll, %d buffers, %d events on queue",
+      basesink->preroll_queued,
+      basesink->buffers_queued, basesink->events_queued);
 
   /* check if we are prerolling */
   if (!basesink->need_preroll)
     goto no_preroll;
 
-  length = basesink->preroll_queue->length;
-  /* this is the first object we queued */
-  if (length == 1) {
+  /* there is a buffer queued */
+  if (basesink->buffers_queued == 1) {
     GST_DEBUG ("do preroll %p", obj);
 
     /* if it's a buffer, we need to call the preroll method */
@@ -459,46 +490,50 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
         bclass->preroll (basesink, GST_BUFFER (obj));
     }
   }
-  /* we are prerolling */
-  GST_DEBUG ("finish preroll %p >", basesink);
-  basesink->have_preroll = TRUE;
-  GST_PREROLL_UNLOCK (pad);
+  length = basesink->preroll_queued;
+  GST_DEBUG ("prerolled length %d", length);
 
-  /* have to release STREAM_LOCK as we cannot take the STATE_LOCK
-   * inside the STREAM_LOCK */
-  t = GST_STREAM_UNLOCK_FULL (pad);
-  GST_DEBUG ("released stream lock %d times", t);
-  if (t == 0) {
-    GST_WARNING ("STREAM_LOCK should have been locked !!");
-    g_warning ("STREAM_LOCK should have been locked !!");
-  }
+  if (length == 1) {
+    basesink->have_preroll = TRUE;
+    /* we are prerolling */
+    GST_PREROLL_UNLOCK (pad);
 
-  /* now we commit our state */
-  GST_STATE_LOCK (basesink);
-  GST_DEBUG ("commit state %p >", basesink);
-  gst_element_commit_state (GST_ELEMENT (basesink));
-  GST_STATE_UNLOCK (basesink);
+    /* have to release STREAM_LOCK as we cannot take the STATE_LOCK
+     * inside the STREAM_LOCK */
+    t = GST_STREAM_UNLOCK_FULL (pad);
+    GST_DEBUG ("released stream lock %d times", t);
+    if (t == 0) {
+      GST_WARNING ("STREAM_LOCK should have been locked !!");
+      g_warning ("STREAM_LOCK should have been locked !!");
+    }
 
-  /* reacquire stream lock, pad could be flushing now */
-  /* FIXME in glib, if t==0, the lock is still taken... hmmm */
-  if (t > 0)
-    GST_STREAM_LOCK_FULL (pad, t);
+    /* now we commit our state */
+    GST_STATE_LOCK (basesink);
+    GST_DEBUG ("commit state %p >", basesink);
+    gst_element_commit_state (GST_ELEMENT (basesink));
+    GST_STATE_UNLOCK (basesink);
 
-  /* and wait if needed */
-  GST_PREROLL_LOCK (pad);
+    /* reacquire stream lock, pad could be flushing now */
+    /* FIXME in glib, if t==0, the lock is still taken... hmmm */
+    if (t > 0)
+      GST_STREAM_LOCK_FULL (pad, t);
 
-  GST_LOCK (pad);
-  if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
-    goto flushing;
-  GST_UNLOCK (pad);
+    /* and wait if needed */
+    GST_PREROLL_LOCK (pad);
 
-  /* it is possible that the application set the state to PLAYING
-   * now in which case we don't need to block anymore. */
-  if (!basesink->need_preroll)
-    goto no_preroll;
+    GST_LOCK (pad);
+    if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
+      goto flushing;
+    GST_UNLOCK (pad);
+
+    /* it is possible that the application set the state to PLAYING
+     * now in which case we don't need to block anymore. */
+    if (!basesink->need_preroll)
+      goto no_preroll;
+
+    length = basesink->preroll_queued;
+  }
 
-  length = basesink->preroll_queue->length;
-  GST_DEBUG ("prerolled length %d", length);
   /* see if we need to block now. We cannot block on events, only
    * on buffers, the reason is that events can be sent from the
    * application thread and we don't want to block there. */
index ceeb2ea..e0d0f8a 100644 (file)
@@ -54,6 +54,9 @@ struct _GstBaseSink {
   /*< protected >*/ /* with PREROLL_LOCK */
   GQueue       *preroll_queue;
   gint          preroll_queue_max_len;
+  gint          preroll_queued;
+  gint          buffers_queued;
+  gint          events_queued;
 
   guint64       offset;
   gboolean      has_loop;