[gtk: 1/2] gtkmediafile: Consider pixel-aspect-ratio for rendering video with the correct aspect ratio




commit 18ea60e2354e50fa4f9da6c83103318f47a47d1e
Author: Sebastian Dröge <sebastian centricular com>
Date:   Sun Dec 27 18:24:26 2020 +0200

    gtkmediafile: Consider pixel-aspect-ratio for rendering video with the correct aspect ratio
    
    Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/3516

 modules/media/gtkgstpaintable.c        | 24 ++++++++++++++++++------
 modules/media/gtkgstpaintableprivate.h |  3 ++-
 modules/media/gtkgstsink.c             | 10 +++++++---
 modules/media/meson.build              |  2 +-
 4 files changed, 28 insertions(+), 11 deletions(-)
---
diff --git a/modules/media/gtkgstpaintable.c b/modules/media/gtkgstpaintable.c
index 838b688db5..8b9c3e5f43 100644
--- a/modules/media/gtkgstpaintable.c
+++ b/modules/media/gtkgstpaintable.c
@@ -25,11 +25,14 @@
 
 #include <gst/player/gstplayer-video-renderer.h>
 
+#include <math.h>
+
 struct _GtkGstPaintable
 {
   GObject parent_instance;
 
   GdkPaintable *image;
+  double pixel_aspect_ratio;
 };
 
 struct _GtkGstPaintableClass
@@ -66,7 +69,8 @@ gtk_gst_paintable_paintable_get_intrinsic_width (GdkPaintable *paintable)
   GtkGstPaintable *self = GTK_GST_PAINTABLE (paintable);
 
   if (self->image)
-    return gdk_paintable_get_intrinsic_width (self->image);
+    return round (self->pixel_aspect_ratio *
+      gdk_paintable_get_intrinsic_width (self->image));
 
   return 0;
 }
@@ -88,7 +92,8 @@ gtk_gst_paintable_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
   GtkGstPaintable *self = GTK_GST_PAINTABLE (paintable);
 
   if (self->image)
-    return gdk_paintable_get_intrinsic_aspect_ratio (self->image);
+    return self->pixel_aspect_ratio *
+      gdk_paintable_get_intrinsic_aspect_ratio (self->image);
 
   return 0.0;
 };
