/*
 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <malloc.h>
#ifdef ANDROID
#include <linux/ion.h>
#endif
#include <va/va_tpi.h>
#include "psb_drv_video.h"
#include "psb_drv_debug.h"
#include "psb_surface.h"
#include "psb_surface_attrib.h"


#define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;

#define CONFIG(id)  ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
#define SURFACE(id)    ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id ))
#define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))


/*
 * Create surface
 */
VAStatus psb_surface_create_from_ub(
    psb_driver_data_p driver_data,
    int width, int height, int fourcc,
    VASurfaceAttributeTPI *graphic_buffers,
    psb_surface_p psb_surface, /* out */
    void *vaddr,
    int fd,
    unsigned flags
)
{
    int ret = 0;

    if ((fourcc == VA_FOURCC_NV12) || (fourcc == VA_FOURCC_YV16) || (fourcc == VA_FOURCC_IYUV) || (fourcc == VA_FOURCC_RGBA)) {
        if ((width <= 0) || (width * height > 5120 * 5120) || (height <= 0)) {
            return VA_STATUS_ERROR_ALLOCATION_FAILED;
        }

        psb_surface->stride = graphic_buffers->luma_stride;
        if (0) {
            ;
        } else if (512 == graphic_buffers->luma_stride) {
            psb_surface->stride_mode = STRIDE_512;
        } else if (1024 == graphic_buffers->luma_stride) {
            psb_surface->stride_mode = STRIDE_1024;
        } else if (1280 == graphic_buffers->luma_stride) {
            psb_surface->stride_mode = STRIDE_1280;
        } else if (2048 == graphic_buffers->luma_stride) {
            psb_surface->stride_mode = STRIDE_2048;
        } else if (4096 == graphic_buffers->luma_stride) {
            psb_surface->stride_mode = STRIDE_4096;
        } else {
            psb_surface->stride_mode = STRIDE_NA;
        }
        if (psb_surface->stride != graphic_buffers->luma_stride) {
            return VA_STATUS_ERROR_ALLOCATION_FAILED;
        }

        psb_surface->luma_offset = 0;
        psb_surface->chroma_offset = psb_surface->stride * height;

        if (VA_FOURCC_NV12 == fourcc) {
            psb_surface->size = ((psb_surface->stride * height) * 3) / 2;
            psb_surface->extra_info[4] = VA_FOURCC_NV12;
        }
        else if (VA_FOURCC_YV16 == fourcc) {
            psb_surface->size = (psb_surface->stride * height) * 2;
            psb_surface->extra_info[4] = VA_FOURCC_YV16;
        }
        else if (VA_FOURCC_IYUV == fourcc) {
            psb_surface->size = ((psb_surface->stride * height) * 3) / 2;
            psb_surface->extra_info[4] = VA_FOURCC_IYUV;
        }
	else if (VA_FOURCC_RGBA == fourcc) {
            psb_surface->size = (psb_surface->stride * height) * 4;
            psb_surface->extra_info[4] = VA_FOURCC_RGBA;
        }

        psb_surface->extra_info[8] = psb_surface->extra_info[4];

    } else {
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
    }
#ifdef PSBVIDEO_MSVDX_DEC_TILING
    if (graphic_buffers->tiling)
        ret = psb_buffer_create_from_ub(driver_data, psb_surface->size,
                psb_bt_mmu_tiling, &psb_surface->buf,
                vaddr, fd, 0);
    else
#endif
        ret = psb_buffer_create_from_ub(driver_data, psb_surface->size,
                psb_bt_surface, &psb_surface->buf,
                vaddr, fd, flags);

    return ret ? VA_STATUS_ERROR_ALLOCATION_FAILED : VA_STATUS_SUCCESS;
}

