[cogl/wip/cogl-gst] cogl-gst: Upgrade cogl-gst to gstreamer-1.0



commit 7cbf3f532ff35e3ac4f5e053f7ecf35f8410ca61
Author: Plamena Manolova <plamena n manolova intel com>
Date:   Thu Feb 28 18:14:54 2013 +0000

    cogl-gst: Upgrade cogl-gst to gstreamer-1.0
    
    Upgrades cogl-gst to gstreamer-1.0 and gets rid
    of the cogl-gst-video-player utility. Implements
    cogl-gst-video-sink-new, but keeps plugin
    registered for user convinience.

 cogl-gst/Makefile.am               |   30 ++-
 cogl-gst/cogl-gst-video-player.c   |  273 -------------
 cogl-gst/cogl-gst-video-player.h   |  121 ------
 cogl-gst/cogl-gst-video-sink.c     |  772 ++++++++++++++++++++++--------------
 cogl-gst/cogl-gst-video-sink.h     |    4 +
 configure.ac                       |   12 +-
 examples/cogl-basic-video-player.c |   43 ++-
 7 files changed, 546 insertions(+), 709 deletions(-)
---
diff --git a/cogl-gst/Makefile.am b/cogl-gst/Makefile.am
index 316656e..d2afa93 100644
--- a/cogl-gst/Makefile.am
+++ b/cogl-gst/Makefile.am
@@ -9,13 +9,12 @@ EXTRA_DIST =
 
 source_c = \
        cogl-gst-shader.c \
-       cogl-gst-video-player.c \
        cogl-gst-video-sink.c \
        $(NULL)
 
 source_h = \
        cogl-gst.h \
-       cogl-gst-video-player.h \
+       cogl-gst-shader.h \
        cogl-gst-video-sink.h \
        $(NULL)
 
@@ -32,7 +31,8 @@ libcogl_gst_la_LDFLAGS = \
        -export-dynamic \
        -export-symbols-regex "^cogl_gst_.*" \
        -no-undefined \
-       -version-info @COGL_LT_CURRENT@:@COGL_LT_REVISION@:@COGL_LT_AGE@
+       -version-info @COGL_LT_CURRENT@:@COGL_LT_REVISION@:@COGL_LT_AGE@ \
+       -rpath $(libdir)
 
 AM_CPPFLAGS = \
        -DCOGL_COMPILATION              \
@@ -43,9 +43,31 @@ AM_CPPFLAGS = \
        -I$(top_srcdir)                 \
        -I$(top_builddir)
 
-cogl_gstheadersdir = $(includedir)/cogl/cogl-gst
+cogl_gstheadersdir = $(includedir)/cogl2/cogl-gst
 cogl_gstheaders_HEADERS = $(source_h)
 
+plugin_source_c =                              \
+  $(srcdir)/cogl-gst.h \
+  $(srcdir)/cogl-gst-shader.c \
+  $(srcdir)/cogl-gst-shader.h \
+       $(srcdir)/cogl-gst-video-sink.c \
+       $(srcdir)/cogl-gst-video-sink.h \
+       $(NULL)
+
+libgstcogl_la_SOURCES =        \
+       $(plugin_source_c)      \
+       $(NULL)
+
+plugin_LTLIBRARIES = libgstcogl.la
+
+libgstcogl_la_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_GST_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS)
+libgstcogl_la_LIBADD = $(top_builddir)/cogl/libcogl2.la
+libgstcogl_la_LIBADD += $(COGL_DEP_LIBS) $(COGL_GST_DEP_LIBS) $(COGL_EXTRA_LDFLAGS)
+libgstcogl_la_LDFLAGS =        \
+       -avoid-version -no-undefined            \
+       $(NULL)
+
+
 pc_files = cogl-gst.pc
 
 pkgconfigdir = $(libdir)/pkgconfig
diff --git a/cogl-gst/cogl-gst-video-sink.c b/cogl-gst/cogl-gst-video-sink.c
index 5bbd651..52ce311 100644
--- a/cogl-gst/cogl-gst-video-sink.c
+++ b/cogl-gst/cogl-gst-video-sink.c
@@ -47,27 +47,32 @@
 
 #define COGL_GST_TEXTURE_FLAGS \
        (COGL_TEXTURE_NO_SLICING | COGL_TEXTURE_NO_ATLAS)
-#define PACKAGE "GStreamer"
-#define VERSION "0.10"
+#define PACKAGE "CoglGst"
+#define VERSION "0.0"
 #define COGL_GST_DEFAULT_PRIORITY    (G_PRIORITY_HIGH_IDLE)
+#ifdef HAVE_HW_DECODER_SUPPORT
+#define GST_USE_UNSTABLE_API 1
+#include <gst/video/gstsurfacemeta.h>
+#endif
+
+#define BASE_SINK_CAPS "{ AYUV," \
+                       "YV12," \
+                       "I420," \
+                       "RGBA," \
+                       "BGRA," \
+                       "RGB," \
+                       "BGR }"
+
+
+#define SINK_CAPS GST_VIDEO_CAPS_MAKE(BASE_SINK_CAPS)
+
+static GstStaticPadTemplate sinktemplate_all = GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS (SINK_CAPS));
 
-static GstStaticPadTemplate sinktemplate_all =
-       GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
-       GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV") ";" \
-                        GST_VIDEO_CAPS_YUV ("YV12") ";" \
-                        GST_VIDEO_CAPS_YUV ("I420") ";" \
-                        GST_VIDEO_CAPS_RGBA         ";" \
-                        GST_VIDEO_CAPS_BGRA         ";" \
-                        GST_VIDEO_CAPS_RGB          ";" \
-                        GST_VIDEO_CAPS_BGR));
-
-static GstElementDetails cogl_gst_video_sink_details =
-       GST_ELEMENT_DETAILS ("Cogl video sink", "Sink/Video",
-       "Sends video data from a GStreamer pipeline to a Cogl pipeline",
-       "Jonathan Matthew <jonathan kaolin wh9 net>, "
-       "Matthew Allum <mallum o-hand com, "
-       "Chris Lord <chris o-hand com>, "
-       "Plamena Manolova <plamena n manolova intel com>");
+#define cogl_gst_video_sink_parent_class parent_class
+G_DEFINE_TYPE (CoglGstVideoSink, cogl_gst_video_sink, GST_TYPE_BASE_SINK);
 
 enum
 {
@@ -82,7 +87,8 @@ typedef enum
   COGL_GST_RGB24,
   COGL_GST_AYUV,
   COGL_GST_YV12,
-  COGL_GST_I420,
+  COGL_GST_SURFACE,
+  COGL_GST_I420
 }CoglGstVideoFormat;
 
 typedef enum
