mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-11 13:10:07 +00:00
gstreamer: Pass viewport along
Obtain the viewport from gstreamer, and pass it to the paintable implemenation, which adds a clip node around the texture to enforce the viewport.
This commit is contained in:
parent
1db696be79
commit
d91d0f1c0a
@ -24,6 +24,7 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gst/player/gstplayer-video-renderer.h>
|
||||
#include <graphene.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@ -33,6 +34,7 @@ struct _GtkGstPaintable
|
||||
|
||||
GdkPaintable *image;
|
||||
double pixel_aspect_ratio;
|
||||
graphene_rect_t viewport;
|
||||
|
||||
GdkGLContext *context;
|
||||
};
|
||||
@ -51,7 +53,24 @@ gtk_gst_paintable_paintable_snapshot (GdkPaintable *paintable,
|
||||
GtkGstPaintable *self = GTK_GST_PAINTABLE (paintable);
|
||||
|
||||
if (self->image)
|
||||
gdk_paintable_snapshot (self->image, snapshot, width, height);
|
||||
{
|
||||
float sx, sy;
|
||||
|
||||
gtk_snapshot_save (snapshot);
|
||||
|
||||
sx = gdk_paintable_get_intrinsic_width (self->image) / self->viewport.size.width;
|
||||
sy = gdk_paintable_get_intrinsic_height (self->image) / self->viewport.size.height;
|
||||
|
||||
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (-self->viewport.origin.x * width / self->viewport.size.width,
|
||||
-self->viewport.origin.y * height / self->viewport.size.height));
|
||||
|
||||
gdk_paintable_snapshot (self->image, snapshot, width * sx, height * sy);
|
||||
|
||||
gtk_snapshot_pop (snapshot);
|
||||
gtk_snapshot_restore (snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
@ -71,8 +90,7 @@ gtk_gst_paintable_paintable_get_intrinsic_width (GdkPaintable *paintable)
|
||||
GtkGstPaintable *self = GTK_GST_PAINTABLE (paintable);
|
||||
|
||||
if (self->image)
|
||||
return round (self->pixel_aspect_ratio *
|
||||
gdk_paintable_get_intrinsic_width (self->image));
|
||||
return round (self->pixel_aspect_ratio * self->viewport.size.width);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -83,7 +101,7 @@ gtk_gst_paintable_paintable_get_intrinsic_height (GdkPaintable *paintable)
|
||||
GtkGstPaintable *self = GTK_GST_PAINTABLE (paintable);
|
||||
|
||||
if (self->image)
|
||||
return gdk_paintable_get_intrinsic_height (self->image);
|
||||
return ceil (self->viewport.size.height);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -94,8 +112,7 @@ gtk_gst_paintable_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
|
||||
GtkGstPaintable *self = GTK_GST_PAINTABLE (paintable);
|
||||
|
||||
if (self->image)
|
||||
return self->pixel_aspect_ratio *
|
||||
gdk_paintable_get_intrinsic_aspect_ratio (self->image);
|
||||
return self->viewport.size.width / self->viewport.size.height;
|
||||
|
||||
return 0.0;
|
||||
};
|
||||
@ -237,9 +254,10 @@ gtk_gst_paintable_unrealize (GtkGstPaintable *self,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gst_paintable_set_paintable (GtkGstPaintable *self,
|
||||
GdkPaintable *paintable,
|
||||
double pixel_aspect_ratio)
|
||||
gtk_gst_paintable_set_paintable (GtkGstPaintable *self,
|
||||
GdkPaintable *paintable,
|
||||
double pixel_aspect_ratio,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
gboolean size_changed;
|
||||
|
||||
@ -250,13 +268,15 @@ gtk_gst_paintable_set_paintable (GtkGstPaintable *self,
|
||||
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))
|
||||
gdk_paintable_get_intrinsic_aspect_ratio (self->image) != gdk_paintable_get_intrinsic_aspect_ratio (paintable) ||
|
||||
!graphene_rect_equal (viewport, &self->viewport))
|
||||
size_changed = TRUE;
|
||||
else
|
||||
size_changed = FALSE;
|
||||
|
||||
g_set_object (&self->image, paintable);
|
||||
self->pixel_aspect_ratio = pixel_aspect_ratio;
|
||||
self->viewport = *viewport;
|
||||
|
||||
if (size_changed)
|
||||
gdk_paintable_invalidate_size (GDK_PAINTABLE (self));
|
||||
@ -270,6 +290,7 @@ struct _SetTextureInvocation {
|
||||
GtkGstPaintable *paintable;
|
||||
GdkTexture *texture;
|
||||
double pixel_aspect_ratio;
|
||||
graphene_rect_t viewport;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -288,15 +309,17 @@ gtk_gst_paintable_set_texture_invoke (gpointer data)
|
||||
|
||||
gtk_gst_paintable_set_paintable (invoke->paintable,
|
||||
GDK_PAINTABLE (invoke->texture),
|
||||
invoke->pixel_aspect_ratio);
|
||||
invoke->pixel_aspect_ratio,
|
||||
&invoke->viewport);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_gst_paintable_queue_set_texture (GtkGstPaintable *self,
|
||||
GdkTexture *texture,
|
||||
double pixel_aspect_ratio)
|
||||
gtk_gst_paintable_queue_set_texture (GtkGstPaintable *self,
|
||||
GdkTexture *texture,
|
||||
double pixel_aspect_ratio,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
SetTextureInvocation *invoke;
|
||||
|
||||
@ -304,6 +327,7 @@ gtk_gst_paintable_queue_set_texture (GtkGstPaintable *self,
|
||||
invoke->paintable = g_object_ref (self);
|
||||
invoke->texture = g_object_ref (texture);
|
||||
invoke->pixel_aspect_ratio = pixel_aspect_ratio;
|
||||
invoke->viewport = *viewport;
|
||||
|
||||
g_main_context_invoke_full (NULL,
|
||||
G_PRIORITY_DEFAULT,
|
||||
|
@ -20,6 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -35,6 +36,7 @@ void gtk_gst_paintable_unrealize (GtkGstPaintable
|
||||
GdkSurface *surface);
|
||||
void gtk_gst_paintable_queue_set_texture (GtkGstPaintable *self,
|
||||
GdkTexture *texture,
|
||||
double pixel_aspect_ratio);
|
||||
double pixel_aspect_ratio,
|
||||
const graphene_rect_t *viewport);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -358,13 +358,19 @@ video_frame_free (GstVideoFrame *frame)
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
|
||||
GstBuffer *buffer,
|
||||
double *pixel_aspect_ratio)
|
||||
gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
|
||||
GstBuffer *buffer,
|
||||
double *pixel_aspect_ratio,
|
||||
graphene_rect_t *viewport)
|
||||
{
|
||||
GstVideoFrame *frame = g_new (GstVideoFrame, 1);
|
||||
GdkTexture *texture;
|
||||
|
||||
viewport->origin.x = 0;
|
||||
viewport->origin.y = 0;
|
||||
viewport->size.width = GST_VIDEO_INFO_WIDTH (&self->v_info);
|
||||
viewport->size.height = GST_VIDEO_INFO_HEIGHT (&self->v_info);
|
||||
|
||||
#ifdef HAVE_GSTREAMER_DRM
|
||||
if (gst_is_dmabuf_memory (gst_buffer_peek_memory (buffer, 0)))
|
||||
{
|
||||
@ -384,9 +390,8 @@ gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
|
||||
gdk_dmabuf_texture_builder_set_display (builder, gdk_gl_context_get_display (self->gdk_context));
|
||||
gdk_dmabuf_texture_builder_set_fourcc (builder, self->drm_info.drm_fourcc);
|
||||
gdk_dmabuf_texture_builder_set_modifier (builder, self->drm_info.drm_modifier);
|
||||
// Padded width/height is set into the vmeta, perhaps we should import using these ?
|
||||
gdk_dmabuf_texture_builder_set_width (builder, GST_VIDEO_INFO_WIDTH (&self->v_info));
|
||||
gdk_dmabuf_texture_builder_set_height (builder, GST_VIDEO_INFO_HEIGHT (&self->v_info));
|
||||
gdk_dmabuf_texture_builder_set_width (builder, vmeta->width);
|
||||
gdk_dmabuf_texture_builder_set_height (builder, vmeta->height);
|
||||
gdk_dmabuf_texture_builder_set_n_planes (builder, vmeta->n_planes);
|
||||
|
||||
for (i = 0; i < vmeta->n_planes; i++)
|
||||
@ -491,6 +496,7 @@ gtk_gst_sink_show_frame (GstVideoSink *vsink,
|
||||
GtkGstSink *self;
|
||||
GdkTexture *texture;
|
||||
double pixel_aspect_ratio;
|
||||
graphene_rect_t viewport;
|
||||
|
||||
GST_TRACE ("rendering buffer:%p", buf);
|
||||
|
||||
@ -498,10 +504,10 @@ gtk_gst_sink_show_frame (GstVideoSink *vsink,
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
|
||||
texture = gtk_gst_sink_texture_from_buffer (self, buf, &pixel_aspect_ratio);
|
||||
texture = gtk_gst_sink_texture_from_buffer (self, buf, &pixel_aspect_ratio, &viewport);
|
||||
if (texture)
|
||||
{
|
||||
gtk_gst_paintable_queue_set_texture (self->paintable, texture, pixel_aspect_ratio);
|
||||
gtk_gst_paintable_queue_set_texture (self->paintable, texture, pixel_aspect_ratio, &viewport);
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user