@@ -157,7 +162,8 @@ gtk_gst_paintable_new (void)
 
 static void
 gtk_gst_paintable_set_paintable (GtkGstPaintable *self,
-                                 GdkPaintable    *paintable)
+                                 GdkPaintable    *paintable,
+                                 double           pixel_aspect_ratio)
 {
   gboolean size_changed;
 
@@ -165,7 +171,8 @@ gtk_gst_paintable_set_paintable (GtkGstPaintable *self,
     return;
 
   if (self->image == NULL ||
-      gdk_paintable_get_intrinsic_width (self->image) != gdk_paintable_get_intrinsic_width (paintable) ||
+      self->pixel_aspect_ratio * gdk_paintable_get_intrinsic_width (self->image) !=
+      pixel_aspect_ratio * gdk_paintable_get_intrinsic_width (paintable) ||
       gdk_paintable_get_intrinsic_height (self->image) != gdk_paintable_get_intrinsic_height (paintable) ||
       gdk_paintable_get_intrinsic_aspect_ratio (self->image) != gdk_paintable_get_intrinsic_aspect_ratio 
(paintable))
     size_changed = TRUE;
@@ -173,6 +180,7 @@ gtk_gst_paintable_set_paintable (GtkGstPaintable *self,
     size_changed = FALSE;
 
   g_set_object (&self->image, paintable);
+  self->pixel_aspect_ratio = pixel_aspect_ratio;
 
   if (size_changed)
     gdk_paintable_invalidate_size (GDK_PAINTABLE (self));
@@ -185,6 +193,7 @@ typedef struct _SetTextureInvocation SetTextureInvocation;
 struct _SetTextureInvocation {
   GtkGstPaintable *paintable;
   GdkTexture      *texture;
+  double           pixel_aspect_ratio;
 };
 
 static void
@@ -202,20 +211,23 @@ gtk_gst_paintable_set_texture_invoke (gpointer data)
   SetTextureInvocation *invoke = data;
 
   gtk_gst_paintable_set_paintable (invoke->paintable,
-                                   GDK_PAINTABLE (invoke->texture));
+                                   GDK_PAINTABLE (invoke->texture),
+                                   invoke->pixel_aspect_ratio);
 
   return G_SOURCE_REMOVE;
 }
 
 void
 gtk_gst_paintable_queue_set_texture (GtkGstPaintable *self,
-                                     GdkTexture      *texture)
+                                     GdkTexture      *texture,
+                                     double           pixel_aspect_ratio)
 {
   SetTextureInvocation *invoke;
 
   invoke = g_slice_new0 (SetTextureInvocation);
   invoke->paintable = g_object_ref (self);
   invoke->texture = g_object_ref (texture);
+  invoke->pixel_aspect_ratio = pixel_aspect_ratio;
 
   g_main_context_invoke_full (NULL,
                               G_PRIORITY_DEFAULT,
diff --git a/modules/media/gtkgstpaintableprivate.h b/modules/media/gtkgstpaintableprivate.h
index 7fc2620f9b..b914346cf3 100644
--- a/modules/media/gtkgstpaintableprivate.h
+++ b/modules/media/gtkgstpaintableprivate.h
@@ -31,7 +31,8 @@ G_DECLARE_FINAL_TYPE (GtkGstPaintable, gtk_gst_paintable, GTK, GST_PAINTABLE, GO
 GdkPaintable *  gtk_gst_paintable_new                   (void);
 
 void            gtk_gst_paintable_queue_set_texture     (GtkGstPaintable        *self,
-                                                         GdkTexture             *texture);
+                                                         GdkTexture             *texture,
+                                                         double                  pixel_aspect_ratio);
 
 G_END_DECLS
 
diff --git a/modules/media/gtkgstsink.c b/modules/media/gtkgstsink.c
index e923ea88d6..8d50ef403f 100644
--- a/modules/media/gtkgstsink.c
+++ b/modules/media/gtkgstsink.c
@@ -120,7 +120,8 @@ video_frame_free (GstVideoFrame *frame)
 
 static GdkTexture *
 gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
-                                  GstBuffer  *buffer)
+                                  GstBuffer  *buffer,
+                                  double     *pixel_aspect_ratio)
 {
   GstVideoFrame frame;
   GdkTexture *texture;
@@ -140,6 +141,8 @@ gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
                                     frame.info.stride[0]);
   g_bytes_unref (bytes);
 
+  *pixel_aspect_ratio = ((double) frame.info.par_n) / ((double) frame.info.par_d);
+
   return texture;
 }
 
@@ -148,6 +151,7 @@ gtk_gst_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
 {
   GtkGstSink *self;
   GdkTexture *texture;
+  double pixel_aspect_ratio;
 
   GST_TRACE ("rendering buffer:%p", buf);
 
@@ -155,10 +159,10 @@ gtk_gst_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
 
   GST_OBJECT_LOCK (self);
 
-  texture = gtk_gst_sink_texture_from_buffer (self, buf);
+  texture = gtk_gst_sink_texture_from_buffer (self, buf, &pixel_aspect_ratio);
   if (texture)
     {
-      gtk_gst_paintable_queue_set_texture (self->paintable, texture);
+      gtk_gst_paintable_queue_set_texture (self->paintable, texture, pixel_aspect_ratio);
       g_object_unref (texture);
     }
 
diff --git a/modules/media/meson.build b/modules/media/meson.build
index 41d6b04d80..42b3c48e4f 100644
--- a/modules/media/meson.build
+++ b/modules/media/meson.build
@@ -52,7 +52,7 @@ if gstplayer_dep.found()
       'gtkgstsink.c',
     ],
     c_args: extra_c_args,
-    dependencies: [ libgtk_dep, gstplayer_dep ],
+    dependencies: [ libm, libgtk_dep, gstplayer_dep ],
     install_dir: media_install_dir,
     install: true,
   )


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