@@ -96,6 +102,7 @@ typedef struct _CoglGstSource
   CoglGstVideoSink *sink;
   GMutex buffer_lock;
   GstBuffer *buffer;
+  CoglBool has_new_caps;
 }CoglGstSource;
 
 typedef void (CoglGstRendererPaint) (CoglGstVideoSink*);
@@ -109,45 +116,31 @@ typedef struct _CoglGstRenderer
   GstStaticCaps caps;
   void (*init)   (CoglGstVideoSink *sink);
   void (*deinit)  (CoglGstVideoSink *sink);
-  void (*upload) (CoglGstVideoSink *sink,
-                  GstBuffer *buffer);
+  CoglBool (*upload) (CoglGstVideoSink *sink,
+                      GstBuffer *buffer);
 }CoglGstRenderer;
 
-typedef enum _CoglGstRendererState
-{
-  COGL_GST_RENDERER_STOPPED,
-  COGL_GST_RENDERER_RUNNING,
-  COGL_GST_RENDERER_NEED_GC,
-}CoglGstRendererState;
-
 struct _CoglGstVideoSinkPrivate
 {
   CoglContext *ctx;
   CoglPipeline *pipeline;
   CoglGstVideoFormat format;
   CoglBool bgr;
-  int width;
-  int height;
-  int fps_n, fps_d;
-  int par_n, par_d;
-  int free_layer;
   CoglGstSource *source;
   GSList *renderers;
   GstCaps *caps;
   CoglGstRenderer *renderer;
-  CoglGstRendererState renderer_state;
   GMainContext *g_ctx;
   GMainLoop *loop;
   CoglSnippetHook hook;
+  GstFlowReturn flow_return;
+  int free_layer;
+  GstVideoInfo info;
+  #ifdef HAVE_HW_DECODER_SUPPORT
+  GstSurfaceConverter *converter;
+  #endif
 };
 
-
-GST_BOILERPLATE (CoglGstVideoSink,
-                 cogl_gst_video_sink,
-                 GstBaseSink,
-                 GST_TYPE_BASE_SINK
-                 );
-
 static void
 cogl_gst_source_finalize (GSource *source)
 {
@@ -161,27 +154,6 @@ cogl_gst_source_finalize (GSource *source)
   g_mutex_clear (&gst_source->buffer_lock);
 }
 
-static void
-cogl_gst_source_push (CoglGstSource *gst_source,
-                      GstBuffer *buffer)
-{
-  CoglGstVideoSinkPrivate *priv = gst_source->sink->priv;
-  g_mutex_lock (&gst_source->buffer_lock);
-  if (gst_source->buffer)
-    gst_buffer_unref (gst_source->buffer);
-  gst_source->buffer = gst_buffer_ref (buffer);
-  g_mutex_unlock (&gst_source->buffer_lock);
-
-  g_main_context_wakeup (priv->g_ctx);
-}
-
-void
-cogl_gst_set_shader_hook (CoglGstVideoSink *sink, CoglSnippetHook hook)
-{
-  sink->priv->hook = hook;
-}
-
-
 CoglPipeline*
 cogl_gst_video_sink_get_pipeline (CoglGstVideoSink *vt)
 {
@@ -219,72 +191,12 @@ cogl_gst_source_check (GSource *source)
   return gst_source->buffer != NULL;
 }
 
-static CoglBool
-cogl_gst_source_dispatch (GSource *source,
-                          GSourceFunc callback,
-                          void* user_data)
-{
-  CoglGstSource *gst_source= (CoglGstSource*) source;
-  CoglGstVideoSinkPrivate *priv = gst_source->sink->priv;
-  GstBuffer *buffer;
-
-  if (G_UNLIKELY (priv->renderer_state == COGL_GST_RENDERER_NEED_GC))
-    {
-      priv->renderer->deinit (gst_source->sink);
-      priv->renderer_state = COGL_GST_RENDERER_STOPPED;
-    }
-  if (G_UNLIKELY (priv->renderer_state == COGL_GST_RENDERER_STOPPED))
-    {
-      priv->renderer->init (gst_source->sink);
-      priv->renderer_state = COGL_GST_RENDERER_RUNNING;
-    }
-
-  g_mutex_lock (&gst_source->buffer_lock);
-  buffer = gst_source->buffer;
-  gst_source->buffer = NULL;
-  g_mutex_unlock (&gst_source->buffer_lock);
-
-  if (buffer)
-    {
-      priv->renderer->upload (gst_source->sink, buffer);
-      gst_buffer_unref (buffer);
-    }
-
-  return TRUE;
-}
-
-static GSourceFuncs gst_source_funcs =
-{
-  cogl_gst_source_prepare,
-  cogl_gst_source_check,
-  cogl_gst_source_dispatch,
-  cogl_gst_source_finalize
-};
-
-static CoglGstSource*
-cogl_gst_source_new (CoglGstVideoSink *sink)
-{
-  GSource *source;
-  CoglGstSource *gst_source;
-
-  source = g_source_new (&gst_source_funcs, sizeof (CoglGstSource));
-  gst_source = (CoglGstSource*) source;
-
-  g_source_set_can_recurse (source, TRUE);
-  g_source_set_priority (source, COGL_GST_DEFAULT_PRIORITY);
-
-  gst_source->sink = sink;
-  g_mutex_init (&gst_source->buffer_lock);
-  gst_source->buffer = NULL;
-
-  return gst_source;
-}
-
 static void
 cogl_gst_video_sink_set_priority (CoglGstVideoSink *sink,
                                   int priority)
 {
-  g_source_set_priority ((GSource*) sink->priv->source, priority);
+  if (sink->priv->source)
+    g_source_set_priority ((GSource*) sink->priv->source, priority);
 }
 
 static void
