1f31d5416a60f83e184b0906a7ec77ba021840531hding/*
2f31d5416a60f83e184b0906a7ec77ba021840531hding * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3f31d5416a60f83e184b0906a7ec77ba021840531hding *
4f31d5416a60f83e184b0906a7ec77ba021840531hding * Permission is hereby granted, free of charge, to any person obtaining a
5f31d5416a60f83e184b0906a7ec77ba021840531hding * copy of this software and associated documentation files (the
6f31d5416a60f83e184b0906a7ec77ba021840531hding * "Software"), to deal in the Software without restriction, including
7f31d5416a60f83e184b0906a7ec77ba021840531hding * without limitation the rights to use, copy, modify, merge, publish,
8f31d5416a60f83e184b0906a7ec77ba021840531hding * distribute, sub license, and/or sell copies of the Software, and to
9f31d5416a60f83e184b0906a7ec77ba021840531hding * permit persons to whom the Software is furnished to do so, subject to
10f31d5416a60f83e184b0906a7ec77ba021840531hding * the following conditions:
11f31d5416a60f83e184b0906a7ec77ba021840531hding *
12f31d5416a60f83e184b0906a7ec77ba021840531hding * The above copyright notice and this permission notice (including the
13f31d5416a60f83e184b0906a7ec77ba021840531hding * next paragraph) shall be included in all copies or substantial portions
14f31d5416a60f83e184b0906a7ec77ba021840531hding * of the Software.
15f31d5416a60f83e184b0906a7ec77ba021840531hding *
16f31d5416a60f83e184b0906a7ec77ba021840531hding * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17f31d5416a60f83e184b0906a7ec77ba021840531hding * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18f31d5416a60f83e184b0906a7ec77ba021840531hding * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19f31d5416a60f83e184b0906a7ec77ba021840531hding * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20f31d5416a60f83e184b0906a7ec77ba021840531hding * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21f31d5416a60f83e184b0906a7ec77ba021840531hding * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22f31d5416a60f83e184b0906a7ec77ba021840531hding * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23f31d5416a60f83e184b0906a7ec77ba021840531hding *
24f31d5416a60f83e184b0906a7ec77ba021840531hding */
25f31d5416a60f83e184b0906a7ec77ba021840531hding
26f31d5416a60f83e184b0906a7ec77ba021840531hding#include <sys/mman.h>
276c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing#include <sys/types.h>
286c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing#include <sys/stat.h>
296c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing#include <sys/ioctl.h>
306c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing#include <fcntl.h>
3196b0e013cefb77a845b6533d4c2ecf6f0aa429fcedward lin#ifdef ANDROID
326c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing#include <linux/ion.h>
3396b0e013cefb77a845b6533d4c2ecf6f0aa429fcedward lin#endif
34f31d5416a60f83e184b0906a7ec77ba021840531hding#include <va/va_tpi.h>
35f31d5416a60f83e184b0906a7ec77ba021840531hding#include "psb_drv_video.h"
36f31d5416a60f83e184b0906a7ec77ba021840531hding#include "psb_drv_debug.h"
37f31d5416a60f83e184b0906a7ec77ba021840531hding#include "psb_surface.h"
38f31d5416a60f83e184b0906a7ec77ba021840531hding#include "psb_surface_attrib.h"
39f31d5416a60f83e184b0906a7ec77ba021840531hding
406c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
41f31d5416a60f83e184b0906a7ec77ba021840531hding#define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
42f31d5416a60f83e184b0906a7ec77ba021840531hding
43f31d5416a60f83e184b0906a7ec77ba021840531hding#define CONFIG(id)  ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
44f31d5416a60f83e184b0906a7ec77ba021840531hding#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
45f31d5416a60f83e184b0906a7ec77ba021840531hding#define SURFACE(id)    ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id ))
46f31d5416a60f83e184b0906a7ec77ba021840531hding#define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
47f31d5416a60f83e184b0906a7ec77ba021840531hding
48f31d5416a60f83e184b0906a7ec77ba021840531hding
49f31d5416a60f83e184b0906a7ec77ba021840531hding/*
50f31d5416a60f83e184b0906a7ec77ba021840531hding * Create surface
51f31d5416a60f83e184b0906a7ec77ba021840531hding */
52f31d5416a60f83e184b0906a7ec77ba021840531hdingVAStatus psb_surface_create_from_ub(
53f31d5416a60f83e184b0906a7ec77ba021840531hding    psb_driver_data_p driver_data,
54f31d5416a60f83e184b0906a7ec77ba021840531hding    int width, int height, int fourcc,
55f31d5416a60f83e184b0906a7ec77ba021840531hding    VASurfaceAttributeTPI *graphic_buffers,
56f31d5416a60f83e184b0906a7ec77ba021840531hding    psb_surface_p psb_surface, /* out */
575ed159b49cff6b05d923bcf00d09c67ee2ce1f80hding    void *vaddr,
585ed159b49cff6b05d923bcf00d09c67ee2ce1f80hding    unsigned flags
59f31d5416a60f83e184b0906a7ec77ba021840531hding)
60f31d5416a60f83e184b0906a7ec77ba021840531hding{
61f31d5416a60f83e184b0906a7ec77ba021840531hding    int ret = 0;
628086c50ddd6fa200beba8d1878a4f0a4ae4de7eeFei Jiang
63e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun    if ((fourcc == VA_FOURCC_NV12) || (fourcc == VA_FOURCC_YV16) || (fourcc == VA_FOURCC_IYUV) || (fourcc == VA_FOURCC_RGBA)) {
64f31d5416a60f83e184b0906a7ec77ba021840531hding        if ((width <= 0) || (width * height > 5120 * 5120) || (height <= 0)) {
65f31d5416a60f83e184b0906a7ec77ba021840531hding            return VA_STATUS_ERROR_ALLOCATION_FAILED;
66f31d5416a60f83e184b0906a7ec77ba021840531hding        }
67f31d5416a60f83e184b0906a7ec77ba021840531hding
68a21b86fefe557d7e92bdc94c85dd2596facb7046Ji Guoliang        psb_surface->stride = graphic_buffers->luma_stride;
69f31d5416a60f83e184b0906a7ec77ba021840531hding        if (0) {
70f31d5416a60f83e184b0906a7ec77ba021840531hding            ;
71f31d5416a60f83e184b0906a7ec77ba021840531hding        } else if (512 == graphic_buffers->luma_stride) {
72f31d5416a60f83e184b0906a7ec77ba021840531hding            psb_surface->stride_mode = STRIDE_512;
73f31d5416a60f83e184b0906a7ec77ba021840531hding        } else if (1024 == graphic_buffers->luma_stride) {
74f31d5416a60f83e184b0906a7ec77ba021840531hding            psb_surface->stride_mode = STRIDE_1024;
75f31d5416a60f83e184b0906a7ec77ba021840531hding        } else if (1280 == graphic_buffers->luma_stride) {
76f31d5416a60f83e184b0906a7ec77ba021840531hding            psb_surface->stride_mode = STRIDE_1280;
77f31d5416a60f83e184b0906a7ec77ba021840531hding#ifdef PSBVIDEO_MSVDX_DEC_TILING
78f31d5416a60f83e184b0906a7ec77ba021840531hding            if (graphic_buffers->tiling) {
79f31d5416a60f83e184b0906a7ec77ba021840531hding                psb_surface->stride_mode = STRIDE_2048;
80f31d5416a60f83e184b0906a7ec77ba021840531hding                psb_surface->stride = 2048;
81f31d5416a60f83e184b0906a7ec77ba021840531hding            }
82f31d5416a60f83e184b0906a7ec77ba021840531hding#endif
83f31d5416a60f83e184b0906a7ec77ba021840531hding        } else if (2048 == graphic_buffers->luma_stride) {
84f31d5416a60f83e184b0906a7ec77ba021840531hding            psb_surface->stride_mode = STRIDE_2048;
85f31d5416a60f83e184b0906a7ec77ba021840531hding        } else if (4096 == graphic_buffers->luma_stride) {
86f31d5416a60f83e184b0906a7ec77ba021840531hding            psb_surface->stride_mode = STRIDE_4096;
87f31d5416a60f83e184b0906a7ec77ba021840531hding        } else {
88f31d5416a60f83e184b0906a7ec77ba021840531hding            psb_surface->stride_mode = STRIDE_NA;
89f31d5416a60f83e184b0906a7ec77ba021840531hding        }
90f31d5416a60f83e184b0906a7ec77ba021840531hding        if (psb_surface->stride != graphic_buffers->luma_stride) {
91f31d5416a60f83e184b0906a7ec77ba021840531hding            return VA_STATUS_ERROR_ALLOCATION_FAILED;
92f31d5416a60f83e184b0906a7ec77ba021840531hding        }
93f31d5416a60f83e184b0906a7ec77ba021840531hding
94f31d5416a60f83e184b0906a7ec77ba021840531hding        psb_surface->luma_offset = 0;
95f31d5416a60f83e184b0906a7ec77ba021840531hding        psb_surface->chroma_offset = psb_surface->stride * height;
96dc2e3e09ee9ac631c9d5a7cd1eb58b1553bfe0a5pingshix
97dc2e3e09ee9ac631c9d5a7cd1eb58b1553bfe0a5pingshix        if (VA_FOURCC_NV12 == fourcc) {
98dc2e3e09ee9ac631c9d5a7cd1eb58b1553bfe0a5pingshix            psb_surface->size = ((psb_surface->stride * height) * 3) / 2;
99dc2e3e09ee9ac631c9d5a7cd1eb58b1553bfe0a5pingshix            psb_surface->extra_info[4] = VA_FOURCC_NV12;
100dc2e3e09ee9ac631c9d5a7cd1eb58b1553bfe0a5pingshix        }
1013c3026ce2dadc43cf23137ca55a2461af4e27b7fpingshix        else if (VA_FOURCC_YV16 == fourcc) {
102dc2e3e09ee9ac631c9d5a7cd1eb58b1553bfe0a5pingshix            psb_surface->size = (psb_surface->stride * height) * 2;
103dc2e3e09ee9ac631c9d5a7cd1eb58b1553bfe0a5pingshix            psb_surface->extra_info[4] = VA_FOURCC_YV16;
104dc2e3e09ee9ac631c9d5a7cd1eb58b1553bfe0a5pingshix        }
1053c3026ce2dadc43cf23137ca55a2461af4e27b7fpingshix        else if (VA_FOURCC_IYUV == fourcc) {
1063c3026ce2dadc43cf23137ca55a2461af4e27b7fpingshix            psb_surface->size = ((psb_surface->stride * height) * 3) / 2;
1073c3026ce2dadc43cf23137ca55a2461af4e27b7fpingshix            psb_surface->extra_info[4] = VA_FOURCC_IYUV;
1083c3026ce2dadc43cf23137ca55a2461af4e27b7fpingshix        }
109e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun	else if (VA_FOURCC_RGBA == fourcc) {
110e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun            psb_surface->size = (psb_surface->stride * height) * 4;
111e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun            psb_surface->extra_info[4] = VA_FOURCC_RGBA;
112e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun        }
113e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun
11402f3955632048eb112d521f9c8e80ab2c911598aXigui Wang        psb_surface->extra_info[8] = psb_surface->extra_info[4];
11502f3955632048eb112d521f9c8e80ab2c911598aXigui Wang
116f31d5416a60f83e184b0906a7ec77ba021840531hding    } else {
117f31d5416a60f83e184b0906a7ec77ba021840531hding        return VA_STATUS_ERROR_ALLOCATION_FAILED;
118f31d5416a60f83e184b0906a7ec77ba021840531hding    }
119f31d5416a60f83e184b0906a7ec77ba021840531hding#ifdef PSBVIDEO_MSVDX_DEC_TILING
120f31d5416a60f83e184b0906a7ec77ba021840531hding    if (graphic_buffers->tiling)
1215ed159b49cff6b05d923bcf00d09c67ee2ce1f80hding        ret = psb_buffer_create_from_ub(driver_data, psb_surface->size,
1225ed159b49cff6b05d923bcf00d09c67ee2ce1f80hding                psb_bt_mmu_tiling, &psb_surface->buf,
1232c6fb3e28229a8b90c4a719caeb0e30b44dc0510Dale Stimson                vaddr, 0);
124f31d5416a60f83e184b0906a7ec77ba021840531hding    else
125f31d5416a60f83e184b0906a7ec77ba021840531hding#endif
1265ed159b49cff6b05d923bcf00d09c67ee2ce1f80hding        ret = psb_buffer_create_from_ub(driver_data, psb_surface->size,
1275ed159b49cff6b05d923bcf00d09c67ee2ce1f80hding                psb_bt_surface, &psb_surface->buf,
1282c6fb3e28229a8b90c4a719caeb0e30b44dc0510Dale Stimson                vaddr, flags);
129f31d5416a60f83e184b0906a7ec77ba021840531hding
130f31d5416a60f83e184b0906a7ec77ba021840531hding    return ret ? VA_STATUS_ERROR_ALLOCATION_FAILED : VA_STATUS_SUCCESS;
131f31d5416a60f83e184b0906a7ec77ba021840531hding}
132f31d5416a60f83e184b0906a7ec77ba021840531hding
13317f42294e6f90d3f19c91a6c3c32c353adf3eb6fhding#if 0
134f31d5416a60f83e184b0906a7ec77ba021840531hdingVAStatus psb_CreateSurfaceFromV4L2Buf(
135f31d5416a60f83e184b0906a7ec77ba021840531hding    VADriverContextP ctx,
136f31d5416a60f83e184b0906a7ec77ba021840531hding    int v4l2_fd,         /* file descriptor of V4L2 device */
137f31d5416a60f83e184b0906a7ec77ba021840531hding    struct v4l2_format *v4l2_fmt,       /* format of V4L2 */
138f31d5416a60f83e184b0906a7ec77ba021840531hding    struct v4l2_buffer *v4l2_buf,       /* V4L2 buffer */
139f31d5416a60f83e184b0906a7ec77ba021840531hding    VASurfaceID *surface        /* out */
140f31d5416a60f83e184b0906a7ec77ba021840531hding)
141f31d5416a60f83e184b0906a7ec77ba021840531hding{
142f31d5416a60f83e184b0906a7ec77ba021840531hding    INIT_DRIVER_DATA;
143f31d5416a60f83e184b0906a7ec77ba021840531hding    VAStatus vaStatus = VA_STATUS_SUCCESS;
144f31d5416a60f83e184b0906a7ec77ba021840531hding    int surfaceID;
145f31d5416a60f83e184b0906a7ec77ba021840531hding    object_surface_p obj_surface;
146f31d5416a60f83e184b0906a7ec77ba021840531hding    psb_surface_p psb_surface;
147f31d5416a60f83e184b0906a7ec77ba021840531hding    int width, height, buf_stride, buf_offset, size;
148f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned long *user_ptr = NULL;
149f31d5416a60f83e184b0906a7ec77ba021840531hding
150f31d5416a60f83e184b0906a7ec77ba021840531hding    if (IS_MRST(driver_data) == 0 && IS_MFLD(driver_data) == 0) {
151f31d5416a60f83e184b0906a7ec77ba021840531hding        drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateSurfaceFromV4L2Buf isn't supported on non-MRST platform\n");
152f31d5416a60f83e184b0906a7ec77ba021840531hding        return VA_STATUS_ERROR_UNKNOWN;
153f31d5416a60f83e184b0906a7ec77ba021840531hding    }
154f31d5416a60f83e184b0906a7ec77ba021840531hding
155f31d5416a60f83e184b0906a7ec77ba021840531hding    /* Todo:
156f31d5416a60f83e184b0906a7ec77ba021840531hding     * sanity check if the v4l2 device on MRST is supported
157f31d5416a60f83e184b0906a7ec77ba021840531hding     */
158f31d5416a60f83e184b0906a7ec77ba021840531hding    if (V4L2_MEMORY_USERPTR == v4l2_buf->memory) {
159f31d5416a60f83e184b0906a7ec77ba021840531hding        unsigned long tmp = (unsigned long)(v4l2_buf->m.userptr);
160f31d5416a60f83e184b0906a7ec77ba021840531hding
161f31d5416a60f83e184b0906a7ec77ba021840531hding        if (tmp & 0xfff) {
162f31d5416a60f83e184b0906a7ec77ba021840531hding            drv_debug_msg(VIDEO_DEBUG_ERROR, "The buffer address 0x%08x must be page aligned\n", tmp);
163f31d5416a60f83e184b0906a7ec77ba021840531hding            return VA_STATUS_ERROR_UNKNOWN;
164f31d5416a60f83e184b0906a7ec77ba021840531hding        }
165f31d5416a60f83e184b0906a7ec77ba021840531hding    }
166f31d5416a60f83e184b0906a7ec77ba021840531hding
167f31d5416a60f83e184b0906a7ec77ba021840531hding    surfaceID = object_heap_allocate(&driver_data->surface_heap);
168f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface = SURFACE(surfaceID);
1696d37ae34fcae80f2e898b61e2506ed8e887bd16anguo    CHECK_ALLOCATION(obj_surface);
1706d37ae34fcae80f2e898b61e2506ed8e887bd16anguo
171f31d5416a60f83e184b0906a7ec77ba021840531hding    MEMSET_OBJECT(obj_surface, struct object_surface_s);
172f31d5416a60f83e184b0906a7ec77ba021840531hding
173f31d5416a60f83e184b0906a7ec77ba021840531hding    width = v4l2_fmt->fmt.pix.width;
174f31d5416a60f83e184b0906a7ec77ba021840531hding    height = v4l2_fmt->fmt.pix.height;
175f31d5416a60f83e184b0906a7ec77ba021840531hding
176f31d5416a60f83e184b0906a7ec77ba021840531hding    buf_stride = width; /* ? */
177f31d5416a60f83e184b0906a7ec77ba021840531hding    buf_offset = v4l2_buf->m.offset;
178f31d5416a60f83e184b0906a7ec77ba021840531hding    size = v4l2_buf->length;
179f31d5416a60f83e184b0906a7ec77ba021840531hding
180f31d5416a60f83e184b0906a7ec77ba021840531hding    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create Surface from V4L2 buffer: %dx%d, stride=%d, buffer offset=0x%08x, size=%d\n",
181f31d5416a60f83e184b0906a7ec77ba021840531hding                             width, height, buf_stride, buf_offset, size);
182f31d5416a60f83e184b0906a7ec77ba021840531hding
183f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->surface_id = surfaceID;
184f31d5416a60f83e184b0906a7ec77ba021840531hding    *surface = surfaceID;
185f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->context_id = -1;
186f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->width = width;
187f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->height = height;
188f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->subpictures = NULL;
189f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->subpic_count = 0;
190f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->derived_imgcnt = 0;
191f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->display_timestamp = 0;
192f31d5416a60f83e184b0906a7ec77ba021840531hding
193f31d5416a60f83e184b0906a7ec77ba021840531hding    psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
194f31d5416a60f83e184b0906a7ec77ba021840531hding    if (NULL == psb_surface) {
195f31d5416a60f83e184b0906a7ec77ba021840531hding        object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
196f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->surface_id = VA_INVALID_SURFACE;
197f31d5416a60f83e184b0906a7ec77ba021840531hding
198f31d5416a60f83e184b0906a7ec77ba021840531hding        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
199f31d5416a60f83e184b0906a7ec77ba021840531hding
200f31d5416a60f83e184b0906a7ec77ba021840531hding        DEBUG_FAILURE;
201f31d5416a60f83e184b0906a7ec77ba021840531hding
202f31d5416a60f83e184b0906a7ec77ba021840531hding        return vaStatus;
203f31d5416a60f83e184b0906a7ec77ba021840531hding    }
204f31d5416a60f83e184b0906a7ec77ba021840531hding
20561e067e1c2cfca5234c4a7fa2af351206b543904hding#if PSB_MFLD_DUMMY_CODE
206f31d5416a60f83e184b0906a7ec77ba021840531hding    /* current assume it is NV12 */
207f31d5416a60f83e184b0906a7ec77ba021840531hding    if (IS_MRST(driver_data))
208f31d5416a60f83e184b0906a7ec77ba021840531hding        vaStatus = psb_surface_create_camera(driver_data, width, height, buf_stride, size, psb_surface, 1, buf_offset);
209f31d5416a60f83e184b0906a7ec77ba021840531hding    else {
210f31d5416a60f83e184b0906a7ec77ba021840531hding        if (V4L2_MEMORY_USERPTR == v4l2_buf->memory)
211f31d5416a60f83e184b0906a7ec77ba021840531hding            user_ptr = (unsigned long *)(v4l2_buf->m.userptr);
212f31d5416a60f83e184b0906a7ec77ba021840531hding        else {
213f31d5416a60f83e184b0906a7ec77ba021840531hding            user_ptr = mmap(NULL /* start anywhere */ ,
214f31d5416a60f83e184b0906a7ec77ba021840531hding                            v4l2_buf->length,
215f31d5416a60f83e184b0906a7ec77ba021840531hding                            PROT_READ ,
216f31d5416a60f83e184b0906a7ec77ba021840531hding                            MAP_SHARED /* recommended */ ,
217f31d5416a60f83e184b0906a7ec77ba021840531hding                            v4l2_fd, v4l2_buf->m.offset);
218f31d5416a60f83e184b0906a7ec77ba021840531hding        }
219f31d5416a60f83e184b0906a7ec77ba021840531hding
220f31d5416a60f83e184b0906a7ec77ba021840531hding        if (NULL != user_ptr && MAP_FAILED != user_ptr)
221f31d5416a60f83e184b0906a7ec77ba021840531hding            vaStatus = psb_surface_create_camera_from_ub(driver_data, width, height,
222f31d5416a60f83e184b0906a7ec77ba021840531hding                       buf_stride, size, psb_surface, 1, buf_offset, user_ptr);
223f31d5416a60f83e184b0906a7ec77ba021840531hding        else {
224f31d5416a60f83e184b0906a7ec77ba021840531hding            DEBUG_FAILURE;
225f31d5416a60f83e184b0906a7ec77ba021840531hding            vaStatus = VA_STATUS_ERROR_UNKNOWN;
226f31d5416a60f83e184b0906a7ec77ba021840531hding        }
227f31d5416a60f83e184b0906a7ec77ba021840531hding    }
22861e067e1c2cfca5234c4a7fa2af351206b543904hding#else
22961e067e1c2cfca5234c4a7fa2af351206b543904hding        vaStatus = VA_STATUS_ERROR_UNKNOWN;
23061e067e1c2cfca5234c4a7fa2af351206b543904hding#endif
23161e067e1c2cfca5234c4a7fa2af351206b543904hding
232f31d5416a60f83e184b0906a7ec77ba021840531hding
233f31d5416a60f83e184b0906a7ec77ba021840531hding    if (VA_STATUS_SUCCESS != vaStatus) {
234f31d5416a60f83e184b0906a7ec77ba021840531hding        free(psb_surface);
235f31d5416a60f83e184b0906a7ec77ba021840531hding        object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
236f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->surface_id = VA_INVALID_SURFACE;
237f31d5416a60f83e184b0906a7ec77ba021840531hding
238f31d5416a60f83e184b0906a7ec77ba021840531hding        DEBUG_FAILURE;
239f31d5416a60f83e184b0906a7ec77ba021840531hding
240f31d5416a60f83e184b0906a7ec77ba021840531hding        return vaStatus;
241f31d5416a60f83e184b0906a7ec77ba021840531hding    }
242f31d5416a60f83e184b0906a7ec77ba021840531hding
243f31d5416a60f83e184b0906a7ec77ba021840531hding    memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info));
244f31d5416a60f83e184b0906a7ec77ba021840531hding    psb_surface->extra_info[4] = VA_FOURCC_NV12; /* temp treat is as IYUV */
245f31d5416a60f83e184b0906a7ec77ba021840531hding
246f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->psb_surface = psb_surface;
247f31d5416a60f83e184b0906a7ec77ba021840531hding
248f31d5416a60f83e184b0906a7ec77ba021840531hding    /* Error recovery */
249f31d5416a60f83e184b0906a7ec77ba021840531hding    if (VA_STATUS_SUCCESS != vaStatus) {
250f31d5416a60f83e184b0906a7ec77ba021840531hding        object_surface_p obj_surface = SURFACE(*surface);
251f31d5416a60f83e184b0906a7ec77ba021840531hding        psb__destroy_surface(driver_data, obj_surface);
252f31d5416a60f83e184b0906a7ec77ba021840531hding        *surface = VA_INVALID_SURFACE;
253f31d5416a60f83e184b0906a7ec77ba021840531hding    }
254f31d5416a60f83e184b0906a7ec77ba021840531hding
255f31d5416a60f83e184b0906a7ec77ba021840531hding    return vaStatus;
256f31d5416a60f83e184b0906a7ec77ba021840531hding}
25717f42294e6f90d3f19c91a6c3c32c353adf3eb6fhding#endif
258f31d5416a60f83e184b0906a7ec77ba021840531hding
259f31d5416a60f83e184b0906a7ec77ba021840531hding
260f31d5416a60f83e184b0906a7ec77ba021840531hdingVAStatus psb_CreateSurfacesForUserPtr(
261f31d5416a60f83e184b0906a7ec77ba021840531hding    VADriverContextP ctx,
262f31d5416a60f83e184b0906a7ec77ba021840531hding    int Width,
263f31d5416a60f83e184b0906a7ec77ba021840531hding    int Height,
264f31d5416a60f83e184b0906a7ec77ba021840531hding    int format,
265f31d5416a60f83e184b0906a7ec77ba021840531hding    int num_surfaces,
266f31d5416a60f83e184b0906a7ec77ba021840531hding    VASurfaceID *surface_list,       /* out */
267f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned size, /* total buffer size need to be allocated */
268f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int fourcc, /* expected fourcc */
269f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int luma_stride, /* luma stride, could be width aligned with a special value */
270f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int chroma_u_stride, /* chroma stride */
271f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int chroma_v_stride,
272f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int luma_offset, /* could be 0 */
273f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int chroma_u_offset, /* UV offset from the beginning of the memory */
274aab47c383c7e535a24f3c7bd0ed17511a97b6416Wang Kun    unsigned int chroma_v_offset,
275aab47c383c7e535a24f3c7bd0ed17511a97b6416Wang Kun    unsigned int tiling
276f31d5416a60f83e184b0906a7ec77ba021840531hding)
277f31d5416a60f83e184b0906a7ec77ba021840531hding{
278f31d5416a60f83e184b0906a7ec77ba021840531hding    INIT_DRIVER_DATA
279f31d5416a60f83e184b0906a7ec77ba021840531hding    VAStatus vaStatus = VA_STATUS_SUCCESS;
280f31d5416a60f83e184b0906a7ec77ba021840531hding    int i, height_origin;
281f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned long buffer_stride;
282f31d5416a60f83e184b0906a7ec77ba021840531hding
283f31d5416a60f83e184b0906a7ec77ba021840531hding    /* silient compiler warning */
284f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int width = (unsigned int)Width;
285f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int height = (unsigned int)Height;
286f31d5416a60f83e184b0906a7ec77ba021840531hding
287f31d5416a60f83e184b0906a7ec77ba021840531hding    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create surface: width %d, height %d, format 0x%08x"
288f31d5416a60f83e184b0906a7ec77ba021840531hding                             "\n\t\t\t\t\tnum_surface %d, buffer size %d, fourcc 0x%08x"
289f31d5416a60f83e184b0906a7ec77ba021840531hding                             "\n\t\t\t\t\tluma_stride %d, chroma u stride %d, chroma v stride %d"
290f31d5416a60f83e184b0906a7ec77ba021840531hding                             "\n\t\t\t\t\tluma_offset %d, chroma u offset %d, chroma v offset %d\n",
291f31d5416a60f83e184b0906a7ec77ba021840531hding                             width, height, format,
292f31d5416a60f83e184b0906a7ec77ba021840531hding                             num_surfaces, size, fourcc,
293f31d5416a60f83e184b0906a7ec77ba021840531hding                             luma_stride, chroma_u_stride, chroma_v_stride,
294f31d5416a60f83e184b0906a7ec77ba021840531hding                             luma_offset, chroma_u_offset, chroma_v_offset);
295f31d5416a60f83e184b0906a7ec77ba021840531hding
2966d37ae34fcae80f2e898b61e2506ed8e887bd16anguo    CHECK_INVALID_PARAM(num_surfaces <= 0);
2976d37ae34fcae80f2e898b61e2506ed8e887bd16anguo    CHECK_SURFACE(surface_list);
298f31d5416a60f83e184b0906a7ec77ba021840531hding
299f31d5416a60f83e184b0906a7ec77ba021840531hding    /* We only support one format */
300e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun    if ((VA_RT_FORMAT_YUV420 != format) && (VA_RT_FORMAT_RGB32 != format)) {
301f31d5416a60f83e184b0906a7ec77ba021840531hding        vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
302f31d5416a60f83e184b0906a7ec77ba021840531hding        DEBUG_FAILURE;
303f31d5416a60f83e184b0906a7ec77ba021840531hding        return vaStatus;
304f31d5416a60f83e184b0906a7ec77ba021840531hding    }
305f31d5416a60f83e184b0906a7ec77ba021840531hding
3063c3026ce2dadc43cf23137ca55a2461af4e27b7fpingshix    /* We only support NV12 */
3073c3026ce2dadc43cf23137ca55a2461af4e27b7fpingshix    if ((VA_RT_FORMAT_YUV420 == format) && (fourcc != VA_FOURCC_NV12)) {
3083c3026ce2dadc43cf23137ca55a2461af4e27b7fpingshix        drv_debug_msg(VIDEO_DEBUG_ERROR, "Only support NV12 format\n");
309f31d5416a60f83e184b0906a7ec77ba021840531hding        return VA_STATUS_ERROR_UNKNOWN;
310f31d5416a60f83e184b0906a7ec77ba021840531hding    }
31194d9df223ac4c604d6ce73c47c4199623a36766dliubolun
312f31d5416a60f83e184b0906a7ec77ba021840531hding    vaStatus = psb__checkSurfaceDimensions(driver_data, width, height);
3136d37ae34fcae80f2e898b61e2506ed8e887bd16anguo    CHECK_VASTATUS();
3146d37ae34fcae80f2e898b61e2506ed8e887bd16anguo
315e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun    if (VA_RT_FORMAT_YUV420 == format) {
3166d37ae34fcae80f2e898b61e2506ed8e887bd16anguo    CHECK_INVALID_PARAM((size < width * height * 1.5) ||
317f31d5416a60f83e184b0906a7ec77ba021840531hding        (luma_stride < width) ||
318f31d5416a60f83e184b0906a7ec77ba021840531hding        (chroma_u_stride * 2 < width) ||
319f31d5416a60f83e184b0906a7ec77ba021840531hding        (chroma_v_stride * 2 < width) ||
320f31d5416a60f83e184b0906a7ec77ba021840531hding        (chroma_u_offset < luma_offset + width * height) ||
3216d37ae34fcae80f2e898b61e2506ed8e887bd16anguo        (chroma_v_offset < luma_offset + width * height));
322e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun    } else if (VA_RT_FORMAT_RGB32 == format) {
323e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun    CHECK_INVALID_PARAM((size < width * height * 4) ||
324e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun        (luma_stride < width) ||
325e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun        (chroma_u_stride * 2 < width) ||
326e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun        (chroma_v_stride * 2 < width) ||
327e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun        (chroma_u_offset < luma_offset + width * height) ||
328e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun        (chroma_v_offset < luma_offset + width * height));
329e982f1e85b688d56a63c7e352281a182753f1e7bWang Kun    }
330f31d5416a60f83e184b0906a7ec77ba021840531hding
331f31d5416a60f83e184b0906a7ec77ba021840531hding    height_origin = height;
332f31d5416a60f83e184b0906a7ec77ba021840531hding
333f31d5416a60f83e184b0906a7ec77ba021840531hding    for (i = 0; i < num_surfaces; i++) {
334f31d5416a60f83e184b0906a7ec77ba021840531hding        int surfaceID;
335f31d5416a60f83e184b0906a7ec77ba021840531hding        object_surface_p obj_surface;
336f31d5416a60f83e184b0906a7ec77ba021840531hding        psb_surface_p psb_surface;
337f31d5416a60f83e184b0906a7ec77ba021840531hding
338f31d5416a60f83e184b0906a7ec77ba021840531hding        surfaceID = object_heap_allocate(&driver_data->surface_heap);
339f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface = SURFACE(surfaceID);
340f31d5416a60f83e184b0906a7ec77ba021840531hding        if (NULL == obj_surface) {
341f31d5416a60f83e184b0906a7ec77ba021840531hding            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
342f31d5416a60f83e184b0906a7ec77ba021840531hding            DEBUG_FAILURE;
343f31d5416a60f83e184b0906a7ec77ba021840531hding            break;
344f31d5416a60f83e184b0906a7ec77ba021840531hding        }
345f31d5416a60f83e184b0906a7ec77ba021840531hding        MEMSET_OBJECT(obj_surface, struct object_surface_s);
346f31d5416a60f83e184b0906a7ec77ba021840531hding
347f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->surface_id = surfaceID;
348f31d5416a60f83e184b0906a7ec77ba021840531hding        surface_list[i] = surfaceID;
349f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->context_id = -1;
350f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->width = width;
351f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->height = height;
352f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->width_r = width;
353f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->height_r = height;
354f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->height_origin = height_origin;
3550cb7e3aca829a30af7cbb32df4271b06c906a323Ren Zhaohan	obj_surface->is_ref_surface = 0;
356f31d5416a60f83e184b0906a7ec77ba021840531hding
357f31d5416a60f83e184b0906a7ec77ba021840531hding        psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
358f31d5416a60f83e184b0906a7ec77ba021840531hding        if (NULL == psb_surface) {
359f31d5416a60f83e184b0906a7ec77ba021840531hding            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
360f31d5416a60f83e184b0906a7ec77ba021840531hding            obj_surface->surface_id = VA_INVALID_SURFACE;
361f31d5416a60f83e184b0906a7ec77ba021840531hding
362f31d5416a60f83e184b0906a7ec77ba021840531hding            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
363f31d5416a60f83e184b0906a7ec77ba021840531hding
364f31d5416a60f83e184b0906a7ec77ba021840531hding            DEBUG_FAILURE;
365f31d5416a60f83e184b0906a7ec77ba021840531hding            break;
366f31d5416a60f83e184b0906a7ec77ba021840531hding        }
367f31d5416a60f83e184b0906a7ec77ba021840531hding
368f31d5416a60f83e184b0906a7ec77ba021840531hding
369f31d5416a60f83e184b0906a7ec77ba021840531hding        vaStatus = psb_surface_create_for_userptr(driver_data, width, height,
370f31d5416a60f83e184b0906a7ec77ba021840531hding                   size,
371f31d5416a60f83e184b0906a7ec77ba021840531hding                   fourcc,
372f31d5416a60f83e184b0906a7ec77ba021840531hding                   luma_stride,
373f31d5416a60f83e184b0906a7ec77ba021840531hding                   chroma_u_stride,
374f31d5416a60f83e184b0906a7ec77ba021840531hding                   chroma_v_stride,
375f31d5416a60f83e184b0906a7ec77ba021840531hding                   luma_offset,
376f31d5416a60f83e184b0906a7ec77ba021840531hding                   chroma_u_offset,
377f31d5416a60f83e184b0906a7ec77ba021840531hding                   chroma_v_offset,
378f31d5416a60f83e184b0906a7ec77ba021840531hding                   psb_surface
379f31d5416a60f83e184b0906a7ec77ba021840531hding                                                 );
380f31d5416a60f83e184b0906a7ec77ba021840531hding
381f31d5416a60f83e184b0906a7ec77ba021840531hding        if (VA_STATUS_SUCCESS != vaStatus) {
382f31d5416a60f83e184b0906a7ec77ba021840531hding            free(psb_surface);
383f31d5416a60f83e184b0906a7ec77ba021840531hding            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
384f31d5416a60f83e184b0906a7ec77ba021840531hding            obj_surface->surface_id = VA_INVALID_SURFACE;
385f31d5416a60f83e184b0906a7ec77ba021840531hding
386f31d5416a60f83e184b0906a7ec77ba021840531hding            DEBUG_FAILURE;
387f31d5416a60f83e184b0906a7ec77ba021840531hding            break;
388f31d5416a60f83e184b0906a7ec77ba021840531hding        }
389f31d5416a60f83e184b0906a7ec77ba021840531hding        buffer_stride = psb_surface->stride;
390f31d5416a60f83e184b0906a7ec77ba021840531hding        /* by default, surface fourcc is NV12 */
391f31d5416a60f83e184b0906a7ec77ba021840531hding        memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info));
392f31d5416a60f83e184b0906a7ec77ba021840531hding        psb_surface->extra_info[4] = fourcc;
39302f3955632048eb112d521f9c8e80ab2c911598aXigui Wang        psb_surface->extra_info[8] = fourcc;
394aab47c383c7e535a24f3c7bd0ed17511a97b6416Wang Kun#ifdef PSBVIDEO_MSVDX_DEC_TILING
395aab47c383c7e535a24f3c7bd0ed17511a97b6416Wang Kun	psb_surface->extra_info[7] = tiling;
396aab47c383c7e535a24f3c7bd0ed17511a97b6416Wang Kun#endif
397f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->psb_surface = psb_surface;
398f31d5416a60f83e184b0906a7ec77ba021840531hding    }
399f31d5416a60f83e184b0906a7ec77ba021840531hding
400f31d5416a60f83e184b0906a7ec77ba021840531hding    /* Error recovery */
401f31d5416a60f83e184b0906a7ec77ba021840531hding    if (VA_STATUS_SUCCESS != vaStatus) {
402f31d5416a60f83e184b0906a7ec77ba021840531hding        /* surface_list[i-1] was the last successful allocation */
403f31d5416a60f83e184b0906a7ec77ba021840531hding        for (; i--;) {
404f31d5416a60f83e184b0906a7ec77ba021840531hding            object_surface_p obj_surface = SURFACE(surface_list[i]);
405f31d5416a60f83e184b0906a7ec77ba021840531hding            psb__destroy_surface(driver_data, obj_surface);
406f31d5416a60f83e184b0906a7ec77ba021840531hding            surface_list[i] = VA_INVALID_SURFACE;
407f31d5416a60f83e184b0906a7ec77ba021840531hding        }
408f31d5416a60f83e184b0906a7ec77ba021840531hding    }
409f31d5416a60f83e184b0906a7ec77ba021840531hding
410f31d5416a60f83e184b0906a7ec77ba021840531hding
411f31d5416a60f83e184b0906a7ec77ba021840531hding    return vaStatus;
412f31d5416a60f83e184b0906a7ec77ba021840531hding}
413f31d5416a60f83e184b0906a7ec77ba021840531hding
414f31d5416a60f83e184b0906a7ec77ba021840531hdingVAStatus  psb_CreateSurfaceFromKBuf(
415f31d5416a60f83e184b0906a7ec77ba021840531hding    VADriverContextP ctx,
416f31d5416a60f83e184b0906a7ec77ba021840531hding    int _width,
417f31d5416a60f83e184b0906a7ec77ba021840531hding    int _height,
418f31d5416a60f83e184b0906a7ec77ba021840531hding    int format,
419f31d5416a60f83e184b0906a7ec77ba021840531hding    VASurfaceID *surface,       /* out */
420f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int kbuf_handle, /* kernel buffer handle*/
421f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned size, /* kernel buffer size */
422f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int kBuf_fourcc, /* expected fourcc */
423f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int luma_stride, /* luma stride, could be width aligned with a special value */
424f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int chroma_u_stride, /* chroma stride */
425f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int chroma_v_stride,
426f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int luma_offset, /* could be 0 */
427f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int chroma_u_offset, /* UV offset from the beginning of the memory */
4285c3a70e3d110fc71ec9b00955c8885310fdf70aeLi Zeng    unsigned int chroma_v_offset,
4295c3a70e3d110fc71ec9b00955c8885310fdf70aeLi Zeng    unsigned int tiling
430f31d5416a60f83e184b0906a7ec77ba021840531hding)
431f31d5416a60f83e184b0906a7ec77ba021840531hding{
432f31d5416a60f83e184b0906a7ec77ba021840531hding    INIT_DRIVER_DATA
433f31d5416a60f83e184b0906a7ec77ba021840531hding    VAStatus vaStatus = VA_STATUS_SUCCESS;
434f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned long buffer_stride;
435f31d5416a60f83e184b0906a7ec77ba021840531hding
436f31d5416a60f83e184b0906a7ec77ba021840531hding    /* silient compiler warning */
437f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int width = (unsigned int)_width;
438f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int height = (unsigned int)_height;
439f31d5416a60f83e184b0906a7ec77ba021840531hding
440f31d5416a60f83e184b0906a7ec77ba021840531hding    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create surface: width %d, height %d, format 0x%08x"
441f31d5416a60f83e184b0906a7ec77ba021840531hding                             "\n\t\t\t\t\tnum_surface %d, buffer size %d, fourcc 0x%08x"
442f31d5416a60f83e184b0906a7ec77ba021840531hding                             "\n\t\t\t\t\tluma_stride %d, chroma u stride %d, chroma v stride %d"
443f31d5416a60f83e184b0906a7ec77ba021840531hding                             "\n\t\t\t\t\tluma_offset %d, chroma u offset %d, chroma v offset %d\n",
444f31d5416a60f83e184b0906a7ec77ba021840531hding                             width, height, format,
445f31d5416a60f83e184b0906a7ec77ba021840531hding                             size, kBuf_fourcc,
446f31d5416a60f83e184b0906a7ec77ba021840531hding                             luma_stride, chroma_u_stride, chroma_v_stride,
447f31d5416a60f83e184b0906a7ec77ba021840531hding                             luma_offset, chroma_u_offset, chroma_v_offset);
448f31d5416a60f83e184b0906a7ec77ba021840531hding
4496d37ae34fcae80f2e898b61e2506ed8e887bd16anguo    CHECK_SURFACE(surface);
450f31d5416a60f83e184b0906a7ec77ba021840531hding
451f31d5416a60f83e184b0906a7ec77ba021840531hding    /* We only support one format */
4523c3026ce2dadc43cf23137ca55a2461af4e27b7fpingshix    if (VA_RT_FORMAT_YUV420 != format) {
453f31d5416a60f83e184b0906a7ec77ba021840531hding        vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
454f31d5416a60f83e184b0906a7ec77ba021840531hding        DEBUG_FAILURE;
455f31d5416a60f83e184b0906a7ec77ba021840531hding        return vaStatus;
456f31d5416a60f83e184b0906a7ec77ba021840531hding    }
457f31d5416a60f83e184b0906a7ec77ba021840531hding
458f31d5416a60f83e184b0906a7ec77ba021840531hding    /* We only support NV12/YV12 */
459f31d5416a60f83e184b0906a7ec77ba021840531hding
4603c3026ce2dadc43cf23137ca55a2461af4e27b7fpingshix    if ((VA_RT_FORMAT_YUV420 == format) && (kBuf_fourcc != VA_FOURCC_NV12)) {
4613c3026ce2dadc43cf23137ca55a2461af4e27b7fpingshix        drv_debug_msg(VIDEO_DEBUG_ERROR, "Only support NV12 format\n");
462f31d5416a60f83e184b0906a7ec77ba021840531hding        return VA_STATUS_ERROR_UNKNOWN;
463f31d5416a60f83e184b0906a7ec77ba021840531hding    }
464f31d5416a60f83e184b0906a7ec77ba021840531hding    /*
465f31d5416a60f83e184b0906a7ec77ba021840531hding    vaStatus = psb__checkSurfaceDimensions(driver_data, width, height);
4666d37ae34fcae80f2e898b61e2506ed8e887bd16anguo    CHECK_VASTATUS();
467f31d5416a60f83e184b0906a7ec77ba021840531hding    */
4686d37ae34fcae80f2e898b61e2506ed8e887bd16anguo
4696d37ae34fcae80f2e898b61e2506ed8e887bd16anguo    CHECK_INVALID_PARAM((size < width * height * 1.5) ||
470f31d5416a60f83e184b0906a7ec77ba021840531hding        (luma_stride < width) ||
471f31d5416a60f83e184b0906a7ec77ba021840531hding        (chroma_u_stride * 2 < width) ||
472f31d5416a60f83e184b0906a7ec77ba021840531hding        (chroma_v_stride * 2 < width) ||
473f31d5416a60f83e184b0906a7ec77ba021840531hding        (chroma_u_offset < luma_offset + width * height) ||
4746d37ae34fcae80f2e898b61e2506ed8e887bd16anguo        (chroma_v_offset < luma_offset + width * height));
475f31d5416a60f83e184b0906a7ec77ba021840531hding
476f31d5416a60f83e184b0906a7ec77ba021840531hding    int surfaceID;
477f31d5416a60f83e184b0906a7ec77ba021840531hding    object_surface_p obj_surface;
478f31d5416a60f83e184b0906a7ec77ba021840531hding    psb_surface_p psb_surface;
479f31d5416a60f83e184b0906a7ec77ba021840531hding
480f31d5416a60f83e184b0906a7ec77ba021840531hding    surfaceID = object_heap_allocate(&driver_data->surface_heap);
481f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface = SURFACE(surfaceID);
4826d37ae34fcae80f2e898b61e2506ed8e887bd16anguo    CHECK_ALLOCATION(obj_surface);
4836d37ae34fcae80f2e898b61e2506ed8e887bd16anguo
484f31d5416a60f83e184b0906a7ec77ba021840531hding    MEMSET_OBJECT(obj_surface, struct object_surface_s);
485f31d5416a60f83e184b0906a7ec77ba021840531hding
486f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->surface_id = surfaceID;
487f31d5416a60f83e184b0906a7ec77ba021840531hding    *surface = surfaceID;
488f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->context_id = -1;
489f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->width = width;
490f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->height = height;
491f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->width_r = width;
492f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->height_r = height;
493f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->height_origin = height;
4940cb7e3aca829a30af7cbb32df4271b06c906a323Ren Zhaohan    obj_surface->is_ref_surface = 0;
495f31d5416a60f83e184b0906a7ec77ba021840531hding
496f31d5416a60f83e184b0906a7ec77ba021840531hding    psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
497f31d5416a60f83e184b0906a7ec77ba021840531hding    if (NULL == psb_surface) {
498f31d5416a60f83e184b0906a7ec77ba021840531hding        object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
499f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->surface_id = VA_INVALID_SURFACE;
500f31d5416a60f83e184b0906a7ec77ba021840531hding
501f31d5416a60f83e184b0906a7ec77ba021840531hding        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
502f31d5416a60f83e184b0906a7ec77ba021840531hding
503f31d5416a60f83e184b0906a7ec77ba021840531hding        DEBUG_FAILURE;
504f31d5416a60f83e184b0906a7ec77ba021840531hding        return vaStatus;
505f31d5416a60f83e184b0906a7ec77ba021840531hding    }
506f31d5416a60f83e184b0906a7ec77ba021840531hding
507f31d5416a60f83e184b0906a7ec77ba021840531hding    vaStatus = psb_surface_create_from_kbuf(driver_data, width, height,
508f31d5416a60f83e184b0906a7ec77ba021840531hding                                            size,
509f31d5416a60f83e184b0906a7ec77ba021840531hding                                            kBuf_fourcc,
510f31d5416a60f83e184b0906a7ec77ba021840531hding                                            kbuf_handle,
511f31d5416a60f83e184b0906a7ec77ba021840531hding                                            luma_stride,
512f31d5416a60f83e184b0906a7ec77ba021840531hding                                            chroma_u_stride,
513f31d5416a60f83e184b0906a7ec77ba021840531hding                                            chroma_v_stride,
514f31d5416a60f83e184b0906a7ec77ba021840531hding                                            luma_offset,
515f31d5416a60f83e184b0906a7ec77ba021840531hding                                            chroma_u_offset,
516f31d5416a60f83e184b0906a7ec77ba021840531hding                                            chroma_v_offset,
517f31d5416a60f83e184b0906a7ec77ba021840531hding                                            psb_surface);
518f31d5416a60f83e184b0906a7ec77ba021840531hding
519f31d5416a60f83e184b0906a7ec77ba021840531hding    if (VA_STATUS_SUCCESS != vaStatus) {
520f31d5416a60f83e184b0906a7ec77ba021840531hding        free(psb_surface);
521f31d5416a60f83e184b0906a7ec77ba021840531hding        object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
522f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->surface_id = VA_INVALID_SURFACE;
523f31d5416a60f83e184b0906a7ec77ba021840531hding
524f31d5416a60f83e184b0906a7ec77ba021840531hding        DEBUG_FAILURE;
525f31d5416a60f83e184b0906a7ec77ba021840531hding        return vaStatus;
526f31d5416a60f83e184b0906a7ec77ba021840531hding    }
527f31d5416a60f83e184b0906a7ec77ba021840531hding    buffer_stride = psb_surface->stride;
528f31d5416a60f83e184b0906a7ec77ba021840531hding    /* by default, surface fourcc is NV12 */
529f31d5416a60f83e184b0906a7ec77ba021840531hding    memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info));
530f31d5416a60f83e184b0906a7ec77ba021840531hding    psb_surface->extra_info[4] = kBuf_fourcc;
53102f3955632048eb112d521f9c8e80ab2c911598aXigui Wang    psb_surface->extra_info[8] = kBuf_fourcc;
5325c3a70e3d110fc71ec9b00955c8885310fdf70aeLi Zeng#ifdef PSBVIDEO_MSVDX_DEC_TILING
5335c3a70e3d110fc71ec9b00955c8885310fdf70aeLi Zeng    psb_surface->extra_info[7] = tiling;
5345c3a70e3d110fc71ec9b00955c8885310fdf70aeLi Zeng#endif
535f31d5416a60f83e184b0906a7ec77ba021840531hding    obj_surface->psb_surface = psb_surface;
536f31d5416a60f83e184b0906a7ec77ba021840531hding
537f31d5416a60f83e184b0906a7ec77ba021840531hding    /* Error recovery */
538f31d5416a60f83e184b0906a7ec77ba021840531hding    if (VA_STATUS_SUCCESS != vaStatus) {
539f31d5416a60f83e184b0906a7ec77ba021840531hding        object_surface_p obj_surface = SURFACE(surfaceID);
540f31d5416a60f83e184b0906a7ec77ba021840531hding        psb__destroy_surface(driver_data, obj_surface);
541f31d5416a60f83e184b0906a7ec77ba021840531hding        *surface = VA_INVALID_SURFACE;
542f31d5416a60f83e184b0906a7ec77ba021840531hding    }
543f31d5416a60f83e184b0906a7ec77ba021840531hding
544f31d5416a60f83e184b0906a7ec77ba021840531hding    return vaStatus;
545f31d5416a60f83e184b0906a7ec77ba021840531hding}
546f31d5416a60f83e184b0906a7ec77ba021840531hding
547f31d5416a60f83e184b0906a7ec77ba021840531hdingVAStatus  psb_CreateSurfaceFromUserspace(
548f31d5416a60f83e184b0906a7ec77ba021840531hding        VADriverContextP ctx,
549f31d5416a60f83e184b0906a7ec77ba021840531hding        int width,
550f31d5416a60f83e184b0906a7ec77ba021840531hding        int height,
551f31d5416a60f83e184b0906a7ec77ba021840531hding        int format,
552f31d5416a60f83e184b0906a7ec77ba021840531hding        int num_surfaces,
553f31d5416a60f83e184b0906a7ec77ba021840531hding        VASurfaceID *surface_list,        /* out */
554f31d5416a60f83e184b0906a7ec77ba021840531hding        VASurfaceAttributeTPI *attribute_tpi
555f31d5416a60f83e184b0906a7ec77ba021840531hding)
556f31d5416a60f83e184b0906a7ec77ba021840531hding{
557f31d5416a60f83e184b0906a7ec77ba021840531hding    INIT_DRIVER_DATA;
558f31d5416a60f83e184b0906a7ec77ba021840531hding    VAStatus vaStatus = VA_STATUS_SUCCESS;
55996b0e013cefb77a845b6533d4c2ecf6f0aa429fcedward lin#ifdef ANDROID
560f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned int *vaddr;
561f31d5416a60f83e184b0906a7ec77ba021840531hding    unsigned long fourcc;
562f31d5416a60f83e184b0906a7ec77ba021840531hding    int surfaceID;
563f31d5416a60f83e184b0906a7ec77ba021840531hding    object_surface_p obj_surface;
564f31d5416a60f83e184b0906a7ec77ba021840531hding    psb_surface_p psb_surface;
565f31d5416a60f83e184b0906a7ec77ba021840531hding    int i;
566f31d5416a60f83e184b0906a7ec77ba021840531hding
567f31d5416a60f83e184b0906a7ec77ba021840531hding    switch (format) {
568f31d5416a60f83e184b0906a7ec77ba021840531hding    case VA_RT_FORMAT_YUV422:
569f31d5416a60f83e184b0906a7ec77ba021840531hding        fourcc = VA_FOURCC_YV16;
570f31d5416a60f83e184b0906a7ec77ba021840531hding        break;
571f31d5416a60f83e184b0906a7ec77ba021840531hding    case VA_RT_FORMAT_YUV420:
572f31d5416a60f83e184b0906a7ec77ba021840531hding    default:
573f31d5416a60f83e184b0906a7ec77ba021840531hding        fourcc = VA_FOURCC_NV12;
574f31d5416a60f83e184b0906a7ec77ba021840531hding        break;
575f31d5416a60f83e184b0906a7ec77ba021840531hding    }
576f31d5416a60f83e184b0906a7ec77ba021840531hding
577f31d5416a60f83e184b0906a7ec77ba021840531hding    for (i=0; i < num_surfaces; i++) {
578cecb10be5449aa74cd1d9a2eb41c2a6a76d9ee79ywan        vaddr = (unsigned int *)(attribute_tpi->buffers[i]);
579f31d5416a60f83e184b0906a7ec77ba021840531hding        surfaceID = object_heap_allocate(&driver_data->surface_heap);
580f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface = SURFACE(surfaceID);
581f31d5416a60f83e184b0906a7ec77ba021840531hding        if (NULL == obj_surface) {
582f31d5416a60f83e184b0906a7ec77ba021840531hding            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
583f31d5416a60f83e184b0906a7ec77ba021840531hding            DEBUG_FAILURE;
584f31d5416a60f83e184b0906a7ec77ba021840531hding            break;
585f31d5416a60f83e184b0906a7ec77ba021840531hding        }
586f31d5416a60f83e184b0906a7ec77ba021840531hding        MEMSET_OBJECT(obj_surface, struct object_surface_s);
587f31d5416a60f83e184b0906a7ec77ba021840531hding
588f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->surface_id = surfaceID;
589f31d5416a60f83e184b0906a7ec77ba021840531hding        surface_list[i] = surfaceID;
590f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->context_id = -1;
591f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->width = attribute_tpi->width;
592f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->height = attribute_tpi->height;
593f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->width_r = attribute_tpi->width;
594f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->height_r = attribute_tpi->height;
5950cb7e3aca829a30af7cbb32df4271b06c906a323Ren Zhaohan	obj_surface->is_ref_surface = 0;
596f31d5416a60f83e184b0906a7ec77ba021840531hding
597f31d5416a60f83e184b0906a7ec77ba021840531hding        psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
598f31d5416a60f83e184b0906a7ec77ba021840531hding        if (NULL == psb_surface) {
599f31d5416a60f83e184b0906a7ec77ba021840531hding            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
600f31d5416a60f83e184b0906a7ec77ba021840531hding            obj_surface->surface_id = VA_INVALID_SURFACE;
601f31d5416a60f83e184b0906a7ec77ba021840531hding            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
602f31d5416a60f83e184b0906a7ec77ba021840531hding            DEBUG_FAILURE;
603f31d5416a60f83e184b0906a7ec77ba021840531hding            break;
604f31d5416a60f83e184b0906a7ec77ba021840531hding        }
605f31d5416a60f83e184b0906a7ec77ba021840531hding
606ef7b3fb37743952a327f1b355fe5ae202c331902Elaine Wang        if (attribute_tpi->type == VAExternalMemoryNoneCacheUserPointer)
607ef7b3fb37743952a327f1b355fe5ae202c331902Elaine Wang            vaStatus = psb_surface_create_from_ub(driver_data, width, height, fourcc,
6082c6fb3e28229a8b90c4a719caeb0e30b44dc0510Dale Stimson                    attribute_tpi, psb_surface, vaddr, PSB_USER_BUFFER_UNCACHED);
609ef7b3fb37743952a327f1b355fe5ae202c331902Elaine Wang        else
610ef7b3fb37743952a327f1b355fe5ae202c331902Elaine Wang            vaStatus = psb_surface_create_from_ub(driver_data, width, height, fourcc,
6112c6fb3e28229a8b90c4a719caeb0e30b44dc0510Dale Stimson                    attribute_tpi, psb_surface, vaddr, 0);
612f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->psb_surface = psb_surface;
613f31d5416a60f83e184b0906a7ec77ba021840531hding
614f31d5416a60f83e184b0906a7ec77ba021840531hding        if (VA_STATUS_SUCCESS != vaStatus) {
615f31d5416a60f83e184b0906a7ec77ba021840531hding            free(psb_surface);
616f31d5416a60f83e184b0906a7ec77ba021840531hding            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
617f31d5416a60f83e184b0906a7ec77ba021840531hding            obj_surface->surface_id = VA_INVALID_SURFACE;
618f31d5416a60f83e184b0906a7ec77ba021840531hding            DEBUG_FAILURE;
619f31d5416a60f83e184b0906a7ec77ba021840531hding            break;
620f31d5416a60f83e184b0906a7ec77ba021840531hding        }
621f31d5416a60f83e184b0906a7ec77ba021840531hding        /* by default, surface fourcc is NV12 */
622f31d5416a60f83e184b0906a7ec77ba021840531hding        memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info));
623f31d5416a60f83e184b0906a7ec77ba021840531hding        psb_surface->extra_info[4] = fourcc;
62402f3955632048eb112d521f9c8e80ab2c911598aXigui Wang        psb_surface->extra_info[8] = fourcc;
625f31d5416a60f83e184b0906a7ec77ba021840531hding        obj_surface->psb_surface = psb_surface;
626f31d5416a60f83e184b0906a7ec77ba021840531hding
627f31d5416a60f83e184b0906a7ec77ba021840531hding        /* Error recovery */
628f31d5416a60f83e184b0906a7ec77ba021840531hding        if (VA_STATUS_SUCCESS != vaStatus) {
629f31d5416a60f83e184b0906a7ec77ba021840531hding            object_surface_p obj_surface = SURFACE(surfaceID);
630f31d5416a60f83e184b0906a7ec77ba021840531hding            psb__destroy_surface(driver_data, obj_surface);
631f31d5416a60f83e184b0906a7ec77ba021840531hding        }
632f31d5416a60f83e184b0906a7ec77ba021840531hding    }
63396b0e013cefb77a845b6533d4c2ecf6f0aa429fcedward lin#endif
634f31d5416a60f83e184b0906a7ec77ba021840531hding    return vaStatus;
635f31d5416a60f83e184b0906a7ec77ba021840531hding}
636f31d5416a60f83e184b0906a7ec77ba021840531hding
6376c0778c779ff536566e0cdf4856bf17784fb0121SUN,JingVAStatus  psb_CreateSurfaceFromION(
6386c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        VADriverContextP ctx,
6396c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        int width,
6406c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        int height,
6416c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        int format,
6426c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        int num_surfaces,
6436c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        VASurfaceID *surface_list,        /* out */
6446c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        VASurfaceAttributeTPI *attribute_tpi
6456c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing)
6466c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing{
6476c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    INIT_DRIVER_DATA;
6486c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    VAStatus vaStatus = VA_STATUS_SUCCESS;
64996b0e013cefb77a845b6533d4c2ecf6f0aa429fcedward lin#ifdef ANDROID
6506c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    unsigned int *vaddr = NULL;
6516c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    unsigned long fourcc;
6526c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    int surfaceID;
6536c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    object_surface_p obj_surface;
6546c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    psb_surface_p psb_surface;
6556c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    int i;
6566c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    unsigned int source_size = 0;
6576c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    int ion_fd = 0;
6586c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    int ion_ret = 0;
6596c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    struct ion_fd_data ion_source_share;
6606c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
6616c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    switch (format) {
6626c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    case VA_RT_FORMAT_YUV422:
6636c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        fourcc = VA_FOURCC_YV16;
6646c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        break;
6656c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    case VA_RT_FORMAT_YUV420:
6666c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    default:
6676c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        fourcc = VA_FOURCC_NV12;
6686c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        break;
6696c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    }
6706c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
6716c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    ion_fd = open("/dev/ion", O_RDWR);
6726c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    if (ion_fd < 0) {
6736c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Fail to open the ion device!\n", __FUNCTION__);
6746c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        return VA_STATUS_ERROR_UNKNOWN;
6756c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    }
6766c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
6776c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    for (i=0; i < num_surfaces; i++) {
678cecb10be5449aa74cd1d9a2eb41c2a6a76d9ee79ywan        ion_source_share.handle = 0;
6796c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        ion_source_share.fd = (int)(attribute_tpi->buffers[i]);
6806c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        ion_ret = ioctl(ion_fd, ION_IOC_IMPORT, &ion_source_share);
681cecb10be5449aa74cd1d9a2eb41c2a6a76d9ee79ywan            if ((ion_ret < 0) || (0 == ion_source_share.handle)) {
6826c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            close(ion_fd);
6836c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Fail to import the ion fd!\n", __FUNCTION__);
6846c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            return VA_STATUS_ERROR_UNKNOWN;
6856c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        }
6866c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
6876c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        if (VA_FOURCC_NV12 == fourcc)
6886c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            source_size = attribute_tpi->width * attribute_tpi->height * 1.5;
6896c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        else
6906c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            source_size = attribute_tpi->width * attribute_tpi->height * 2;
6916c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
6926c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        vaddr = mmap(NULL, source_size, PROT_READ|PROT_WRITE, MAP_SHARED, ion_source_share.fd, 0);
6936c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        if (MAP_FAILED == vaddr) {
6946c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            close(ion_fd);
6956c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Fail to mmap the ion buffer!\n", __FUNCTION__);
6966c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            return VA_STATUS_ERROR_UNKNOWN;
6976c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        }
6986c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
6996c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        surfaceID = object_heap_allocate(&driver_data->surface_heap);
7006c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        obj_surface = SURFACE(surfaceID);
7016c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        if (NULL == obj_surface) {
7026c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            close(ion_fd);
7036c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
7046c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            DEBUG_FAILURE;
7056c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            break;
7066c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        }
7076c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        MEMSET_OBJECT(obj_surface, struct object_surface_s);
7086c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
7096c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        obj_surface->surface_id = surfaceID;
7106c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        surface_list[i] = surfaceID;
7116c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        obj_surface->context_id = -1;
7126c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        obj_surface->width = attribute_tpi->width;
7136c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        obj_surface->height = attribute_tpi->height;
7146c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        obj_surface->width_r = attribute_tpi->width;
7156c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        obj_surface->height_r = attribute_tpi->height;
7160cb7e3aca829a30af7cbb32df4271b06c906a323Ren Zhaohan	obj_surface->is_ref_surface = 0;
7176c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
7186c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
7196c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        if (NULL == psb_surface) {
7206c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
7216c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            obj_surface->surface_id = VA_INVALID_SURFACE;
7226c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            close(ion_fd);
7236c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
7246c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            DEBUG_FAILURE;
7256c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            break;
7266c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        }
7276c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
7286c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        vaStatus = psb_surface_create_from_ub(driver_data, width, height, fourcc,
7292c6fb3e28229a8b90c4a719caeb0e30b44dc0510Dale Stimson                attribute_tpi, psb_surface, vaddr, 0);
7306c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        obj_surface->psb_surface = psb_surface;
7316c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
7326c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        if (VA_STATUS_SUCCESS != vaStatus) {
7336c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            free(psb_surface);
7346c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
7356c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            obj_surface->surface_id = VA_INVALID_SURFACE;
7366c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            close(ion_fd);
7376c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            DEBUG_FAILURE;
7386c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            break;
7396c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        }
7406c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        /* by default, surface fourcc is NV12 */
7416c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info));
7426c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        psb_surface->extra_info[4] = fourcc;
74302f3955632048eb112d521f9c8e80ab2c911598aXigui Wang        psb_surface->extra_info[8] = fourcc;
7446c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        obj_surface->psb_surface = psb_surface;
7456c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
7466c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        /* Error recovery */
7476c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        if (VA_STATUS_SUCCESS != vaStatus) {
7486c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            object_surface_p obj_surface = SURFACE(surfaceID);
7496c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            psb__destroy_surface(driver_data, obj_surface);
7506c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing            close(ion_fd);
7516c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        }
7526c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
7536c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        vaddr = NULL;
7546c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    }
7556c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
7566c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    close(ion_fd);
75796b0e013cefb77a845b6533d4c2ecf6f0aa429fcedward lin#endif
7586c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    return vaStatus;
7596c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing}
7606c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing
761f31d5416a60f83e184b0906a7ec77ba021840531hdingVAStatus psb_CreateSurfacesWithAttribute(
762f31d5416a60f83e184b0906a7ec77ba021840531hding    VADriverContextP ctx,
763f31d5416a60f83e184b0906a7ec77ba021840531hding    int width,
764f31d5416a60f83e184b0906a7ec77ba021840531hding    int height,
765f31d5416a60f83e184b0906a7ec77ba021840531hding    int format,
766f31d5416a60f83e184b0906a7ec77ba021840531hding    int num_surfaces,
767f31d5416a60f83e184b0906a7ec77ba021840531hding    VASurfaceID *surface_list,        /* out */
768f31d5416a60f83e184b0906a7ec77ba021840531hding    VASurfaceAttributeTPI *attribute_tpi
769f31d5416a60f83e184b0906a7ec77ba021840531hding)
770f31d5416a60f83e184b0906a7ec77ba021840531hding{
771f31d5416a60f83e184b0906a7ec77ba021840531hding    VAStatus vaStatus = VA_STATUS_SUCCESS;
7728bc6a6aa815a18f936036b5a47106b47aa904b1bhding    int i;
7735c3a70e3d110fc71ec9b00955c8885310fdf70aeLi Zeng    int tiling;
774f31d5416a60f83e184b0906a7ec77ba021840531hding
7756d37ae34fcae80f2e898b61e2506ed8e887bd16anguo    CHECK_INVALID_PARAM(attribute_tpi == NULL);
776f31d5416a60f83e184b0906a7ec77ba021840531hding
7771e3daae79c77ac457bad20d3758ab1523c79e7f3Li Zeng    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create %d surface(%dx%d) with type %d, tiling is %d\n",
7781e3daae79c77ac457bad20d3758ab1523c79e7f3Li Zeng            num_surfaces, width, height, attribute_tpi->type, attribute_tpi->tiling);
779684f0e29e29ca32fad49439cfe0392417361d34dLi Zeng
7805c3a70e3d110fc71ec9b00955c8885310fdf70aeLi Zeng    tiling = attribute_tpi->tiling;
781f31d5416a60f83e184b0906a7ec77ba021840531hding    switch (attribute_tpi->type) {
782f31d5416a60f83e184b0906a7ec77ba021840531hding    case VAExternalMemoryNULL:
783f31d5416a60f83e184b0906a7ec77ba021840531hding        vaStatus = psb_CreateSurfacesForUserPtr(ctx, width, height, format, num_surfaces, surface_list,
784f31d5416a60f83e184b0906a7ec77ba021840531hding                                     attribute_tpi->size, attribute_tpi->pixel_format,
785f31d5416a60f83e184b0906a7ec77ba021840531hding                                     attribute_tpi->luma_stride, attribute_tpi->chroma_u_stride,
786f31d5416a60f83e184b0906a7ec77ba021840531hding                                     attribute_tpi->chroma_v_stride, attribute_tpi->luma_offset,
787aab47c383c7e535a24f3c7bd0ed17511a97b6416Wang Kun                                     attribute_tpi->chroma_u_offset, attribute_tpi->chroma_v_offset,
788aab47c383c7e535a24f3c7bd0ed17511a97b6416Wang Kun                                     attribute_tpi->tiling);
789f31d5416a60f83e184b0906a7ec77ba021840531hding        return vaStatus;
79096b0e013cefb77a845b6533d4c2ecf6f0aa429fcedward lin#ifdef ANDROID
791ef7b3fb37743952a327f1b355fe5ae202c331902Elaine Wang    case VAExternalMemoryNoneCacheUserPointer:
79296b0e013cefb77a845b6533d4c2ecf6f0aa429fcedward lin#endif
793f31d5416a60f83e184b0906a7ec77ba021840531hding    case VAExternalMemoryUserPointer:
794f31d5416a60f83e184b0906a7ec77ba021840531hding        vaStatus = psb_CreateSurfaceFromUserspace(ctx, width, height,
795f31d5416a60f83e184b0906a7ec77ba021840531hding                                                 format, num_surfaces, surface_list,
796f31d5416a60f83e184b0906a7ec77ba021840531hding                                                 attribute_tpi);
797f31d5416a60f83e184b0906a7ec77ba021840531hding        return vaStatus;
798f31d5416a60f83e184b0906a7ec77ba021840531hding    case VAExternalMemoryKernelDRMBufffer:
799f31d5416a60f83e184b0906a7ec77ba021840531hding        for (i=0; i < num_surfaces; i++) {
800f31d5416a60f83e184b0906a7ec77ba021840531hding            vaStatus = psb_CreateSurfaceFromKBuf(
801f31d5416a60f83e184b0906a7ec77ba021840531hding                ctx, width, height, format, &surface_list[i],
802f31d5416a60f83e184b0906a7ec77ba021840531hding                attribute_tpi->buffers[i],
803f31d5416a60f83e184b0906a7ec77ba021840531hding                attribute_tpi->size, attribute_tpi->pixel_format,
804f31d5416a60f83e184b0906a7ec77ba021840531hding                attribute_tpi->luma_stride, attribute_tpi->chroma_u_stride,
805f31d5416a60f83e184b0906a7ec77ba021840531hding                attribute_tpi->chroma_v_stride, attribute_tpi->luma_offset,
8065c3a70e3d110fc71ec9b00955c8885310fdf70aeLi Zeng                attribute_tpi->chroma_u_offset, attribute_tpi->chroma_v_offset, tiling);
8076d37ae34fcae80f2e898b61e2506ed8e887bd16anguo            CHECK_VASTATUS();
808f31d5416a60f83e184b0906a7ec77ba021840531hding        }
809f31d5416a60f83e184b0906a7ec77ba021840531hding        return vaStatus;
810f31d5416a60f83e184b0906a7ec77ba021840531hding    case VAExternalMemoryAndroidGrallocBuffer:
811f31d5416a60f83e184b0906a7ec77ba021840531hding        vaStatus = psb_CreateSurfacesFromGralloc(ctx, width, height,
812f31d5416a60f83e184b0906a7ec77ba021840531hding                                                 format, num_surfaces, surface_list,
813cecb10be5449aa74cd1d9a2eb41c2a6a76d9ee79ywan                                                 (PsbSurfaceAttributeTPI *)attribute_tpi);
814f31d5416a60f83e184b0906a7ec77ba021840531hding        return vaStatus;
81596b0e013cefb77a845b6533d4c2ecf6f0aa429fcedward lin#ifdef ANDROID
8166c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing    case VAExternalMemoryIONSharedFD:
8176c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        vaStatus = psb_CreateSurfaceFromION(ctx, width, height,
8186c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing                                                 format, num_surfaces, surface_list,
8196c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing                                                 attribute_tpi);
8206c0778c779ff536566e0cdf4856bf17784fb0121SUN,Jing        return vaStatus;
82196b0e013cefb77a845b6533d4c2ecf6f0aa429fcedward lin#endif
822f31d5416a60f83e184b0906a7ec77ba021840531hding    default:
823f31d5416a60f83e184b0906a7ec77ba021840531hding        return VA_STATUS_ERROR_INVALID_PARAMETER;
824f31d5416a60f83e184b0906a7ec77ba021840531hding    }
825f31d5416a60f83e184b0906a7ec77ba021840531hding
826f31d5416a60f83e184b0906a7ec77ba021840531hding    return VA_STATUS_ERROR_INVALID_PARAMETER;
827f31d5416a60f83e184b0906a7ec77ba021840531hding}
828