summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2020-12-27 18:24:26 +0200
committerSebastian Dröge <sebastian@centricular.com>2020-12-27 19:33:55 +0200
commit18ea60e2354e50fa4f9da6c83103318f47a47d1e (patch)
tree5ad0424e8e8f77192ba3b78b155c2ba4d8c5ea04
parent5f41d26abc24cddd80794ad5df9f3b5253124fb2 (diff)
downloadgtk+-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.c24
-rw-r--r--modules/media/gtkgstpaintableprivate.h3
-rw-r--r--modules/media/gtkgstsink.c10
-rw-r--r--modules/media/meson.build2
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,
)