diff options
author | Lionel Landwerlin <llandwerlin@gmail.com> | 2015-10-09 02:46:25 +0100 |
---|---|---|
committer | Lionel Landwerlin <llandwerlin@gmail.com> | 2015-10-09 02:46:31 +0100 |
commit | f4c48c4e50b4406e0e6949a7d97650c295ec9cb2 (patch) | |
tree | 9dd3e5fe80d3bb81ee33de4e04924bd3399409ab | |
parent | 8dfdcfa10874702040d0fe7b37021d77960eecd9 (diff) | |
download | clutter-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.c | 29 |
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); } } |