@@ -296,13 +208,8 @@ create_template_pipeline (CoglGstVideoSink *sink,
   priv->free_layer = n_layers;
 
   if (priv->pipeline)
-    {
-      CoglPipeline *pln = cogl_pipeline_copy (priv->pipeline);
-      cogl_object_unref (priv->pipeline);
-      priv->pipeline = pln;
-    }
-  else
-    priv->pipeline = cogl_pipeline_new (priv->ctx);
+    cogl_object_unref (priv->pipeline);
+  priv->pipeline = cogl_pipeline_new (priv->ctx);
 
   if (decl)
     {
@@ -336,7 +243,7 @@ create_template_pipeline (CoglGstVideoSink *sink,
       cogl_object_unref (snippet);
     }
 
-  g_signal_emit_by_name (sink, "cogl-pipeline-ready", 0);
+  g_signal_emit_by_name (sink, "cogl-pipeline-ready", NULL);
 }
 
 static void
@@ -386,25 +293,39 @@ cogl_gst_rgb_init (CoglGstVideoSink *sink)
     create_template_pipeline (sink, NULL, 1);
 }
 
-static void
+static CoglBool
 cogl_gst_rgb24_upload (CoglGstVideoSink *sink,
                        GstBuffer *buffer)
 {
   CoglGstVideoSinkPrivate *priv = sink->priv;
   CoglPixelFormat format;
   CoglTexture *tex;
+  GstVideoFrame frame;
 
   if (priv->bgr)
     format = COGL_PIXEL_FORMAT_BGR_888;
   else
     format = COGL_PIXEL_FORMAT_RGB_888;
-
-  tex = cogl_texture_new_from_data (priv->ctx, priv->width, priv->height,
-                                    COGL_GST_TEXTURE_FLAGS, format, format,
-                                    GST_ROUND_UP_4 (3 * priv->width),
-                                    GST_BUFFER_DATA (buffer), NULL);
+  
+  if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ))
+    goto map_fail;
+  
+  tex = cogl_texture_new_from_data (priv->ctx, priv->info.width, 
+                                    priv->info.height, COGL_GST_TEXTURE_FLAGS, 
+                                    format, format, priv->info.stride[0], 
+                                    frame.data[0], NULL);
+                                    
+  gst_video_frame_unmap (&frame);
 
   create_paint_pipeline (sink, tex, NULL, NULL);
+  
+  return TRUE;
+  
+map_fail:
+  {
+    GST_ERROR_OBJECT (sink, "Could not map incoming video frame");
+    return FALSE;
+  }
 }
 
 
@@ -412,75 +333,103 @@ static CoglGstRenderer rgb24_renderer =
 {
   "RGB 24",
   COGL_GST_RGB24,
-  0,
-  GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR),
+  COGL_GST_RENDERER_NEEDS_GLSL,
+  GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGB, BGR }")),
   cogl_gst_rgb_init,
   cogl_gst_dummy_deinit,
   cogl_gst_rgb24_upload,
 };
 
-static void
+static CoglBool
 cogl_gst_rgb32_upload (CoglGstVideoSink *sink,
                        GstBuffer *buffer)
 {
   CoglGstVideoSinkPrivate *priv = sink->priv;
   CoglPixelFormat format;
   CoglTexture *tex;
+  GstVideoFrame frame;
 
   if (priv->bgr)
     format = COGL_PIXEL_FORMAT_BGRA_8888;
   else
     format = COGL_PIXEL_FORMAT_RGBA_8888;
+    
+  if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ))
+    goto map_fail;
 
-  tex = cogl_texture_new_from_data (priv->ctx, priv->width, priv->height,
-                                    COGL_GST_TEXTURE_FLAGS, format, format,
-                                    GST_ROUND_UP_4 (4 * priv->width),
-                                    GST_BUFFER_DATA (buffer), NULL);
+  tex = cogl_texture_new_from_data (priv->ctx, priv->info.width, 
+                                    priv->info.height, COGL_GST_TEXTURE_FLAGS, 
+                                    format, format, priv->info.stride[0], 
+                                    frame.data[0], NULL);
+                                    
+  gst_video_frame_unmap (&frame);
 
   create_paint_pipeline (sink, tex, NULL, NULL);
+  
+  return TRUE;
+  
+map_fail:
+  {
+    GST_ERROR_OBJECT (sink, "Could not map incoming video frame");
+    return FALSE;
+  }
 }
 
 static CoglGstRenderer rgb32_renderer =
 {
   "RGB 32",
   COGL_GST_RGB32,
-  0,
-  GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_BGRA),
+  COGL_GST_RENDERER_NEEDS_GLSL,
+  GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGBA, BGRA }")),
   cogl_gst_rgb_init,
   cogl_gst_dummy_deinit,
   cogl_gst_rgb32_upload,
 };
 
