[Cogl] [PATCH] gst:Implement frame grab behaviour

Plamena Manolova plamena.n.manolova at intel.com
Thu Mar 7 09:30:10 PST 2013


- Implement an attach frame method to avoid directly modifying
  the cogl-gst CoglPipeline.
---
 cogl-gst/cogl-gst-video-sink.c | 114 ++++++++++++++++++++++++++---------------
 cogl-gst/cogl-gst-video-sink.h |   4 ++
 2 files changed, 78 insertions(+), 40 deletions(-)

diff --git a/cogl-gst/cogl-gst-video-sink.c b/cogl-gst/cogl-gst-video-sink.c
index 1e49b9a..d669d2d 100644
--- a/cogl-gst/cogl-gst-video-sink.c
+++ b/cogl-gst/cogl-gst-video-sink.c
@@ -132,6 +132,7 @@ struct _CoglGstVideoSinkPrivate
 {
   CoglContext *ctx;
   CoglPipeline *pipeline;
+  CoglTexture *frame [3];
   CoglGstVideoFormat format;
   CoglBool bgr;
   CoglGstSource *source;
@@ -159,15 +160,23 @@ cogl_gst_source_finalize (GSource *source)
   g_mutex_clear (&gst_source->buffer_lock);
 }
 
-CoglPipeline*
-cogl_gst_video_sink_get_pipeline (CoglGstVideoSink *vt)
+int
+cogl_gst_video_sink_get_free_layer (CoglGstVideoSink* sink)
 {
-  return vt->priv->pipeline;
+  return sink->priv->free_layer;
 }
 
 int
-cogl_gst_video_sink_get_free_layer (CoglGstVideoSink* sink)
+cogl_gst_video_sink_attach_frame (CoglGstVideoSink *sink,
+                                  CoglPipeline *pln)
 {
+  if (sink->priv->frame[0] != NULL)
+    cogl_pipeline_set_layer_texture (pln, 0, sink->priv->frame[0]);
+  if (sink->priv->frame[1] != NULL)
+    cogl_pipeline_set_layer_texture (pln, 1, sink->priv->frame[1]);
+  if (sink->priv->frame[2] != NULL)
+    cogl_pipeline_set_layer_texture (pln, 2, sink->priv->frame[2]);
+    
   return sink->priv->free_layer;
 }
 
@@ -276,20 +285,20 @@ create_paint_pipeline (CoglGstVideoSink *sink,
   priv->pipeline = pln;
 
   if (tex0 != NULL)
-    {
-      cogl_pipeline_set_layer_texture (priv->pipeline, 0, tex0);
-      cogl_object_unref (tex0);
-    }
+    cogl_pipeline_set_layer_texture (priv->pipeline, 0, tex0);
   if (tex1 != NULL)
-    {
-      cogl_pipeline_set_layer_texture (priv->pipeline, 1, tex1);
-      cogl_object_unref (tex1);
-    }
+    cogl_pipeline_set_layer_texture (priv->pipeline, 1, tex1);
   if (tex2 != NULL)
-    {
-      cogl_pipeline_set_layer_texture (priv->pipeline, 2, tex2);
-      cogl_object_unref (tex2);
-    }
+    cogl_pipeline_set_layer_texture (priv->pipeline, 2, tex2);
+}
+
+CoglPipeline*
+cogl_gst_video_sink_get_pipeline (CoglGstVideoSink *vt)
+{
+  if (vt->priv->frame[0])
+    create_paint_pipeline (vt, vt->priv->frame[0], vt->priv->frame[1], 
+                           vt->priv->frame[2]);
+  return vt->priv->pipeline;
 }
 
 static void
