texture: add support for cropping rectangle during transfer.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Thu, 23 Oct 2014 09:56:31 +0000 (11:56 +0200)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Tue, 27 Jan 2015 17:11:44 +0000 (18:11 +0100)
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
gst-libs/gst/vaapi/gstvaapitexture.h
gst/vaapi/gstvaapivideoconverter_glx.c
gst/vaapi/gstvaapivideometa_texture.c
tests/test-textures.c

index 6874752..0ccc057 100644 (file)
@@ -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 = &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);
 }
index 2c6a8f0..5ae71c2 100644 (file)
@@ -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
 
index 162bf6f..06ca7c5 100644 (file)
@@ -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));
 }
index 5a1a824..429a8b3 100644 (file)
@@ -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));
 }
 
index 9e60860..c4673ad 100644 (file)
@@ -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)