[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