frontends/va: Derive image from interlaced buffers
Allow vaDriveImage to derive a vaImage from interlaced buffers by creating a new progressive buffer. v2: Keeps the surface used by DeriveImage untouched (Pierre-Eric) v3: Fixed a segfault reported by Roman Elshin Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/1428 Signed-off-by: Thong Thai <thong.thai@amd.com> Reviewed-by: Leo Liu <leo.liu@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5942>
This commit is contained in:
parent
8c7ca97d3e
commit
fcb558321e
|
@ -204,9 +204,13 @@ vlVaDestroyBuffer(VADriverContextP ctx, VABufferID buf_id)
|
||||||
return VA_STATUS_ERROR_INVALID_BUFFER;
|
return VA_STATUS_ERROR_INVALID_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf->derived_surface.resource)
|
if (buf->derived_surface.resource) {
|
||||||
pipe_resource_reference(&buf->derived_surface.resource, NULL);
|
pipe_resource_reference(&buf->derived_surface.resource, NULL);
|
||||||
|
|
||||||
|
if (buf->derived_image_buffer)
|
||||||
|
buf->derived_image_buffer->destroy(buf->derived_image_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
FREE(buf->data);
|
FREE(buf->data);
|
||||||
FREE(buf);
|
FREE(buf);
|
||||||
handle_table_remove(VL_VA_DRIVER(ctx)->htab, buf_id);
|
handle_table_remove(VL_VA_DRIVER(ctx)->htab, buf_id);
|
||||||
|
|
|
@ -201,6 +201,7 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
|
||||||
VAImage *img;
|
VAImage *img;
|
||||||
struct pipe_screen *screen;
|
struct pipe_screen *screen;
|
||||||
struct pipe_surface **surfaces;
|
struct pipe_surface **surfaces;
|
||||||
|
struct pipe_video_buffer *new_buffer = NULL;
|
||||||
int w;
|
int w;
|
||||||
int h;
|
int h;
|
||||||
int i;
|
int i;
|
||||||
|
@ -225,9 +226,6 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
|
||||||
if (!surf || !surf->buffer)
|
if (!surf || !surf->buffer)
|
||||||
return VA_STATUS_ERROR_INVALID_SURFACE;
|
return VA_STATUS_ERROR_INVALID_SURFACE;
|
||||||
|
|
||||||
if (surf->buffer->interlaced)
|
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
|
||||||
|
|
||||||
surfaces = surf->buffer->get_surfaces(surf->buffer);
|
surfaces = surf->buffer->get_surfaces(surf->buffer);
|
||||||
if (!surfaces || !surfaces[0]->texture)
|
if (!surfaces || !surfaces[0]->texture)
|
||||||
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
@ -285,6 +283,38 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
|
||||||
case VA_FOURCC('N','V','1','2'):
|
case VA_FOURCC('N','V','1','2'):
|
||||||
case VA_FOURCC('P','0','1','0'):
|
case VA_FOURCC('P','0','1','0'):
|
||||||
case VA_FOURCC('P','0','1','6'):
|
case VA_FOURCC('P','0','1','6'):
|
||||||
|
if (surf->buffer->interlaced) {
|
||||||
|
struct u_rect src_rect, dst_rect;
|
||||||
|
struct pipe_video_buffer new_template;
|
||||||
|
|
||||||
|
new_template = surf->templat;
|
||||||
|
new_template.interlaced = false;
|
||||||
|
new_buffer = drv->pipe->create_video_buffer(drv->pipe, &new_template);
|
||||||
|
|
||||||
|
/* convert the interlaced to the progressive */
|
||||||
|
src_rect.x0 = dst_rect.x0 = 0;
|
||||||
|
src_rect.x1 = dst_rect.x1 = surf->templat.width;
|
||||||
|
src_rect.y0 = dst_rect.y0 = 0;
|
||||||
|
src_rect.y1 = dst_rect.y1 = surf->templat.height;
|
||||||
|
|
||||||
|
vl_compositor_yuv_deint_full(&drv->cstate, &drv->compositor,
|
||||||
|
surf->buffer, new_buffer,
|
||||||
|
&src_rect, &dst_rect,
|
||||||
|
VL_COMPOSITOR_WEAVE);
|
||||||
|
|
||||||
|
/* recalculate the values now that we have a new surface */
|
||||||
|
surfaces = surf->buffer->get_surfaces(new_buffer);
|
||||||
|
if (screen->resource_get_info) {
|
||||||
|
screen->resource_get_info(screen, surfaces[0]->texture, &stride,
|
||||||
|
&offset);
|
||||||
|
if (!stride)
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
w = align(new_buffer->width, 2);
|
||||||
|
h = align(new_buffer->height, 2);
|
||||||
|
}
|
||||||
|
|
||||||
img->num_planes = 2;
|
img->num_planes = 2;
|
||||||
img->pitches[0] = stride > 0 ? stride : w;
|
img->pitches[0] = stride > 0 ? stride : w;
|
||||||
img->pitches[1] = stride > 0 ? stride : w;
|
img->pitches[1] = stride > 0 ? stride : w;
|
||||||
|
@ -314,6 +344,7 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
|
||||||
img_buf->num_elements = 1;
|
img_buf->num_elements = 1;
|
||||||
|
|
||||||
pipe_resource_reference(&img_buf->derived_surface.resource, surfaces[0]->texture);
|
pipe_resource_reference(&img_buf->derived_surface.resource, surfaces[0]->texture);
|
||||||
|
img_buf->derived_image_buffer = new_buffer;
|
||||||
|
|
||||||
img->buf = handle_table_add(VL_VA_DRIVER(ctx)->htab, img_buf);
|
img->buf = handle_table_add(VL_VA_DRIVER(ctx)->htab, img_buf);
|
||||||
mtx_unlock(&drv->mutex);
|
mtx_unlock(&drv->mutex);
|
||||||
|
|
|
@ -267,6 +267,7 @@ typedef struct {
|
||||||
unsigned int export_refcount;
|
unsigned int export_refcount;
|
||||||
VABufferInfo export_state;
|
VABufferInfo export_state;
|
||||||
unsigned int coded_size;
|
unsigned int coded_size;
|
||||||
|
struct pipe_video_buffer *derived_image_buffer;
|
||||||
} vlVaBuffer;
|
} vlVaBuffer;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
Loading…
Reference in New Issue