[Mesa-dev] [PATCH 04/12] st/va: use correct pitch value for deriveimage call

Boyuan Zhang boyuan.zhang at amd.com
Thu Jun 30 18:30:45 UTC 2016


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

diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c
index 1b956e3..c82b554 100644
--- a/src/gallium/state_trackers/va/image.c
+++ b/src/gallium/state_trackers/va/image.c
@@ -185,10 +185,12 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
    vlVaSurface *surf;
    vlVaBuffer *img_buf;
    VAImage *img;
+   struct pipe_sampler_view **views;
    struct pipe_surface **surfaces;
    int w;
    int h;
    int i;
+   int pitch[3];
 
    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
@@ -220,6 +222,51 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
    w = align(surf->buffer->width, 2);
    h = align(surf->buffer->height, 2);
 
+   switch (img->format.fourcc) {
+      case VA_FOURCC('N','V','1','2'):
+         img->num_planes = 2;
+         break;
+
+      case VA_FOURCC('I','4','2','0'):
+      case VA_FOURCC('Y','V','1','2'):
+         img->num_planes = 3;
+         break;
+
+      case VA_FOURCC('U','Y','V','Y'):
+      case VA_FOURCC('Y','U','Y','V'):
+      case VA_FOURCC('B','G','R','A'):
+      case VA_FOURCC('R','G','B','A'):
+      case VA_FOURCC('B','G','R','X'):
+      case VA_FOURCC('R','G','B','X'):
+         img->num_planes = 1;
+         break;
+
+      default:
+         /* VaDeriveImage is designed for contiguous planes. */
+         FREE(img);
+         return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
+   }
+
+   views = surf->buffer->get_sampler_view_planes(surf->buffer);
+   if (!views)
+      return VA_STATUS_ERROR_OPERATION_FAILED;
+
+   for (i = 0; i < img->num_planes; i++) {
+      unsigned width, height;
+      if (!views[i]) continue;
+      vlVaVideoSurfaceSize(surf, i, &width, &height);
+      struct pipe_box box = {0, 0, 0, width, height, 1};
+      struct pipe_transfer *transfer;
+      uint8_t *map;
+      map = drv->pipe->transfer_map(drv->pipe, views[i]->texture, 0,
+                                    PIPE_TRANSFER_READ, &box, &transfer);
+      if (!map)
+         return VA_STATUS_ERROR_OPERATION_FAILED;
+
+      pitch[i] = transfer->stride;
+      pipe_transfer_unmap(drv->pipe, transfer);
+   }
+
    for (i = 0; i < ARRAY_SIZE(formats); ++i) {
       if (img->format.fourcc == formats[i].fourcc) {
          img->format = formats[i];
@@ -231,9 +278,9 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
    case VA_FOURCC('U','Y','V','Y'):
    case VA_FOURCC('Y','U','Y','V'):
       img->num_planes = 1;
-      img->pitches[0] = w * 2;
+      img->pitches[0] = pitch[0] * 2;
       img->offsets[0] = 0;
-      img->data_size  = w * h * 2;
+      img->data_size  = pitch[0] * h * 2;
       break;
 
    case VA_FOURCC('B','G','R','A'):
@@ -241,9 +288,9 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
    case VA_FOURCC('B','G','R','X'):
    case VA_FOURCC('R','G','B','X'):
       img->num_planes = 1;
-      img->pitches[0] = w * 4;
+      img->pitches[0] = pitch[0] * 4;
       img->offsets[0] = 0;
-      img->data_size  = w * h * 4;
+      img->data_size  = pitch[0] * h * 4;
       break;
 
    default:
-- 
2.7.4



More information about the mesa-dev mailing list