[Mesa-dev] [PATCH 07/11] st/va: add conversion for yv12 to nv12in putimage

Boyuan Zhang boyuan.zhang at amd.com
Thu Jul 14 21:06:28 UTC 2016


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.

Signed-off-by: Boyuan Zhang <boyuan.zhang at amd.com>
---
 src/gallium/state_trackers/va/image.c | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c
index 1b956e3..47895ee 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,29 @@ 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->transfer_inline_write(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 (data, map, vaimage->offsets, 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->transfer_inline_write(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);
-- 
2.7.4



More information about the mesa-dev mailing list