-static void
+static CoglBool
 cogl_gst_yv12_upload (CoglGstVideoSink *sink,
                       GstBuffer *buffer)
 {
   CoglGstVideoSinkPrivate *priv = sink->priv;
-  int y_row_stride = GST_ROUND_UP_4 (priv->width);
-  int uv_row_stride = GST_ROUND_UP_4 (priv->width / 2);
   CoglTexture *y_tex, *u_tex, *v_tex;
-
+  GstVideoFrame frame;
   CoglPixelFormat format = COGL_PIXEL_FORMAT_G_8;
-
-  y_tex = cogl_texture_new_from_data (priv->ctx, priv->width, priv->height,
-                                      COGL_GST_TEXTURE_FLAGS, format, format,
-                                      y_row_stride, GST_BUFFER_DATA (buffer),
-                                      NULL);
-
-  u_tex = cogl_texture_new_from_data (priv->ctx, priv->width / 2,
-                                      priv->height / 2, COGL_GST_TEXTURE_FLAGS,
-                                      format, format, uv_row_stride,
-                                      GST_BUFFER_DATA (buffer) +
-                                      (y_row_stride * priv->height), NULL);
-
-  v_tex = cogl_texture_new_from_data (priv->ctx, priv->width / 2,
-                                      priv->height / 2, COGL_GST_TEXTURE_FLAGS,
-                                      format, format, uv_row_stride,
-                                      GST_BUFFER_DATA (buffer) +
-                                      (y_row_stride * priv->height) +
-                                      (uv_row_stride * priv->height / 2), NULL);
+  
+  if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ))
+    goto map_fail;
+
+  y_tex = 
+     cogl_texture_new_from_data (priv->ctx, 
+                                 GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 0), 
+                                 GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 0),
+                                 COGL_GST_TEXTURE_FLAGS, format, format,
+                                 priv->info.stride[0], frame.data[0], NULL);
+
+  u_tex = 
+     cogl_texture_new_from_data (priv->ctx, 
+                                 GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 1), 
+                                 GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 1),
+                                 COGL_GST_TEXTURE_FLAGS, format, format,
+                                 priv->info.stride[1], frame.data[1], NULL);
+
+  v_tex = 
+     cogl_texture_new_from_data (priv->ctx, 
+                                 GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 2), 
+                                 GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 2),
+                                 COGL_GST_TEXTURE_FLAGS, format, format,
+                                 priv->info.stride[2], frame.data[2], NULL);
+                                 
+  gst_video_frame_unmap (&frame);
 
   create_paint_pipeline (sink, y_tex, u_tex, v_tex);
+  
+  return TRUE;
+  
+map_fail:
+  {
+    GST_ERROR_OBJECT (sink, "Could not map incoming video frame");
+    return FALSE;
+  }
 }
 
 static void
@@ -496,7 +445,7 @@ static CoglGstRenderer yv12_glsl_renderer =
   "YV12 glsl",
   COGL_GST_YV12,
   COGL_GST_RENDERER_NEEDS_GLSL,
-  GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("YV12")),
+  GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("YV12")),
   cogl_gst_yv12_glsl_init,
   cogl_gst_dummy_deinit,
   cogl_gst_yv12_upload,
@@ -515,7 +464,7 @@ static CoglGstRenderer i420_glsl_renderer =
   "I420 glsl",
   COGL_GST_I420,
   COGL_GST_RENDERER_NEEDS_GLSL,
-  GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")),
+  GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420")),
   cogl_gst_i420_glsl_init,
   cogl_gst_dummy_deinit,
   cogl_gst_yv12_upload,
@@ -529,20 +478,34 @@ cogl_gst_ayuv_glsl_init (CoglGstVideoSink *sink)
                             1);
 }
 
-static void
+static CoglBool
 cogl_gst_ayuv_upload (CoglGstVideoSink *sink,
                       GstBuffer *buffer)
 {
   CoglGstVideoSinkPrivate *priv = sink->priv;
   CoglPixelFormat format = COGL_PIXEL_FORMAT_RGBA_8888;
   CoglTexture *tex;
-
-  tex = cogl_texture_new_from_data (priv->ctx, priv->width, priv->height,
-                                    COGL_GST_TEXTURE_FLAGS, format, format,
-                                    GST_ROUND_UP_4 (4 * priv->width),
-                                    GST_BUFFER_DATA (buffer), NULL);
+  GstVideoFrame frame;
+  
+  if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ))
+    goto map_fail;
+
+  tex = cogl_texture_new_from_data (priv->ctx, priv->info.width, 
+                                    priv->info.height, COGL_GST_TEXTURE_FLAGS, 
+                                    format, format, priv->info.stride[0],
+                                    frame.data[0], NULL);
+                                    
+  gst_video_frame_unmap (&frame);
 
   create_paint_pipeline (sink, tex, NULL, NULL);
+  
+  return TRUE;
+  
+map_fail:
+  {
+    GST_ERROR_OBJECT (sink, "Could not map incoming video frame");
+    return FALSE;
+  }
 }
 
 static CoglGstRenderer ayuv_glsl_renderer =
@@ -550,24 +513,90 @@ static CoglGstRenderer ayuv_glsl_renderer =
   "AYUV glsl",
   COGL_GST_AYUV,
   COGL_GST_RENDERER_NEEDS_GLSL,
-  GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV")),
+  GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("AYUV")),
   cogl_gst_ayuv_glsl_init,
   cogl_gst_dummy_deinit,
   cogl_gst_ayuv_upload,
 };
 
