[cogl/wip/cogl-gst] gst:Implement frame grab behaviour
- From: Neil Roberts <nroberts src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/cogl-gst] gst:Implement frame grab behaviour
- Date: Fri, 8 Mar 2013 17:26:14 +0000 (UTC)
commit 2dc3d52bfa2d058b2f8fd156eb490318c0b668fa
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 | 116 ++++++++++++++++++++++++++--------------
cogl-gst/cogl-gst-video-sink.h | 4 ++
2 files changed, 79 insertions(+), 41 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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]