gtkmediafile: Consider pixel-aspect-ratio for rendering video with the correct aspect ratio

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/3516
This commit is contained in:
Sebastian Dröge 2020-12-27 18:24:26 +02:00
parent 5f41d26abc
commit 18ea60e235
4 changed files with 28 additions and 11 deletions

View File

@ -25,11 +25,14 @@
#include <gst/player/gstplayer-video-renderer.h> #include <gst/player/gstplayer-video-renderer.h>
#include <math.h>
struct _GtkGstPaintable struct _GtkGstPaintable
{ {
GObject parent_instance; GObject parent_instance;
GdkPaintable *image; GdkPaintable *image;
double pixel_aspect_ratio;
}; };
struct _GtkGstPaintableClass struct _GtkGstPaintableClass
@ -66,7 +69,8 @@ gtk_gst_paintable_paintable_get_intrinsic_width (GdkPaintable *paintable)
GtkGstPaintable *self = GTK_GST_PAINTABLE (paintable); GtkGstPaintable *self = GTK_GST_PAINTABLE (paintable);
if (self->image) 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; return 0;
} }
@ -88,7 +92,8 @@ gtk_gst_paintable_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
GtkGstPaintable *self = GTK_GST_PAINTABLE (paintable); GtkGstPaintable *self = GTK_GST_PAINTABLE (paintable);
if (self->image) 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; return 0.0;
}; };
@ -157,7 +162,8 @@ gtk_gst_paintable_new (void)
static void static void
gtk_gst_paintable_set_paintable (GtkGstPaintable *self, gtk_gst_paintable_set_paintable (GtkGstPaintable *self,
GdkPaintable *paintable) GdkPaintable *paintable,
double pixel_aspect_ratio)
{ {
gboolean size_changed; gboolean size_changed;
@ -165,7 +171,8 @@ gtk_gst_paintable_set_paintable (GtkGstPaintable *self,
return; return;
if (self->image == NULL || 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_height (self->image) != gdk_paintable_get_intrinsic_height (paintable) ||
gdk_paintable_get_intrinsic_aspect_ratio (self->image) != gdk_paintable_get_intrinsic_aspect_ratio (paintable)) gdk_paintable_get_intrinsic_aspect_ratio (self->image) != gdk_paintable_get_intrinsic_aspect_ratio (paintable))
size_changed = TRUE; size_changed = TRUE;
@ -173,6 +180,7 @@ gtk_gst_paintable_set_paintable (GtkGstPaintable *self,
size_changed = FALSE; size_changed = FALSE;
g_set_object (&self->image, paintable); g_set_object (&self->image, paintable);
self->pixel_aspect_ratio = pixel_aspect_ratio;
if (size_changed) if (size_changed)
gdk_paintable_invalidate_size (GDK_PAINTABLE (self)); gdk_paintable_invalidate_size (GDK_PAINTABLE (self));
@ -185,6 +193,7 @@ typedef struct _SetTextureInvocation SetTextureInvocation;
struct _SetTextureInvocation { struct _SetTextureInvocation {
GtkGstPaintable *paintable; GtkGstPaintable *paintable;
GdkTexture *texture; GdkTexture *texture;
double pixel_aspect_ratio;
}; };
static void static void
@ -202,20 +211,23 @@ gtk_gst_paintable_set_texture_invoke (gpointer data)
SetTextureInvocation *invoke = data; SetTextureInvocation *invoke = data;
gtk_gst_paintable_set_paintable (invoke->paintable, gtk_gst_paintable_set_paintable (invoke->paintable,
GDK_PAINTABLE (invoke->texture)); GDK_PAINTABLE (invoke->texture),
invoke->pixel_aspect_ratio);
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
void void
gtk_gst_paintable_queue_set_texture (GtkGstPaintable *self, gtk_gst_paintable_queue_set_texture (GtkGstPaintable *self,
GdkTexture *texture) GdkTexture *texture,
double pixel_aspect_ratio)
{ {
SetTextureInvocation *invoke; SetTextureInvocation *invoke;
invoke = g_slice_new0 (SetTextureInvocation); invoke = g_slice_new0 (SetTextureInvocation);
invoke->paintable = g_object_ref (self); invoke->paintable = g_object_ref (self);
invoke->texture = g_object_ref (texture); invoke->texture = g_object_ref (texture);
invoke->pixel_aspect_ratio = pixel_aspect_ratio;
g_main_context_invoke_full (NULL, g_main_context_invoke_full (NULL,
G_PRIORITY_DEFAULT, G_PRIORITY_DEFAULT,

View File

@ -31,7 +31,8 @@ G_DECLARE_FINAL_TYPE (GtkGstPaintable, gtk_gst_paintable, GTK, GST_PAINTABLE, GO
GdkPaintable * gtk_gst_paintable_new (void); GdkPaintable * gtk_gst_paintable_new (void);
void gtk_gst_paintable_queue_set_texture (GtkGstPaintable *self, void gtk_gst_paintable_queue_set_texture (GtkGstPaintable *self,
GdkTexture *texture); GdkTexture *texture,
double pixel_aspect_ratio);
G_END_DECLS G_END_DECLS

View File

@ -120,7 +120,8 @@ video_frame_free (GstVideoFrame *frame)
static GdkTexture * static GdkTexture *
gtk_gst_sink_texture_from_buffer (GtkGstSink *self, gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
GstBuffer *buffer) GstBuffer *buffer,
double *pixel_aspect_ratio)
{ {
GstVideoFrame frame; GstVideoFrame frame;
GdkTexture *texture; GdkTexture *texture;
@ -140,6 +141,8 @@ gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
frame.info.stride[0]); frame.info.stride[0]);
g_bytes_unref (bytes); g_bytes_unref (bytes);
*pixel_aspect_ratio = ((double) frame.info.par_n) / ((double) frame.info.par_d);
return texture; return texture;
} }
@ -148,6 +151,7 @@ gtk_gst_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
{ {
GtkGstSink *self; GtkGstSink *self;
GdkTexture *texture; GdkTexture *texture;
double pixel_aspect_ratio;
GST_TRACE ("rendering buffer:%p", buf); GST_TRACE ("rendering buffer:%p", buf);
@ -155,10 +159,10 @@ gtk_gst_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
GST_OBJECT_LOCK (self); 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) 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); g_object_unref (texture);
} }

View File

@ -52,7 +52,7 @@ if gstplayer_dep.found()
'gtkgstsink.c', 'gtkgstsink.c',
], ],
c_args: extra_c_args, c_args: extra_c_args,
dependencies: [ libgtk_dep, gstplayer_dep ], dependencies: [ libm, libgtk_dep, gstplayer_dep ],
install_dir: media_install_dir, install_dir: media_install_dir,
install: true, install: true,
) )