basesink: Don't nest prepare/render calls
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Wed, 5 Oct 2016 18:26:11 +0000 (14:26 -0400)
committerNicolas Dufresne <nicolas.dufresne@collabora.com>
Thu, 3 Nov 2016 17:19:46 +0000 (13:19 -0400)
When the first buffer arrives, we endup calling:

  ->prepare()
    ->prepare()
    ->preroll()
  ->render()

This will likely confuse any element using this method. With this patch,
we ensure the preroll take place before the first render prepare() is
called. This will result in:

  ->prepare()
  ->preroll()
  ->prepare()
  ->render()

https://bugzilla.gnome.org/show_bug.cgi?id=772468

libs/gst/base/gstbasesink.c

index 606c40f..97e0573 100644 (file)
@@ -3479,6 +3479,12 @@ gst_base_sink_chain_unlocked (GstBaseSink * basesink, GstPad * pad,
     if (G_UNLIKELY (late))
       goto dropped;
 
+    /* We are about to prepare the first frame, make sure we have prerolled
+     * already. This prevent nesting prepare/render calls. */
+    ret = gst_base_sink_do_preroll (basesink, obj);
+    if (G_UNLIKELY (ret != GST_FLOW_OK))
+      goto preroll_failed;
+
     if (!is_list) {
       if (bclass->prepare) {
         ret = bclass->prepare (basesink, GST_BUFFER_CAST (obj));
@@ -3639,6 +3645,11 @@ dropped:
     }
     goto done;
   }
+preroll_failed:
+  {
+    GST_DEBUG_OBJECT (basesink, "preroll failed: %s", gst_flow_get_name (ret));
+    return ret;
+  }
 }
 
 /* with STREAM_LOCK