[Cogl] [PATCH] cogl-gst: Add a functions to facilitate layering This functions are used when attaching frames at a start point other than layer 0 is required. This could potentially be used to "layer" videos and textures on top of each other in the CoglPipeline. This layering could come handy if videos are used as alpha masks or normal maps, or when arranging layers in a perticular order, so Cogl could blend them nicely without extra hassle.

Plamena Manolova plamena.n.manolova at intel.com
Tue Apr 16 10:15:28 PDT 2013


---
 cogl-gst/Makefile.am               |   7 +-
 cogl-gst/cogl-gst-shader-private.h |  48 ------
 cogl-gst/cogl-gst-shader.c         |  81 ---------
 cogl-gst/cogl-gst-video-sink.c     | 329 ++++++++++++++++++++++++++++++-------
 cogl-gst/cogl-gst-video-sink.h     |  11 ++
 5 files changed, 280 insertions(+), 196 deletions(-)
 delete mode 100644 cogl-gst/cogl-gst-shader-private.h
 delete mode 100644 cogl-gst/cogl-gst-shader.c

diff --git a/cogl-gst/Makefile.am b/cogl-gst/Makefile.am
index 57a64d8..d5e49ae 100644
--- a/cogl-gst/Makefile.am
+++ b/cogl-gst/Makefile.am
@@ -8,7 +8,6 @@ DISTCLEANFILES =
 EXTRA_DIST =
 
 source_c = \
-	cogl-gst-shader.c \
 	cogl-gst-video-sink.c \
 	$(NULL)
 
@@ -17,13 +16,9 @@ source_h = \
 	cogl-gst-video-sink.h \
 	$(NULL)
 
-source_h_priv = \
-	cogl-gst-shader-private.h \
-	$(NULL)
-
 lib_LTLIBRARIES = libcogl-gst.la
 
-libcogl_gst_la_SOURCES = $(source_c) $(source_h) $(source_h_priv)
+libcogl_gst_la_SOURCES = $(source_c) $(source_h)
 libcogl_gst_la_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_GST_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS)
 libcogl_gst_la_LIBADD = $(top_builddir)/cogl/libcogl2.la
 libcogl_gst_la_LIBADD += $(COGL_DEP_LIBS) $(COGL_GST_DEP_LIBS) $(COGL_EXTRA_LDFLAGS)
diff --git a/cogl-gst/cogl-gst-shader-private.h b/cogl-gst/cogl-gst-shader-private.h
deleted file mode 100644
index bdf7164..0000000
--- a/cogl-gst/cogl-gst-shader-private.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Cogl-GStreamer.
- *
- * GStreamer integration library for Cogl.
- *
- * cogl-gst-video-sink-private.h - Miscellaneous video sink functions
- *
- * 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_SHADER_PRIVATE_H__
-#define __COGL_GST_SHADER_PRIVATE_H__
-
-extern const char
-_cogl_gst_shader_rgba_to_rgba_decl[];
-
-extern const char
-_cogl_gst_shader_yv12_to_rgba_decl[];
-
-extern const char
-_cogl_gst_shader_ayuv_to_rgba_decl[];
-
-extern const char
-_cogl_gst_shader_default_sample[];
-
-#endif /* __COGL_GST_SHADER_PRIVATE_H__ */
diff --git a/cogl-gst/cogl-gst-shader.c b/cogl-gst/cogl-gst-shader.c
deleted file mode 100644
index 49d4671..0000000
--- a/cogl-gst/cogl-gst-shader.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Cogl-GStreamer.
- *
- * GStreamer integration library for Cogl.
- *
- * cogl-gst-video-sink-private.h - Miscellaneous video sink functions
- *
- * 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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "cogl-gst-shader-private.h"
-
-const char
-_cogl_gst_shader_rgba_to_rgba_decl[] =
-  "vec4\n"
-  "cogl_gst_sample_video (vec2 UV)\n"
-  "{\n"
-  "  return texture2D (cogl_sampler0, UV);\n"
-  "}\n";
-
-const char
-_cogl_gst_shader_yv12_to_rgba_decl[] =
-  "vec4\n"
-  "cogl_gst_sample_video (vec2 UV)\n"
-  "{\n"
-  "  float y = 1.1640625 * (texture2D (cogl_sampler0, UV).a - 0.0625);\n"
-  "  float u = texture2D (cogl_sampler1, UV).a - 0.5;\n"
-  "  float v = texture2D (cogl_sampler2, UV).a - 0.5;\n"
-  "  vec4 color;\n"
-  "  color.r = y + 1.59765625 * v;\n"
-  "  color.g = y - 0.390625 * u - 0.8125 * v;\n"
-  "  color.b = y + 2.015625 * u;\n"
-  "  color.a = 1.0;\n"
-  "  return color;\n"
-  "}\n";
-
-const char
-_cogl_gst_shader_ayuv_to_rgba_decl[] =
-  "vec4\n"
-  "cogl_gst_sample_video (vec2 UV)\n"
-  "{\n"
-  "  vec4 color = texture2D (cogl_sampler0, UV);\n"
-  "  float y = 1.1640625 * (color.g - 0.0625);\n"
-  "  float u = color.b - 0.5;\n"
-  "  float v = color.a - 0.5;\n"
-  "  color.a = color.r;\n"
-  "  color.r = y + 1.59765625 * v;\n"
-  "  color.g = y - 0.390625 * u - 0.8125 * v;\n"
-  "  color.b = y + 2.015625 * u;\n"
-  "  return color;\n"
-  "}\n";
-
-const char
-_cogl_gst_shader_default_sample[] =
-  "  cogl_layer = cogl_gst_sample_video (cogl_tex_coord0_in.st);\n";
diff --git a/cogl-gst/cogl-gst-video-sink.c b/cogl-gst/cogl-gst-video-sink.c
index 5b17e53..814d269 100644
--- a/cogl-gst/cogl-gst-video-sink.c
+++ b/cogl-gst/cogl-gst-video-sink.c
@@ -43,7 +43,6 @@
 #include <string.h>
 
 #include "cogl-gst-video-sink.h"