+#ifdef HAVE_HW_DECODER_SUPPORT
+
+static void
+cogl_gst_hw_init (CoglGstVideoSink *sink)
+{
+  create_template_pipeline (sink, NULL, NULL, FALSE, 1);
+}
+
+static void
+cogl_gst_hw_deinit (CoglGstVideoSink* sink)
+{
+  if (sink->priv->converter != NULL)
+    g_object_unref (sink->priv->converter);
+  sink->priv->converter = NULL;
+}
+
+static void
+cogl_gst_hw_upload (CoglGstVideoSink *sink, 
+                    GstBuffer *buffer)
+{
+  CoglGstVideoSinkPriv *priv = sink->priv;
+  GstSurfaceMeta* surface = gst_buffer_get_surface_meta (buffer);
+
+  g_return_if_fail (surface != NULL);
+  
+  if (G_UNLIKELY (priv->converter == NULL))
+    {
+      CoglTexture* tex;
+      unsigned int gl_tex;
+      unsigned int gl_tar;
+      GValue value = {0};
+      
+      tex = cogl_texture_new_with_size (priv->ctx, priv->info.width, 
+                                        priv->info.height, 
+                                        COGL_GST_TEXTURE_FLAGS, 
+                                        COGL_PIXEL_FORMAT_BGRA_8888, NULL);
+                                        
+      cogl_pipeline_set_layer_texture (priv->pipeline, 0, tex);
+      cogl_texture_get_gl_texture (tex, &gl_texture, &gl_target);
+      
+      g_value_init (&value, gl_texture);
+      g_value_set_uint (&value, gl_texture);
+      
+      priv->converter = gst_surface_meta_create_converter (surface, "opengl"
+                                                           &value);
+      cogl_object_unref (tex);
+      g_return_if_fail (priv->converter);
+    }
+  gst_surface_converter_upload (priv->converter, buffer);
+}
+
+static CoglGstRenderer hw_renderer = {
+  "HW surface",
+  COGL_GST_SURFACE,
+  0,
+  GST_STATIC_CAPS ("x-video/surface, opengl=true"),
+  cogl_gst_hw_init,
+  cogl_gst_hw_deinit,
+  cogl_gst_hw_upload,
+};
+
+#endif
+
 static GSList*
 cogl_gst_build_renderers_list (CoglContext *ctx)
 {
   GSList *list = NULL;
   CoglBool has_glsl;
   int i;
-  static CoglGstRenderer * const renderers[] =
+  static CoglGstRenderer *const renderers[] =
   {
     &rgb24_renderer,
     &rgb32_renderer,
     &yv12_glsl_renderer,
     &i420_glsl_renderer,
+    #ifdef HAVE_HW_DECODER_SUPPORT
+    &hw_renderer,
+    #endif
     &ayuv_glsl_renderer
   };
 
@@ -587,7 +616,6 @@ append_cap (gpointer data,
   CoglGstRenderer *renderer = (CoglGstRenderer*) data;
   GstCaps *caps = (GstCaps*) user_data;
   GstCaps *writable_caps;
-
   writable_caps =
     gst_caps_make_writable (gst_static_caps_get (&renderer->caps));
   gst_caps_append (caps, writable_caps);
@@ -654,50 +682,110 @@ cogl_gst_find_renderer_by_format (CoglGstVideoSink *sink,
   return renderer;
 }
 
-static void
-cogl_gst_video_sink_base_init (void *g_class)
+static GstCaps*
+cogl_gst_video_sink_get_caps (GstBaseSink *bsink,
+                              GstCaps *filter)
 {
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-  gst_element_class_add_pad_template (element_class,
-                               gst_static_pad_template_get (&sinktemplate_all));
-  gst_element_class_set_details (element_class, &cogl_gst_video_sink_details);
-
+  CoglGstVideoSink *sink;
+  sink = COGL_GST_VIDEO_SINK (bsink);
+  return gst_caps_ref (sink->priv->caps);
 }
 
-
-static void
-cogl_gst_video_sink_init (CoglGstVideoSink *sink,
-                          CoglGstVideoSinkClass *klass)
+static CoglBool
+cogl_gst_video_sink_parse_caps (GstCaps *caps,
+                                CoglGstVideoSink *sink, 
+                                CoglBool save)
 {
-  CoglGstVideoSinkPrivate* priv;
+  CoglGstVideoSinkPrivate *priv = sink->priv;
+  GstCaps *intersection;
+  GstVideoInfo vinfo;
+  CoglGstVideoFormat format;
+  CoglBool bgr = FALSE;
+  CoglGstRenderer* renderer;
+  
+  intersection = gst_caps_intersect (priv->caps, caps);
+  if (gst_caps_is_empty (intersection))
+    goto no_intersection;
+    
+  gst_caps_unref (intersection);
+  
+  if (!gst_video_info_from_caps (&vinfo, caps))
+    goto unknown_format;
+    
+  switch (vinfo.finfo->format) {
+    case GST_VIDEO_FORMAT_YV12:
+      format = COGL_GST_YV12;
+      break;
+    case GST_VIDEO_FORMAT_I420:
+      format = COGL_GST_I420;
+      break;
+    case GST_VIDEO_FORMAT_AYUV:
+      format = COGL_GST_AYUV;
+      bgr = FALSE;
+      break;
+    case GST_VIDEO_FORMAT_RGB:
+      format = COGL_GST_RGB24;
+      bgr = FALSE;
+      break;
+    case GST_VIDEO_FORMAT_BGR:
+      format = COGL_GST_RGB24;
+      bgr = TRUE;
+      break;
+    case GST_VIDEO_FORMAT_RGBA:
+      format = COGL_GST_RGB32;
+      bgr = FALSE;
+      break;
+    case GST_VIDEO_FORMAT_BGRA:
+      format = COGL_GST_RGB32;
+      bgr = TRUE;
+      break;
+    default:
+      goto unhandled_format;
+  }
+  
+  renderer = cogl_gst_find_renderer_by_format (sink, format);
 
-  sink->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (sink,
-                                                   COGL_GST_TYPE_VIDEO_SINK,
-                                                   CoglGstVideoSinkPrivate);
+  if (G_UNLIKELY (renderer == NULL))
+    goto no_suitable_renderer;
 
-  sink->priv->loop = g_main_loop_new (NULL, TRUE);
-  sink->priv->g_ctx = g_main_loop_get_context (sink->priv->loop);
+  GST_INFO_OBJECT (sink, "found the %s renderer", renderer->name);
 
-  priv->renderer_state = COGL_GST_RENDERER_STOPPED;
-  priv->hook = COGL_SNIPPET_HOOK_FRAGMENT;
-}
+  if (save) {
+    priv->info = vinfo;
 
-static GstFlowReturn
-_cogl_gst_video_sink_render (GstBaseSink *bsink,
-                             GstBuffer *buffer)
-{
-  CoglGstVideoSink *sink = COGL_GST_VIDEO_SINK (bsink);
-  cogl_gst_source_push (sink->priv->source, buffer);
+    priv->format = format;
+    priv->bgr = bgr;
 
-  return GST_FLOW_OK;
-}
+    priv->renderer = renderer;
+  }
 
-static GstCaps*
-cogl_gst_video_sink_get_caps (GstBaseSink *bsink)
-{
-  CoglGstVideoSink *sink;
-  sink = COGL_GST_VIDEO_SINK (bsink);
-  return gst_caps_ref (sink->priv->caps);
+  return TRUE;
+
+
+no_intersection:
+  {
+    GST_WARNING_OBJECT (sink,
+        "Incompatible caps, don't intersect with %" GST_PTR_FORMAT, priv->caps);
+    return FALSE;
+  }
+
+unknown_format:
+  {
+    GST_WARNING_OBJECT (sink, "Could not figure format of input caps");
+    return FALSE;
+  }
+
+unhandled_format:
+  {
+    GST_ERROR_OBJECT (sink, "Provided caps aren't supported by clutter-gst");
+    return FALSE;
+  }
+
+no_suitable_renderer:
+  {
+    GST_ERROR_OBJECT (sink, "could not find a suitable renderer");
+    return FALSE;
+  }
 }
 
 static CoglBool
@@ -706,88 +794,153 @@ cogl_gst_video_sink_set_caps (GstBaseSink *bsink,
 {
   CoglGstVideoSink *sink;
   CoglGstVideoSinkPrivate *priv;
-  GstCaps *intersection;
-  GstStructure *structure;
-  CoglBool ret;
-  const GValue *fps;
-  const GValue *par;
-  int width, height;
-  uint32_t fourcc;
-  int red_mask, blue_mask;
 
   sink = COGL_GST_VIDEO_SINK (bsink);
   priv = sink->priv;
 
-  intersection = gst_caps_intersect (priv->caps, caps);
-  if (gst_caps_is_empty (intersection))
+  if (!cogl_gst_video_sink_parse_caps (caps, sink, FALSE))
     return FALSE;
 
-  gst_caps_unref (intersection);
+  g_mutex_lock (&priv->source->buffer_lock);
+  priv->source->has_new_caps = TRUE;
+  g_mutex_unlock (&priv->source->buffer_lock);
 
-  structure = gst_caps_get_structure (caps, 0);
+  return TRUE;
+}
 
-  ret = gst_structure_get_int (structure, "width", &width);
-  ret &= gst_structure_get_int (structure, "height", &height);
-  fps = gst_structure_get_value (structure, "framerate");
-  ret &= (fps != NULL);
+static CoglBool
+cogl_gst_source_dispatch (GSource *source,
+                          GSourceFunc callback,
+                          void* user_data)
+{
+  CoglGstSource *gst_source= (CoglGstSource*) source;
+  CoglGstVideoSinkPrivate *priv = gst_source->sink->priv;
+  GstBuffer *buffer;
 
-  par = gst_structure_get_value (structure, "pixel-aspect-ratio");
+  g_mutex_lock (&gst_source->buffer_lock);
+  
+  if (G_UNLIKELY (gst_source->has_new_caps))
+    {
+      GstCaps *caps =
+        gst_pad_get_current_caps (GST_BASE_SINK_PAD ((GST_BASE_SINK
+                (gst_source->sink))));
 
-  if (!ret)
-    return FALSE;
+      if (priv->renderer)
+        priv->renderer->deinit (gst_source->sink);
+      
+      if (!cogl_gst_video_sink_parse_caps (caps, gst_source->sink, TRUE))
+        goto negotiation_fail;
 
-  priv->width = width;
-  priv->height = height;
+      priv->renderer->init (gst_source->sink);
+      gst_source->has_new_caps = FALSE;
+    }
+  
+  buffer = gst_source->buffer;
+  gst_source->buffer = NULL;
 
-  priv->fps_n = gst_value_get_fraction_numerator (fps);
-  priv->fps_d = gst_value_get_fraction_denominator (fps);
+  g_mutex_unlock (&gst_source->buffer_lock);
 
-  if (par)
-    {
-      priv->par_n = gst_value_get_fraction_numerator (par);
-      priv->par_d = gst_value_get_fraction_denominator (par);
-    }
-  else
-    priv->par_n = priv->par_d = 1;
-
-  ret = gst_structure_get_fourcc (structure, "format", &fourcc);
-  if (ret && (fourcc == GST_MAKE_FOURCC ('Y', 'V', '1', '2')))
-    priv->format = COGL_GST_YV12;
-  else if (ret && (fourcc == GST_MAKE_FOURCC ('I', '4', '2', '0')))
-    priv->format = COGL_GST_I420;
-  else if (ret && (fourcc == GST_MAKE_FOURCC ('A', 'Y', 'U', 'V')))
+  if (buffer) 
     {
-      priv->format = COGL_GST_AYUV;
-      priv->bgr = FALSE;
-    }
+      if (!priv->renderer->upload (gst_source->sink, buffer))
+        goto fail_upload;
+
+      g_signal_emit_by_name (gst_source->sink, "cogl-gst-new-frame", NULL);
+      gst_buffer_unref (buffer);
+    } 
   else
-    {
-      uint32_t mask;
-      gst_structure_get_int (structure, "red_mask", &red_mask);
-      gst_structure_get_int (structure, "blue_mask", &blue_mask);
+    GST_WARNING_OBJECT (gst_source->sink, "No buffers available for display");
 
-      mask = red_mask | blue_mask;
+  return TRUE;
 
-      if (mask < 0x1000000)
-        {
-          priv->format = COGL_GST_RGB24;
-          priv->bgr = (red_mask == 0xff0000) ? FALSE : TRUE;
-        }
-      else
-        {
-          priv->format = COGL_GST_RGB32;
-          priv->bgr = (red_mask == 0xff000000) ? FALSE : TRUE;
-        }
-    }
 
-  priv->renderer = cogl_gst_find_renderer_by_format (sink, priv->format);
-  if (priv->renderer == NULL)
-    {
-      GST_ERROR_OBJECT (sink, "Could not find suitable renderer");
-      return FALSE;
-    }
+negotiation_fail:
+  {
+    GST_WARNING_OBJECT (gst_source->sink,
+        "Failed to handle caps. Stopping GSource");
+    priv->flow_return = GST_FLOW_NOT_NEGOTIATED;
+    g_mutex_unlock (&gst_source->buffer_lock);
 
-  return TRUE;
+    return FALSE;
+  }
+
+fail_upload:
+  {
+    GST_WARNING_OBJECT (gst_source->sink, "Failed to upload buffer");
+    priv->flow_return = GST_FLOW_ERROR;
+    gst_buffer_unref (buffer);
+    return FALSE;
+  }
+}
+
+static GSourceFuncs gst_source_funcs =
+{
+  cogl_gst_source_prepare,
+  cogl_gst_source_check,
+  cogl_gst_source_dispatch,
+  cogl_gst_source_finalize
+};
+
+static CoglGstSource*
+cogl_gst_source_new (CoglGstVideoSink *sink)
+{
+  GSource *source;
+  CoglGstSource *gst_source;
+
+  source = g_source_new (&gst_source_funcs, sizeof (CoglGstSource));
+  gst_source = (CoglGstSource*) source;
+
+  g_source_set_can_recurse (source, TRUE);
+  g_source_set_priority (source, COGL_GST_DEFAULT_PRIORITY);
+
+  gst_source->sink = sink;
+  g_mutex_init (&gst_source->buffer_lock);
+  gst_source->buffer = NULL;
+
+  return gst_source;
+}
+
+static void
+cogl_gst_video_sink_init (CoglGstVideoSink *sink)
+{
+  CoglGstVideoSinkPrivate* priv;
+
+  sink->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (sink,
+                                                   COGL_GST_TYPE_VIDEO_SINK,
+                                                   CoglGstVideoSinkPrivate);
+
+  sink->priv->loop = g_main_loop_new (NULL, TRUE);
+  sink->priv->g_ctx = g_main_loop_get_context (sink->priv->loop);
+}
+
+static GstFlowReturn
+_cogl_gst_video_sink_render (GstBaseSink *bsink,
+                             GstBuffer *buffer)
+{
+  CoglGstVideoSink *sink = COGL_GST_VIDEO_SINK (bsink);
+  CoglGstVideoSinkPrivate *priv = sink->priv;
+  CoglGstSource *gst_source = priv->source;
+  
+  g_mutex_lock (&gst_source->buffer_lock);
+  
+  if (G_UNLIKELY (priv->flow_return != GST_FLOW_OK))
+    goto dispatch_flow_ret;
+  
+  if (gst_source->buffer)
+    gst_buffer_unref (gst_source->buffer);
+    
+  gst_source->buffer = gst_buffer_ref (buffer);
+  g_mutex_unlock (&gst_source->buffer_lock);
+
+  g_main_context_wakeup (priv->g_ctx);
+
+  return GST_FLOW_OK;
+  
+  dispatch_flow_ret:
+  {
+    g_mutex_unlock (&gst_source->buffer_lock);
+    return priv->flow_return;
+  }
 }
 
 static void
@@ -798,12 +951,11 @@ cogl_gst_video_sink_dispose (GObject *object)
 
   self = COGL_GST_VIDEO_SINK (object);
   priv = self->priv;
-
-  if (priv->renderer_state == COGL_GST_RENDERER_RUNNING ||
-      priv->renderer_state == COGL_GST_RENDERER_NEED_GC)
+  
+  if (priv->renderer) 
     {
       priv->renderer->deinit (self);
-      priv->renderer_state = COGL_GST_RENDERER_STOPPED;
+      priv->renderer = NULL;
     }
 
   if (priv->pipeline)
@@ -818,7 +970,7 @@ cogl_gst_video_sink_dispose (GObject *object)
       priv->caps = NULL;
     }
 
-  G_OBJECT_CLASS (parent_class)->dispose (object);
+  G_OBJECT_CLASS(parent_class)->dispose (object);
 }
 
 static void
