[clutter-gst/clutter-gst-3.0] video-sink: deal with cropped videos



commit f4c48c4e50b4406e0e6949a7d97650c295ec9cb2
Author: Lionel Landwerlin <llandwerlin gmail com>
Date:   Fri Oct 9 02:46:25 2015 +0100

    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.

 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);
     }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]