-#include "cogl-gst-shader-private.h"
 
 #define COGL_GST_TEXTURE_FLAGS \
        (COGL_TEXTURE_NO_SLICING | COGL_TEXTURE_NO_ATLAS)
@@ -99,6 +98,20 @@ typedef enum
   COGL_GST_RENDERER_NEEDS_GLSL = (1 << 0)
 } CoglGstRendererFlag;
 
+/* We want to cache the snippets instead of recreating a new one every
+ * time we initialise a pipeline so that if we end up recreating the
+ * same pipeline again then Cogl will be able to use the pipeline
+ * cache to avoid linking a redundant identical shader program */
+typedef struct
+{
+  CoglSnippet *vertex_snippet;
+  CoglSnippet *fragment_snippet;
+  CoglSnippet *default_sample_snippet;
+  int start_position;
+  CoglBool default_sample;
+  char *renderer;
+} SnippetCache;
+
 typedef struct _CoglGstSource
 {
   GSource source;
@@ -117,7 +130,7 @@ typedef struct _CoglGstRenderer
   CoglGstVideoFormat format;
   int flags;
   GstStaticCaps caps;
-  void (*init) (CoglGstVideoSink *sink);
+  void (*setup_pipeline) (CoglGstVideoSink *sink, CoglPipeline *pipeline);
   void (*deinit) (CoglGstVideoSink *sink);
   CoglBool (*upload) (CoglGstVideoSink *sink,
                       GstBuffer *buffer);
@@ -133,10 +146,13 @@ struct _CoglGstVideoSinkPrivate
   CoglBool bgr;
   CoglGstSource *source;
   GSList *renderers;
+  GList *snippet_cache;
   GstCaps *caps;
   CoglGstRenderer *renderer;
   GstFlowReturn flow_return;
+  int custom_start;
   int free_layer;
+  CoglBool default_sample;
   GstVideoInfo info;
 };
 
@@ -168,7 +184,8 @@ cogl_gst_video_sink_attach_frame (CoglGstVideoSink *sink,
 
   for (i = 0; i < G_N_ELEMENTS (priv->frame); i++)
     if (priv->frame[i] != NULL)
-      cogl_pipeline_set_layer_texture (pln, i, priv->frame[i]);
+      cogl_pipeline_set_layer_texture (pln, i + priv->custom_start,
+                                       priv->frame[i]);
 
   return priv->free_layer;
 }
@@ -200,32 +217,68 @@ cogl_gst_video_sink_set_priority (CoglGstVideoSink *sink,
     g_source_set_priority ((GSource *) sink->priv->source, priority);
 }
 