#if 0
VAStatus psb_CreateSurfaceFromV4L2Buf(
    VADriverContextP ctx,
    int v4l2_fd,         /* file descriptor of V4L2 device */
    struct v4l2_format *v4l2_fmt,       /* format of V4L2 */
    struct v4l2_buffer *v4l2_buf,       /* V4L2 buffer */
    VASurfaceID *surface        /* out */
)
{
    INIT_DRIVER_DATA;
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    int surfaceID;
    object_surface_p obj_surface;
    psb_surface_p psb_surface;
    int width, height, buf_stride, buf_offset, size;
    unsigned long *user_ptr = NULL;

    if (IS_MRST(driver_data) == 0 && IS_MFLD(driver_data) == 0) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateSurfaceFromV4L2Buf isn't supported on non-MRST platform\n");
        return VA_STATUS_ERROR_UNKNOWN;
    }

    /* Todo:
     * sanity check if the v4l2 device on MRST is supported
     */
    if (V4L2_MEMORY_USERPTR == v4l2_buf->memory) {
        unsigned long tmp = (unsigned long)(v4l2_buf->m.userptr);

        if (tmp & 0xfff) {
            drv_debug_msg(VIDEO_DEBUG_ERROR, "The buffer address 0x%08x must be page aligned\n", tmp);
            return VA_STATUS_ERROR_UNKNOWN;
        }
    }

    surfaceID = object_heap_allocate(&driver_data->surface_heap);
    obj_surface = SURFACE(surfaceID);
    CHECK_ALLOCATION(obj_surface);

    MEMSET_OBJECT(obj_surface, struct object_surface_s);

    width = v4l2_fmt->fmt.pix.width;
    height = v4l2_fmt->fmt.pix.height;

    buf_stride = width; /* ? */
    buf_offset = v4l2_buf->m.offset;
    size = v4l2_buf->length;

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create Surface from V4L2 buffer: %dx%d, stride=%d, buffer offset=0x%08x, size=%d\n",
                             width, height, buf_stride, buf_offset, size);

    obj_surface->surface_id = surfaceID;
    *surface = surfaceID;
    obj_surface->context_id = -1;
    obj_surface->width = width;
    obj_surface->height = height;
    obj_surface->subpictures = NULL;
    obj_surface->subpic_count = 0;
    obj_surface->derived_imgcnt = 0;
    obj_surface->display_timestamp = 0;

    psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
    if (NULL == psb_surface) {
        object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
        obj_surface->surface_id = VA_INVALID_SURFACE;

        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;

        DEBUG_FAILURE;

        return vaStatus;
    }

#if PSB_MFLD_DUMMY_CODE
    /* current assume it is NV12 */
    if (IS_MRST(driver_data))
        vaStatus = psb_surface_create_camera(driver_data, width, height, buf_stride, size, psb_surface, 1, buf_offset);
    else {
        if (V4L2_MEMORY_USERPTR == v4l2_buf->memory)
            user_ptr = (unsigned long *)(v4l2_buf->m.userptr);
        else {
            user_ptr = mmap(NULL /* start anywhere */ ,
                            v4l2_buf->length,
                            PROT_READ ,
                            MAP_SHARED /* recommended */ ,
                            v4l2_fd, v4l2_buf->m.offset);
        }

        if (NULL != user_ptr && MAP_FAILED != user_ptr)
            vaStatus = psb_surface_create_camera_from_ub(driver_data, width, height,
                       buf_stride, size, psb_surface, 1, buf_offset, user_ptr);
        else {
            DEBUG_FAILURE;
            vaStatus = VA_STATUS_ERROR_UNKNOWN;
        }
    }
#else
        vaStatus = VA_STATUS_ERROR_UNKNOWN;
#endif


    if (VA_STATUS_SUCCESS != vaStatus) {
        free(psb_surface);
        object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
        obj_surface->surface_id = VA_INVALID_SURFACE;

        DEBUG_FAILURE;

        return vaStatus;
    }

    memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info));
    psb_surface->extra_info[4] = VA_FOURCC_NV12; /* temp treat is as IYUV */

    obj_surface->psb_surface = psb_surface;

    /* Error recovery */
    if (VA_STATUS_SUCCESS != vaStatus) {
        object_surface_p obj_surface = SURFACE(*surface);
        psb__destroy_surface(driver_data, obj_surface);
        *surface = VA_INVALID_SURFACE;
    }

    return vaStatus;
}
#endif


