[Cogl] [PATCH 8/9] basic-video-player: Delay drawing until the framebuffer is ready

Neil Roberts neil at linux.intel.com
Fri Mar 1 05:31:59 PST 2013


Instead of drawing immediately in the callback which reports when
GStreamer has a new frame ready it now just sets a flag. The drawing
is now only done when both a new frame is ready and we have received a
framebuffer sync event from Cogl.
---
 examples/cogl-basic-video-player.c | 84 ++++++++++++++++++++++++--------------
 1 file changed, 53 insertions(+), 31 deletions(-)

diff --git a/examples/cogl-basic-video-player.c b/examples/cogl-basic-video-player.c
index 156c4eb..51929a1 100644
--- a/examples/cogl-basic-video-player.c
+++ b/examples/cogl-basic-video-player.c
@@ -7,6 +7,7 @@ typedef struct _Data
   CoglPipeline *pln;
   CoglGstVideoSink *sink;
   CoglBool draw_ready;
+  CoglBool frame_ready;
   GMainLoop *main_loop;
 }Data;
 
@@ -47,23 +48,8 @@ _bus_watch (GstBus *bus,
 }
 
 static void
-_frame_callback (CoglOnscreen *onscreen,
-                 CoglFrameEvent event,
-                 CoglFrameInfo *info,
-                 void *user_data)
-{
-  Data *data = user_data;
-
-  if (event == COGL_FRAME_EVENT_SYNC)
-    data->draw_ready = TRUE;
-}
-
-static CoglBool
-_draw  (gpointer instance,
-        gpointer user_data)
+_draw (Data *data)
 {
-  Data *data = (Data*) user_data;
-
   /*
     The cogl pipeline needs to be retrieved from the sink before every draw.
     This is due to the cogl-gst sink creating a new cogl pipeline for each frame
@@ -71,23 +57,55 @@ _draw  (gpointer instance,
   */
   CoglPipeline* current = cogl_gst_video_sink_get_pipeline (data->sink);
 
-  if (data->draw_ready)
+  cogl_framebuffer_clear4f (data->fb,
+                            COGL_BUFFER_BIT_COLOR|COGL_BUFFER_BIT_DEPTH, 0,
+                            0, 0, 1);
+  data->pln = current;
+
+  cogl_framebuffer_push_matrix (data->fb);
+  cogl_framebuffer_translate (data->fb, 640 / 2, 480 / 2, 0);
+  cogl_framebuffer_draw_textured_rectangle (data->fb, data->pln, -320, -240,
+                                            320, 240, 0, 0, 1, 1);
+  cogl_framebuffer_pop_matrix (data->fb);
+
+  cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));
+}
+
+static void
+_check_draw (Data *data)
+{
+  /* The frame is only drawn once we know that a new buffer is ready
+   * from GStreamer and that Cogl is ready to accept some new
+   * rendering */
+  if (data->draw_ready && data->frame_ready)
+    {
+      _draw (data);
+      data->draw_ready = FALSE;
+      data->frame_ready = FALSE;
+    }
+}
+
+static void
+_frame_callback (CoglOnscreen *onscreen,
+                 CoglFrameEvent event,
+                 CoglFrameInfo *info,
+                 void *user_data)
+{
+  Data *data = user_data;
+
+  if (event == COGL_FRAME_EVENT_SYNC)
     {
-      cogl_framebuffer_clear4f (data->fb,
-                                COGL_BUFFER_BIT_COLOR|COGL_BUFFER_BIT_DEPTH, 0,
-                                0, 0, 1);
-      data->pln = current;
-
-      cogl_framebuffer_push_matrix (data->fb);
-      cogl_framebuffer_translate (data->fb, 640 / 2, 480 / 2, 0);
-      cogl_framebuffer_draw_textured_rectangle (data->fb, data->pln, -320, -240,
-                                                320, 240, 0, 0, 1, 1);
-      cogl_framebuffer_pop_matrix (data->fb);
-
-      cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));
+      data->draw_ready = TRUE;
+      _check_draw (data);
     }
+}
 
-  return TRUE;
+static void
+_new_frame_cb (CoglGstVideoSink *sink,
+               Data *data)
+{
+  data->frame_ready = TRUE;
+  _check_draw (data);
 }
 
 /*
@@ -131,7 +149,10 @@ _set_up_pipeline (gpointer instance,
      frame-rate of the video.
   */
 
-  g_signal_connect (data->sink,"cogl-gst-new-frame", G_CALLBACK (_draw), data);
+  g_signal_connect (data->sink,
+                    "cogl-gst-new-frame",
+                    G_CALLBACK (_new_frame_cb),
+                    data);
 }
 
 int
@@ -217,6 +238,7 @@ main (int argc,
                     G_CALLBACK (_set_up_pipeline), &data);
 
   data.draw_ready = TRUE;
+  data.frame_ready = FALSE;
 
   g_main_loop_run (data.main_loop);
 
-- 
1.7.11.3.g3c3efa5



More information about the Cogl mailing list