From 0a108653f2f78d7c25e3d20226cad0990d211f7e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Oct 2014 11:56:31 +0200 Subject: [PATCH] texture: add support for cropping rectangle during transfer. The gst_vaapi_texture_put_surface() function is missing a crop_rect argument that would be used during transfer for cropping the source surface to the desired dimensions. Note: from a user point-of-view, he should create the GstVaapiTexture object with the cropped size. That's the default behaviour in software decoding pipelines that we need to cope with. This is an API/ABI change, and SONAME version needs to be bumped. https://bugzilla.gnome.org/show_bug.cgi?id=736712 --- gst-libs/gst/vaapi/gstvaapitexture.c | 17 +++++++++++------ gst-libs/gst/vaapi/gstvaapitexture.h | 3 ++- gst/vaapi/gstvaapivideoconverter_glx.c | 5 ++++- gst/vaapi/gstvaapivideometa_texture.c | 5 ++++- tests/test-textures.c | 4 ++-- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 68747528bd..0ccc0579bb 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -468,7 +468,7 @@ gst_vaapi_texture_get_size (GstVaapiTexture * texture, */ static gboolean _gst_vaapi_texture_put_surface (GstVaapiTexture * texture, - GstVaapiSurface * surface, guint flags) + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) { VAStatus status; @@ -482,17 +482,22 @@ _gst_vaapi_texture_put_surface (GstVaapiTexture * texture, if (!vaapi_check_status (status, "vaCopySurfaceGLX()")) return FALSE; #else - guint surface_width, surface_height; + GstVaapiRectangle rect; GLContextState old_cs; gboolean success = FALSE; - gst_vaapi_surface_get_size (surface, &surface_width, &surface_height); + if (!crop_rect) { + rect.x = 0; + rect.y = 0; + gst_vaapi_surface_get_size (surface, &rect.width, &rect.height); + crop_rect = ▭ + } GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture), GST_VAAPI_OBJECT_ID (surface), texture->pixo->pixmap, - 0, 0, surface_width, surface_height, + crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height, 0, 0, texture->width, texture->height, NULL, 0, from_GstVaapiSurfaceRenderFlags (flags) ); @@ -562,10 +567,10 @@ end: gboolean gst_vaapi_texture_put_surface (GstVaapiTexture * texture, - GstVaapiSurface * surface, guint flags) + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) { g_return_val_if_fail (texture != NULL, FALSE); g_return_val_if_fail (surface != NULL, FALSE); - return _gst_vaapi_texture_put_surface (texture, surface, flags); + return _gst_vaapi_texture_put_surface (texture, surface, crop_rect, flags); } diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index 2c6a8f0b7f..5ae71c201a 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -74,7 +74,8 @@ gst_vaapi_texture_get_size (GstVaapiTexture * texture, guint * width_ptr, gboolean gst_vaapi_texture_put_surface (GstVaapiTexture * texture, - GstVaapiSurface * surface, guint flags); + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, + guint flags); G_END_DECLS diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c index 162bf6fcf5..06ca7c5f64 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst/vaapi/gstvaapivideoconverter_glx.c @@ -137,7 +137,9 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter * self, GstVaapiVideoConverterGLXPrivate *const priv = GST_VAAPI_VIDEO_CONVERTER_GLX (self)->priv; GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer); - GstVaapiSurface *const surface = gst_vaapi_video_meta_get_surface (meta); + GstVaapiSurfaceProxy *const proxy = + gst_vaapi_video_meta_get_surface_proxy (meta); + GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy); GstVaapiDisplay *new_dpy, *old_dpy; new_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); @@ -155,5 +157,6 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter * self, GST_WARNING ("could not update subtitles"); return gst_vaapi_texture_put_surface (priv->texture, surface, + gst_vaapi_surface_proxy_get_crop_rect (proxy), gst_vaapi_video_meta_get_render_flags (meta)); } diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 5a1a824ffc..429a8b3303 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -80,7 +80,9 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, GstVaapiVideoMeta *const vmeta = gst_buffer_get_vaapi_video_meta (meta->buffer); GstVaapiVideoMetaTexture *const meta_texture = meta->user_data; - GstVaapiSurface *const surface = gst_vaapi_video_meta_get_surface (vmeta); + GstVaapiSurfaceProxy *const proxy = + gst_vaapi_video_meta_get_surface_proxy (vmeta); + GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy); GstVaapiDisplay *const dpy = GST_VAAPI_OBJECT_DISPLAY (surface); if (gst_vaapi_display_get_display_type (dpy) != GST_VAAPI_DISPLAY_TYPE_GLX) @@ -101,6 +103,7 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, gst_vaapi_texture_unref (texture); } return gst_vaapi_texture_put_surface (meta_texture->texture, surface, + gst_vaapi_surface_proxy_get_crop_rect (proxy), gst_vaapi_video_meta_get_render_flags (vmeta)); } diff --git a/tests/test-textures.c b/tests/test-textures.c index 9e608601a5..c4673adedd 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -105,7 +105,7 @@ main(int argc, char *argv[]) textures[0] = texture; texture_id = gst_vaapi_texture_get_id(texture); - if (!gst_vaapi_texture_put_surface(texture, surface, flags)) + if (!gst_vaapi_texture_put_surface(texture, surface, NULL, flags)) g_error("could not transfer VA surface to texture"); if (!gst_vaapi_window_glx_put_texture(glx_window, texture, NULL, NULL)) @@ -156,7 +156,7 @@ main(int argc, char *argv[]) textures[1] = texture; - if (!gst_vaapi_texture_put_surface(texture, surface, flags)) + if (!gst_vaapi_texture_put_surface(texture, surface, NULL, flags)) g_error("could not transfer VA surface to texture"); if (gl_get_current_texture_2d() != texture_id)