VAStatus psb_CreateSurfacesForUserPtr(
    VADriverContextP ctx,
    int Width,
    int Height,
    int format,
    int num_surfaces,
    VASurfaceID *surface_list,       /* out */
    unsigned size, /* total buffer size need to be allocated */
    unsigned int fourcc, /* expected fourcc */
    unsigned int luma_stride, /* luma stride, could be width aligned with a special value */
    unsigned int chroma_u_stride, /* chroma stride */
    unsigned int chroma_v_stride,
    unsigned int luma_offset, /* could be 0 */
    unsigned int chroma_u_offset, /* UV offset from the beginning of the memory */
    unsigned int chroma_v_offset,
    unsigned int tiling
)
{
    INIT_DRIVER_DATA
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    int i, height_origin;
    unsigned long buffer_stride;

    /* silient compiler warning */
    unsigned int width = (unsigned int)Width;
    unsigned int height = (unsigned int)Height;

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create surface: width %d, height %d, format 0x%08x"
                             "\n\t\t\t\t\tnum_surface %d, buffer size %d, fourcc 0x%08x"
                             "\n\t\t\t\t\tluma_stride %d, chroma u stride %d, chroma v stride %d"
                             "\n\t\t\t\t\tluma_offset %d, chroma u offset %d, chroma v offset %d\n",
                             width, height, format,
                             num_surfaces, size, fourcc,
                             luma_stride, chroma_u_stride, chroma_v_stride,
                             luma_offset, chroma_u_offset, chroma_v_offset);

    CHECK_INVALID_PARAM(num_surfaces <= 0);
    CHECK_SURFACE(surface_list);

    /* We only support one format */
    if ((VA_RT_FORMAT_YUV420 != format) && (VA_RT_FORMAT_RGB32 != format)) {
        vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
        DEBUG_FAILURE;
        return vaStatus;
    }

    /* We only support NV12 */
    if ((VA_RT_FORMAT_YUV420 == format) && (fourcc != VA_FOURCC_NV12)) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "Only support NV12 format\n");
        return VA_STATUS_ERROR_UNKNOWN;
    }

    vaStatus = psb__checkSurfaceDimensions(driver_data, width, height);
    CHECK_VASTATUS();

    if (VA_RT_FORMAT_YUV420 == format) {
    CHECK_INVALID_PARAM((size < width * height * 1.5) ||
        (luma_stride < width) ||
        (chroma_u_stride * 2 < width) ||
        (chroma_v_stride * 2 < width) ||
        (chroma_u_offset < luma_offset + width * height) ||
        (chroma_v_offset < luma_offset + width * height));
    } else if (VA_RT_FORMAT_RGB32 == format) {
    CHECK_INVALID_PARAM((size < width * height * 4) ||
        (luma_stride < width) ||
        (chroma_u_stride * 2 < width) ||
        (chroma_v_stride * 2 < width) ||
        (chroma_u_offset < luma_offset + width * height) ||
        (chroma_v_offset < luma_offset + width * height));
    }

    height_origin = height;

    for (i = 0; i < num_surfaces; i++) {
        int surfaceID;
        object_surface_p obj_surface;
        psb_surface_p psb_surface;

        surfaceID = object_heap_allocate(&driver_data->surface_heap);
        obj_surface = SURFACE(surfaceID);
        if (NULL == obj_surface) {
            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
            DEBUG_FAILURE;
            break;
        }
        MEMSET_OBJECT(obj_surface, struct object_surface_s);

        obj_surface->surface_id = surfaceID;
        surface_list[i] = surfaceID;
        obj_surface->context_id = -1;
        obj_surface->width = width;
        obj_surface->height = height;
        obj_surface->width_r = width;
        obj_surface->height_r = height;
        obj_surface->height_origin = height_origin;
	obj_surface->is_ref_surface = 0;

        psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
        if (NULL == psb_surface) {
            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
            obj_surface->surface_id = VA_INVALID_SURFACE;

            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;

            DEBUG_FAILURE;
            break;
        }


        vaStatus = psb_surface_create_for_userptr(driver_data, width, height,
                   size,
                   fourcc,
                   luma_stride,
                   chroma_u_stride,
                   chroma_v_stride,
                   luma_offset,
                   chroma_u_offset,
                   chroma_v_offset,
                   psb_surface
                                                 );

        if (VA_STATUS_SUCCESS != vaStatus) {
            free(psb_surface);
            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
            obj_surface->surface_id = VA_INVALID_SURFACE;

            DEBUG_FAILURE;
            break;
        }
        buffer_stride = psb_surface->stride;
        /* by default, surface fourcc is NV12 */
        memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info));
        psb_surface->extra_info[4] = fourcc;
        psb_surface->extra_info[8] = fourcc;
