[cogl/wip/cogl-gst] gst-video-sink: Implement a dirty flag for fetching the pipeline



commit 43e3501393cdfee6ed551b3902da2c4ebb02cdf5
Author: Neil Roberts <neil linux intel com>
Date:   Fri Mar 8 17:12:13 2013 +0000

    gst-video-sink: Implement a dirty flag for fetching the pipeline
    
    Previously whenever the pipeline is fetched from the video sink it
    would always make a copy of the pipeline and update the textures on
    it. It's not totally unlikely that an application would query the
    pipeline multiple times per frame so it seems worthwhile to prevent it
    allocating a new pipeline if the frames haven't changed. To make this
    work this patch adds a dirty flag which gets set whenever there are
    new textures. The sink now only updates the pipeline when the flag is
    dirty.
    
    As a side effect this also fixes it so that whenever a new frame is
    created it makes sure to clear all of the frame textures, not just the
    ones for the number of layers that the current renderer uses. As far
    as I can tell it might be possible for the renderer to change using a
    single sink and that would cause it to continue adding frame textures
    from the old renderer if the number of layers changed.
    
    There's no need to explicitly set the frame textures to NULL in the
    init function because the private data is always cleared to zero on
    allocation anyway.

 cogl-gst/cogl-gst-video-sink.c |  171 +++++++++++++++++++---------------------
 1 files changed, 81 insertions(+), 90 deletions(-)
---
diff --git a/cogl-gst/cogl-gst-video-sink.c b/cogl-gst/cogl-gst-video-sink.c
index 49e115d..205ed92 100644
--- a/cogl-gst/cogl-gst-video-sink.c
+++ b/cogl-gst/cogl-gst-video-sink.c
@@ -132,7 +132,8 @@ struct _CoglGstVideoSinkPrivate
 {
   CoglContext *ctx;
   CoglPipeline *pipeline;
-  CoglTexture *frame [3];
+  CoglTexture *frame[3];
+  CoglBool frame_dirty;
   CoglGstVideoFormat format;
   CoglBool bgr;
   CoglGstSource *source;
@@ -170,14 +171,14 @@ int
 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]);
+  CoglGstVideoSinkPrivate *priv = sink->priv;
+  int i;
 
-  return sink->priv->free_layer;
+  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]);
+
+  return priv->free_layer;
 }
 
 static CoglBool
@@ -269,35 +270,27 @@ create_template_pipeline (CoglGstVideoSink *sink,
                                        default_sample_snippet);
     }
 
+  priv->frame_dirty = TRUE;
+
   g_signal_emit (sink, video_sink_signals[PIPELINE_READY_SIGNAL], 0, NULL);
 }
 
-static void
-create_paint_pipeline (CoglGstVideoSink *sink,
-                       CoglTexture *tex0,
-                       CoglTexture *tex1,
-                       CoglTexture *tex2)
+CoglPipeline*
+cogl_gst_video_sink_get_pipeline (CoglGstVideoSink *vt)
 {
-  CoglGstVideoSinkPrivate *priv = sink->priv;
+  CoglGstVideoSinkPrivate *priv = vt->priv;
 
-  CoglPipeline *pln = cogl_pipeline_copy (priv->pipeline);
-  cogl_object_unref (priv->pipeline);
-  priv->pipeline = pln;
+  if (priv->frame_dirty)
+    {
+      CoglPipeline *pipeline = cogl_pipeline_copy (priv->pipeline);
+      cogl_object_unref (priv->pipeline);
+      priv->pipeline = pipeline;
 
-  if (tex0 != NULL)
-    cogl_pipeline_set_layer_texture (priv->pipeline, 0, tex0);
-  if (tex1 != NULL)
-    cogl_pipeline_set_layer_texture (priv->pipeline, 1, tex1);
-  if (tex2 != NULL)
-    cogl_pipeline_set_layer_texture (priv->pipeline, 2, tex2);
-}
+      cogl_gst_video_sink_attach_frame (vt, pipeline);
+
+      priv->frame_dirty = FALSE;
+    }
 
-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;
 }
 
@@ -307,6 +300,25 @@ cogl_gst_dummy_deinit (CoglGstVideoSink *sink)
 }
 
 static void
+clear_frame_textures (CoglGstVideoSink *sink)
+{
+  CoglGstVideoSinkPrivate *priv = sink->priv;
+  int i;
+
+  for (i = 0; i < G_N_ELEMENTS (priv->frame); i++)
+    {
+      if (priv->frame[i] == NULL)
+        break;
+      else
+        cogl_object_unref (priv->frame[i]);
+    }
+
+  memset (priv->frame, 0, sizeof (priv->frame));
+
+  priv->frame_dirty = TRUE;
+}
+
+static void
 cogl_gst_rgb_init (CoglGstVideoSink *sink)
 {
   CoglGstVideoSinkPrivate *priv = sink->priv;
@@ -340,16 +352,14 @@ 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;
-    }
+  clear_frame_textures (sink);
 
   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);
+                                               priv->info.height,
+                                               COGL_GST_TEXTURE_FLAGS,
+                                               format, format,
+                                               priv->info.stride[0],
+                                               frame.data[0], NULL);
 
   gst_video_frame_unmap (&frame);
 
@@ -390,16 +400,14 @@ 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;
-    }
+  clear_frame_textures (sink);
 
   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);
+                                               priv->info.height,
+                                               COGL_GST_TEXTURE_FLAGS,
+                                               format, format,
+                                               priv->info.stride[0],
+                                               frame.data[0], NULL);
 
   gst_video_frame_unmap (&frame);
 
@@ -434,37 +442,28 @@ cogl_gst_yv12_upload (CoglGstVideoSink *sink,
   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;
-    }
+  clear_frame_textures (sink);
 
   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);
+    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);
 
   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);
+    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);
 
   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),
-                                 COGL_GST_TEXTURE_FLAGS, format, format,
-                                 priv->info.stride[2], frame.data[2], NULL);
+    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);
 
@@ -543,16 +542,14 @@ cogl_gst_ayuv_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;
-    }
+  clear_frame_textures (sink);
 
   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);
+                                               priv->info.height,
+                                               COGL_GST_TEXTURE_FLAGS,
+                                               format, format,
+                                               priv->info.stride[0],
+                                               frame.data[0], NULL);
 
   gst_video_frame_unmap (&frame);
 
@@ -607,16 +604,13 @@ cogl_gst_hw_upload (CoglGstVideoSink *sink,
       unsigned int gl_tar;
       GValue value = {0};
 
-      if (priv->frame[0])
-        {
-          cogl_object_unref (priv->frame[0]);
-          priv->frame[0] = NULL;
-        }
+      clear_frame_textures (sink);
 
       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);
+                                                   priv->info.height,
+                                                   COGL_GST_TEXTURE_FLAGS,
+                                                   COGL_PIXEL_FORMAT_BGRA_8888,
+                                                   NULL);
 
       cogl_pipeline_set_layer_texture (priv->pipeline, 0, priv->frame[0]);
       cogl_texture_get_gl_texture (tex, &gl_texture, &gl_target);
@@ -972,9 +966,6 @@ 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


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