@@ -321,7 +330,6 @@ cogl_gst_rgb24_upload (CoglGstVideoSink *sink,
 {
   CoglGstVideoSinkPrivate *priv = sink->priv;
   CoglPixelFormat format;
-  CoglTexture *tex;
   GstVideoFrame frame;
 
   if (priv->bgr)
@@ -331,16 +339,20 @@ cogl_gst_rgb24_upload (CoglGstVideoSink *sink,
 
   if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ))
     goto map_fail;
+    
+  if (priv->frame[0])
+    {
+      cogl_object_unref (priv->frame[0]);
+      priv->frame[0] = NULL;
+    }
 
-  tex = cogl_texture_new_from_data (priv->ctx, priv->info.width,
+  priv->frame[0] = 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:
@@ -355,7 +367,7 @@ static CoglGstRenderer rgb24_renderer =
 {
   "RGB 24",
   COGL_GST_RGB24,
-  COGL_GST_RENDERER_NEEDS_GLSL,
+  0,
   GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGB, BGR }")),
   cogl_gst_rgb_init,
   cogl_gst_dummy_deinit,
@@ -368,7 +380,6 @@ cogl_gst_rgb32_upload (CoglGstVideoSink *sink,
 {
   CoglGstVideoSinkPrivate *priv = sink->priv;
   CoglPixelFormat format;
-  CoglTexture *tex;
   GstVideoFrame frame;
 
   if (priv->bgr)
@@ -378,16 +389,20 @@ cogl_gst_rgb32_upload (CoglGstVideoSink *sink,
 
   if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ))
     goto map_fail;
+  
+  if (priv->frame[0])
+    {
+      cogl_object_unref (priv->frame[0]);
+      priv->frame[0] = NULL;
+    }
 
-  tex = cogl_texture_new_from_data (priv->ctx, priv->info.width,
+  priv->frame[0] = 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:
@@ -401,7 +416,7 @@ static CoglGstRenderer rgb32_renderer =
 {
   "RGB 32",
   COGL_GST_RGB32,
-  COGL_GST_RENDERER_NEEDS_GLSL,
+  0,
   GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGBA, BGRA }")),
   cogl_gst_rgb_init,
   cogl_gst_dummy_deinit,
@@ -413,28 +428,38 @@ cogl_gst_yv12_upload (CoglGstVideoSink *sink,
                       GstBuffer *buffer)
 {
   CoglGstVideoSinkPrivate *priv = sink->priv;
-  CoglTexture *y_tex, *u_tex, *v_tex;
   GstVideoFrame frame;
   CoglPixelFormat format = COGL_PIXEL_FORMAT_G_8;
 
   if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ))
     goto map_fail;
+    
+  if (priv->frame[0] && priv->frame[1] && priv->frame[2])
+    {
+      cogl_object_unref (priv->frame[0]);
+      cogl_object_unref (priv->frame[1]);
+      cogl_object_unref (priv->frame[2]);
+      
+      priv->frame[0] = NULL;
+      priv->frame[1] = NULL;
+      priv->frame[2] = NULL;
+    }
 
-  y_tex =
+  priv->frame[0] =
      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 =
+  priv->frame[1] =
      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 =
+  priv->frame[2] =
      cogl_texture_new_from_data (priv->ctx,
                                  GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 2),
                                  GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 2),
@@ -443,8 +468,6 @@ cogl_gst_yv12_upload (CoglGstVideoSink *sink,
 
   gst_video_frame_unmap (&frame);
 
-  create_paint_pipeline (sink, y_tex, u_tex, v_tex);
-
   return TRUE;
 
 map_fail:
@@ -515,21 +538,24 @@ cogl_gst_ayuv_upload (CoglGstVideoSink *sink,
 {
   CoglGstVideoSinkPrivate *priv = sink->priv;
   CoglPixelFormat format = COGL_PIXEL_FORMAT_RGBA_8888;
-  CoglTexture *tex;
   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,
+  if (priv->frame[0])
+    {
+      cogl_object_unref (priv->frame[0]);
+      priv->frame[0] = NULL;
+    }
+
+  priv->frame[0] = 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:
@@ -577,17 +603,22 @@ cogl_gst_hw_upload (CoglGstVideoSink *sink,
 
   if (G_UNLIKELY (priv->converter == NULL))
     {
-      CoglTexture* tex;
       unsigned int gl_tex;
       unsigned int gl_tar;
       GValue value = {0};
+      
+      if (priv->frame[0])
+        {
+          cogl_object_unref (priv->frame[0]);
+          priv->frame[0] = NULL;
+        }
 
-      tex = cogl_texture_new_with_size (priv->ctx, priv->info.width,
+      priv->frame[0] = 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_pipeline_set_layer_texture (priv->pipeline, 0, priv->frame[0]);
       cogl_texture_get_gl_texture (tex, &gl_texture, &gl_target);
 
       g_value_init (&value, gl_texture);
@@ -595,7 +626,6 @@ cogl_gst_hw_upload (CoglGstVideoSink *sink,
 
       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);
@@ -844,6 +874,7 @@ cogl_gst_source_dispatch (GSource *source,
                           GSourceFunc callback,
                           void* user_data)
 {
+  g_warning ("Dispatching\n");
   CoglGstSource *gst_source= (CoglGstSource*) source;
   CoglGstVideoSinkPrivate *priv = gst_source->sink->priv;
   GstBuffer *buffer;
@@ -941,6 +972,9 @@ cogl_gst_video_sink_init (CoglGstVideoSink *sink)
   sink->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (sink,
                                                    COGL_GST_TYPE_VIDEO_SINK,
                                                    CoglGstVideoSinkPrivate);
+  sink->priv->frame[0] = NULL;
+  sink->priv->frame[1] = NULL;
+  sink->priv->frame[2] = NULL;
 }
 
 static GstFlowReturn
diff --git a/cogl-gst/cogl-gst-video-sink.h b/cogl-gst/cogl-gst-video-sink.h
index 26e34b1..9ad4837 100644
--- a/cogl-gst/cogl-gst-video-sink.h
+++ b/cogl-gst/cogl-gst-video-sink.h
@@ -112,6 +112,10 @@ cogl_gst_video_sink_get_main_loop (CoglGstVideoSink *loop);
 int
 cogl_gst_video_sink_get_free_layer (CoglGstVideoSink *sink);
 
+int
+cogl_gst_video_sink_attach_frame (CoglGstVideoSink *sink,
+                                  CoglPipeline *pln);
+
 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