summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorBoyuan Zhang <[email protected]>2016-07-21 19:40:16 -0400
committerChristian König <[email protected]>2016-07-25 13:39:51 +0200
commit34f46348438b29e20d06cca312616cfba8ee05f6 (patch)
treebf3c5ee0bd013419380822c236a06e09f767e4ac /src/gallium
parent23b4ab1738f0f4470449c848b37b43568df4a60c (diff)
st/va: add conversion for yv12 to nv12in putimage v2
For putimage call, if image format is yv12 (or IYUV with U V field swap) and surface format is nv12, then we need to convert yv12 to nv12 and then copy the converted data from image to surface. We can't use the existing logic where surface is destroyed and re-created with yv12 format. v2 (chk): fix some compiler warnings and commit message Signed-off-by: Boyuan Zhang <[email protected]> Signed-off-by: Christian König <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/state_trackers/va/image.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c
index 36b24695edf..bd60d3eb1d8 100644
--- a/src/gallium/state_trackers/va/image.c
+++ b/src/gallium/state_trackers/va/image.c
@@ -471,7 +471,9 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
return VA_STATUS_ERROR_OPERATION_FAILED;
}
- if (format != surf->buffer->buffer_format) {
+ if ((format != surf->buffer->buffer_format) &&
+ ((format != PIPE_FORMAT_YV12) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12)) &&
+ ((format != PIPE_FORMAT_IYUV) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12))) {
struct pipe_video_buffer *tmp_buf;
struct pipe_video_buffer templat = surf->templat;
@@ -513,12 +515,30 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
unsigned width, height;
if (!views[i]) continue;
vlVaVideoSurfaceSize(surf, i, &width, &height);
- for (j = 0; j < views[i]->texture->array_size; ++j) {
- struct pipe_box dst_box = {0, 0, j, width, height, 1};
- drv->pipe->texture_subdata(drv->pipe, views[i]->texture, 0,
- PIPE_TRANSFER_WRITE, &dst_box,
- data[i] + pitches[i] * j,
- pitches[i] * views[i]->texture->array_size, 0);
+ if (((format == PIPE_FORMAT_YV12) || (format == PIPE_FORMAT_IYUV)) &&
+ (surf->buffer->buffer_format == PIPE_FORMAT_NV12)) {
+ struct pipe_transfer *transfer = NULL;
+ uint8_t *map = NULL;
+ struct pipe_box dst_box_1 = {0, 0, 0, width, height, 1};
+ map = drv->pipe->transfer_map(drv->pipe,
+ views[i]->texture,
+ 0,
+ PIPE_TRANSFER_DISCARD_RANGE,
+ &dst_box_1, &transfer);
+ if (map == NULL)
+ return VA_STATUS_ERROR_OPERATION_FAILED;
+
+ u_copy_yv12_img_to_nv12_surf ((ubyte * const*)data, map, width, height,
+ pitches[i], transfer->stride, i);
+ pipe_transfer_unmap(drv->pipe, transfer);
+ } else {
+ for (j = 0; j < views[i]->texture->array_size; ++j) {
+ struct pipe_box dst_box = {0, 0, j, width, height, 1};
+ drv->pipe->texture_subdata(drv->pipe, views[i]->texture, 0,
+ PIPE_TRANSFER_WRITE, &dst_box,
+ data[i] + pitches[i] * j,
+ pitches[i] * views[i]->texture->array_size, 0);
+ }
}
}
pipe_mutex_unlock(drv->mutex);