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
This commit is contained in:
Gwenole Beauchesne 2014-10-23 11:56:31 +02:00
parent 48fabae3ec
commit 0a108653f2
5 changed files with 23 additions and 11 deletions

View file

@ -468,7 +468,7 @@ gst_vaapi_texture_get_size (GstVaapiTexture * texture,
*/ */
static gboolean static gboolean
_gst_vaapi_texture_put_surface (GstVaapiTexture * texture, _gst_vaapi_texture_put_surface (GstVaapiTexture * texture,
GstVaapiSurface * surface, guint flags) GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
{ {
VAStatus status; VAStatus status;
@ -482,17 +482,22 @@ _gst_vaapi_texture_put_surface (GstVaapiTexture * texture,
if (!vaapi_check_status (status, "vaCopySurfaceGLX()")) if (!vaapi_check_status (status, "vaCopySurfaceGLX()"))
return FALSE; return FALSE;
#else #else
guint surface_width, surface_height; GstVaapiRectangle rect;
GLContextState old_cs; GLContextState old_cs;
gboolean success = FALSE; 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); GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture), status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture),
GST_VAAPI_OBJECT_ID (surface), GST_VAAPI_OBJECT_ID (surface),
texture->pixo->pixmap, 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, 0, 0, texture->width, texture->height,
NULL, 0, from_GstVaapiSurfaceRenderFlags (flags) NULL, 0, from_GstVaapiSurfaceRenderFlags (flags)
); );
@ -562,10 +567,10 @@ end:
gboolean gboolean
gst_vaapi_texture_put_surface (GstVaapiTexture * texture, 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 (texture != NULL, FALSE);
g_return_val_if_fail (surface != 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);
} }

View file

@ -74,7 +74,8 @@ gst_vaapi_texture_get_size (GstVaapiTexture * texture, guint * width_ptr,
gboolean gboolean
gst_vaapi_texture_put_surface (GstVaapiTexture * texture, gst_vaapi_texture_put_surface (GstVaapiTexture * texture,
GstVaapiSurface * surface, guint flags); GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect,
guint flags);
G_END_DECLS G_END_DECLS

View file

@ -137,7 +137,9 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter * self,
GstVaapiVideoConverterGLXPrivate *const priv = GstVaapiVideoConverterGLXPrivate *const priv =
GST_VAAPI_VIDEO_CONVERTER_GLX (self)->priv; GST_VAAPI_VIDEO_CONVERTER_GLX (self)->priv;
GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer); 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; GstVaapiDisplay *new_dpy, *old_dpy;
new_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); 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"); GST_WARNING ("could not update subtitles");
return gst_vaapi_texture_put_surface (priv->texture, surface, 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)); gst_vaapi_video_meta_get_render_flags (meta));
} }

View file

@ -80,7 +80,9 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta,
GstVaapiVideoMeta *const vmeta = GstVaapiVideoMeta *const vmeta =
gst_buffer_get_vaapi_video_meta (meta->buffer); gst_buffer_get_vaapi_video_meta (meta->buffer);
GstVaapiVideoMetaTexture *const meta_texture = meta->user_data; 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); GstVaapiDisplay *const dpy = GST_VAAPI_OBJECT_DISPLAY (surface);
if (gst_vaapi_display_get_display_type (dpy) != GST_VAAPI_DISPLAY_TYPE_GLX) 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); gst_vaapi_texture_unref (texture);
} }
return gst_vaapi_texture_put_surface (meta_texture->texture, surface, 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)); gst_vaapi_video_meta_get_render_flags (vmeta));
} }

View file

@ -105,7 +105,7 @@ main(int argc, char *argv[])
textures[0] = texture; textures[0] = texture;
texture_id = gst_vaapi_texture_get_id(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"); g_error("could not transfer VA surface to texture");
if (!gst_vaapi_window_glx_put_texture(glx_window, texture, NULL, NULL)) if (!gst_vaapi_window_glx_put_texture(glx_window, texture, NULL, NULL))
@ -156,7 +156,7 @@ main(int argc, char *argv[])
textures[1] = texture; 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"); g_error("could not transfer VA surface to texture");
if (gl_get_current_texture_2d() != texture_id) if (gl_get_current_texture_2d() != texture_id)