From 7b82efe4ee6b9a3453f87e301e93d3e403c8f5de Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 22 Feb 2017 13:07:47 +0100 Subject: [PATCH] st/va: Fix up YV12 to NV12 putImage conversion MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Thomas Hellstrom --- src/gallium/auxiliary/util/u_video.h | 37 --------------------------- src/gallium/state_trackers/va/image.c | 48 ++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 57 deletions(-) diff --git a/src/gallium/auxiliary/util/u_video.h b/src/gallium/auxiliary/util/u_video.h index 7cd6268..251e144 100644 --- a/src/gallium/auxiliary/util/u_video.h +++ b/src/gallium/auxiliary/util/u_video.h @@ -173,43 +173,6 @@ u_copy_yv12_to_nv12(void *const *destination_data, } static inline void -u_copy_yv12_img_to_nv12_surf(ubyte *const *src, - ubyte *dst, - unsigned width, - unsigned height, - unsigned src_stride, - unsigned dst_stride, - int field) -{ - if (field == 0) { - ubyte *src_0 = src[field]; - for (int i = 0; i < height ; i++) { - memcpy(dst, src_0, width); - dst += dst_stride; - src_0 += src_stride; - } - } else if (field == 1) { - const ubyte *src_1 = src[field]; - const ubyte *src_2 = src[field+1]; - bool odd = true; - for (unsigned i = 0; i < height ; i++) { - for (unsigned j = 0; j < width*2 ; j++) { - if (odd == false) { - dst[j] = src_1[j/2]; - odd = true; - } else { - dst[j] = src_2[j/2]; - odd = false; - } - } - dst += dst_stride; - src_1 += src_stride; - src_2 += src_stride; - } - } -} - -static inline void u_copy_swap422_packed(void *const *destination_data, uint32_t const *destination_pitches, int src_plane, int src_field, diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index bd60d3e..47d31de 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); -- 2.7.4