diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2020-12-27 18:24:26 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2020-12-27 19:33:55 +0200 |
commit | 18ea60e2354e50fa4f9da6c83103318f47a47d1e (patch) | |
tree | 5ad0424e8e8f77192ba3b78b155c2ba4d8c5ea04 | |
parent | 5f41d26abc24cddd80794ad5df9f3b5253124fb2 (diff) | |
download | gtk+-18ea60e2354e50fa4f9da6c83103318f47a47d1e.tar.gz |
gtkmediafile: Consider pixel-aspect-ratio for rendering video with the correct aspect ratio
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/3516
-rw-r--r-- | modules/media/gtkgstpaintable.c | 24 | ||||
-rw-r--r-- | modules/media/gtkgstpaintableprivate.h | 3 | ||||
-rw-r--r-- | modules/media/gtkgstsink.c | 10 | ||||
-rw-r--r-- | 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, ) |