#ifdef PSBVIDEO_MSVDX_DEC_TILING
	psb_surface->extra_info[7] = tiling;
#endif
        obj_surface->psb_surface = psb_surface;
    }

    /* Error recovery */
    if (VA_STATUS_SUCCESS != vaStatus) {
        /* surface_list[i-1] was the last successful allocation */
        for (; i--;) {
            object_surface_p obj_surface = SURFACE(surface_list[i]);
            psb__destroy_surface(driver_data, obj_surface);
            surface_list[i] = VA_INVALID_SURFACE;
        }
    }


    return vaStatus;
}

VAStatus  psb_CreateSurfaceFromKBuf(
    VADriverContextP ctx,
    int _width,
    int _height,
    int format,
    VASurfaceID *surface,       /* out */
    unsigned int kbuf_handle, /* kernel buffer handle*/
    unsigned size, /* kernel buffer size */
    unsigned int kBuf_fourcc, /* expected fourcc */
    unsigned int luma_stride, /* luma stride, could be width aligned with a special value */
    unsigned int chroma_u_stride, /* chroma stride */
    unsigned int chroma_v_stride,
    unsigned int luma_offset, /* could be 0 */
    unsigned int chroma_u_offset, /* UV offset from the beginning of the memory */
    unsigned int chroma_v_offset,
    unsigned int tiling
)
{
    INIT_DRIVER_DATA
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    unsigned long buffer_stride;

    /* silient compiler warning */
    unsigned int width = (unsigned int)_width;
    unsigned int height = (unsigned int)_height;

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create surface: width %d, height %d, format 0x%08x"
                             "\n\t\t\t\t\tnum_surface %d, buffer size %d, fourcc 0x%08x"
                             "\n\t\t\t\t\tluma_stride %d, chroma u stride %d, chroma v stride %d"
                             "\n\t\t\t\t\tluma_offset %d, chroma u offset %d, chroma v offset %d\n",
                             width, height, format,
                             size, kBuf_fourcc,
                             luma_stride, chroma_u_stride, chroma_v_stride,
                             luma_offset, chroma_u_offset, chroma_v_offset);

    CHECK_SURFACE(surface);

    /* We only support one format */
    if (VA_RT_FORMAT_YUV420 != format) {
        vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
        DEBUG_FAILURE;
        return vaStatus;
    }

    /* We only support NV12/YV12 */

    if ((VA_RT_FORMAT_YUV420 == format) && (kBuf_fourcc != VA_FOURCC_NV12)) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "Only support NV12 format\n");
        return VA_STATUS_ERROR_UNKNOWN;
    }
    /*
    vaStatus = psb__checkSurfaceDimensions(driver_data, width, height);
    CHECK_VASTATUS();
    */

    CHECK_INVALID_PARAM((size < width * height * 1.5) ||
        (luma_stride < width) ||
        (chroma_u_stride * 2 < width) ||
        (chroma_v_stride * 2 < width) ||
        (chroma_u_offset < luma_offset + width * height) ||
        (chroma_v_offset < luma_offset + width * height));

    int surfaceID;
    object_surface_p obj_surface;
    psb_surface_p psb_surface;

    surfaceID = object_heap_allocate(&driver_data->surface_heap);
    obj_surface = SURFACE(surfaceID);
    CHECK_ALLOCATION(obj_surface);

    MEMSET_OBJECT(obj_surface, struct object_surface_s);

    obj_surface->surface_id = surfaceID;
    *surface = surfaceID;
    obj_surface->context_id = -1;
    obj_surface->width = width;
    obj_surface->height = height;
    obj_surface->width_r = width;
    obj_surface->height_r = height;
    obj_surface->height_origin = height;
    obj_surface->is_ref_surface = 0;

    psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
    if (NULL == psb_surface) {
        object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
        obj_surface->surface_id = VA_INVALID_SURFACE;

        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;

        DEBUG_FAILURE;
        return vaStatus;
    }

    vaStatus = psb_surface_create_from_kbuf(driver_data, width, height,
                                            size,
                                            kBuf_fourcc,
                                            kbuf_handle,
                                            luma_stride,
                                            chroma_u_stride,
                                            chroma_v_stride,
                                            luma_offset,
                                            chroma_u_offset,
                                            chroma_v_offset,
                                            psb_surface);

    if (VA_STATUS_SUCCESS != vaStatus) {
        free(psb_surface);
        object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
        obj_surface->surface_id = VA_INVALID_SURFACE;

        DEBUG_FAILURE;
        return vaStatus;
    }
    buffer_stride = psb_surface->stride;
    /* by default, surface fourcc is NV12 */
    memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info));
    psb_surface->extra_info[4] = kBuf_fourcc;
    psb_surface->extra_info[8] = kBuf_fourcc;
