[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