@@ -839,6 +991,7 @@ cogl_gst_video_sink_start (GstBaseSink *base_sink)
 
   priv->source = cogl_gst_source_new (sink);
   g_source_attach ((GSource*) priv->source, priv->g_ctx);
+  priv->flow_return = GST_FLOW_OK;
   return TRUE;
 }
 
@@ -895,8 +1048,6 @@ cogl_gst_video_sink_stop (GstBaseSink *base_sink)
       priv->source = NULL;
     }
 
-  priv->renderer_state = COGL_GST_RENDERER_STOPPED;
-
   return TRUE;
 }
 
@@ -905,13 +1056,24 @@ cogl_gst_video_sink_class_init (CoglGstVideoSinkClass *klass)
 {
   GObjectClass *go_class = G_OBJECT_CLASS (klass);
   GstBaseSinkClass *gb_class = GST_BASE_SINK_CLASS (klass);
-  GParamSpec *pspec;
+  GstElementClass *ge_class = GST_ELEMENT_CLASS (klass);
+  GParamSpec *pspec; 
 
   g_type_class_add_private (klass, sizeof (CoglGstVideoSinkPrivate));
   go_class->set_property = cogl_gst_video_sink_set_property;
   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;
+  
+  gst_element_class_add_pad_template (ge_class, 
+                                      gst_static_pad_template_get (&sinktemplate_all));
+  gst_element_class_set_metadata (ge_class, "Cogl video sink", "Sink/Video",
+            "Sends video data from GStreamer to a Cogl pipeline",
+            "Jonathan Matthew <jonathan kaolin wh9 net>, "
+            "Matthew Allum <mallum o-hand com, "
+            "Chris Lord <chris o-hand com>, " 
+            "Plamena Manolova <plamena n manolova intel com>");
+
   gb_class->render = _cogl_gst_video_sink_render;
   gb_class->preroll = _cogl_gst_video_sink_render;
   gb_class->start = cogl_gst_video_sink_start;
@@ -931,18 +1093,40 @@ cogl_gst_video_sink_class_init (CoglGstVideoSinkClass *klass)
   g_signal_new ("cogl-pipeline-ready", COGL_GST_TYPE_VIDEO_SINK,
                 G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
                 G_TYPE_NONE, 0, G_TYPE_NONE);
+                
+  g_signal_new ("cogl-gst-new-frame", COGL_GST_TYPE_VIDEO_SINK, 
+                G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
+                G_TYPE_NONE, 0, G_TYPE_NONE);
+}
 
