summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/omx/vid_enc.c3
-rw-r--r--src/gallium/state_trackers/va/buffer.c70
-rw-r--r--src/gallium/state_trackers/va/context.c6
-rw-r--r--src/gallium/state_trackers/va/image.c81
-rw-r--r--src/gallium/state_trackers/va/picture.c29
-rw-r--r--src/gallium/state_trackers/va/postproc.c207
-rw-r--r--src/gallium/state_trackers/va/subpicture.c68
-rw-r--r--src/gallium/state_trackers/va/surface.c36
-rw-r--r--src/gallium/state_trackers/va/va_private.h2
-rw-r--r--src/gallium/state_trackers/vdpau/surface.c13
10 files changed, 403 insertions, 112 deletions
diff --git a/src/gallium/state_trackers/omx/vid_enc.c b/src/gallium/state_trackers/omx/vid_enc.c
index aa45089..df22a97 100644
--- a/src/gallium/state_trackers/omx/vid_enc.c
+++ b/src/gallium/state_trackers/omx/vid_enc.c
@@ -869,6 +869,9 @@ static void enc_ReleaseTasks(struct list_head *head)
{
struct encode_task *i, *next;
+ if (!head)
+ return;
+
LIST_FOR_EACH_ENTRY_SAFE(i, next, head, list) {
pipe_resource_reference(&i->bitstream, NULL);
i->buf->destroy(i->buf);
diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c
index 8de7935..c2c24d6 100644
--- a/src/gallium/state_trackers/va/buffer.c
+++ b/src/gallium/state_trackers/va/buffer.c
@@ -40,6 +40,7 @@ vlVaCreateBuffer(VADriverContextP ctx, VAContextID context, VABufferType type,
unsigned int size, unsigned int num_elements, void *data,
VABufferID *buf_id)
{
+ vlVaDriver *drv;
vlVaBuffer *buf;
if (!ctx)
@@ -62,7 +63,10 @@ vlVaCreateBuffer(VADriverContextP ctx, VAContextID context, VABufferType type,
if (data)
memcpy(buf->data, data, size * num_elements);
- *buf_id = handle_table_add(VL_VA_DRIVER(ctx)->htab, buf);
+ drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
+ *buf_id = handle_table_add(drv->htab, buf);
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
@@ -71,12 +75,16 @@ VAStatus
vlVaBufferSetNumElements(VADriverContextP ctx, VABufferID buf_id,
unsigned int num_elements)
{
+ vlVaDriver *drv;
vlVaBuffer *buf;
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
- buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id);
+ drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
+ buf = handle_table_get(drv->htab, buf_id);
+ pipe_mutex_unlock(drv->mutex);
if (!buf)
return VA_STATUS_ERROR_INVALID_BUFFER;
@@ -109,22 +117,24 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void **pbuff)
if (!pbuff)
return VA_STATUS_ERROR_INVALID_PARAMETER;
+ pipe_mutex_lock(drv->mutex);
buf = handle_table_get(drv->htab, buf_id);
- if (!buf)
- return VA_STATUS_ERROR_INVALID_BUFFER;
-
- if (buf->export_refcount > 0)
+ if (!buf || buf->export_refcount > 0) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_BUFFER;
+ }
if (buf->derived_surface.resource) {
*pbuff = pipe_buffer_map(drv->pipe, buf->derived_surface.resource,
PIPE_TRANSFER_WRITE,
&buf->derived_surface.transfer);
+ pipe_mutex_unlock(drv->mutex);
if (!buf->derived_surface.transfer || !*pbuff)
return VA_STATUS_ERROR_INVALID_BUFFER;
} else {
+ pipe_mutex_unlock(drv->mutex);
*pbuff = buf->data;
}
@@ -144,20 +154,23 @@ vlVaUnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
if (!drv)
return VA_STATUS_ERROR_INVALID_CONTEXT;
+ pipe_mutex_lock(drv->mutex);
buf = handle_table_get(drv->htab, buf_id);
- if (!buf)
- return VA_STATUS_ERROR_INVALID_BUFFER;
-
- if (buf->export_refcount > 0)
+ if (!buf || buf->export_refcount > 0) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_BUFFER;
+ }
if (buf->derived_surface.resource) {
- if (!buf->derived_surface.transfer)
+ if (!buf->derived_surface.transfer) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_BUFFER;
+ }
pipe_buffer_unmap(drv->pipe, buf->derived_surface.transfer);
buf->derived_surface.transfer = NULL;
}
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
@@ -165,18 +178,25 @@ vlVaUnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
VAStatus
vlVaDestroyBuffer(VADriverContextP ctx, VABufferID buf_id)
{
+ vlVaDriver *drv;
vlVaBuffer *buf;
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
- buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id);
- if (!buf)
+ drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
+ buf = handle_table_get(drv->htab, buf_id);
+ if (!buf) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_BUFFER;
+ }
if (buf->derived_surface.resource) {
- if (buf->export_refcount > 0)
+ if (buf->export_refcount > 0) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_BUFFER;
+ }
pipe_resource_reference(&buf->derived_surface.resource, NULL);
}
@@ -184,6 +204,7 @@ vlVaDestroyBuffer(VADriverContextP ctx, VABufferID buf_id)
FREE(buf->data);
FREE(buf);
handle_table_remove(VL_VA_DRIVER(ctx)->htab, buf_id);
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
@@ -192,12 +213,16 @@ VAStatus
vlVaBufferInfo(VADriverContextP ctx, VABufferID buf_id, VABufferType *type,
unsigned int *size, unsigned int *num_elements)
{
+ vlVaDriver *drv;
vlVaBuffer *buf;
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
- buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id);
+ drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
+ buf = handle_table_get(drv->htab, buf_id);
+ pipe_mutex_unlock(drv->mutex);
if (!buf)
return VA_STATUS_ERROR_INVALID_BUFFER;
@@ -227,7 +252,11 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
+ drv = VL_VA_DRIVER(ctx);
+ screen = VL_VA_PSCREEN(ctx);
+ pipe_mutex_lock(drv->mutex);
buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id);
+ pipe_mutex_unlock(drv->mutex);
if (!buf)
return VA_STATUS_ERROR_INVALID_BUFFER;
@@ -256,9 +285,6 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
if (!buf->derived_surface.resource)
return VA_STATUS_ERROR_INVALID_BUFFER;
- drv = VL_VA_DRIVER(ctx);
- screen = VL_VA_PSCREEN(ctx);
-
if (buf->export_refcount > 0) {
if (buf->export_state.mem_type != mem_type)
return VA_STATUS_ERROR_INVALID_PARAMETER;
@@ -269,7 +295,9 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
struct winsys_handle whandle;
+ pipe_mutex_lock(drv->mutex);
drv->pipe->flush(drv->pipe, NULL, 0);
+ pipe_mutex_unlock(drv->mutex);
memset(&whandle, 0, sizeof(whandle));
whandle.type = DRM_API_HANDLE_TYPE_FD;
@@ -299,12 +327,16 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
VAStatus
vlVaReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id)
{
+ vlVaDriver *drv;
vlVaBuffer *buf;
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
- buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id);
+ drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
+ buf = handle_table_get(drv->htab, buf_id);
+ pipe_mutex_unlock(drv->mutex);
if (!buf)
return VA_STATUS_ERROR_INVALID_BUFFER;
diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c
index 192794f..37a0117 100644
--- a/src/gallium/state_trackers/va/context.c
+++ b/src/gallium/state_trackers/va/context.c
@@ -155,6 +155,7 @@ VA_DRIVER_INIT_FUNC(VADriverContextP ctx)
vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, true, &drv->csc);
vl_compositor_set_csc_matrix(&drv->cstate, (const vl_csc_matrix *)&drv->csc);
+ pipe_mutex_init(drv->mutex);
ctx->pDriverData = (void *)drv;
ctx->version_major = 0;
@@ -262,7 +263,9 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
}
context->desc.base.profile = config_id;
+ pipe_mutex_lock(drv->mutex);
*context_id = handle_table_add(drv->htab, context);
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
@@ -277,6 +280,7 @@ vlVaDestroyContext(VADriverContextP ctx, VAContextID context_id)
return VA_STATUS_ERROR_INVALID_CONTEXT;
drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
context = handle_table_get(drv->htab, context_id);
if (context->decoder) {
@@ -294,6 +298,7 @@ vlVaDestroyContext(VADriverContextP ctx, VAContextID context_id)
}
FREE(context);
handle_table_remove(drv->htab, context_id);
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
@@ -312,6 +317,7 @@ vlVaTerminate(VADriverContextP ctx)
drv->pipe->destroy(drv->pipe);
drv->vscreen->destroy(drv->vscreen);
handle_table_destroy(drv->htab);
+ pipe_mutex_destroy(drv->mutex);
FREE(drv);
return VA_STATUS_SUCCESS;
diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c
index ccc263f..2c42a98 100644
--- a/src/gallium/state_trackers/va/image.c
+++ b/src/gallium/state_trackers/va/image.c
@@ -34,6 +34,7 @@
#include "util/u_video.h"
#include "vl/vl_winsys.h"
+#include "vl/vl_video_buffer.h"
#include "va_private.h"
@@ -61,15 +62,9 @@ vlVaVideoSurfaceSize(vlVaSurface *p_surf, int component,
*width = p_surf->templat.width;
*height = p_surf->templat.height;
- if (component > 0) {
- if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
- *width /= 2;
- *height /= 2;
- } else if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422)
- *width /= 2;
- }
- if (p_surf->templat.interlaced)
- *height /= 2;
+ vl_video_buffer_adjust_size(width, height, component,
+ p_surf->templat.chroma_format,
+ p_surf->templat.interlaced);
}
VAStatus
@@ -119,7 +114,9 @@ vlVaCreateImage(VADriverContextP ctx, VAImageFormat *format, int width, int heig
img = CALLOC(1, sizeof(VAImage));
if (!img)
return VA_STATUS_ERROR_ALLOCATION_FAILED;
+ pipe_mutex_lock(drv->mutex);
img->image_id = handle_table_add(drv->htab, img);
+ pipe_mutex_unlock(drv->mutex);
img->format = *format;
img->width = width;
@@ -261,6 +258,7 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
+ pipe_mutex_lock(drv->mutex);
img->image_id = handle_table_add(drv->htab, img);
img_buf->type = VAImageBufferType;
@@ -270,6 +268,7 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
pipe_resource_reference(&img_buf->derived_surface.resource, surfaces[0]->texture);
img->buf = handle_table_add(VL_VA_DRIVER(ctx)->htab, img_buf);
+ pipe_mutex_unlock(drv->mutex);
*image = *img;
@@ -279,16 +278,22 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
VAStatus
vlVaDestroyImage(VADriverContextP ctx, VAImageID image)
{
+ vlVaDriver *drv;
VAImage *vaimage;
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
- vaimage = handle_table_get(VL_VA_DRIVER(ctx)->htab, image);
- if (!vaimage)
+ drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
+ vaimage = handle_table_get(drv->htab, image);
+ if (!vaimage) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_IMAGE;
+ }
handle_table_remove(VL_VA_DRIVER(ctx)->htab, image);
+ pipe_mutex_unlock(drv->mutex);
FREE(vaimage);
return vlVaDestroyBuffer(ctx, vaimage->buf);
}
@@ -321,21 +326,30 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
surf = handle_table_get(drv->htab, surface);
- if (!surf || !surf->buffer)
+ if (!surf || !surf->buffer) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;
+ }
vaimage = handle_table_get(drv->htab, image);
- if (!vaimage)
+ if (!vaimage) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_IMAGE;
+ }
img_buf = handle_table_get(drv->htab, vaimage->buf);
- if (!img_buf)
+ if (!img_buf) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_BUFFER;
+ }
format = VaFourccToPipeFormat(vaimage->format.fourcc);
- if (format == PIPE_FORMAT_NONE)
+ if (format == PIPE_FORMAT_NONE) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
if (format != surf->buffer->buffer_format) {
/* support NV12 to YV12 and IYUV conversion now only */
@@ -344,13 +358,17 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
(format == PIPE_FORMAT_IYUV &&
surf->buffer->buffer_format == PIPE_FORMAT_NV12))
convert = true;
- else
+ else {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
}
views = surf->buffer->get_sampler_view_planes(surf->buffer);
- if (!views)
+ if (!views) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
for (i = 0; i < vaimage->num_planes; i++) {
data[i] = img_buf->data + vaimage->offsets[i];
@@ -377,8 +395,10 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
uint8_t *map;
map = drv->pipe->transfer_map(drv->pipe, views[i]->texture, 0,
PIPE_TRANSFER_READ, &box, &transfer);
- if (!map)
+ if (!map) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
if (i == 1 && convert) {
u_copy_nv12_to_yv12(data, pitches, i, j,
@@ -393,6 +413,7 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
pipe_transfer_unmap(drv->pipe, transfer);
}
}
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
@@ -415,28 +436,38 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
return VA_STATUS_ERROR_INVALID_CONTEXT;
drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
surf = handle_table_get(drv->htab, surface);
- if (!surf || !surf->buffer)
+ if (!surf || !surf->buffer) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;
+ }
vaimage = handle_table_get(drv->htab, image);
- if (!vaimage)
+ if (!vaimage) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_IMAGE;
+ }
img_buf = handle_table_get(drv->htab, vaimage->buf);
- if (!img_buf)
+ if (!img_buf) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_BUFFER;
+ }
if (img_buf->derived_surface.resource) {
/* Attempting to transfer derived image to surface */
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
format = VaFourccToPipeFormat(vaimage->format.fourcc);
- if (format == PIPE_FORMAT_NONE)
+ if (format == PIPE_FORMAT_NONE) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
if (format != surf->buffer->buffer_format) {
struct pipe_video_buffer *tmp_buf;
@@ -447,6 +478,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
if (!tmp_buf) {
surf->templat.buffer_format = old_surf_format;
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
@@ -455,8 +487,10 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
}
views = surf->buffer->get_sampler_view_planes(surf->buffer);
- if (!views)
+ if (!views) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
for (i = 0; i < vaimage->num_planes; i++) {
data[i] = img_buf->data + vaimage->offsets[i];
@@ -485,6 +519,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
pitches[i] * views[i]->texture->array_size, 0);
}
}
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c
index da9ca5a..89ac024 100644
--- a/src/gallium/state_trackers/va/picture.c
+++ b/src/gallium/state_trackers/va/picture.c
@@ -50,24 +50,29 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende
if (!drv)
return VA_STATUS_ERROR_INVALID_CONTEXT;
+ pipe_mutex_lock(drv->mutex);
context = handle_table_get(drv->htab, context_id);
- if (!context)
+ if (!context) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_CONTEXT;
+ }
surf = handle_table_get(drv->htab, render_target);
+ pipe_mutex_unlock(drv->mutex);
if (!surf || !surf->buffer)
return VA_STATUS_ERROR_INVALID_SURFACE;
context->target = surf->buffer;
if (!context->decoder) {
+
/* VPP */
if (context->templat.profile == PIPE_VIDEO_PROFILE_UNKNOWN &&
- ((context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM &&
- context->target->buffer_format != PIPE_FORMAT_R8G8B8A8_UNORM &&
- context->target->buffer_format != PIPE_FORMAT_B8G8R8X8_UNORM &&
- context->target->buffer_format != PIPE_FORMAT_R8G8B8X8_UNORM) ||
- context->target->interlaced))
+ context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM &&
+ context->target->buffer_format != PIPE_FORMAT_R8G8B8A8_UNORM &&
+ context->target->buffer_format != PIPE_FORMAT_B8G8R8X8_UNORM &&
+ context->target->buffer_format != PIPE_FORMAT_R8G8B8X8_UNORM &&
+ context->target->buffer_format != PIPE_FORMAT_NV12)
return VA_STATUS_ERROR_UNIMPLEMENTED;
return VA_STATUS_SUCCESS;
@@ -289,14 +294,19 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff
if (!drv)
return VA_STATUS_ERROR_INVALID_CONTEXT;
+ pipe_mutex_lock(drv->mutex);
context = handle_table_get(drv->htab, context_id);
- if (!context)
+ if (!context) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_CONTEXT;
+ }
for (i = 0; i < num_buffers; ++i) {
vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]);
- if (!buf)
+ if (!buf) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_BUFFER;
+ }
switch (buf->type) {
case VAPictureParameterBufferType:
@@ -322,6 +332,7 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff
break;
}
}
+ pipe_mutex_unlock(drv->mutex);
return vaStatus;
}
@@ -339,7 +350,9 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
if (!drv)
return VA_STATUS_ERROR_INVALID_CONTEXT;
+ pipe_mutex_lock(drv->mutex);
context = handle_table_get(drv->htab, context_id);
+ pipe_mutex_unlock(drv->mutex);
if (!context)
return VA_STATUS_ERROR_INVALID_CONTEXT;
diff --git a/src/gallium/state_trackers/va/postproc.c b/src/gallium/state_trackers/va/postproc.c
index 15053a9..0cec0c8 100644
--- a/src/gallium/state_trackers/va/postproc.c
+++ b/src/gallium/state_trackers/va/postproc.c
@@ -27,6 +27,9 @@
#include "util/u_handle_table.h"
+#include "vl/vl_defines.h"
+#include "vl/vl_video_buffer.h"
+
#include "va_private.h"
static const VARectangle *
@@ -44,43 +47,22 @@ vlVaRegionDefault(const VARectangle *region, struct pipe_video_buffer *buf,
return def;
}
-VAStatus
-vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
+static VAStatus
+vlVaPostProcCompositor(vlVaDriver *drv, vlVaContext *context,
+ const VARectangle *src_region,
+ const VARectangle *dst_region,
+ struct pipe_video_buffer *src,
+ struct pipe_video_buffer *dst,
+ enum vl_compositor_deinterlace deinterlace)
{
- VARectangle def_src_region, def_dst_region;
- const VARectangle *src_region, *dst_region;
+ struct pipe_surface **surfaces;
struct u_rect src_rect;
struct u_rect dst_rect;
- vlVaSurface *src_surface;
- VAProcPipelineParameterBuffer *pipeline_param;
- struct pipe_surface **surfaces;
- struct pipe_surface *psurf;
-
- if (!drv || !context)
- return VA_STATUS_ERROR_INVALID_CONTEXT;
-
- if (!buf || !buf->data)
- return VA_STATUS_ERROR_INVALID_BUFFER;
-
- if (!context->target)
- return VA_STATUS_ERROR_INVALID_SURFACE;
-
- pipeline_param = (VAProcPipelineParameterBuffer *)buf->data;
-
- src_surface = handle_table_get(drv->htab, pipeline_param->surface);
- if (!src_surface || !src_surface->buffer)
- return VA_STATUS_ERROR_INVALID_SURFACE;
-
- surfaces = context->target->get_surfaces(context->target);
+ surfaces = dst->get_surfaces(dst);
if (!surfaces || !surfaces[0])
return VA_STATUS_ERROR_INVALID_SURFACE;
- psurf = surfaces[0];
-
- src_region = vlVaRegionDefault(pipeline_param->surface_region, src_surface->buffer, &def_src_region);
- dst_region = vlVaRegionDefault(pipeline_param->output_region, context->target, &def_dst_region);
-
src_rect.x0 = src_region->x;
src_rect.y0 = src_region->y;
src_rect.x1 = src_region->x + src_region->width;
@@ -92,9 +74,99 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex
dst_rect.y1 = dst_region->y + dst_region->height;
vl_compositor_clear_layers(&drv->cstate);
- vl_compositor_set_buffer_layer(&drv->cstate, &drv->compositor, 0, src_surface->buffer, &src_rect, NULL, VL_COMPOSITOR_WEAVE);
+ vl_compositor_set_buffer_layer(&drv->cstate, &drv->compositor, 0, src,
+ &src_rect, NULL, deinterlace);
vl_compositor_set_layer_dst_area(&drv->cstate, 0, &dst_rect);
- vl_compositor_render(&drv->cstate, &drv->compositor, psurf, NULL, false);
+ vl_compositor_render(&drv->cstate, &drv->compositor, surfaces[0], NULL, false);
+
+ return VA_STATUS_SUCCESS;
+}
+
+static void vlVaGetBox(struct pipe_video_buffer *buf, unsigned idx,
+ struct pipe_box *box, const VARectangle *region)
+{
+ unsigned plane = buf->interlaced ? idx / 2: idx;
+ unsigned x, y, width, height;
+
+ x = abs(region->x);
+ y = abs(region->y);
+ width = region->width;
+ height = region->height;
+
+ vl_video_buffer_adjust_size(&x, &y, plane, buf->chroma_format,
+ buf->interlaced);
+ vl_video_buffer_adjust_size(&width, &height, plane, buf->chroma_format,
+ buf->interlaced);
+
+ box->x = region->x < 0 ? -x : x;
+ box->y = region->y < 0 ? -y : y;
+ box->width = width;
+ box->height = height;
+}
+
+static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context,
+ const VARectangle *src_region,
+ const VARectangle *dst_region,
+ struct pipe_video_buffer *src,
+ struct pipe_video_buffer *dst,
+ enum vl_compositor_deinterlace deinterlace)
+{
+ struct pipe_surface **src_surfaces;
+ struct pipe_surface **dst_surfaces;
+ unsigned i;
+
+ if (src->interlaced != dst->interlaced)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ src_surfaces = src->get_surfaces(src);
+ if (!src_surfaces || !src_surfaces[0])
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ dst_surfaces = dst->get_surfaces(dst);
+ if (!dst_surfaces || !dst_surfaces[0])
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ for (i = 0; i < VL_MAX_SURFACES; ++i) {
+ struct pipe_surface *from = src_surfaces[i];
+ struct pipe_blit_info blit;
+
+ if (src->interlaced) {
+ /* Not 100% accurate, but close enough */
+ switch (deinterlace) {
+ case VL_COMPOSITOR_BOB_TOP:
+ from = src_surfaces[i & ~1];
+ break;
+ case VL_COMPOSITOR_BOB_BOTTOM:
+ from = src_surfaces[(i & ~1) + 1];
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!from || !dst_surfaces[i])
+ continue;
+
+ memset(&blit, 0, sizeof(blit));
+ blit.src.resource = from->texture;
+ blit.src.format = from->format;
+ blit.src.level = 0;
+ blit.src.box.z = from->u.tex.first_layer;
+ blit.src.box.depth = 1;
+ vlVaGetBox(src, i, &blit.src.box, src_region);
+
+ blit.dst.resource = dst_surfaces[i]->texture;
+ blit.dst.format = dst_surfaces[i]->format;
+ blit.dst.level = 0;
+ blit.dst.box.z = dst_surfaces[i]->u.tex.first_layer;
+ blit.dst.box.depth = 1;
+ vlVaGetBox(dst, i, &blit.dst.box, dst_region);
+
+ blit.mask = PIPE_MASK_RGBA;
+ blit.filter = PIPE_TEX_MIPFILTER_LINEAR;
+
+ drv->pipe->blit(drv->pipe, &blit);
+ }
// TODO: figure out why this is necessary for DMA-buf sharing
drv->pipe->flush(drv->pipe, NULL, 0);
@@ -102,4 +174,75 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex
return VA_STATUS_SUCCESS;
}
+VAStatus
+vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
+{
+ enum vl_compositor_deinterlace deinterlace = VL_COMPOSITOR_WEAVE;
+ VARectangle def_src_region, def_dst_region;
+ const VARectangle *src_region, *dst_region;
+ VAProcPipelineParameterBuffer *param;
+ vlVaSurface *src_surface;
+ unsigned i;
+ if (!drv || !context)
+ return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+ if (!buf || !buf->data)
+ return VA_STATUS_ERROR_INVALID_BUFFER;
+
+ if (!context->target)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ param = buf->data;
+
+ src_surface = handle_table_get(drv->htab, param->surface);
+ if (!src_surface || !src_surface->buffer)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ for (i = 0; i < param->num_filters; i++) {
+ vlVaBuffer *buf = handle_table_get(drv->htab, param->filters[i]);
+ VAProcFilterParameterBufferBase *filter;
+
+ if (!buf || buf->type != VAProcFilterParameterBufferType)
+ return VA_STATUS_ERROR_INVALID_BUFFER;
+
+ filter = buf->data;
+ switch (filter->type) {
+ case VAProcFilterDeinterlacing: {
+ VAProcFilterParameterBufferDeinterlacing *deint = buf->data;
+ switch (deint->algorithm) {
+ case VAProcDeinterlacingBob:
+ if (deint->flags & VA_DEINTERLACING_BOTTOM_FIELD)
+ deinterlace = VL_COMPOSITOR_BOB_BOTTOM;
+ else
+ deinterlace = VL_COMPOSITOR_BOB_TOP;
+ break;
+
+ case VAProcDeinterlacingWeave:
+ deinterlace = VL_COMPOSITOR_WEAVE;
+ break;
+
+ default:
+ return VA_STATUS_ERROR_UNIMPLEMENTED;
+ }
+
+ break;
+ }
+
+ default:
+ return VA_STATUS_ERROR_UNIMPLEMENTED;
+ }
+ }
+
+ src_region = vlVaRegionDefault(param->surface_region, src_surface->buffer, &def_src_region);
+ dst_region = vlVaRegionDefault(param->output_region, context->target, &def_dst_region);
+
+ if (context->target->buffer_format != PIPE_FORMAT_NV12)
+ return vlVaPostProcCompositor(drv, context, src_region, dst_region,
+ src_surface->buffer, context->target,
+ deinterlace);
+ else
+ return vlVaPostProcBlit(drv, context, src_region, dst_region,
+ src_surface->buffer, context->target,
+ deinterlace);
+}
diff --git a/src/gallium/state_trackers/va/subpicture.c b/src/gallium/state_trackers/va/subpicture.c
index f146189..f546e56 100644
--- a/src/gallium/state_trackers/va/subpicture.c
+++ b/src/gallium/state_trackers/va/subpicture.c
@@ -65,22 +65,30 @@ VAStatus
vlVaCreateSubpicture(VADriverContextP ctx, VAImageID image,
VASubpictureID *subpicture)
{
+ vlVaDriver *drv;
vlVaSubpicture *sub;
VAImage *img;
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
- img = handle_table_get(VL_VA_DRIVER(ctx)->htab, image);
- if (!img)
+ drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
+ img = handle_table_get(drv->htab, image);
+ if (!img) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_IMAGE;
+ }
sub = CALLOC(1, sizeof(*sub));
- if (!sub)
+ if (!sub) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
+ }
sub->image = img;
*subpicture = handle_table_add(VL_VA_DRIVER(ctx)->htab, sub);
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
@@ -88,17 +96,24 @@ vlVaCreateSubpicture(VADriverContextP ctx, VAImageID image,
VAStatus
vlVaDestroySubpicture(VADriverContextP ctx, VASubpictureID subpicture)
{
+ vlVaDriver *drv;
vlVaSubpicture *sub;
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
- sub = handle_table_get(VL_VA_DRIVER(ctx)->htab, subpicture);
- if (!sub)
+ drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
+
+ sub = handle_table_get(drv->htab, subpicture);
+ if (!sub) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_SUBPICTURE;
+ }
FREE(sub);
- handle_table_remove(VL_VA_DRIVER(ctx)->htab, subpicture);
+ handle_table_remove(drv->htab, subpicture);
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
@@ -106,17 +121,24 @@ vlVaDestroySubpicture(VADriverContextP ctx, VASubpictureID subpicture)
VAStatus
vlVaSubpictureImage(VADriverContextP ctx, VASubpictureID subpicture, VAImageID image)
{
+ vlVaDriver *drv;
vlVaSubpicture *sub;
VAImage *img;
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
- img = handle_table_get(VL_VA_DRIVER(ctx)->htab, image);
- if (!img)
+ drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
+
+ img = handle_table_get(drv->htab, image);
+ if (!img) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_IMAGE;
+ }
- sub = handle_table_get(VL_VA_DRIVER(ctx)->htab, subpicture);
+ sub = handle_table_get(drv->htab, subpicture);
+ pipe_mutex_unlock(drv->mutex);
if (!sub)
return VA_STATUS_ERROR_INVALID_SUBPICTURE;
@@ -164,15 +186,20 @@ vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
sub = handle_table_get(drv->htab, subpicture);
- if (!sub)
+ if (!sub) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_SUBPICTURE;
+ }
for (i = 0; i < num_surfaces; i++) {
surf = handle_table_get(drv->htab, target_surfaces[i]);
- if (!surf)
+ if (!surf) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;
+ }
}
sub->src_rect = src_rect;
@@ -191,8 +218,10 @@ vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
tex_temp.flags = 0;
if (!drv->pipe->screen->is_format_supported(
drv->pipe->screen, tex_temp.format, tex_temp.target,
- tex_temp.nr_samples, tex_temp.bind))
+ tex_temp.nr_samples, tex_temp.bind)) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
+ }
tex = drv->pipe->screen->resource_create(drv->pipe->screen, &tex_temp);
@@ -200,13 +229,16 @@ vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
u_sampler_view_default_template(&sampler_templ, tex, tex->format);
sub->sampler = drv->pipe->create_sampler_view(drv->pipe, tex, &sampler_templ);
pipe_resource_reference(&tex, NULL);
- if (!sub->sampler)
+ if (!sub->sampler) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
+ }
for (i = 0; i < num_surfaces; i++) {
surf = handle_table_get(drv->htab, target_surfaces[i]);
util_dynarray_append(&surf->subpics, vlVaSubpicture *, sub);
}
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
@@ -224,15 +256,20 @@ vlVaDeassociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
sub = handle_table_get(drv->htab, subpicture);
- if (!sub)
+ if (!sub) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_SUBPICTURE;
+ }
for (i = 0; i < num_surfaces; i++) {
surf = handle_table_get(drv->htab, target_surfaces[i]);
- if (!surf)
+ if (!surf) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;
+ }
array = surf->subpics.data;
if (!array)
@@ -246,6 +283,7 @@ vlVaDeassociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
while (surf->subpics.size && util_dynarray_top(&surf->subpics, vlVaSubpicture *) == NULL)
(void)util_dynarray_pop(&surf->subpics, vlVaSubpicture *);
}
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c
index 5ddaf04..f23a889 100644
--- a/src/gallium/state_trackers/va/surface.c
+++ b/src/gallium/state_trackers/va/surface.c
@@ -68,6 +68,7 @@ vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_sur
return VA_STATUS_ERROR_INVALID_CONTEXT;
drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
for (i = 0; i < num_surfaces; ++i) {
vlVaSurface *surf = handle_table_get(drv->htab, surface_list[i]);
if (surf->buffer)
@@ -76,6 +77,7 @@ vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_sur
FREE(surf);
handle_table_remove(drv->htab, surface_list[i]);
}
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
@@ -236,16 +238,21 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s
return VA_STATUS_ERROR_INVALID_CONTEXT;
drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
surf = handle_table_get(drv->htab, surface_id);
- if (!surf)
+ if (!surf) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;
+ }
screen = drv->pipe->screen;
vscreen = drv->vscreen;
tex = vscreen->texture_from_drawable(vscreen, draw);
- if (!tex)
+ if (!tex) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_DISPLAY;
+ }
dirty_area = vscreen->get_dirty_area(vscreen);
@@ -254,6 +261,7 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s
surf_draw = drv->pipe->create_surface(drv->pipe, tex, &surf_templ);
if (!surf_draw) {
pipe_resource_reference(&tex, NULL);
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_DISPLAY;
}
@@ -268,8 +276,10 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s
vl_compositor_render(&drv->cstate, &drv->compositor, surf_draw, dirty_area, true);
status = vlVaPutSubpictures(surf, drv, surf_draw, dirty_area, &src_rect, &dst_rect);
- if (status)
+ if (status) {
+ pipe_mutex_unlock(drv->mutex);
return status;
+ }
screen->flush_frontbuffer(screen, tex, 0, 0,
vscreen->get_private(vscreen), NULL);
@@ -278,6 +288,7 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s
pipe_resource_reference(&tex, NULL);
pipe_surface_reference(&surf_draw, NULL);
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
@@ -599,6 +610,7 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID));
+ pipe_mutex_lock(drv->mutex);
for (i = 0; i < num_surfaces; i++) {
vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface));
if (!surf)
@@ -627,10 +639,12 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
assert(0);
}
}
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
no_res:
+ pipe_mutex_unlock(drv->mutex);
if (i)
vlVaDestroySurfaces(ctx, surfaces, i);
@@ -649,7 +663,7 @@ vlVaQueryVideoProcFilters(VADriverContextP ctx, VAContextID context,
if (!num_filters || !filters)
return VA_STATUS_ERROR_INVALID_PARAMETER;
- filters[num++] = VAProcFilterNone;
+ filters[num++] = VAProcFilterDeinterlacing;
*num_filters = num;
@@ -674,8 +688,20 @@ vlVaQueryVideoProcFilterCaps(VADriverContextP ctx, VAContextID context,
switch (type) {
case VAProcFilterNone:
break;
+ case VAProcFilterDeinterlacing: {
+ VAProcFilterCapDeinterlacing *deint = filter_caps;
+
+ if (*num_filter_caps < 2) {
+ *num_filter_caps = 2;
+ return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
+ }
+
+ deint[i++].type = VAProcDeinterlacingBob;
+ deint[i++].type = VAProcDeinterlacingWeave;
+ break;
+ }
+
case VAProcFilterNoiseReduction:
- case VAProcFilterDeinterlacing:
case VAProcFilterSharpening:
case VAProcFilterColorBalance:
case VAProcFilterSkinToneEnhancement:
diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h
index bf9d24b..7afd81a 100644
--- a/src/gallium/state_trackers/va/va_private.h
+++ b/src/gallium/state_trackers/va/va_private.h
@@ -44,6 +44,7 @@
#include "vl/vl_csc.h"
#include "util/u_dynarray.h"
+#include "os/os_thread.h"
#define VL_VA_DRIVER(ctx) ((vlVaDriver *)ctx->pDriverData)
#define VL_VA_PSCREEN(ctx) (VL_VA_DRIVER(ctx)->vscreen->pscreen)
@@ -203,6 +204,7 @@ typedef struct {
struct vl_compositor compositor;
struct vl_compositor_state cstate;
vl_csc_matrix csc;
+ pipe_mutex mutex;
} vlVaDriver;
typedef struct {
diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c
index 55d0d76..ffcedc1 100644
--- a/src/gallium/state_trackers/vdpau/surface.c
+++ b/src/gallium/state_trackers/vdpau/surface.c
@@ -183,16 +183,9 @@ vlVdpVideoSurfaceSize(vlVdpSurface *p_surf, int component,
*width = p_surf->templat.width;
*height = p_surf->templat.height;
- if (component > 0) {
- if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
- *width /= 2;
- *height /= 2;
- } else if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
- *width /= 2;
- }
- }
- if (p_surf->templat.interlaced)
- *height /= 2;
+ vl_video_buffer_adjust_size(width, height, component,
+ p_surf->templat.chroma_format,
+ p_surf->templat.interlaced);
}
/**