[Cogl] [PATCH 3/3] cogl-gst: Apply suggested API fixes

Plamena Manolova plamena.n.manolova at intel.com
Thu Feb 21 09:25:09 PST 2013


cogl-gst: Make color model conversion shaders more flexible

Instead of direclty assigning the output color, the
cogl_gst_sample_video function is used for the color
model conversion and a default fragment shader is attached.
Also replaces gl names with their cogl equivalents and
removes cogl-gst-shaders.h from the list of installed
headers.

cogl-gst: Include the cogl frame callback api in the video player example

The basic video player now only redraws after receiving a sync
notification from cogl and a new frame from the cogl sink. Also
includes some stylistic changes like switching to g_error etc.

cogl-gst: Reimplement CoglGstVideoPlayer as a GObject

The cogl gst video player utility is now a GObject and
can be disposed of using g_object_unref.
---
 cogl-gst/Makefile.am                     |   1 -
 cogl-gst/cogl-gst-shaders.h              |  97 ---------------------------
 cogl-gst/cogl-gst-util.c                 |  10 +--
 cogl-gst/cogl-gst-util.h                 |   2 +-
 cogl-gst/cogl-gst-video-player-private.h |  13 ++--
 cogl-gst/cogl-gst-video-player.c         | 108 ++++++++++++++-----------------
 cogl-gst/cogl-gst-video-player.h         |  44 ++++++++++++-
 cogl-gst/cogl-gst-video-sink-private.h   |  39 ++++++++++-
 cogl-gst/cogl-gst-video-sink.c           | 107 +++++++++++-------------------
 cogl-gst/cogl-gst-video-sink.h           |   5 +-
 examples/cogl-basic-video-player.c       |  96 +++++++++++++++++----------
 11 files changed, 236 insertions(+), 286 deletions(-)
 delete mode 100644 cogl-gst/cogl-gst-shaders.h

diff --git a/cogl-gst/Makefile.am b/cogl-gst/Makefile.am
index 494c419..598b13d 100644
--- a/cogl-gst/Makefile.am
+++ b/cogl-gst/Makefile.am
@@ -14,7 +14,6 @@ source_c = \
 	$(NULL)
 
 source_h = cogl-gst.h \
-	cogl-gst-shaders.h \
 	cogl-gst-util.h \
 	cogl-gst-video-player.h \
 	cogl-gst-video-sink.h \
diff --git a/cogl-gst/cogl-gst-shaders.h b/cogl-gst/cogl-gst-shaders.h
deleted file mode 100644
index 978bfce..0000000
--- a/cogl-gst/cogl-gst-shaders.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Cogl-GStreamer.
- *
- * GStreamer integration library for Cogl.
- *
- * cogl-gst-shaders.h - Shaders for yuv to rgb conversion
- *
- * Authored by Jonathan Matthew  <jonathan at kaolin.wh9.net>,
- *             Chris Lord        <chris at openedhand.com>
- *             Damien Lespiau    <damien.lespiau at intel.com>
- *             Matthew Allum     <mallum at openedhand.com>
- *             Plamena Manolova  <plamena.n.manolova at intel.com>
- *
- * Copyright (C) 2007, 2008 OpenedHand
- * Copyright (C) 2009, 2010, 2013 Intel Corporation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __COGL_GST_SHADERS_H__
-#define __COGL_GST_SHADERS_H__
-
-static char *yv12_to_rgba_shader_pre = \
-  "uniform sampler2D ytex;"
-  "uniform sampler2D utex;"
-  "uniform sampler2D vtex;"
-  "varying vec4 rgb_color;"
-  ;
-
-static char *yv12_to_rgba_frag_shader_post = \
-  "vec2 coord = vec2(gl_TexCoord[0].st);"
-  "float y = 1.1640625 * (texture2D (ytex, coord).g - 0.0625);"
-  "float u = texture2D (utex, coord).g - 0.5;"
-  "float v = texture2D (vtex, coord).g - 0.5;"
-  "vec4 color;"
-  "color.r = y + 1.59765625 * v;"
-  "color.g = y - 0.390625 * u - 0.8125 * v;"
-  "color.b = y + 2.015625 * u;"
-  "color.a = 1.0;"
-  "gl_FragColor = color;";
-
-static char *yv12_to_rgba_vertex_shader_post = \
-  "vec2 coord = vec2(gl_MultiTexCoord0.st);"
-  "float y = 1.1640625 * (texture2D (ytex, coord).g - 0.0625);"
-  "float u = texture2D (utex, coord).g - 0.5;"
-  "float v = texture2D (vtex, coord).g - 0.5;"
-  "vec4 color;"
-  "color.r = y + 1.59765625 * v;"
-  "color.g = y - 0.390625 * u - 0.8125 * v;"
-  "color.b = y + 2.015625 * u;"
-  "color.a = 1.0;"
-  "gl_FrontColor = color;"
-  "rgb_color = color;";
-
-static char *ayuv_to_rgba_shader_pre = \
-  "uniform sampler2D tex;"
-  "varying vec4 rgb_color;";
-
-static char *ayuv_to_rgba_frag_shader_post = \
-  "vec4 color = texture2D (tex, gl_TexCoord[0].st);"
-  "float y = 1.1640625 * (color.g - 0.0625);"
-  "float u = color.b - 0.5;"
-  "float v = color.a - 0.5;"
-  "color.a = color.r;"
-  "color.r = y + 1.59765625 * v;"
-  "color.g = y - 0.390625 * u - 0.8125 * v;"
-  "color.b = y + 2.015625 * u;"
-  "gl_FragColor = color;";
-
-static char *ayuv_to_rgba_vertex_shader_post = \
-  "vec4 color = texture2D (tex, gl_MultiTexCoord0.st);"
-  "float y = 1.1640625 * (color.g - 0.0625);"
-  "float u = color.b - 0.5;"
-  "float v = color.a - 0.5;"
-  "color.a = color.r;"
-  "color.r = y + 1.59765625 * v;"
-  "color.g = y - 0.390625 * u - 0.8125 * v;"
-  "color.b = y + 2.015625 * u;"
-  "gl_FrontColor = color;";
-
-static char *canned_fragment = \
-  "gl_FragColor = rgb_color;\n";
-
-#endif
diff --git a/cogl-gst/cogl-gst-util.c b/cogl-gst/cogl-gst-util.c
index c9c37ee..d87d8d4 100644
--- a/cogl-gst/cogl-gst-util.c
+++ b/cogl-gst/cogl-gst-util.c
@@ -33,7 +33,7 @@
 #include <cogl-gst/cogl-gst-util.h>
 #include <gst/gst.h>
 