+CoglGstVideoSink*
+cogl_gst_video_sink_new (CoglContext *ctx)
+{
+  CoglGstVideoSink* sink = g_object_new (COGL_GST_TYPE_VIDEO_SINK, NULL);
+  cogl_gst_video_sink_set_context (sink, ctx);
+  
+  return sink;
 }
 
+
 static CoglBool
-plugin_init (GstPlugin *plugin)
+_plugin_init (GstPlugin * coglgstvideosink)
 {
-  CoglBool ret = gst_element_register (plugin, "coglsink", GST_RANK_PRIMARY,
-                                       COGL_GST_TYPE_VIDEO_SINK);
-
-  return ret;
+  return gst_element_register (coglgstvideosink, "coglsink", GST_RANK_PRIMARY,
+      COGL_GST_TYPE_VIDEO_SINK);
 }
 
-GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR, GST_VERSION_MINOR, "coglsink",
-                          "Element to attach frames to cogl pipelines",
-                          plugin_init, VERSION, "LGPL", PACKAGE, "...");
+GST_PLUGIN_DEFINE (
+    GST_VERSION_MAJOR,
+    GST_VERSION_MINOR,
+    cogl,
+    "Sends video data from GStreamer to a Cogl pipeline",
+    _plugin_init,
+    VERSION,
+    "LGPL",
+    "CoglGst",
+    "http://gstreamer.net/";
+)
+                   
+      
+
diff --git a/cogl-gst/cogl-gst-video-sink.h b/cogl-gst/cogl-gst-video-sink.h
index d3d9580..decf284 100644
--- a/cogl-gst/cogl-gst-video-sink.h
+++ b/cogl-gst/cogl-gst-video-sink.h
@@ -29,6 +29,7 @@
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
+ FLOP
  */
 
 #ifndef __COGL_GST_VIDEO_SINK_H__
