forked from AuroraMiddleware/gtk
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:
parent
5f41d26abc
commit
18ea60e235
@ -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,
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user