-CoglBool
+void
 cogl_gst_init (int* argc,
                char*** argv)
 {
@@ -43,11 +43,5 @@ cogl_gst_init (int* argc,
   success = gst_init_check (argc, argv, &error);
 
   if (success == FALSE && error != NULL)
-    {
-      fprintf (stderr, "COGL-GST: Failed to initialize GStreamer: %s\n",
-               error->message);
-      abort ();
-    }
-
-  return success;
+    g_error ("COGL-GST: Failed to initialize GStreamer: %s\n", error->message);
 }
diff --git a/cogl-gst/cogl-gst-util.h b/cogl-gst/cogl-gst-util.h
index 071586d..fe92004 100644
--- a/cogl-gst/cogl-gst-util.h
+++ b/cogl-gst/cogl-gst-util.h
@@ -36,7 +36,7 @@
 
 #include <cogl/cogl.h>
 
-CoglBool
+void
 cogl_gst_init (int* argc,
                char*** argv);
 
diff --git a/cogl-gst/cogl-gst-video-player-private.h b/cogl-gst/cogl-gst-video-player-private.h
index 95c851d..060023b 100644
--- a/cogl-gst/cogl-gst-video-player-private.h
+++ b/cogl-gst/cogl-gst-video-player-private.h
@@ -29,16 +29,11 @@
 #define __COGL_GST_VIDEO_PLAYER_PRIVATE_H__
 #include "cogl-gst-video-player.h"
 
-static GstSeekFlags
-cogl_gst_seek_flags = GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT;
+#define COGL_GST_SEEK_FLAGS (GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT)
 
-gboolean
-cogl_gst_bus_watch (GstBus *bus,
-                    GstMessage *msg,
-                    void *user_data);
 void
-cogl_gst_prepare_new_video_pipeline (CoglContext *ctx,
-                                     CoglGstVideoPlayer *player,
-                                     char *uri);
+_cogl_gst_prepare_new_video_pipeline (CoglContext *ctx,
+                                      CoglGstVideoPlayer *player,
+                                      char *uri);
 #endif
 
diff --git a/cogl-gst/cogl-gst-video-player.c b/cogl-gst/cogl-gst-video-player.c
index 2b81f24..67b26c7 100644
--- a/cogl-gst/cogl-gst-video-player.c
+++ b/cogl-gst/cogl-gst-video-player.c
@@ -25,10 +25,11 @@
  * Boston, MA 02111-1307, USA.
  */
 
-#include <malloc.h>
 #include "cogl-gst-video-player-private.h"
 
-struct _CoglGstVideoPlayer
+G_DEFINE_TYPE(CoglGstVideoPlayer, cogl_gst_video_player, G_TYPE_OBJECT);
+
+struct _CoglGstVideoPlayerPrivate
 {
   CoglContext *ctx;
   GstElement *sink;
@@ -38,53 +39,38 @@ struct _CoglGstVideoPlayer
   unsigned int bus_watch;
 };
 
-CoglBool
-cogl_gst_bus_watch (GstBus *bus,
-                    GstMessage *msg,
-                    void *data)
+static void
+cogl_gst_video_player_class_init (CoglGstVideoPlayerClass *klass)
 {
-  if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR)
-    {
-      char *debug;
-      GError *error = NULL;
-
-      gst_message_parse_error (msg, &error, &debug);
-      free (debug);
-
-      if (error != NULL)
-        {
-          fprintf (stderr, "COGL-GST: Playback error: %s\n",
-                    error->message);
-          g_error_free (error);
-        }
-    }
+}
 