-/* We want to cache the snippets instead of recreating a new one every
- * time we initialise a pipeline so that if we end up recreating the
- * same pipeline again then Cogl will be able to use the pipeline
- * cache to avoid linking a redundant identical shader program */
-typedef struct
+void
+cogl_gst_video_sink_set_first_layer (CoglGstVideoSink *sink,
+                                     int first_layer)
 {
-  CoglSnippet *vertex_snippet;
-  CoglSnippet *fragment_snippet;
-} SnippetCache;
+  if (first_layer != sink->priv->custom_start)
+    {
+      sink->priv->custom_start = first_layer;
+      sink->priv->renderer->setup_pipeline (sink, NULL);
+    }
+}
+
+void
+cogl_gst_video_sink_set_default_sample (CoglGstVideoSink *sink,
+                                        CoglBool default_sample)
+{
+  if (default_sample != sink->priv->default_sample)
+    {
+      sink->priv->default_sample = default_sample;
+      sink->priv->renderer->setup_pipeline (sink, NULL);
+    }
+}
+
+void
+cogl_gst_video_sink_setup_pipeline (CoglGstVideoSink *sink,
+                                    CoglPipeline *pipeline)
+{
+  sink->priv->renderer->setup_pipeline (sink, pipeline);
+}
 
 static void
 create_template_pipeline (CoglGstVideoSink *sink,
+                          CoglPipeline *pln,
                           const char *decl,
                           SnippetCache *snippet_cache,
                           int n_layers)
 {
   CoglGstVideoSinkPrivate *priv = sink->priv;
-  priv->free_layer = n_layers;
-
-  if (priv->pipeline)
-    cogl_object_unref (priv->pipeline);
-  priv->pipeline = cogl_pipeline_new (priv->ctx);
+  GList *list = NULL;
+  int i;
+  CoglBool snippet_exists = FALSE;
+  priv->free_layer = priv->custom_start + n_layers;
 
   if (decl)
     {
-      static CoglSnippet *default_sample_snippet = NULL;
+      i = 0;
+
+      for (list = priv->snippet_cache; list; list = g_list_next (list))
+        {
+          SnippetCache *cache = (SnippetCache*) g_list_nth_data (list, i);
+          if (g_strcmp0 (cache->renderer, snippet_cache->renderer) == 0)
+            {
+              if (cache->start_position == snippet_cache->start_position &&
+                  cache->default_sample == cache->default_sample)
+                {
+                  g_free (snippet_cache);
+                  snippet_cache = cache;
+                  snippet_exists = TRUE;
+                  break;
+                }
+            }
+          i++;
+        }
 
       /* The global sampling function gets added to both the fragment
        * and vertex stages. The hope is that the GLSL compiler will
@@ -235,31 +288,56 @@ create_template_pipeline (CoglGstVideoSink *sink,
           cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_GLOBALS,
                             decl,
                             NULL /* post */);
-      cogl_pipeline_add_snippet (priv->pipeline,
-                                 snippet_cache->vertex_snippet);
+      cogl_pipeline_add_snippet (pln, snippet_cache->vertex_snippet);
 
       if (snippet_cache->fragment_snippet == NULL)
         snippet_cache->fragment_snippet =
           cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS,
                             decl,
                             NULL /* post */);
-      cogl_pipeline_add_snippet (priv->pipeline,
-                                 snippet_cache->fragment_snippet);
+      cogl_pipeline_add_snippet (pln, snippet_cache->fragment_snippet);
 
       /* Set the replace string for the last layer so that no
        * redundant code for the previous layers will be generated. The
        * application can also replace this default sampling by adding
        * another layer */
-      if (default_sample_snippet == NULL)
+
+      if (priv->default_sample)
         {
-          default_sample_snippet =
-            cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT, NULL, NULL);
-          cogl_snippet_set_replace (default_sample_snippet,
-                                    _cogl_gst_shader_default_sample);
+          if (snippet_cache->default_sample_snippet == NULL)
+            {
+              char *snippet;
+
+              if (priv->custom_start == 0)
+                snippet = g_strdup_printf ("cogl_layer = \n"
+                  "cogl_gst_sample_video%i (cogl_tex_coord%i_in.st);\n",
+                  priv->custom_start, priv->custom_start);
+              else
+                snippet = g_strdup_printf ("cogl_layer = \n"
+                  "cogl_gst_sample_video%i (cogl_tex_coord%i_in.st) *"
+                  "cogl_layer%i;\n",
+                  priv->custom_start, priv->custom_start,
+                  priv->custom_start - 1);
+
+              snippet_cache->default_sample_snippet =
+                cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT, NULL,
+                                  snippet);
+
+              g_free (snippet);
+            }
+
+           cogl_pipeline_add_layer_snippet (pln,
+             priv->custom_start + (n_layers - 1),
+             snippet_cache->default_sample_snippet);
         }