#ifdef PSBVIDEO_MSVDX_DEC_TILING
    psb_surface->extra_info[7] = tiling;
#endif
    obj_surface->psb_surface = psb_surface;

    /* Error recovery */
    if (VA_STATUS_SUCCESS != vaStatus) {
        object_surface_p obj_surface = SURFACE(surfaceID);
        psb__destroy_surface(driver_data, obj_surface);
        *surface = VA_INVALID_SURFACE;
    }

    return vaStatus;
}

VAStatus  psb_CreateSurfaceFromUserspace(
        VADriverContextP ctx,
        int width,
        int height,
        int format,
        int num_surfaces,
        VASurfaceID *surface_list,        /* out */
        VASurfaceAttributeTPI *attribute_tpi
)
{
    INIT_DRIVER_DATA;
    VAStatus vaStatus = VA_STATUS_SUCCESS;
#ifdef ANDROID
    unsigned int *vaddr;
    unsigned long fourcc;
    int surfaceID;
    object_surface_p obj_surface;
    psb_surface_p psb_surface;
    int i;

    switch (format) {
    case VA_RT_FORMAT_YUV422:
        fourcc = VA_FOURCC_YV16;
        break;
    case VA_RT_FORMAT_YUV420:
    default:
        fourcc = VA_FOURCC_NV12;
        break;
    }

    for (i=0; i < num_surfaces; i++) {
        vaddr = (unsigned int *)(attribute_tpi->buffers[i]);
        surfaceID = object_heap_allocate(&driver_data->surface_heap);
        obj_surface = SURFACE(surfaceID);
        if (NULL == obj_surface) {
            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
            DEBUG_FAILURE;
            break;
        }
        MEMSET_OBJECT(obj_surface, struct object_surface_s);

        obj_surface->surface_id = surfaceID;
        surface_list[i] = surfaceID;
        obj_surface->context_id = -1;
        obj_surface->width = attribute_tpi->width;
        obj_surface->height = attribute_tpi->height;
        obj_surface->width_r = attribute_tpi->width;
        obj_surface->height_r = attribute_tpi->height;
	obj_surface->is_ref_surface = 0;

        psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
        if (NULL == psb_surface) {
            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
            obj_surface->surface_id = VA_INVALID_SURFACE;
            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
            DEBUG_FAILURE;
            break;
        }

        if (attribute_tpi->type == VAExternalMemoryNoneCacheUserPointer)
            vaStatus = psb_surface_create_from_ub(driver_data, width, height, fourcc,
                    attribute_tpi, psb_surface, vaddr, -1, PSB_USER_BUFFER_UNCACHED);
        else {
            vaStatus = psb_surface_create_from_ub(driver_data, width, height, fourcc,
                    attribute_tpi, psb_surface, vaddr, -1,  0);
            psb_surface->buf.unfence_flag = 2;
        }
        obj_surface->psb_surface = psb_surface;

        if (VA_STATUS_SUCCESS != vaStatus) {
            free(psb_surface);
            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
            obj_surface->surface_id = VA_INVALID_SURFACE;
            DEBUG_FAILURE;
            break;
        }
        /* by default, surface fourcc is NV12 */
        memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info));
        psb_surface->extra_info[4] = fourcc;
        psb_surface->extra_info[8] = fourcc;
        obj_surface->psb_surface = psb_surface;

        /* Error recovery */
        if (VA_STATUS_SUCCESS != vaStatus) {
            object_surface_p obj_surface = SURFACE(surfaceID);
            psb__destroy_surface(driver_data, obj_surface);
        }
    }