-  return TRUE;
+static void
+cogl_gst_video_player_init (CoglGstVideoPlayer *self)
+{
 }
 
 void
-cogl_gst_prepare_new_video_pipeline (CoglContext *ctx,
-                                     CoglGstVideoPlayer *player,
-                                     char *uri)
+_cogl_gst_prepare_new_video_pipeline (CoglContext *ctx,
+                                      CoglGstVideoPlayer *player,
+                                      char *uri)
 {
-  player->pipeline = gst_pipeline_new ("gst-player");
-  player->bin = gst_element_factory_make ("playbin", "bin");
-  player->sink = gst_element_factory_make ("coglsink", "videosink");
-  player->uri = uri;
-  player->ctx = ctx;
-  player->bus_watch = 0;
-
-  cogl_gst_video_sink_set_context (COGL_GST_VIDEO_SINK (player->sink), ctx);
+  CoglGstVideoPlayerPrivate* priv = player->priv;
+  priv->pipeline = gst_pipeline_new ("gst-player");
+  priv->bin = gst_element_factory_make ("playbin", "bin");
+  priv->sink = gst_element_factory_make ("coglsink", "videosink");
+  priv->uri = uri;
+  priv->ctx = ctx;
+  priv->bus_watch = 0;
 
-  g_object_set (G_OBJECT (player->bin), "video-sink", player->sink, NULL);
+  cogl_gst_video_sink_set_context (COGL_GST_VIDEO_SINK (priv->sink), ctx);
 
+  g_object_set (G_OBJECT (priv->bin), "video-sink", priv->sink, NULL);
 
-  gst_bin_add (GST_BIN (player->pipeline), player->bin);
 
-  cogl_gst_video_player_add_bus_watch (player, cogl_gst_bus_watch, NULL);
+  gst_bin_add (GST_BIN (priv->pipeline), priv->bin);
 
-  if (player->uri != NULL)
-    g_object_set (G_OBJECT (player->bin), "uri", player->uri, NULL);
+  if (priv->uri != NULL)
+    g_object_set (G_OBJECT (priv->bin), "uri", priv->uri, NULL);
 }
 
 CoglGstVideoPlayer*
@@ -92,12 +78,14 @@ cogl_gst_video_player_new (CoglContext *ctx,
                            CoglBool play,
                            char *uri)
 {
-  CoglGstVideoPlayer* player = g_new (CoglGstVideoPlayer, 1);
+  CoglGstVideoPlayerPrivate* priv = g_new (CoglGstVideoPlayerPrivate, 1);
+  CoglGstVideoPlayer* player = g_object_new (COGL_GST_TYPE_VIDEO_PLAYER, NULL);
+  player->priv = priv;
 
-  cogl_gst_prepare_new_video_pipeline (ctx, player, uri);
+  _cogl_gst_prepare_new_video_pipeline (ctx, player, uri);
 
   if (play == TRUE)
-    cogl_gst_play_video (player, player->uri);
+    cogl_gst_play_video (player, priv->uri);
 
   return player;
 }
@@ -109,20 +97,20 @@ cogl_gst_play_video (CoglGstVideoPlayer *player,
   if (uri)
     {
       cogl_gst_video_player_stop (player);
-      cogl_gst_prepare_new_video_pipeline (player->ctx, player, uri);
-      gst_element_set_state (player->pipeline, GST_STATE_PLAYING);
+      _cogl_gst_prepare_new_video_pipeline (player->priv->ctx, player, uri);
+      gst_element_set_state (player->priv->pipeline, GST_STATE_PLAYING);
     }
   else
     {
-      gst_element_set_state (player->pipeline, GST_STATE_NULL);
-      fprintf (stderr, "COGL-GST: Invalid uri");
+      gst_element_set_state (player->priv->pipeline, GST_STATE_NULL);
+      g_error ("COGL-GST: Invalid uri");
     }
 }
 
 CoglGstVideoSink*
 cogl_gst_video_player_get_sink (CoglGstVideoPlayer *player)
 {
-  return COGL_GST_VIDEO_SINK (player->sink);
+  return COGL_GST_VIDEO_SINK (player->priv->sink);
 }
 
 void
