summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Landwerlin <llandwerlin@gmail.com>2015-10-09 02:46:25 +0100
committerLionel Landwerlin <llandwerlin@gmail.com>2015-10-09 02:46:31 +0100
commitf4c48c4e50b4406e0e6949a7d97650c295ec9cb2 (patch)
tree9dd3e5fe80d3bb81ee33de4e04924bd3399409ab
parent8dfdcfa10874702040d0fe7b37021d77960eecd9 (diff)
downloadclutter-gst-f4c48c4e50b4406e0e6949a7d97650c295ec9cb2.tar.gz
video-sink: deal with cropped videos
In codecs like H264, the encoder can work with memory frames larger than the actual video frames. H264 deals with this by specifying both sizes within its bitstream. Failure to take into account a difference between the two sizes will likely result in garbage being displayed at the bottom/right of the video. In GStreamer these informations are given by the caps and the GstVideoFrame structure. The caps gives the actual video size, while GstVideFrame indicates the memory layout. This patch adds a 2x2 matrix uniform used to reconciliate these 2 different sizes by scaling the video textures in the sink's shader.
-rw-r--r--clutter-gst/clutter-gst-video-sink.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/clutter-gst/clutter-gst-video-sink.c b/clutter-gst/clutter-gst-video-sink.c
index c40e6e9..d57a6c8 100644
--- a/clutter-gst/clutter-gst-video-sink.c
+++ b/clutter-gst/clutter-gst-video-sink.c
@@ -400,12 +400,12 @@ add_layer_cache_entry (ClutterGstVideoSink *sink,
default_source =
g_strdup_printf (" cogl_layer *= clutter_gst_sample_video%i "
- "(cogl_tex_coord%i_in.st);\n",
+ "(cogl_tex_coord%i_in.st * clutter_gst_transform);\n",
priv->video_start,
priv->video_start);
entry->default_sample_snippet =
cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT,
- NULL, /* declarations */
+ "uniform mat2 clutter_gst_transform;\n",
default_source);
g_free (default_source);
@@ -966,6 +966,30 @@ clutter_gst_video_sink_setup_conversions (ClutterGstVideoSink *sink,
cogl_pipeline_add_snippet (pipeline, entry->fragment_snippet);
}
+/* Transformation for cropped videos */
+
+static void
+clutter_gst_video_sink_setup_transformation (ClutterGstVideoSink *sink,
+ CoglPipeline *pipeline)
+{
+ ClutterGstVideoSinkPrivate *priv = sink->priv;
+ float transform[] = { 1.0, 0.0,
+ 0.0, 1.0 };
+ gint transform_location;
+
+ if (priv->frame[0] != NULL)
+ {
+ transform[0] = (float) GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 0) /
+ (float) cogl_texture_get_width (priv->frame[0]);
+ transform[3] = (float) GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 0) /
+ (float) cogl_texture_get_height (priv->frame[0]);
+ }
+ transform_location =
+ cogl_pipeline_get_uniform_location (pipeline, "clutter_gst_transform");
+ cogl_pipeline_set_uniform_matrix (pipeline, transform_location,
+ 2, 1, FALSE, transform);
+}
+
/**/
static gboolean
@@ -2625,6 +2649,7 @@ clutter_gst_video_sink_setup_pipeline (ClutterGstVideoSink *sink,
{
clutter_gst_video_sink_setup_conversions (sink, pipeline);
clutter_gst_video_sink_setup_balance (sink, pipeline);
+ clutter_gst_video_sink_setup_transformation (sink, pipeline);
priv->renderer->setup_pipeline (sink, pipeline);
}
}