-      cogl_pipeline_add_layer_snippet (priv->pipeline,
-                                       n_layers - 1,
-                                       default_sample_snippet);
+
+      for (i = 0; i < n_layers; i++)
+         cogl_pipeline_set_layer_combine (pln, priv->custom_start + i,
+                                          "RGBA=REPLACE(PREVIOUS)", NULL);
+
+      if (!snippet_exists)
+        priv->snippet_cache = g_list_prepend (priv->snippet_cache,
+                                              snippet_cache);
     }
 
   priv->frame_dirty = TRUE;
@@ -311,21 +389,44 @@ clear_frame_textures (CoglGstVideoSink *sink)
 }
 
 static void
-cogl_gst_rgb_init (CoglGstVideoSink *sink)
+cogl_gst_rgb_setup_pipeline (CoglGstVideoSink *sink,
+                             CoglPipeline *pipeline)
 {
   CoglGstVideoSinkPrivate *priv = sink->priv;
+  CoglPipeline *pln = pipeline;
 
-  if (cogl_has_feature (priv->ctx, COGL_FEATURE_ID_GLSL))
+  if (!pln)
     {
-      static SnippetCache snippet_cache;
+      if (priv->pipeline)
+        cogl_object_unref (priv->pipeline);
+      priv->pipeline = cogl_pipeline_new (priv->ctx);
+      pln = priv->pipeline;
+    }
 
-      create_template_pipeline (sink,
-                                _cogl_gst_shader_rgba_to_rgba_decl,
-                                &snippet_cache,
-                                1);
+  if (cogl_has_feature (priv->ctx, COGL_FEATURE_ID_GLSL))
+    {
+      SnippetCache *snippet_cache = NULL;
+      char *snippet;
+
+      snippet_cache = g_new (SnippetCache, 1);
+      snippet_cache->start_position = priv->custom_start;
+      snippet_cache->default_sample = priv->default_sample;
+      snippet_cache->renderer = priv->renderer->name;
+      snippet_cache->vertex_snippet = NULL;
+      snippet_cache->fragment_snippet = NULL;
+      snippet_cache->default_sample_snippet = NULL;
+
+      snippet = g_strdup_printf ("vec4\n"
+                                 "cogl_gst_sample_video%i (vec2 UV)\n"
+                                 "{\n"
+                                 "  return texture2D (cogl_sampler%i, UV);\n"
+                                 "}\n", priv->custom_start, priv->custom_start);
+
+      create_template_pipeline (sink, pln, snippet, snippet_cache, 1);
+      g_free (snippet);
     }
   else
-    create_template_pipeline (sink, NULL, NULL, 1);
+    create_template_pipeline (sink, pln, NULL, NULL, 1);
 }
 
 static CoglBool
@@ -370,7 +471,7 @@ static CoglGstRenderer rgb24_renderer =
   COGL_GST_RGB24,
   0,
   GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGB, BGR }")),
-  cogl_gst_rgb_init,
+  cogl_gst_rgb_setup_pipeline,
   cogl_gst_dummy_deinit,
   cogl_gst_rgb24_upload,
 };
@@ -417,7 +518,7 @@ static CoglGstRenderer rgb32_renderer =
   COGL_GST_RGB32,
   0,
   GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGBA, BGRA }")),
-  cogl_gst_rgb_init,
+  cogl_gst_rgb_setup_pipeline,
   cogl_gst_dummy_deinit,
   cogl_gst_rgb32_upload,
 };
@@ -468,14 +569,49 @@ map_fail:
 }
 
 static void