@@ -90,6 +91,9 @@ struct _CoglGstVideoSinkClass
 
 GType       cogl_gst_video_sink_get_type    (void) G_GNUC_CONST;
 
+CoglGstVideoSink*
+cogl_gst_video_sink_new (CoglContext *ctx);
+
 CoglPipeline*
 cogl_gst_video_sink_get_pipeline (CoglGstVideoSink *vt);
 
diff --git a/configure.ac b/configure.ac
index 2404545..28dc240 100644
--- a/configure.ac
+++ b/configure.ac
@@ -447,10 +447,20 @@ AC_ARG_ENABLE(
 )
 AS_IF([test "x$enable_cogl_gst" = "xyes"],
       [
-  COGL_GST_PKG_REQUIRES="$COGL_GST_PKG_REQUIRES gstreamer-0.10 >= 0.10 gstreamer-fft-0.10 >= 0.10 
gstreamer-interfaces-0.10 >= 0.10 gstreamer-base-0.10 >= 0.10"
+  COGL_GST_PKG_REQUIRES="$COGL_GST_PKG_REQUIRES gstreamer-1.0  gstreamer-fft-1.0 \
+                         gstreamer-audio-1.0 gstreamer-base-1.0 \
+                         gstreamer-video-1.0 gstreamer-plugins-base-1.0 \
+                         gstreamer-tag-1.0 gstreamer-controller-1.0"
+                         
+  GST_MAJORMINOR=1.0
+
+  dnl define location of gstreamer plugin directory
+  plugindir="\$(libdir)/gstreamer-$GST_MAJORMINOR"
+  AC_SUBST(plugindir)
       ]
 )
 
+
 dnl     ============================================================
 dnl     Choose image loading backend
 dnl     ============================================================
diff --git a/examples/cogl-basic-video-player.c b/examples/cogl-basic-video-player.c
index 2f72a74..183b1e3 100644
--- a/examples/cogl-basic-video-player.c
+++ b/examples/cogl-basic-video-player.c
@@ -58,20 +58,13 @@ _frame_callback (CoglOnscreen *onscreen,
 }
 
 static CoglBool
-_draw (void *user_data)
+_draw  (gpointer instance,
+        gpointer 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)
+  if (data->draw_ready)
     {
       cogl_framebuffer_clear4f (data->fb,
                                 COGL_BUFFER_BIT_COLOR|COGL_BUFFER_BIT_DEPTH, 0,
@@ -108,7 +101,7 @@ _set_up_pipeline (gpointer instance,
 
   cogl_onscreen_add_frame_callback(COGL_ONSCREEN (data->fb), _frame_callback,
                                    &data, NULL);
-  g_idle_add (_draw, data);
+  g_signal_connect (data->sink,"cogl-gst-new-frame", G_CALLBACK (_draw), data);
 }
 
 int
@@ -119,9 +112,12 @@ main (int argc,
   CoglContext *ctx;
   CoglOnscreen *onscreen;
   CoglMatrix view;
-  CoglGstVideoPlayer *player;
   GMainLoop *loop;
   float fovy, aspect, z_near, z_2d, z_far;
+  GstElement *pipeline;
+  GstElement *bin;
+  GstBus *bus;
+  char *uri;
 
   ctx = cogl_context_new (NULL, NULL);
   onscreen = cogl_onscreen_new (ctx, 640, 480);
@@ -142,13 +138,28 @@ main (int argc,
   cogl_framebuffer_set_modelview_matrix (data.fb, &view);
 
   gst_init (&argc, &argv);
+  
+  data.sink = cogl_gst_video_sink_new (ctx); 
+
+  pipeline = gst_pipeline_new ("gst-player");
+  bin = gst_element_factory_make ("playbin", "bin");
+  
+  if (argc < 2)
+    uri = "http://docs.gstreamer.com/media/sintel_trailer-480p.webm";;
+  else
+    uri = argv[1];
+
+  g_object_set (G_OBJECT (bin), "video-sink", GST_ELEMENT (data.sink), NULL);
+
 
-  player = cogl_gst_video_player_new (ctx, TRUE,
-                                      "http://docs.gstreamer.com/media/sintel_trailer-480p.webm";);
+  gst_bin_add (GST_BIN (pipeline), bin);
 
-  data.sink = cogl_gst_video_player_get_sink (player);
+  g_object_set (G_OBJECT (bin), "uri", uri, NULL);
+  
+  gst_element_set_state (pipeline, GST_STATE_PLAYING);
+  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+  gst_bus_add_watch (bus, _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",


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]