#endif
    return vaStatus;
}

VAStatus  psb_CreateSurfaceFromION(
        VADriverContextP ctx,
        int width,
        int height,
        int format,
        int num_surfaces,
        VASurfaceID *surface_list,        /* out */
        VASurfaceAttributeTPI *attribute_tpi
)
{
    INIT_DRIVER_DATA;
    VAStatus vaStatus = VA_STATUS_SUCCESS;
#ifdef ANDROID
    unsigned int *vaddr = NULL;
    unsigned long fourcc;
    int surfaceID;
    object_surface_p obj_surface;
    psb_surface_p psb_surface;
    int i;
    unsigned int source_size = 0;
    int ion_fd = 0;
    int ion_ret = 0;
    struct ion_fd_data ion_source_share;

    switch (format) {
    case VA_RT_FORMAT_YUV422:
        fourcc = VA_FOURCC_YV16;
        break;
    case VA_RT_FORMAT_YUV420:
    default:
        fourcc = VA_FOURCC_NV12;
        break;
    }

    ion_fd = open("/dev/ion", O_RDWR);
    if (ion_fd < 0) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Fail to open the ion device!\n", __FUNCTION__);
        return VA_STATUS_ERROR_UNKNOWN;
    }

    for (i=0; i < num_surfaces; i++) {
        ion_source_share.handle = 0;
        ion_source_share.fd = (int)(attribute_tpi->buffers[i]);
        ion_ret = ioctl(ion_fd, ION_IOC_IMPORT, &ion_source_share);
            if ((ion_ret < 0) || (0 == ion_source_share.handle)) {
            close(ion_fd);
            drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Fail to import the ion fd!\n", __FUNCTION__);
            return VA_STATUS_ERROR_UNKNOWN;
        }

        if (VA_FOURCC_NV12 == fourcc)
            source_size = attribute_tpi->width * attribute_tpi->height * 1.5;
        else
            source_size = attribute_tpi->width * attribute_tpi->height * 2;

        vaddr = mmap(NULL, source_size, PROT_READ|PROT_WRITE, MAP_SHARED, ion_source_share.fd, 0);
        if (MAP_FAILED == vaddr) {
            close(ion_fd);
            drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Fail to mmap the ion buffer!\n", __FUNCTION__);
            return VA_STATUS_ERROR_UNKNOWN;
        }

        surfaceID = object_heap_allocate(&driver_data->surface_heap);
        obj_surface = SURFACE(surfaceID);
        if (NULL == obj_surface) {
            close(ion_fd);
            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
            DEBUG_FAILURE;
            break;
        }
        MEMSET_OBJECT(obj_surface, struct object_surface_s);

        obj_surface->surface_id = surfaceID;
        surface_list[i] = surfaceID;
        obj_surface->context_id = -1;
        obj_surface->width = attribute_tpi->width;
        obj_surface->height = attribute_tpi->height;
        obj_surface->width_r = attribute_tpi->width;
        obj_surface->height_r = attribute_tpi->height;
	obj_surface->is_ref_surface = 0;

        psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
        if (NULL == psb_surface) {
            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
            obj_surface->surface_id = VA_INVALID_SURFACE;
            close(ion_fd);
            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
            DEBUG_FAILURE;
            break;
        }

        vaStatus = psb_surface_create_from_ub(driver_data, width, height, fourcc,
                attribute_tpi, psb_surface, vaddr, ion_source_share.fd, 0);
        obj_surface->psb_surface = psb_surface;

        if (VA_STATUS_SUCCESS != vaStatus) {
            free(psb_surface);
            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
            obj_surface->surface_id = VA_INVALID_SURFACE;
            close(ion_fd);
            DEBUG_FAILURE;
            break;
        }
        /* by default, surface fourcc is NV12 */
        memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info));
        psb_surface->extra_info[4] = fourcc;
        psb_surface->extra_info[8] = fourcc;
        obj_surface->psb_surface = psb_surface;

        /* Error recovery */
        if (VA_STATUS_SUCCESS != vaStatus) {
            object_surface_p obj_surface = SURFACE(surfaceID);
            psb__destroy_surface(driver_data, obj_surface);
            close(ion_fd);
        }

        vaddr = NULL;
    }

    close(ion_fd);