-cogl_gst_yv12_glsl_init (CoglGstVideoSink *sink)
+cogl_gst_yv12_glsl_setup_pipeline (CoglGstVideoSink *sink,
+                                   CoglPipeline *pipeline)
 {
-  static SnippetCache snippet_cache;
+  SnippetCache *snippet_cache = NULL;
+  CoglGstVideoSinkPrivate *priv = sink->priv;
+  char *snippet;
+  CoglPipeline *pln = pipeline;
 
-  create_template_pipeline (sink,
-                            _cogl_gst_shader_yv12_to_rgba_decl,
-                            &snippet_cache,
-                            3);
+  if (!pln)
+    {
+      if (priv->pipeline)
+        cogl_object_unref (priv->pipeline);
+      priv->pipeline = cogl_pipeline_new (priv->ctx);
+      pln = priv->pipeline;
+    }
+
+  snippet_cache = g_new (SnippetCache, 1);
+  snippet_cache->start_position = priv->custom_start;
+  snippet_cache->default_sample = priv->default_sample;
+  snippet_cache->renderer = priv->renderer->name;
+  snippet_cache->vertex_snippet = NULL;
+  snippet_cache->fragment_snippet = NULL;
+  snippet_cache->default_sample_snippet = NULL;
+
+  snippet = g_strdup_printf ("vec4\n"
+                             "cogl_gst_sample_video%i (vec2 UV)\n"
+                             "{\n"
+                             "  float y = 1.1640625 * (texture2D (cogl_sampler%i, UV).a - 0.0625);\n"
+                             "  float u = texture2D (cogl_sampler%i, UV).a - 0.5;\n"
+                             "  float v = texture2D (cogl_sampler%i, UV).a - 0.5;\n"
+                             "  vec4 color;\n"
+                             "  color.r = y + 1.59765625 * v;\n"
+                             "  color.g = y - 0.390625 * u - 0.8125 * v;\n"
+                             "  color.b = y + 2.015625 * u;\n"
+                             "  color.a = 1.0;\n"
+                             "  return color;\n"
+                             "}\n",
+                             priv->custom_start, priv->custom_start,
+                             priv->custom_start + 1,
+                             priv->custom_start + 2);
+
+  create_template_pipeline (sink, pln, snippet, snippet_cache, 3);
+  g_free (snippet);
 }
 
 static CoglGstRenderer yv12_glsl_renderer =
@@ -484,20 +620,55 @@ static CoglGstRenderer yv12_glsl_renderer =
   COGL_GST_YV12,
   COGL_GST_RENDERER_NEEDS_GLSL,
   GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("YV12")),
-  cogl_gst_yv12_glsl_init,
+  cogl_gst_yv12_glsl_setup_pipeline,
   cogl_gst_dummy_deinit,
   cogl_gst_yv12_upload,
 };
 
 static void
-cogl_gst_i420_glsl_init (CoglGstVideoSink *sink)
+cogl_gst_i420_glsl_setup_pipeline (CoglGstVideoSink *sink,
+                                   CoglPipeline *pipeline)
 {
-  static SnippetCache snippet_cache;
+  SnippetCache *snippet_cache = NULL;
+  CoglGstVideoSinkPrivate *priv = sink->priv;
+  char *snippet;
+  CoglPipeline *pln = pipeline;
 
-  create_template_pipeline (sink,
-                            _cogl_gst_shader_yv12_to_rgba_decl,
-                            &snippet_cache,
-                            3);
+  if (!pln)
+    {
+      if (priv->pipeline)
+        cogl_object_unref (priv->pipeline);
+      priv->pipeline = cogl_pipeline_new (priv->ctx);
+      pln = priv->pipeline;
+    }
+
+  snippet_cache = g_new (SnippetCache, 1);
+  snippet_cache->start_position = priv->custom_start;
+  snippet_cache->default_sample = priv->default_sample;
+  snippet_cache->renderer = priv->renderer->name;
+  snippet_cache->vertex_snippet = NULL;
+  snippet_cache->fragment_snippet = NULL;
+  snippet_cache->default_sample_snippet = NULL;
+
+  snippet = g_strdup_printf ("vec4\n"
+                             "cogl_gst_sample_video%i (vec2 UV)\n"
+                             "{\n"
+                             "  float y = 1.1640625 * (texture2D (cogl_sampler%i, UV).a - 0.0625);\n"
+                             "  float u = texture2D (cogl_sampler%i, UV).a - 0.5;\n"
+                             "  float v = texture2D (cogl_sampler%i, UV).a - 0.5;\n"
+                             "  vec4 color;\n"
+                             "  color.r = y + 1.59765625 * v;\n"
+                             "  color.g = y - 0.390625 * u - 0.8125 * v;\n"
+                             "  color.b = y + 2.015625 * u;\n"
+                             "  color.a = 1.0;\n"
+                             "  return color;\n"
+                             "}\n",
+                             priv->custom_start, priv->custom_start,
+                             priv->custom_start + 1,
+                             priv->custom_start + 2);
+
+  create_template_pipeline (sink, pln, snippet, snippet_cache, 3);
+  g_free (snippet);
 }
 
 static CoglGstRenderer i420_glsl_renderer =
@@ -506,20 +677,53 @@ static CoglGstRenderer i420_glsl_renderer =
   COGL_GST_I420,
   COGL_GST_RENDERER_NEEDS_GLSL,
   GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420")),