@@ -131,28 +119,28 @@ cogl_gst_video_player_add_bus_watch (CoglGstVideoPlayer *player,
                                      void *user_data)
 {
   GstBus *bus;
-  bus = gst_pipeline_get_bus (GST_PIPELINE (player->pipeline));
-  if (player->bus_watch != 0)
-    g_source_remove(player->bus_watch);
+  bus = gst_pipeline_get_bus (GST_PIPELINE (player->priv->pipeline));
+  if (player->priv->bus_watch != 0)
+    g_source_remove(player->priv->bus_watch);
 
-  player->bus_watch = gst_bus_add_watch (bus, func, user_data);
+  player->priv->bus_watch = gst_bus_add_watch (bus, func, user_data);
   gst_object_unref (bus);
 }
 
 void
 cogl_gst_video_player_stop (CoglGstVideoPlayer *player)
 {
-  if (player->pipeline)
+  if (player->priv->pipeline)
     {
-      gst_element_set_state (player->pipeline, GST_STATE_NULL);
-      gst_object_unref (GST_OBJECT (player->pipeline));
+      gst_element_set_state (player->priv->pipeline, GST_STATE_NULL);
+      gst_object_unref (GST_OBJECT (player->priv->pipeline));
     }
 }
 
 void
 cogl_gst_video_player_reset (CoglGstVideoPlayer *player)
 {
-  gst_element_seek (player->pipeline, 1.0, GST_FORMAT_TIME, cogl_gst_seek_flags,
+  gst_element_seek (player->priv->pipeline, 1.0, GST_FORMAT_TIME, COGL_GST_SEEK_FLAGS,
                     GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE,
                     GST_CLOCK_TIME_NONE);
 }
@@ -160,20 +148,20 @@ cogl_gst_video_player_reset (CoglGstVideoPlayer *player)
 void
 cogl_gst_video_player_pause (CoglGstVideoPlayer *player)
 {
-  gst_element_set_state (player->pipeline, GST_STATE_PAUSED);
+  gst_element_set_state (player->priv->pipeline, GST_STATE_PAUSED);
 }
 
 void
 cogl_gst_video_player_resume (CoglGstVideoPlayer *player)
 {
-  gst_element_set_state (player->pipeline, GST_STATE_PLAYING);
+  gst_element_set_state (player->priv->pipeline, GST_STATE_PLAYING);
 }
 
 void
 cogl_gst_video_player_seek (CoglGstVideoPlayer *player,
                             int value)
 {
-  gst_element_seek (player->pipeline, 1.0, GST_FORMAT_TIME, cogl_gst_seek_flags,
+  gst_element_seek (player->priv->pipeline, 1.0, GST_FORMAT_TIME, COGL_GST_SEEK_FLAGS,
                     GST_SEEK_TYPE_CUR, value * GST_SECOND, GST_SEEK_TYPE_NONE,
                     GST_CLOCK_TIME_NONE);
 }
@@ -182,7 +170,7 @@ void
 cogl_gst_video_player_seek_absolute (CoglGstVideoPlayer *player,
                                      uint64_t value)
 {
-  gst_element_seek (player->pipeline, 1.0, GST_FORMAT_TIME, cogl_gst_seek_flags,
+  gst_element_seek (player->priv->pipeline, 1.0, GST_FORMAT_TIME, COGL_GST_SEEK_FLAGS,
                     GST_SEEK_TYPE_SET, value, GST_SEEK_TYPE_NONE,
                     GST_CLOCK_TIME_NONE);
 }
@@ -193,7 +181,7 @@ cogl_gst_video_player_get_progress (CoglGstVideoPlayer *player)
   GstFormat format = GST_FORMAT_TIME;
   int64_t prog;
 
-  gst_element_query_position (player->pipeline, &format, &prog);
+  gst_element_query_position (player->priv->pipeline, &format, &prog);
   if (format != GST_FORMAT_TIME)
     return GST_CLOCK_TIME_NONE;
 
@@ -206,7 +194,7 @@ cogl_gst_video_player_get_duration (CoglGstVideoPlayer *player)
   GstFormat format = GST_FORMAT_TIME;
   int64_t dur;
 
-  gst_element_query_duration (player->pipeline, &format, &dur);
+  gst_element_query_duration (player->priv->pipeline, &format, &dur);
   if (format != GST_FORMAT_TIME)
     return GST_CLOCK_TIME_NONE;
 
diff --git a/cogl-gst/cogl-gst-video-player.h b/cogl-gst/cogl-gst-video-player.h
index 2b9cac1..7a818e8 100644
--- a/cogl-gst/cogl-gst-video-player.h
+++ b/cogl-gst/cogl-gst-video-player.h
@@ -28,8 +28,49 @@
 #ifndef __COGL_GST_VIDEO_PLAYER_H__
 #define __COGL_GST_VIDEO_PLAYER_H__
 
-#include "cogl-gst-video-sink.h"
+#include <cogl-gst/cogl-gst-video-sink.h>
+
+G_BEGIN_DECLS
+
+#define COGL_GST_TYPE_VIDEO_PLAYER cogl_gst_video_player_get_type()
+
+#define COGL_GST_VIDEO_PLAYER(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  COGL_GST_TYPE_VIDEO_PLAYER, CoglGstVideoPlayer))
+
+#define COGL_GST_VIDEO_PLAYER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  COGL_GST_TYPE_VIDEO_PLAYER, CoglGstVideoPlayerClass))
+
+#define COGL_GST_IS_VIDEO_PLAYER(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  COGL_GST_TYPE_VIDEO_PLAYER))
+
+#define COGL_GST_IS_VIDEO_PLAYER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  COGL_GST_TYPE_VIDEO_PLAYER))
+
+#define COGL_GST_VIDEO_PLAYER_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  COGL_GST_TYPE_VIDEO_PLAYER, CoglGstVideoPlayerClass))
+
+
 typedef struct _CoglGstVideoPlayer CoglGstVideoPlayer;
+typedef struct _CoglGstVideoPlayerClass CoglGstVideoPlayerClass;
+typedef struct _CoglGstVideoPlayerPrivate CoglGstVideoPlayerPrivate;
+
+struct _CoglGstVideoPlayer
+{
+  GObject parent;
+  CoglGstVideoPlayerPrivate *priv;
+};
+
+struct _CoglGstVideoPlayerClass
+{
+  GObjectClass parent_class;
+};
+
+GType cogl_gst_video_player_get_type (void) G_GNUC_CONST;
 
 CoglGstVideoPlayer*
 cogl_gst_video_player_new (CoglContext *ctx,
@@ -74,5 +115,6 @@ cogl_gst_video_player_get_progress (CoglGstVideoPlayer *player);
 int64_t
 cogl_gst_video_player_get_duration (CoglGstVideoPlayer *player);
 
+G_END_DECLS
 
 #endif
diff --git a/cogl-gst/cogl-gst-video-sink-private.h b/cogl-gst/cogl-gst-video-sink-private.h
index 725437c..0646828 100644
--- a/cogl-gst/cogl-gst-video-sink-private.h
+++ b/cogl-gst/cogl-gst-video-sink-private.h
@@ -34,7 +34,42 @@
 #define __COGL_GST_VIDEO_SINK_PRIVATE_H__
 #include "cogl-gst-video-sink.h"
 
+static char *yv12_to_rgba_decl = \
+  "uniform sampler2D ytex;"
+  "uniform sampler2D utex;"
+  "uniform sampler2D vtex;"
+  "varying vec4 rgb_color;"
+  "vec4 cogl_gst_sample_video (vec2 UV) {"
+    "float y = 1.1640625 * (texture2D (ytex, UV).g - 0.0625);"
+    "float u = texture2D (utex, UV).g - 0.5;"
+    "float v = texture2D (vtex, UV).g - 0.5;"
+    "vec4 color;"
+    "color.r = y + 1.59765625 * v;"
+    "color.g = y - 0.390625 * u - 0.8125 * v;"
+    "color.b = y + 2.015625 * u;"
+    "color.a = 1.0;"
+    "return color;"
+  "}";
+
+static char *ayuv_to_rgba_decl = \
+  "uniform sampler2D tex;"
+  "varying vec4 rgb_color;"
+  "vec4 cogl_gst_sample_video (vec2 UV) {"
+    "vec4 color = texture2D (tex, UV);"
+    "float y = 1.1640625 * (color.g - 0.0625);"
+    "float u = color.b - 0.5;"
+    "float v = color.a - 0.5;"
+    "color.a = color.r;"
+    "color.r = y + 1.59765625 * v;"
+    "color.g = y - 0.390625 * u - 0.8125 * v;"
+    "color.b = y + 2.015625 * u;"
+    "return color;"
+  "}";
+
+static char *default_shader_post = \
+  "cogl_color_out = cogl_gst_sample_video (cogl_tex_coord0_in.st);";
+
 GstFlowReturn
-cogl_gst_video_sink_render (GstBaseSink *bsink,
-                            GstBuffer *buffer);
+_cogl_gst_video_sink_render (GstBaseSink *bsink,
+                             GstBuffer *buffer);
 #endif
diff --git a/cogl-gst/cogl-gst-video-sink.c b/cogl-gst/cogl-gst-video-sink.c
index 4c6b149..51dd503 100644
--- a/cogl-gst/cogl-gst-video-sink.c
+++ b/cogl-gst/cogl-gst-video-sink.c
@@ -31,8 +31,6 @@
  * Boston, MA 02111-1307, USA.
  */
 
-#include "cogl-gst-video-sink.h"
-#include "cogl-gst-shaders.h"
 #include "cogl-gst-video-sink-private.h"
 #include <gst/gst.h>
 #include <gst/gstvalue.h>
@@ -287,7 +285,7 @@ cogl_gst_video_sink_set_priority (CoglGstVideoSink *sink,
 
 static void
 create_template_pipeline (CoglGstVideoSink *sink,
-                          const char *pre,
+                          const char *decl,
                           const char *post,
                           CoglBool set_uniforms,
                           int n_layers)
@@ -303,44 +301,37 @@ create_template_pipeline (CoglGstVideoSink *sink,
     }
   else
     priv->pipeline = cogl_pipeline_new (priv->ctx);
-
-  if (pre || post)
-    {
-      CoglSnippet *snippet = cogl_snippet_new (priv->hook, pre, post);
-      cogl_pipeline_add_snippet (priv->pipeline, snippet);
-      cogl_object_unref (snippet);
-
-      if (priv->hook == COGL_SNIPPET_HOOK_VERTEX)
-        {
-          snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, pre,
-                                      canned_fragment);
-          cogl_pipeline_add_snippet (priv->pipeline, snippet);
-          cogl_object_unref (snippet);
-        }
-      if (set_uniforms)
-        {
-          unsigned int location;
-          location = cogl_pipeline_get_uniform_location (priv->pipeline,
+    
+    if (decl && post)
+      {
+        CoglSnippet *snippet = cogl_snippet_new (priv->hook, decl, post);
+        cogl_pipeline_add_snippet (priv->pipeline, snippet);
+        cogl_object_unref (snippet);
+      }
+
+    if (set_uniforms)
+      {
+        unsigned int location;
+        location = cogl_pipeline_get_uniform_location (priv->pipeline,
                                                              "ytex");
-          cogl_pipeline_set_uniform_1i (priv->pipeline, location, 0);
+        cogl_pipeline_set_uniform_1i (priv->pipeline, location, 0);
 
-          if (n_layers > 1)
-            {
-              location = cogl_pipeline_get_uniform_location (priv->pipeline,
+        if (n_layers > 1)
+          {
+            location = cogl_pipeline_get_uniform_location (priv->pipeline,
                                                                  "utex");
-              cogl_pipeline_set_uniform_1i (priv->pipeline, location, 1);
-              priv->free_layer++;
-            }
+            cogl_pipeline_set_uniform_1i (priv->pipeline, location, 1);
+            priv->free_layer++;
+          }
 
-          if (n_layers > 2)
-            {
-              location = cogl_pipeline_get_uniform_location (priv->pipeline,
+        if (n_layers > 2)
+          {
+            location = cogl_pipeline_get_uniform_location (priv->pipeline,
                                                              "vtex");
-              cogl_pipeline_set_uniform_1i (priv->pipeline, location, 2);
-              priv->free_layer++;
-            }
-        }
-    }
+            cogl_pipeline_set_uniform_1i (priv->pipeline, location, 2);
+            priv->free_layer++;
+          }
+      }
 
   g_signal_emit_by_name (sink, "cogl-pipeline-ready", 0);
 }
@@ -485,14 +476,8 @@ cogl_gst_yv12_upload (CoglGstVideoSink *sink,
 static void
 cogl_gst_yv12_glsl_init (CoglGstVideoSink *sink)
 {
-  char *post;
-  if (sink->priv->hook == COGL_SNIPPET_HOOK_VERTEX ||
-      sink->priv->hook == COGL_SNIPPET_HOOK_VERTEX_TRANSFORM)
-    post = yv12_to_rgba_vertex_shader_post;
-  else
-    post = yv12_to_rgba_frag_shader_post;
-
-  create_template_pipeline (sink, yv12_to_rgba_shader_pre, post, TRUE, 3);
+  create_template_pipeline (sink, yv12_to_rgba_decl, default_shader_post, TRUE, 
+                            3);
 }
 
 static CoglGstRenderer yv12_glsl_renderer =
@@ -509,14 +494,8 @@ static CoglGstRenderer yv12_glsl_renderer =
 static void
 cogl_gst_i420_glsl_init (CoglGstVideoSink *sink)
 {
-  char *post;
-  if (sink->priv->hook == COGL_SNIPPET_HOOK_VERTEX ||
-      sink->priv->hook == COGL_SNIPPET_HOOK_VERTEX_TRANSFORM)
-    post = yv12_to_rgba_vertex_shader_post;
-  else
-    post = yv12_to_rgba_frag_shader_post;
-
-  create_template_pipeline (sink, yv12_to_rgba_shader_pre, post, TRUE, 3);
+  create_template_pipeline (sink, yv12_to_rgba_decl, default_shader_post, TRUE, 
+                            3);
 }
 
 static CoglGstRenderer i420_glsl_renderer =
@@ -533,14 +512,8 @@ static CoglGstRenderer i420_glsl_renderer =
 static void
 cogl_gst_ayuv_glsl_init (CoglGstVideoSink *sink)
 {
-  char *post;
-  if (sink->priv->hook == COGL_SNIPPET_HOOK_VERTEX ||
-      sink->priv->hook == COGL_SNIPPET_HOOK_VERTEX_TRANSFORM)
-    post = ayuv_to_rgba_vertex_shader_post;
-  else
-    post = ayuv_to_rgba_frag_shader_post;
-
-  create_template_pipeline (sink, ayuv_to_rgba_shader_pre, post, TRUE, 1);
+  create_template_pipeline (sink, ayuv_to_rgba_decl, default_shader_post, TRUE, 
+                            1);
 }
 
 static void
@@ -668,8 +641,8 @@ cogl_gst_video_sink_init (CoglGstVideoSink *sink,
 }
 
 GstFlowReturn
-cogl_gst_video_sink_render (GstBaseSink *bsink,
-                            GstBuffer *buffer)
+_cogl_gst_video_sink_render (GstBaseSink *bsink,
+                             GstBuffer *buffer)
 {
   CoglGstVideoSink *sink = COGL_GST_VIDEO_SINK (bsink);
   cogl_gst_source_push (sink->priv->source, buffer);
@@ -901,8 +874,8 @@ cogl_gst_video_sink_class_init (CoglGstVideoSinkClass *klass)
   go_class->get_property = cogl_gst_video_sink_get_property;
   go_class->dispose = cogl_gst_video_sink_dispose;
   go_class->finalize = cogl_gst_video_sink_finalize;
-  gb_class->render = cogl_gst_video_sink_render;
-  gb_class->preroll = cogl_gst_video_sink_render;
+  gb_class->render = _cogl_gst_video_sink_render;
+  gb_class->preroll = _cogl_gst_video_sink_render;
   gb_class->start = cogl_gst_video_sink_start;
   gb_class->stop = cogl_gst_video_sink_stop;
   gb_class->set_caps = cogl_gst_video_sink_set_caps;
@@ -922,12 +895,6 @@ cogl_gst_video_sink_class_init (CoglGstVideoSinkClass *klass)
 
 }
 
-GstElement*
-cogl_gst_video_sink_new (CoglContext *ctx)
-{
-  return g_object_new (COGL_GST_TYPE_VIDEO_SINK, "ctx", ctx,  NULL);
-}
-
 static CoglBool
 plugin_init (GstPlugin *plugin)
 {
diff --git a/cogl-gst/cogl-gst-video-sink.h b/cogl-gst/cogl-gst-video-sink.h
index 97237a3..d3d9580 100644
--- a/cogl-gst/cogl-gst-video-sink.h
+++ b/cogl-gst/cogl-gst-video-sink.h
@@ -73,8 +73,8 @@ G_BEGIN_DECLS
 #define COGL_GST_PARAM_READWRITE     \
   (G_PARAM_READABLE | G_PARAM_WRITABLE | COGL_GST_PARAM_STATIC)
 
-typedef struct _CoglGstVideoSink        CoglGstVideoSink;
-typedef struct _CoglGstVideoSinkClass   CoglGstVideoSinkClass;
+typedef struct _CoglGstVideoSink CoglGstVideoSink;
+typedef struct _CoglGstVideoSinkClass CoglGstVideoSinkClass;
 typedef struct _CoglGstVideoSinkPrivate CoglGstVideoSinkPrivate;
 
 struct _CoglGstVideoSink
@@ -89,7 +89,6 @@ struct _CoglGstVideoSinkClass
 };
 
 GType       cogl_gst_video_sink_get_type    (void) G_GNUC_CONST;
-GstElement* cogl_gst_video_sink_new ();
 
 CoglPipeline*
 cogl_gst_video_sink_get_pipeline (CoglGstVideoSink *vt);
diff --git a/examples/cogl-basic-video-player.c b/examples/cogl-basic-video-player.c
index dc4d908..431c6a6 100644
--- a/examples/cogl-basic-video-player.c
+++ b/examples/cogl-basic-video-player.c
@@ -3,16 +3,16 @@
 
 typedef struct _Data
 {
-  CoglContext *ctx;
   CoglFramebuffer *fb;
   CoglPipeline *pln;
   CoglGstVideoSink *sink;
+  CoglBool draw_ready;
 }Data;
 
 static CoglBool
-bus_watch (GstBus *bus,
-           GstMessage *msg,
-           void *user_data)
+_bus_watch (GstBus *bus,
+            GstMessage *msg,
+            void *user_data)
 {
   Data *data = (Data*) user_data;
   switch (GST_MESSAGE_TYPE (msg))
@@ -28,12 +28,11 @@ bus_watch (GstBus *bus,
           GError *error = NULL;
 
           gst_message_parse_error (msg, &error, &debug);
-          free (debug);
+          g_free (debug);
 
           if (error != NULL)
             {
-              fprintf (stderr, "Playback error: %s\n",
-                        error->message);
+              g_error ("Playback error: %s\n", error->message);
               g_error_free (error);
             }
           g_main_loop_quit (cogl_gst_video_sink_get_main_loop (data->sink));
@@ -46,31 +45,54 @@ bus_watch (GstBus *bus,
   return TRUE;
 }
 
-static CoglBool
-draw (void* user_data)
+static void 
+_frame_callback (CoglOnscreen *onscreen,
+                 CoglFrameEvent event,
+                 CoglFrameInfo *info,
+                 void *user_data)
 {
-  Data *data = (Data*) user_data;
-
-  cogl_framebuffer_clear4f (data->fb, COGL_BUFFER_BIT_COLOR|COGL_BUFFER_BIT_DEPTH,
-                            0, 0, 0, 1);
-
-  data->pln = cogl_gst_video_sink_get_pipeline (data->sink);
+  Data *data = user_data;
 
-  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);
+  if (event == COGL_FRAME_EVENT_SYNC)
+    data->draw_ready = TRUE;
+}
 
-  cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));
+static CoglBool
+_draw (void *user_data)
+{
+  Data *data = (Data*) user_data;
+  CoglPipeline* current = cogl_gst_video_sink_get_pipeline (data->sink);
+  
+/* 
+ * This checks whether the system compositor is ready to render and that 
+ * sink has retrieved a new frame (the cogl sink creates a new cogl pipeline 
+ * (by copying the previous one) for each frame so checking whether the 
+ * pipeline has changed is a way of querying whether there is a new frame to 
+ * render).
+ */
+
+  if (data->draw_ready && current != data->pln && current)
+    { 
+      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));
+    }
 
   return TRUE;
 }
 
 static void
-set_up_pipeline (gpointer instance, gpointer user_data)
+_set_up_pipeline (gpointer instance, 
+                  gpointer user_data)
 {
   Data* data = (Data*) user_data;
   int free_layer = cogl_gst_video_sink_get_free_layer (data->sink);
@@ -83,8 +105,10 @@ set_up_pipeline (gpointer instance, gpointer user_data)
                                        COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR,
                                        COGL_PIPELINE_FILTER_LINEAR);
     }
-
-  g_idle_add ((GSourceFunc)draw, (Data*) user_data);
+  
+  cogl_onscreen_add_frame_callback(COGL_ONSCREEN (data->fb), _frame_callback, 
+                                   &data, NULL);
+  g_idle_add (_draw, data);                           
 }
 
 int
@@ -92,14 +116,15 @@ main (int argc,
       char **argv)
 {
   Data data;
+  CoglContext *ctx;
+  CoglOnscreen *onscreen;
   CoglMatrix view;
-  float fovy, aspect, z_near, z_2d, z_far;
   CoglGstVideoPlayer *player;
-  CoglOnscreen *onscreen;
   GMainLoop *loop;
+  float fovy, aspect, z_near, z_2d, z_far;
 
-  data.ctx = cogl_context_new (NULL, NULL);
-  onscreen = cogl_onscreen_new (data.ctx, 640, 480);
+  ctx = cogl_context_new (NULL, NULL);
+  onscreen = cogl_onscreen_new (ctx, 640, 480);
   data.fb = COGL_FRAMEBUFFER (onscreen);
   cogl_onscreen_show (onscreen);
 
@@ -118,15 +143,18 @@ main (int argc,
 
   cogl_gst_init (&argc, &argv);
 
-  player = cogl_gst_video_player_new  (data.ctx, TRUE,
-                                       "http://docs.gstreamer.com/media/sintel_trailer-480p.webm");
+  player = cogl_gst_video_player_new (ctx, TRUE,
+                                      "http://docs.gstreamer.com/media/sintel_trailer-480p.webm");
 
   data.sink = cogl_gst_video_player_get_sink (player);
 
-  cogl_gst_video_player_add_bus_watch (player, bus_watch, &data);
+  cogl_gst_video_player_add_bus_watch (player, _bus_watch, &data);
   loop = cogl_gst_video_sink_get_main_loop (data.sink);
+
   g_signal_connect (data.sink, "cogl-pipeline-ready",
-                    G_CALLBACK (set_up_pipeline), &data);
+                    G_CALLBACK (_set_up_pipeline), &data);
+
+  data.draw_ready = TRUE;
 
   g_main_loop_run (loop);
   return 0;
-- 
1.8.1.2

---------------------------------------------------------------------
Intel Corporation (UK) Limited
Registered No. 1134945 (England)
Registered Office: Pipers Way, Swindon SN3 1RJ
VAT No: 860 2173 47

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.



More information about the Cogl mailing list