[cogl/wip/cogl-gst-1.x: 22/29] gst-video-sink: Implement a dirty flag for fetching the pipeline
- From: Lionel Landwerlin <llandwerlin src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/cogl-gst-1.x: 22/29] gst-video-sink: Implement a dirty flag for fetching the pipeline
- Date: Mon, 18 Mar 2013 15:59:36 +0000 (UTC)
commit 485a1df24c78be86bef8ef9c8986f9256a20f70c
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]