#endif
    return vaStatus;
}

VAStatus psb_CreateSurfacesWithAttribute(
    VADriverContextP ctx,
    int width,
    int height,
    int format,
    int num_surfaces,
    VASurfaceID *surface_list,        /* out */
    VASurfaceAttributeTPI *attribute_tpi
)
{
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    int i;
    int tiling;

    CHECK_INVALID_PARAM(attribute_tpi == NULL);

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create %d surface(%dx%d) with type %d, tiling is %d\n",
            num_surfaces, width, height, attribute_tpi->type, attribute_tpi->tiling);

    tiling = attribute_tpi->tiling;
    switch (attribute_tpi->type) {
    case VAExternalMemoryNULL:
        vaStatus = psb_CreateSurfacesForUserPtr(ctx, width, height, format, num_surfaces, surface_list,
                                     attribute_tpi->size, attribute_tpi->pixel_format,
                                     attribute_tpi->luma_stride, attribute_tpi->chroma_u_stride,
                                     attribute_tpi->chroma_v_stride, attribute_tpi->luma_offset,
                                     attribute_tpi->chroma_u_offset, attribute_tpi->chroma_v_offset,
                                     attribute_tpi->tiling);
        return vaStatus;
#ifdef ANDROID
    case VAExternalMemoryNoneCacheUserPointer:
#endif
    case VAExternalMemoryUserPointer:
        vaStatus = psb_CreateSurfaceFromUserspace(ctx, width, height,
                                                 format, num_surfaces, surface_list,
                                                 attribute_tpi);
        return vaStatus;
    case VAExternalMemoryKernelDRMBufffer:
        for (i=0; i < num_surfaces; i++) {
            vaStatus = psb_CreateSurfaceFromKBuf(
                ctx, width, height, format, &surface_list[i],
                attribute_tpi->buffers[i],
                attribute_tpi->size, attribute_tpi->pixel_format,
                attribute_tpi->luma_stride, attribute_tpi->chroma_u_stride,
                attribute_tpi->chroma_v_stride, attribute_tpi->luma_offset,
                attribute_tpi->chroma_u_offset, attribute_tpi->chroma_v_offset, tiling);
            CHECK_VASTATUS();
        }
        return vaStatus;
    case VAExternalMemoryAndroidGrallocBuffer:
        vaStatus = psb_CreateSurfacesFromGralloc(ctx, width, height,
                                                 format, num_surfaces, surface_list,
                                                 (PsbSurfaceAttributeTPI *)attribute_tpi);
        return vaStatus;
#ifdef ANDROID
    case VAExternalMemoryIONSharedFD:
        vaStatus = psb_CreateSurfaceFromION(ctx, width, height,
                                                 format, num_surfaces, surface_list,
                                                 attribute_tpi);
        return vaStatus;
#endif
    default:
        return VA_STATUS_ERROR_INVALID_PARAMETER;
    }

    return VA_STATUS_ERROR_INVALID_PARAMETER;
}