-  cogl_gst_i420_glsl_init,
+  cogl_gst_i420_glsl_setup_pipeline,
   cogl_gst_dummy_deinit,
   cogl_gst_yv12_upload,
 };
 
 static void
-cogl_gst_ayuv_glsl_init (CoglGstVideoSink *sink)
+cogl_gst_ayuv_glsl_setup_pipeline (CoglGstVideoSink *sink,
+                                   CoglPipeline *pipeline)
 {
-  static SnippetCache snippet_cache;
+  SnippetCache *snippet_cache;
+  CoglGstVideoSinkPrivate *priv = sink->priv;
+  char *snippet;
+  CoglPipeline *pln = pipeline;
+
+  if (!pln)
+    {
+      if (priv->pipeline)
+        cogl_object_unref (priv->pipeline);
+      priv->pipeline = cogl_pipeline_new (priv->ctx);
+      pln = priv->pipeline;
+    }
 
-  create_template_pipeline (sink,
-                            _cogl_gst_shader_ayuv_to_rgba_decl,
-                            &snippet_cache,
-                            1);
+  snippet_cache = g_new (SnippetCache, 1);
+  snippet_cache->start_position = priv->custom_start;
+  snippet_cache->default_sample = priv->default_sample;
+  snippet_cache->renderer = priv->renderer->name;
+  snippet_cache->vertex_snippet = NULL;
+  snippet_cache->fragment_snippet = NULL;
+  snippet_cache->default_sample_snippet = NULL;
+
+  snippet = g_strdup_printf ("vec4\n"
+                             "cogl_gst_sample_video%i (vec2 UV)\n"
+                             "{\n"
+                             "  vec4 color = texture2D (cogl_sampler%i, UV);\n"
+                             "  float y = 1.1640625 * (color.g - 0.0625);\n"
+                             "  float u = color.b - 0.5;\n"
+                             "  float v = color.a - 0.5;\n"
+                             "  color.a = color.r;\n"
+                             "  color.r = y + 1.59765625 * v;\n"
+                             "  color.g = y - 0.390625 * u - 0.8125 * v;\n"
+                             "  color.b = y + 2.015625 * u;\n"
+                             "  return color;\n"
+                             "}\n", priv->custom_start,
+                             priv->custom_start);
+
+  create_template_pipeline (sink, pln, snippet, snippet_cache, 1);
+  g_free (snippet);
 }
 
 static CoglBool
@@ -559,7 +763,7 @@ static CoglGstRenderer ayuv_glsl_renderer =
   COGL_GST_AYUV,
   COGL_GST_RENDERER_NEEDS_GLSL,
   GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("AYUV")),
-  cogl_gst_ayuv_glsl_init,
+  cogl_gst_ayuv_glsl_setup_pipeline,
   cogl_gst_dummy_deinit,
   cogl_gst_ayuv_upload,
 };
@@ -814,7 +1018,7 @@ cogl_gst_source_dispatch (GSource *source,
       if (!cogl_gst_video_sink_parse_caps (caps, gst_source->sink, TRUE))
         goto negotiation_fail;
 
-      priv->renderer->init (gst_source->sink);
+      priv->renderer->setup_pipeline (gst_source->sink, NULL);
       gst_source->has_new_caps = FALSE;
     }
 
@@ -1107,6 +1311,9 @@ 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);
+  sink->priv->custom_start = 0;
+  sink->priv->default_sample = TRUE;
+  sink->priv->snippet_cache = NULL;
 
   return sink;
 }
diff --git a/cogl-gst/cogl-gst-video-sink.h b/cogl-gst/cogl-gst-video-sink.h
index 7ca054b..0bdf679 100644
--- a/cogl-gst/cogl-gst-video-sink.h
+++ b/cogl-gst/cogl-gst-video-sink.h
@@ -117,6 +117,17 @@ int
 cogl_gst_video_sink_attach_frame (CoglGstVideoSink *sink,
                                   CoglPipeline *pln);
 
+void
+cogl_gst_video_sink_set_first_layer (CoglGstVideoSink *sink,
+                                     int first_layer);
+
+void
+cogl_gst_video_sink_set_default_sample (CoglGstVideoSink *sink,
+                                        CoglBool default_sample);
+
+void
+cogl_gst_video_sink_setup_pipeline (CoglGstVideoSink *sink,
+                                    CoglPipeline *pipeline);
 G_END_DECLS
 
 #endif
-- 
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