Hi Ilia, >-----Original Message----- >From: ibmir...@gmail.com [mailto:ibmir...@gmail.com] On Behalf Of Ilia Mirkin >Sent: Friday, September 26, 2014 4:37 PM >To: Liu, Leo >Cc: mesa-dev@lists.freedesktop.org >Subject: Re: [Mesa-dev] [PATCH v2 6/6] st/va: implement >vlVa(Query|Create|Get|Put|Destroy)Image > [....]
>> + case VA_FOURCC('U','Y','V','Y'): >> + case VA_FOURCC('Y','U','Y','V'): >> + image->num_planes = 1; >> + image->pitches[0] = w * 4; >> + image->offsets[0] = 0; >> + image->data_size = w * h * 4; > >Is this right? YUYV/UYVY stores 2 pixels in 4 bytes, so it should be * 2, no? >Also, >for this case, h probably doesn't need to be even, although it may still be a >good >idea... You are right. I will fix it . Thanks, Leo > >> + break; >> + >> + default: >> return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; >> + } >> >> - return VA_STATUS_ERROR_UNIMPLEMENTED; >> + return vlVaCreateBuffer(ctx, 0, VAImageBufferType, >> + align(image->data_size, 16), >> + 1, NULL, &image->buf); >> } >> >> VAStatus >> @@ -69,10 +162,16 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID >> surface, VAImage *image) VAStatus vlVaDestroyImage(VADriverContextP >> ctx, VAImageID image) { >> + VAImage *vaimage; >> + >> if (!ctx) >> return VA_STATUS_ERROR_INVALID_CONTEXT; >> >> - return VA_STATUS_ERROR_UNIMPLEMENTED; >> + vaimage = handle_table_get(VL_VA_DRIVER(ctx)->htab, image); >> + if (!vaimage) >> + return VA_STATUS_ERROR_INVALID_IMAGE; >> + >> + return vlVaDestroyBuffer(ctx, vaimage->buf); >> } >> >> VAStatus >> @@ -88,10 +187,87 @@ VAStatus >> vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y, >> unsigned int width, unsigned int height, VAImageID >> image) { >> + vlVaDriver *drv; >> + vlVaSurface *surf; >> + vlVaBuffer *img_buf; >> + VAImage *vaimage; >> + struct pipe_sampler_view **views; >> + enum pipe_format format; >> + void *data[3]; >> + bool convert = false; >> + unsigned i, j; >> + >> if (!ctx) >> return VA_STATUS_ERROR_INVALID_CONTEXT; >> >> - return VA_STATUS_ERROR_UNIMPLEMENTED; >> + drv = VL_VA_DRIVER(ctx); >> + >> + surf = handle_table_get(drv->htab, surface); >> + if (!surf || !surf->buffer) >> + return VA_STATUS_ERROR_INVALID_SURFACE; >> + >> + vaimage = handle_table_get(drv->htab, image); >> + if (!vaimage) >> + return VA_STATUS_ERROR_INVALID_IMAGE; >> + >> + img_buf = handle_table_get(drv->htab, vaimage->buf); >> + if (!img_buf) >> + return VA_STATUS_ERROR_INVALID_BUFFER; >> + >> + format = YCbCrToPipe(vaimage->format.fourcc); >> + if (format == PIPE_FORMAT_NONE) >> + return VA_STATUS_ERROR_OPERATION_FAILED; >> + >> + if (format != surf->buffer->buffer_format) { >> + /* support NV12 to YV12 conversion now only */ >> + if (format == PIPE_FORMAT_YV12 && >> + surf->buffer->buffer_format == PIPE_FORMAT_NV12) >> + convert = true; >> + else >> + return VA_STATUS_ERROR_OPERATION_FAILED; >> + } >> + >> + views = surf->buffer->get_sampler_view_planes(surf->buffer); >> + if (!views) >> + return VA_STATUS_ERROR_OPERATION_FAILED; >> + >> + for (i = 0; i < vaimage->num_planes; i++) >> + data[i] = img_buf->data + vaimage->offsets[i]; >> + if (vaimage->format.fourcc == VA_FOURCC('I','4','2','0')) { >> + void *tmp = data[1]; >> + data[1] = data[2]; >> + data[2] = tmp; >> + } >> + >> + for (i = 0; i < vaimage->num_planes; i++) { >> + unsigned width, height; >> + if (!views[i]) continue; >> + data[i] = img_buf->data + vaimage->offsets[i]; >> + vlVaVideoSurfaceSize(surf, i, &width, &height); >> + for (j = 0; j < views[i]->texture->array_size; ++j) { >> + struct pipe_box box = {0, 0, j, 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; >> + >> + if (i == 1 && convert) { >> + u_copy_nv12_to_yv12(data, vaimage->pitches, >> + i, j, transfer->stride, views[i]->texture->array_size, >> + map, box.width, box.height); >> + } else { >> + util_copy_rect(data[i] + vaimage->pitches[i] * j, >> + views[i]->texture->format, >> + vaimage->pitches[i] * views[i]->texture->array_size, 0, 0, >> + box.width, box.height, map, transfer->stride, 0, 0); >> + } >> + pipe_transfer_unmap(drv->pipe, transfer); >> + } >> + } >> + >> + return VA_STATUS_SUCCESS; >> } >> >> VAStatus >> @@ -99,8 +275,70 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID >surface, VAImageID image, >> int src_x, int src_y, unsigned int src_width, unsigned int >> src_height, >> int dest_x, int dest_y, unsigned int dest_width, >> unsigned int dest_height) { >> + vlVaDriver *drv; >> + vlVaSurface *surf; >> + vlVaBuffer *img_buf; >> + VAImage *vaimage; >> + struct pipe_sampler_view **views; >> + enum pipe_format format; >> + void *data[3]; >> + unsigned i, j; >> + >> if (!ctx) >> return VA_STATUS_ERROR_INVALID_CONTEXT; >> >> - return VA_STATUS_ERROR_UNIMPLEMENTED; >> + drv = VL_VA_DRIVER(ctx); >> + >> + surf = handle_table_get(drv->htab, surface); >> + if (!surf || !surf->buffer) >> + return VA_STATUS_ERROR_INVALID_SURFACE; >> + >> + vaimage = handle_table_get(drv->htab, image); >> + if (!vaimage) >> + return VA_STATUS_ERROR_INVALID_IMAGE; >> + >> + img_buf = handle_table_get(drv->htab, vaimage->buf); >> + if (!img_buf) >> + return VA_STATUS_ERROR_INVALID_BUFFER; >> + >> + format = YCbCrToPipe(vaimage->format.fourcc); >> + if (format == PIPE_FORMAT_NONE) >> + return VA_STATUS_ERROR_OPERATION_FAILED; >> + >> + if (surf->buffer == NULL || format != surf->buffer->buffer_format) { >> + if (surf->buffer) >> + surf->buffer->destroy(surf->buffer); >> + surf->templat.buffer_format = format; >> + surf->buffer = drv->pipe->create_video_buffer(drv->pipe, >> &surf->templat); >> + if (!surf->buffer) >> + return VA_STATUS_ERROR_ALLOCATION_FAILED; >> + } >> + >> + views = surf->buffer->get_sampler_view_planes(surf->buffer); >> + if (!views) >> + return VA_STATUS_ERROR_OPERATION_FAILED; >> + >> + for (i = 0; i < vaimage->num_planes; i++) >> + data[i] = img_buf->data + vaimage->offsets[i]; >> + if (vaimage->format.fourcc == VA_FOURCC('I','4','2','0')) { >> + void *tmp = data[1]; >> + data[1] = data[2]; >> + data[2] = tmp; >> + } >> + >> + for (i = 0; i < vaimage->num_planes; ++i) { >> + 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] + vaimage->pitches[i] * j, >> + vaimage->pitches[i] * views[i]->texture->array_size, >> + 0); >> + } >> + } >> + >> + return VA_STATUS_SUCCESS; >> } >> diff --git a/src/gallium/state_trackers/va/va_private.h >> b/src/gallium/state_trackers/va/va_private.h >> index 34e1f3e..060a1fa 100644 >> --- a/src/gallium/state_trackers/va/va_private.h >> +++ b/src/gallium/state_trackers/va/va_private.h >> @@ -44,6 +44,8 @@ >> #define VL_VA_DRIVER(ctx) ((vlVaDriver *)ctx->pDriverData) #define >> VL_VA_PSCREEN(ctx) (VL_VA_DRIVER(ctx)->vscreen->pscreen) >> >> +#define VL_VA_MAX_IMAGE_FORMATS 5 >> + >> static inline enum pipe_video_chroma_format ChromaToPipe(int format) >> { @@ -60,6 +62,26 @@ ChromaToPipe(int format) >> } >> } >> >> +static inline enum pipe_format >> +YCbCrToPipe(unsigned format) >> +{ >> + switch(format) { >> + case VA_FOURCC('N','V','1','2'): >> + return PIPE_FORMAT_NV12; >> + case VA_FOURCC('I','4','2','0'): >> + return PIPE_FORMAT_IYUV; >> + case VA_FOURCC('Y','V','1','2'): >> + return PIPE_FORMAT_YV12; >> + case VA_FOURCC('Y','U','Y','V'): >> + return PIPE_FORMAT_YUYV; >> + case VA_FOURCC('U','Y','V','Y'): >> + return PIPE_FORMAT_UYVY; >> + default: >> + assert(0); >> + return PIPE_FORMAT_NONE; >> + } >> +} >> + >> static inline VAProfile >> PipeToProfile(enum pipe_video_profile profile) { >> -- >> 1.9.1 >> >> _______________________________________________ >> mesa-dev mailing list >> mesa-dev@lists.freedesktop.org >> http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev