Commit 558b0797 authored by Gwenole Beauchesne's avatar Gwenole Beauchesne Committed by Xiang, Haihao

Simplify vaGetImage().

parent eb3dd03b
...@@ -1469,13 +1469,26 @@ i965_SetImagePalette(VADriverContextP ctx, ...@@ -1469,13 +1469,26 @@ i965_SetImagePalette(VADriverContextP ctx,
return VA_STATUS_SUCCESS; return VA_STATUS_SUCCESS;
} }
static inline void
memcpy_pic(uint8_t *dst, unsigned int dst_stride,
const uint8_t *src, unsigned int src_stride,
unsigned int len, unsigned int height)
{
unsigned int i;
for (i = 0; i < height; i++) {
memcpy(dst, src, len);
dst += dst_stride;
src += src_stride;
}
}
static void static void
get_image_yv12(struct object_image *obj_image, uint8_t *image_data, get_image_i420(struct object_image *obj_image, uint8_t *image_data,
struct object_surface *obj_surface, struct object_surface *obj_surface,
const VARectangle *rect) const VARectangle *rect)
{ {
uint8_t *dst[3], *src[3]; uint8_t *dst[3], *src[3];
int i, x, y, w, h;
if (!obj_surface->bo) if (!obj_surface->bo)
return; return;
...@@ -1485,11 +1498,8 @@ get_image_yv12(struct object_image *obj_image, uint8_t *image_data, ...@@ -1485,11 +1498,8 @@ get_image_yv12(struct object_image *obj_image, uint8_t *image_data,
if (!obj_surface->bo->virtual) if (!obj_surface->bo->virtual)
return; return;
x = rect->x; /* Dest VA image has either I420 or YV12 format.
y = rect->y; Source VA surface alway has I420 format */
w = rect->width;
h = rect->height;
dst[0] = image_data + obj_image->image.offsets[0]; dst[0] = image_data + obj_image->image.offsets[0];
src[0] = (uint8_t *)obj_surface->bo->virtual; src[0] = (uint8_t *)obj_surface->bo->virtual;
dst[1] = image_data + obj_image->image.offsets[1]; dst[1] = image_data + obj_image->image.offsets[1];
...@@ -1497,34 +1507,26 @@ get_image_yv12(struct object_image *obj_image, uint8_t *image_data, ...@@ -1497,34 +1507,26 @@ get_image_yv12(struct object_image *obj_image, uint8_t *image_data,
dst[2] = image_data + obj_image->image.offsets[2]; dst[2] = image_data + obj_image->image.offsets[2];
src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2); src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
dst[0] += y * obj_image->image.pitches[0] + x; /* Y plane */
src[0] += y * obj_surface->width + x; dst[0] += rect->y * obj_image->image.pitches[0] + rect->x;
for (i = 0; i < h; i++) { src[0] += rect->y * obj_surface->width + rect->x;
memcpy(dst[0], src[0], w); memcpy_pic(dst[0], obj_image->image.pitches[0],
dst[0] += obj_image->image.pitches[0]; src[0], obj_surface->width,
src[0] += obj_surface->width; rect->width, rect->height);
}
/* U plane */
x /= 2; dst[1] += (rect->y / 2) * obj_image->image.pitches[1] + rect->x / 2;
y /= 2; src[1] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
w /= 2; memcpy_pic(dst[1], obj_image->image.pitches[1],
h /= 2; src[1], obj_surface->width / 2,
rect->width / 2, rect->height / 2);
dst[1] += y * obj_image->image.pitches[1] + x;
src[1] += y * obj_surface->width / 2 + x; /* V plane */
for (i = 0; i < h; i++) { dst[2] += (rect->y / 2) * obj_image->image.pitches[2] + rect->x / 2;
memcpy(dst[1], src[1], w); src[2] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
dst[1] += obj_image->image.pitches[1]; memcpy_pic(dst[2], obj_image->image.pitches[2],
src[1] += obj_surface->width / 2; src[2], obj_surface->width / 2,
} rect->width / 2, rect->height / 2);
dst[2] += y * obj_image->image.pitches[2] + y;
src[2] += y * obj_surface->width / 2 + x;
for (i = 0; i < h; i++) {
memcpy(dst[2], src[2], w);
dst[2] += obj_image->image.pitches[2];
src[2] += obj_surface->width / 2;
}
dri_bo_unmap(obj_surface->bo); dri_bo_unmap(obj_surface->bo);
} }
...@@ -1534,8 +1536,7 @@ get_image_nv12(struct object_image *obj_image, uint8_t *image_data, ...@@ -1534,8 +1536,7 @@ get_image_nv12(struct object_image *obj_image, uint8_t *image_data,
struct object_surface *obj_surface, struct object_surface *obj_surface,
const VARectangle *rect) const VARectangle *rect)
{ {
uint8_t *dst, *src; uint8_t *dst[2], *src[2];
int i, x, y, w, h;
if (!obj_surface->bo) if (!obj_surface->bo)
return; return;
...@@ -1545,30 +1546,25 @@ get_image_nv12(struct object_image *obj_image, uint8_t *image_data, ...@@ -1545,30 +1546,25 @@ get_image_nv12(struct object_image *obj_image, uint8_t *image_data,
if (!obj_surface->bo->virtual) if (!obj_surface->bo->virtual)
return; return;
x = rect->x; /* Both dest VA image and source surface have NV12 format */
y = rect->y; dst[0] = image_data + obj_image->image.offsets[0];
w = rect->width; src[0] = (uint8_t *)obj_surface->bo->virtual;
h = rect->height; dst[1] = image_data + obj_image->image.offsets[1];
src[1] = src[0] + obj_surface->width * obj_surface->height;
dst = image_data + obj_image->image.offsets[0] + y * obj_image->image.pitches[0] + x;
src = (uint8_t *)obj_surface->bo->virtual + y * obj_surface->width + x;
for (i = 0; i < h; i++) {
memcpy(dst, src, w);
dst += obj_image->image.pitches[0];
src += obj_surface->width;
}
x /= 2; /* Y plane */
y /= 2; dst[0] += rect->y * obj_image->image.pitches[0] + rect->x;
h /= 2; src[0] += rect->y * obj_surface->width + rect->x;
memcpy_pic(dst[0], obj_image->image.pitches[0],
src[0], obj_surface->width,
rect->width, rect->height);
dst = image_data + obj_image->image.offsets[1] + y * obj_image->image.pitches[1] + x * 2; /* UV plane */
src = (uint8_t *)obj_surface->bo->virtual + obj_surface->width * obj_surface->height + y * obj_surface->width + x * 2; dst[1] += (rect->y / 2) * obj_image->image.pitches[1] + (rect->x & -2);
for (i = 0; i < h; i++) { src[1] += (rect->y / 2) * obj_surface->width + (rect->x & -2);
memcpy(dst, src, w); memcpy_pic(dst[1], obj_image->image.pitches[1],
dst += obj_image->image.pitches[1]; src[1], obj_surface->width,
src += obj_surface->width; rect->width, rect->height / 2);
}
dri_bo_unmap(obj_surface->bo); dri_bo_unmap(obj_surface->bo);
} }
...@@ -1624,7 +1620,7 @@ i965_GetImage(VADriverContextP ctx, ...@@ -1624,7 +1620,7 @@ i965_GetImage(VADriverContextP ctx,
/* I420 is native format for MPEG-2 decoded surfaces */ /* I420 is native format for MPEG-2 decoded surfaces */
if (render_state->interleaved_uv) if (render_state->interleaved_uv)
goto operation_failed; goto operation_failed;
get_image_yv12(obj_image, image_data, obj_surface, &rect); get_image_i420(obj_image, image_data, obj_surface, &rect);
break; break;
case VA_FOURCC('N','V','1','2'): case VA_FOURCC('N','V','1','2'):
/* NV12 is native format for H.264 decoded surfaces */ /* NV12 is native format for H.264 decoded surfaces */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment