[Libva] [PATCH V2 3/6] Addin the implementation into i965_ouput_xv module.
Ung, Teng En
teng.en.ung at intel.com
Thu Sep 19 01:07:01 PDT 2013
Signed-off-by: Ung, Teng En <teng.en.ung at intel.com>
---
src/i965_output_xv.c | 203 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 198 insertions(+), 5 deletions(-)
diff --git a/src/i965_output_xv.c b/src/i965_output_xv.c
index 8b361da..0138e99 100644
--- a/src/i965_output_xv.c
+++ b/src/i965_output_xv.c
@@ -30,26 +30,92 @@
#include "i965_drv_video.h"
#include "i965_output_xv.h"
+#include "va_xv.h"
+
+#define NUM_VAXV_BUF 3
+
struct va_xv_output {
int vaxv_port;
unsigned int vaxv_format;
+ unsigned int vaxv_caps;
+ int vaxv_format_index;
+
+ int current_buf;
+ VASurfaceID va_surf_id[NUM_VAXV_BUF];
+};
+
+static struct vaxv_formats {
+ unsigned int fourcc;
+ unsigned int va_format;
+ unsigned int subsample;
+} vaxv_formats_list[] = {
+ { VA_FOURCC('Y', 'U', 'Y', '2'), VA_RT_FORMAT_YUV422, SUBSAMPLE_YUV422H },
+ { VA_FOURCC('U', 'Y', 'V', 'Y'), VA_RT_FORMAT_YUV422, SUBSAMPLE_YUV422H },
};
+VAStatus
+i965_DestroySurfaces(VADriverContextP ctx,
+ VASurfaceID *surface_list,
+ int num_surfaces);
+VAStatus
+i965_CreateSurfaces(VADriverContextP ctx,
+ int width,
+ int height,
+ int format,
+ int num_surfaces,
+ VASurfaceID *surfaces);
+
+static void i965_CreateVAXVBuffer(VADriverContextP ctx,
+ struct va_xv_output *xv_output,
+ int width,
+ int height,
+ int fmt_idx,
+ int index)
+{
+ struct i965_driver_data *i965 = i965_driver_data(ctx);
+ struct object_surface *obj_surface;
+
+ i965_CreateSurfaces(ctx, width, height, vaxv_formats_list[fmt_idx].va_format, 1, &xv_output->va_surf_id[index]);
+ obj_surface = SURFACE(xv_output->va_surf_id[index]);
+ i965_check_alloc_surface_bo(ctx, obj_surface, 0, vaxv_formats_list[fmt_idx].fourcc, vaxv_formats_list[fmt_idx].subsample);
+}
+
+static void i965_DestroyVAXVBuffer(VADriverContextP ctx,
+ struct va_xv_output *xv_output,
+ int index)
+{
+ if (xv_output->va_surf_id[index] != 0) {
+ i965_DestroySurfaces(ctx, &xv_output->va_surf_id[index], 1);
+ xv_output->va_surf_id[index] = 0;
+ }
+}
+
bool
i965_output_xv_init(VADriverContextP ctx)
{
struct i965_driver_data * const i965 = i965_driver_data(ctx);
+ unsigned short major = 0, minor = 0;
+ int port_id = 0;
+
+ if (va_xvQueryVersion(ctx, &major, &minor) != VA_XV_STATUS_SUCCESS)
+ goto error;
+
+ if ((major != VAXV_MAJOR) || (minor != VAXV_MINOR))
+ goto error;
i965->xv_output = calloc(1, sizeof(struct va_xv_output));
if (!i965->xv_output) {
goto error;
+ } else {
+ i965->xv_output->vaxv_format_index = -1;
}
- /* Need to addin implementation, currently just disable all those
- * overlay and render attributes.
- */
- i965->num_display_attributes = 1;
+ if ((va_xvFindAndReservePort(ctx, &port_id) != VA_XV_STATUS_SUCCESS) &&
+ (!port_id))
+ goto error;
+
+ i965->xv_output->vaxv_port = port_id;
return true;
@@ -65,10 +131,23 @@ void
i965_output_xv_terminate(VADriverContextP ctx)
{
struct i965_driver_data * const i965 = i965_driver_data(ctx);
+ struct va_xv_output * const xv_output = i965->xv_output;
+ int i = 0;
if (!xv_output)
return;
+ if (xv_output->vaxv_port) {
+ va_xvFreePort(ctx, xv_output->vaxv_port);
+ xv_output->vaxv_port = 0;
+ }
+
+ for (i = 0; i < (NUM_VAXV_BUF - 1); ++i) {
+ if (xv_output->va_surf_id[i]) {
+ i965_DestroyVAXVBuffer(ctx, xv_output, i);
+ }
+ }
+
free(xv_output);
i965->xv_output = NULL;
}
@@ -87,6 +166,120 @@ i965_put_surface_xv(
{
struct i965_driver_data * const i965 = i965_driver_data(ctx);
struct va_xv_output * const xv_output = i965->xv_output;
+ VARectangle dest_rect;
+ struct i965_surface src_surface;
+ struct i965_surface dst_surface;
+ struct object_surface *obj_surface;
+ int next, width, height, ret, i;
+ va_xv_buf_t buf_out;
+
+ _i965LockMutex(&i965->render_mutex);
+
+ if (xv_output->current_buf >= (NUM_VAXV_BUF - 1)) {
+ next = 0;
+ } else {
+ next = xv_output->current_buf;
+ ++next;
+ }
+
+ if (!xv_output->vaxv_format) {
+ if (va_xvQueryPortFormat(ctx, xv_output->vaxv_port, &xv_output->vaxv_format)
+ != VA_XV_STATUS_SUCCESS)
+ goto error;
+
+ if (va_xvQueryPortCapabilities(ctx, xv_output->vaxv_port, &xv_output->vaxv_caps)
+ != VA_XV_STATUS_SUCCESS)
+ goto error;
+
+ if (xv_output->vaxv_format != VA_FOURCC('N', 'V', '1', '2')) {
+ for (i = 0; i < ARRAY_ELEMS(vaxv_formats_list); ++i) {
+ if (xv_output->vaxv_format == vaxv_formats_list[i].fourcc) break;
+ }
+ xv_output->vaxv_format_index = i;
+ }
+ }
+
+ if (xv_output->vaxv_format_index > -1) {
+ /* Currently only support YUY2 buffer. */
+ if (xv_output->vaxv_format_index >= ARRAY_ELEMS(vaxv_formats_list))
+ goto error;
+
+ buf_out.pixel_format = vaxv_formats_list[xv_output->vaxv_format_index].fourcc;
+
+ /* Use the if statement, future may need more checkings for different formats */
+ if (buf_out.pixel_format == VA_FOURCC('Y', 'U', 'Y', '2')) {
+ width = ALIGN(dst_rect->width, 32);
+ height = ALIGN(dst_rect->height, 2);
+
+ buf_out.pitches[0] = width * 2;
+ buf_out.pitches[1] = buf_out.pitches[2] = 0;
+
+ buf_out.offsets[0] = buf_out.offsets[1] = buf_out.offsets[2] = 0;
+ }
+
+ buf_out.buf_width = width;
+ buf_out.buf_height = height;
+
+ /* Create the surface buffer if it does not exist or different size. We
+ * are using triple buffering.
+ */
+ if (xv_output->va_surf_id[next]) {
+ obj_surface = SURFACE(xv_output->va_surf_id[next]);
+
+ if ((obj_surface->orig_width != width) ||
+ (obj_surface->orig_height != height)) {
+ i965_DestroyVAXVBuffer(ctx, xv_output, next);
+ i965_CreateVAXVBuffer(ctx, xv_output, width, height, xv_output->vaxv_format_index, next);
+ }
+ } else {
+ i965_CreateVAXVBuffer(ctx, xv_output, width, height, xv_output->vaxv_format_index, next);
+ }
+
+ obj_surface = SURFACE(surface);
+ src_surface.base = (struct object_base *) obj_surface;
+ src_surface.type = I965_SURFACE_TYPE_SURFACE;
+ src_surface.flags = I965_SURFACE_FLAG_FRAME;
+
+ obj_surface = SURFACE(xv_output->va_surf_id[next]);
+ dst_surface.base = (struct object_base *) obj_surface;
+ dst_surface.type = I965_SURFACE_TYPE_SURFACE;
+ dst_surface.flags = I965_SURFACE_FLAG_FRAME;
+
+ dest_rect.x = 0;
+ dest_rect.y = 0;
+
+ /* Scale the image to output size. */
+ dest_rect.width = dst_rect->width;
+ dest_rect.height = dst_rect->height;
+
+ /* Use VPP features to convert and scale. */
+ i965_image_processing(ctx,
+ &src_surface,
+ src_rect,
+ &dst_surface,
+ &dest_rect);
+ } else {
+ goto error; /* Currently there is no direct support for NV12 */
+ }
+
+ drm_intel_bo_flink(obj_surface->bo, &buf_out.buf_handle);
+
+ ret = va_xvPutImage(ctx, xv_output->vaxv_port, draw, &buf_out,
+ dest_rect.x, dest_rect.y, dest_rect.width, dest_rect.height,
+ dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height, flags);
+
+ if (ret == VA_XV_STATUS_SUCCESS) {
+ xv_output->current_buf = next;
+ } else {
+ goto error;
+ }
+
+ _i965UnlockMutex(&i965->render_mutex);
+
+ return VA_STATUS_SUCCESS;
+
+error:
+ _i965UnlockMutex(&i965->render_mutex);
- return VA_STATUS_ERROR_UNIMPLEMENTED;
+ return VA_STATUS_ERROR_UNKNOWN;
}
--
1.8.4
More information about the Libva
mailing list