[Cogl] [PATCH 05/13] cogl-gst: video-sink: add NV12 support
Lionel Landwerlin
llandwerlin at gmail.com
Mon Dec 9 03:17:52 PST 2013
Based on a patch from Edward Hervey and Matthieu Bouron for
Clutter-Gst :
https://bugzilla.gnome.org/show_bug.cgi?id=712832
---
cogl-gst/cogl-gst-video-sink.c | 113 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 110 insertions(+), 3 deletions(-)
diff --git a/cogl-gst/cogl-gst-video-sink.c b/cogl-gst/cogl-gst-video-sink.c
index 94e54bc..57dd3e9 100644
--- a/cogl-gst/cogl-gst-video-sink.c
+++ b/cogl-gst/cogl-gst-video-sink.c
@@ -57,7 +57,8 @@
"RGBA," \
"BGRA," \
"RGB," \
- "BGR }"
+ "BGR," \
+ "NV12 }"
#define COGL_GST_PARAM_STATIC \
(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)
@@ -106,7 +107,8 @@ typedef enum
COGL_GST_AYUV,
COGL_GST_YV12,
COGL_GST_SURFACE,
- COGL_GST_I420
+ COGL_GST_I420,
+ COGL_GST_NV12
} CoglGstVideoFormat;
typedef enum
@@ -865,6 +867,108 @@ static CoglGstRenderer ayuv_glsl_renderer =
cogl_gst_ayuv_upload,
};
+/**/
+
+static void
+cogl_gst_nv12_glsl_setup_pipeline (CoglGstVideoSink *sink,
+ CoglPipeline *pipeline)
+{
+ CoglGstVideoSinkPrivate *priv = sink->priv;
+ static SnippetCache snippet_cache;
+ SnippetCacheEntry *entry;
+
+ entry = get_cache_entry (sink, &snippet_cache);
+
+ if (entry == NULL)
+ {
+ char *source;
+
+ source
+ = g_strdup_printf ("vec4\n"
+ "cogl_gst_sample_video%i (vec2 UV)\n"
+ "{\n"
+ " vec4 color;\n"
+ " float y = 1.1640625 * (texture2D (cogl_sampler%i, UV).r - 0.0625);\n"
+ " float uvr = int (texture2D (cogl_sampler%i, UV).r * 32);\n"
+ " float uvg = int (texture2D (cogl_sampler%i, UV).g * 64);\n"
+ " float uvb = int (texture2D (cogl_sampler%i, UV).b * 32);\n"
+ " float tg = floor (uvg / 8.0);\n"
+ " float u = (uvb + (uvg - tg * 8.0) * 32.0) / 256.0;\n"
+ " float v = (uvr * 8.0 + tg) / 256.0;\n"
+ " u -= 0.5;\n"
+ " v -= 0.5;\n"
+ " color.r = y + 1.59765625 * v;\n"
+ " color.g = y - 0.390625 * u - 0.8125 * v;\n"
+ " color.b = y + 2.015625 * u;\n"
+ " color.a = 1.0;\n"
+ " return color;\n"
+ "}\n", priv->custom_start,
+ priv->custom_start,
+ priv->custom_start + 1,
+ priv->custom_start + 1,
+ priv->custom_start + 1);
+
+ entry = add_cache_entry (sink, &snippet_cache, source);
+ g_free (source);
+ }
+
+ setup_pipeline_from_cache_entry (sink, pipeline, entry, 2);
+}
+
+static CoglBool
+cogl_gst_nv12_upload (CoglGstVideoSink *sink,
+ GstBuffer *buffer)
+{
+ CoglGstVideoSinkPrivate *priv = sink->priv;
+ GstVideoFrame frame;
+
+ if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ))
+ goto map_fail;
+
+ clear_frame_textures (sink);
+
+ priv->frame[0] =
+ video_texture_new_from_data (priv->ctx,
+ GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 0),
+ GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 0),
+ COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8,
+ priv->info.stride[0], frame.data[0], NULL);
+
+ priv->frame[1] =
+ video_texture_new_from_data (priv->ctx,
+ GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 1),
+ GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 1),
+ COGL_PIXEL_FORMAT_RGB_565, COGL_PIXEL_FORMAT_RGB_565,
+ priv->info.stride[1], frame.data[1], NULL);
+
+ gst_video_frame_unmap (&frame);
+
+ return TRUE;
+
+map_fail:
+ {
+ GST_ERROR_OBJECT (sink, "Could not map incoming video frame");
+ return FALSE;
+ }
+}
+
+static CoglGstRenderer nv12_glsl_renderer =
+{
+ "NV12 glsl",
+ COGL_GST_NV12,
+ COGL_GST_RENDERER_NEEDS_GLSL,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES("memory:SystemMemory", "NV12")),
+ 2, /* n_layers */
+ {
+ COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR, COGL_PIPELINE_FILTER_LINEAR,
+ COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR, COGL_PIPELINE_FILTER_NEAREST,
+ },
+ cogl_gst_nv12_glsl_setup_pipeline,
+ cogl_gst_nv12_upload,
+};
+
+/**/
+
static GSList*
cogl_gst_build_renderers_list (CoglContext *ctx)
{
@@ -878,6 +982,7 @@ cogl_gst_build_renderers_list (CoglContext *ctx)
&yv12_glsl_renderer,
&i420_glsl_renderer,
&ayuv_glsl_renderer,
+ &nv12_glsl_renderer,
NULL
};
@@ -1004,7 +1109,9 @@ cogl_gst_video_sink_parse_caps (GstCaps *caps,
break;
case GST_VIDEO_FORMAT_AYUV:
format = COGL_GST_AYUV;
- bgr = FALSE;
+ break;
+ case GST_VIDEO_FORMAT_NV12:
+ format = COGL_GST_NV12;
break;
case GST_VIDEO_FORMAT_RGB:
format = COGL_GST_RGB24;
--
1.8.5
More information about the Cogl
mailing list