summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
authorThomas Hellstrom <[email protected]>2017-02-22 13:07:47 +0100
committerThomas Hellstrom <[email protected]>2017-02-24 16:44:34 +0100
commit7b82efe4ee6b9a3453f87e301e93d3e403c8f5de (patch)
tree122bcead183c674fc90e56af50aeae3b56d5b419 /src/gallium/state_trackers
parent3a418322ec6d540b1334f42688839aefb5d88d6d (diff)
st/va: Fix up YV12 to NV12 putImage conversion
Use the utility u_copy_nv12_from_yv12 to implement this similarly to how it's been done in the VPAU state tracker. The old code mixed up planes and fields and didn't correctly handle video surfaces in interlaced format. Acked-by: Christian König <[email protected]> Signed-off-by: Thomas Hellstrom <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/va/image.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c
index bd60d3eb1d8..47d31de2dbe 100644
--- a/src/gallium/state_trackers/va/image.c
+++ b/src/gallium/state_trackers/va/image.c
@@ -513,28 +513,36 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
for (i = 0; i < vaimage->num_planes; ++i) {
unsigned width, height;
+ struct pipe_resource *tex;
+
if (!views[i]) continue;
- vlVaVideoSurfaceSize(surf, i, &width, &height);
- 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;
+ tex = views[i]->texture;
- 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,
+ vlVaVideoSurfaceSize(surf, i, &width, &height);
+ for (j = 0; j < tex->array_size; ++j) {
+ struct pipe_box dst_box = {0, 0, j, width, height, 1};
+
+ if (((format == PIPE_FORMAT_YV12) || (format == PIPE_FORMAT_IYUV))
+ && (surf->buffer->buffer_format == PIPE_FORMAT_NV12)
+ && i == 1) {
+ struct pipe_transfer *transfer = NULL;
+ uint8_t *map = NULL;
+
+ map = drv->pipe->transfer_map(drv->pipe,
+ tex,
+ 0,
+ PIPE_TRANSFER_WRITE |
+ PIPE_TRANSFER_DISCARD_RANGE,
+ &dst_box, &transfer);
+ if (map == NULL)
+ return VA_STATUS_ERROR_OPERATION_FAILED;
+
+ u_copy_nv12_from_yv12((const void * const*) data, pitches, i, j,
+ transfer->stride, tex->array_size,
+ map, dst_box.width, dst_box.height);
+ pipe_transfer_unmap(drv->pipe, transfer);
+ } else {
+ drv->pipe->texture_subdata(drv->pipe, tex, 0,
PIPE_TRANSFER_WRITE, &dst_box,
data[i] + pitches[i] * j,
pitches[i] * views[i]->texture->array_size, 0);