[cogl/wip/cogl-gst-1.x: 20/29] gst:Implement frame grab behaviour



commit bd103a922b8c9b767319bf5e205e786ef256119a
Author: Plamena Manolova <plamena n manolova intel com>
Date:   Thu Mar 7 17:30:10 2013 +0000

    gst:Implement frame grab behaviour
    
    - 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..49e115d 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)
@@ -332,15 +340,19 @@ cogl_gst_rgb24_upload (CoglGstVideoSink *sink,
   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:
@@ -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)
@@ -379,15 +390,19 @@ cogl_gst_rgb32_upload (CoglGstVideoSink *sink,
   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:
@@ -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;
 
-  y_tex =
+  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;
+    }
+
+  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};
 
-      tex = cogl_texture_new_with_size (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_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


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