From 7233c5a2ae053e0018661b9dbf3192ccedb5e848 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Sat, 11 May 2019 18:06:02 -0400 Subject: [PATCH] image: Partially implement vaGetImage This enables raw playback within GStreamer. This is useful for testing even if slower then DMABuf. This is a partial implementation since we don't implement partial copy of the surface. Signed-off-by: Nicolas Dufresne --- src/image.c | 79 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 24 deletions(-) diff --git a/src/image.c b/src/image.c index ed21de3..ec2a0c1 100644 --- a/src/image.c +++ b/src/image.c @@ -143,32 +143,12 @@ VAStatus RequestDestroyImage(VADriverContextP context, VAImageID image_id) return VA_STATUS_SUCCESS; } -VAStatus RequestDeriveImage(VADriverContextP context, VASurfaceID surface_id, - VAImage *image) +static VAStatus copy_surface_to_image (struct request_data *driver_data, + struct object_surface *surface_object, + VAImage *image) { - struct request_data *driver_data = context->pDriverData; - struct object_surface *surface_object; struct object_buffer *buffer_object; - VAImageFormat format; unsigned int i; - VAStatus status; - - surface_object = SURFACE(driver_data, surface_id); - if (surface_object == NULL) - return VA_STATUS_ERROR_INVALID_SURFACE; - - if (surface_object->status == VASurfaceRendering) { - status = RequestSyncSurface(context, surface_id); - if (status != VA_STATUS_SUCCESS) - return status; - } - - format.fourcc = VA_FOURCC_NV12; - - status = RequestCreateImage(context, &format, surface_object->width, - surface_object->height, image); - if (status != VA_STATUS_SUCCESS) - return status; buffer_object = BUFFER(driver_data, image->buf); if (buffer_object == NULL) @@ -188,8 +168,42 @@ VAStatus RequestDeriveImage(VADriverContextP context, VASurfaceID surface_id, } } + return VA_STATUS_SUCCESS; +} + +VAStatus RequestDeriveImage(VADriverContextP context, VASurfaceID surface_id, + VAImage *image) +{ + struct request_data *driver_data = context->pDriverData; + struct object_surface *surface_object; + struct object_buffer *buffer_object; + VAImageFormat format; + VAStatus status; + + surface_object = SURFACE(driver_data, surface_id); + if (surface_object == NULL) + return VA_STATUS_ERROR_INVALID_SURFACE; + + if (surface_object->status == VASurfaceRendering) { + status = RequestSyncSurface(context, surface_id); + if (status != VA_STATUS_SUCCESS) + return status; + } + + format.fourcc = VA_FOURCC_NV12; + + status = RequestCreateImage(context, &format, surface_object->width, + surface_object->height, image); + if (status != VA_STATUS_SUCCESS) + return status; + + status = copy_surface_to_image (driver_data, surface_object, image); + if (status != VA_STATUS_SUCCESS) + return status; + surface_object->status = VASurfaceReady; + buffer_object = BUFFER(driver_data, image->buf); buffer_object->derived_surface_id = surface_id; return VA_STATUS_SUCCESS; @@ -214,7 +228,24 @@ VAStatus RequestGetImage(VADriverContextP context, VASurfaceID surface_id, int x, int y, unsigned int width, unsigned int height, VAImageID image_id) { - return VA_STATUS_ERROR_UNIMPLEMENTED; + struct request_data *driver_data = context->pDriverData; + struct object_surface *surface_object; + struct object_image *image_object; + VAImage *image; + + surface_object = SURFACE(driver_data, surface_id); + if (surface_object == NULL) + return VA_STATUS_ERROR_INVALID_SURFACE; + + image_object = IMAGE(driver_data, image_id); + if (image_object == NULL) + return VA_STATUS_ERROR_INVALID_IMAGE; + + image = &image_object->image; + if (x != 0 || y != 0 || width != image->width || height != image->height) + return VA_STATUS_ERROR_UNIMPLEMENTED; + + return copy_surface_to_image (driver_data, surface_object, image); } VAStatus RequestPutImage(VADriverContextP context, VASurfaceID surface_id,