psb_drv_video.c revision 8a158b454ab3005c8faf8bd8c8511c34e9c0cce3
1/*
2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3 * Copyright (c) Imagination Technologies Limited, UK
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 *    Waldo Bastian <waldo.bastian@intel.com>
27 *
28 */
29
30#include <va/va_backend.h>
31#include <va/va_backend_tpi.h>
32#include <va/va_backend_egl.h>
33#ifdef PSBVIDEO_MRFL_VPP
34#include <va/va_backend_vpp.h>
35#endif
36#ifdef PSBVIDEO_MFLD
37#include <va/va_backend_vpp.h>
38#endif
39#include <va/va_drmcommon.h>
40#include <va/va_android.h>
41
42#include "psb_drv_video.h"
43#include "psb_texture.h"
44#include "psb_cmdbuf.h"
45#ifndef BAYTRAIL
46#include "pnw_cmdbuf.h"
47#include "tng_cmdbuf.h"
48#endif
49#ifdef PSBVIDEO_MRFL_VPP
50#include "vsp_cmdbuf.h"
51#endif
52#include "psb_surface.h"
53
54#include "pnw_MPEG2.h"
55#include "pnw_MPEG4.h"
56#include "pnw_H264.h"
57#include "pnw_VC1.h"
58#include "tng_jpegdec.h"
59#include "tng_VP8.h"
60#include "tng_yuv_processor.h"
61
62#ifdef PSBVIDEO_MFLD
63#include "pnw_MPEG4ES.h"
64#include "pnw_H264ES.h"
65#include "pnw_H263ES.h"
66#include "pnw_jpeg.h"
67#endif
68#ifdef PSBVIDEO_MRFL
69#include "tng_H264ES.h"
70#include "tng_H263ES.h"
71#include "tng_MPEG4ES.h"
72#include "tng_jpegES.h"
73#endif
74#ifdef PSBVIDEO_MRFL_VPP
75#include "vsp_VPP.h"
76#include "vsp_vp8.h"
77#endif
78#include "psb_output.h"
79#include <stdio.h>
80#include <string.h>
81#include <stdarg.h>
82#include <time.h>
83#include <unistd.h>
84#include <wsbm/wsbm_pool.h>
85#include <wsbm/wsbm_manager.h>
86#include <wsbm/wsbm_util.h>
87#include <wsbm/wsbm_fencemgr.h>
88#include <linux/videodev2.h>
89#include <errno.h>
90
91#include "psb_def.h"
92#include "psb_drv_debug.h"
93#ifndef BAYTRAIL
94#include "psb_ws_driver.h"
95#endif
96#include "pnw_rotate.h"
97#include "psb_surface_attrib.h"
98
99#ifndef PSB_PACKAGE_VERSION
100#define PSB_PACKAGE_VERSION "Undefined"
101#endif
102
103#define PSB_DRV_VERSION  PSB_PACKAGE_VERSION
104#define PSB_CHG_REVISION "(0X00000071)"
105
106#define PSB_STR_VENDOR_MRST     "Intel GMA500-MRST-" PSB_DRV_VERSION " " PSB_CHG_REVISION
107#define PSB_STR_VENDOR_MFLD     "Intel GMA500-MFLD-" PSB_DRV_VERSION " " PSB_CHG_REVISION
108#define PSB_STR_VENDOR_MRFL     "Intel GMA500-MRFL-" PSB_DRV_VERSION " " PSB_CHG_REVISION
109#define PSB_STR_VENDOR_BAYTRAIL     "Intel GMA500-BAYTRAIL-" PSB_DRV_VERSION " " PSB_CHG_REVISION
110#define PSB_STR_VENDOR_LEXINGTON     "Intel GMA500-LEXINGTON-" PSB_DRV_VERSION " " PSB_CHG_REVISION
111
112#define MAX_UNUSED_BUFFERS      16
113
114#define PSB_MAX_FLIP_DELAY (1000/30/10)
115
116#include <signal.h>
117
118#define EXPORT __attribute__ ((visibility("default")))
119
120#define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
121
122#ifdef PSBVIDEO_MRFL_VPP
123#define INIT_FORMAT_VTABLE format_vtable_p format_vtable = ((profile < PSB_MAX_PROFILES) && (entrypoint < PSB_MAX_ENTRYPOINTS)) ? (profile == VAProfileNone? driver_data->vpp_profile : driver_data->profile2Format[profile][entrypoint]) : NULL;
124#endif
125#ifdef PSBVIDEO_MFLD
126#define INIT_FORMAT_VTABLE format_vtable_p format_vtable = ((profile < PSB_MAX_PROFILES) && (entrypoint < PSB_MAX_ENTRYPOINTS)) ? (profile == VAProfileNone? driver_data->vpp_profile : driver_data->profile2Format[profile][entrypoint]) : NULL;
127#endif
128
129#define CONFIG(id)  ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
130#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
131#define SURFACE(id)    ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id ))
132#define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
133
134#define CONFIG_ID_OFFSET        0x01000000
135#define CONTEXT_ID_OFFSET       0x02000000
136#define SURFACE_ID_OFFSET       0x03000000
137#define BUFFER_ID_OFFSET        0x04000000
138#define IMAGE_ID_OFFSET         0x05000000
139#define SUBPIC_ID_OFFSET        0x06000000
140
141static int psb_get_device_info(VADriverContextP ctx);
142
143
144void psb_init_surface_pvr2dbuf(psb_driver_data_p driver_data);
145void psb_free_surface_pvr2dbuf(psb_driver_data_p driver_data);
146
147VAStatus psb_QueryConfigProfiles(
148    VADriverContextP ctx,
149    VAProfile *profile_list,    /* out */
150    int *num_profiles            /* out */
151)
152{
153    DEBUG_FUNC_ENTER
154    (void) ctx; /* unused */
155    int i = 0;
156    VAStatus vaStatus = VA_STATUS_SUCCESS;
157    INIT_DRIVER_DATA
158
159    CHECK_INVALID_PARAM(profile_list == NULL);
160    CHECK_INVALID_PARAM(num_profiles == NULL);
161
162#ifdef PSBVIDEO_MRFL_VPP
163    profile_list[i++] = VAProfileNone;
164#endif
165//    profile_list[i++] = VAProfileMPEG2Simple;
166    profile_list[i++] = VAProfileMPEG2Main;
167    profile_list[i++] = VAProfileMPEG4Simple;
168    profile_list[i++] = VAProfileMPEG4AdvancedSimple;
169//    profile_list[i++] = VAProfileMPEG4Main;
170    profile_list[i++] = VAProfileH264Baseline;
171    profile_list[i++] = VAProfileH264Main;
172    profile_list[i++] = VAProfileH264High;
173    profile_list[i++] = VAProfileH264StereoHigh;
174    profile_list[i++] = VAProfileVC1Simple;
175    profile_list[i++] = VAProfileVC1Main;
176    profile_list[i++] = VAProfileVC1Advanced;
177
178    if (IS_MRFL(driver_data) || IS_BAYTRAIL(driver_data)) {
179        profile_list[i++] = VAProfileH263Baseline;
180        profile_list[i++] = VAProfileJPEGBaseline;
181        profile_list[i++] = VAProfileVP8Version0_3;
182    } else if (IS_MFLD(driver_data)) {
183        profile_list[i++] = VAProfileH263Baseline;
184        profile_list[i++] = VAProfileJPEGBaseline;
185    }
186    profile_list[i++] = VAProfileH264ConstrainedBaseline;
187
188    /* If the assert fails then PSB_MAX_PROFILES needs to be bigger */
189    ASSERT(i <= PSB_MAX_PROFILES);
190    *num_profiles = i;
191    DEBUG_FUNC_EXIT
192    return VA_STATUS_SUCCESS;
193}
194
195VAStatus psb_QueryConfigEntrypoints(
196    VADriverContextP ctx,
197    VAProfile profile,
198    VAEntrypoint  *entrypoint_list,    /* out */
199    int *num_entrypoints        /* out */
200)
201{
202    DEBUG_FUNC_ENTER
203    INIT_DRIVER_DATA
204    VAStatus vaStatus = VA_STATUS_SUCCESS;
205    int entrypoints = 0;
206    int i;
207
208    CHECK_INVALID_PARAM(entrypoint_list == NULL);
209    CHECK_INVALID_PARAM((num_entrypoints == NULL) || (profile >= PSB_MAX_PROFILES));
210
211    for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) {
212#ifndef BAYTRAIL
213        if (profile == VAProfileNone && driver_data->vpp_profile &&
214            i == VAEntrypointVideoProc) {
215                entrypoints++;
216                *entrypoint_list++ = i;
217	} else
218#endif
219	if (profile != VAProfileNone && driver_data->profile2Format[profile][i]) {
220                entrypoints++;
221                *entrypoint_list++ = i;
222        }
223    }
224
225    /* If the assert fails then PSB_MAX_ENTRYPOINTS needs to be bigger */
226    ASSERT(entrypoints <= PSB_MAX_ENTRYPOINTS);
227
228    if (0 == entrypoints) {
229        return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
230    }
231
232    *num_entrypoints = entrypoints;
233    DEBUG_FUNC_EXIT
234    return VA_STATUS_SUCCESS;
235}
236
237/*
238 * Figure out if we should return VA_STATUS_ERROR_UNSUPPORTED_PROFILE
239 * or VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT
240 */
241static VAStatus psb__error_unsupported_profile_entrypoint(psb_driver_data_p driver_data, VAProfile profile, VAEntrypoint entrypoint)
242{
243    /* Does the driver support _any_ entrypoint for this profile? */
244    if (profile < PSB_MAX_PROFILES) {
245        int i;
246
247        /* Do the parameter check for MFLD and MRFLD */
248        if (profile == VAProfileNone)
249            return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
250
251        for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) {
252            if (driver_data->profile2Format[profile][i]) {
253                /* There is an entrypoint, so the profile is supported */
254                return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
255            }
256        }
257    }
258    return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
259}
260
261VAStatus psb_GetConfigAttributes(
262    VADriverContextP ctx,
263    VAProfile profile,
264    VAEntrypoint entrypoint,
265    VAConfigAttrib *attrib_list,    /* in/out */
266    int num_attribs
267)
268{
269    DEBUG_FUNC_ENTER
270    INIT_DRIVER_DATA
271
272#if defined(BAYTRAIL)
273    format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
274#else
275    INIT_FORMAT_VTABLE
276#endif
277    int i;
278    VAStatus vaStatus = VA_STATUS_SUCCESS;
279    if (NULL == format_vtable) {
280        return psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint);
281    }
282
283    CHECK_INVALID_PARAM(attrib_list == NULL);
284    CHECK_INVALID_PARAM(num_attribs <= 0);
285
286    /* Generic attributes */
287    for (i = 0; i < num_attribs; i++) {
288        switch (attrib_list[i].type) {
289        case VAConfigAttribRTFormat:
290            attrib_list[i].value = VA_RT_FORMAT_YUV420;
291            if (entrypoint == VAEntrypointEncPicture)
292                attrib_list[i].value |= VA_RT_FORMAT_YUV422;
293            if ((profile == VAProfileJPEGBaseline) && (entrypoint == VAEntrypointVLD))
294                attrib_list[i].value |= VA_RT_FORMAT_YUV444;
295            break;
296
297        default:
298            attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
299            break;
300        }
301    }
302    /* format specific attributes */
303    format_vtable->queryConfigAttributes(profile, entrypoint, attrib_list, num_attribs);
304    DEBUG_FUNC_EXIT
305    return VA_STATUS_SUCCESS;
306}
307
308static VAStatus psb__update_attribute(object_config_p obj_config, VAConfigAttrib *attrib)
309{
310    int i;
311    /* Check existing attributes */
312    for (i = 0; i < obj_config->attrib_count; i++) {
313        if (obj_config->attrib_list[i].type == attrib->type) {
314            /* Update existing attribute */
315            obj_config->attrib_list[i].value = attrib->value;
316            return VA_STATUS_SUCCESS;
317        }
318    }
319    if (obj_config->attrib_count < PSB_MAX_CONFIG_ATTRIBUTES) {
320        i = obj_config->attrib_count;
321        obj_config->attrib_list[i].type = attrib->type;
322        obj_config->attrib_list[i].value = attrib->value;
323        obj_config->attrib_count++;
324        return VA_STATUS_SUCCESS;
325    }
326    return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
327}
328
329static VAStatus psb__validate_config(object_config_p obj_config)
330{
331    int i;
332    /* Check all attributes */
333    for (i = 0; i < obj_config->attrib_count; i++) {
334        switch (obj_config->attrib_list[i].type) {
335        case VAConfigAttribRTFormat:
336            if (!(obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV420
337                  || (obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV422 &&
338                      obj_config->entrypoint == VAEntrypointEncPicture)
339                  || (obj_config->attrib_list[i].value == (VA_RT_FORMAT_YUV444 | VA_RT_FORMAT_YUV420 )))) {
340                return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
341            }
342            break;
343
344        default:
345            /*
346             * Ignore unknown attributes here, it
347             * may be format specific.
348             */
349            break;
350        }
351    }
352    return VA_STATUS_SUCCESS;
353}
354
355static int psb_get_active_entrypoint_number(
356    VADriverContextP ctx,
357    unsigned int entrypoint)
358{
359    INIT_DRIVER_DATA;
360    struct drm_lnc_video_getparam_arg arg;
361    int count = 0;
362    int ret;
363
364    if (VAEntrypointVLD > entrypoint ||
365        entrypoint > VAEntrypointEncPicture) {
366        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s :Invalid entrypoint %d.\n",
367                           __FUNCTION__, entrypoint);
368        return -1;
369    }
370
371    arg.key = PNW_VIDEO_QUERY_ENTRY;
372    arg.value = (uint64_t)((unsigned long) &count);
373    arg.arg = (uint64_t)((unsigned int)&entrypoint);
374    ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
375                              &arg, sizeof(arg));
376    if (ret) {
377        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s drmCommandWriteRead fails %d.\n",
378                           __FUNCTION__, ret);
379        return -1;
380    }
381
382    return count;
383}
384
385VAStatus psb_CreateConfig(
386    VADriverContextP ctx,
387    VAProfile profile,
388    VAEntrypoint entrypoint,
389    VAConfigAttrib *attrib_list,
390    int num_attribs,
391    VAConfigID *config_id        /* out */
392)
393{
394    DEBUG_FUNC_ENTER
395    INIT_DRIVER_DATA
396#if defined(BAYTRAIL)
397    format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
398#else
399    INIT_FORMAT_VTABLE
400#endif
401
402    VAStatus vaStatus = VA_STATUS_SUCCESS;
403    int configID;
404    object_config_p obj_config;
405    int i;
406
407    drv_debug_msg(VIDEO_DEBUG_INIT, "CreateConfig profile:%d, entrypoint:%d, num_attribs:%d.\n",
408        profile, entrypoint, num_attribs);
409    /*echo 8 > /sys/module/pvrsrvkm/parameters/no_ec will disable error concealment*/
410    if ((profile == VAProfileH264ConstrainedBaseline) && (VAEntrypointVLD == entrypoint)) {
411        char ec_disable[2];
412        FILE *ec_fp = fopen("/sys/module/pvrsrvkm/parameters/no_ec", "r");
413        if (ec_fp) {
414            if (fgets(ec_disable, 2, ec_fp) != NULL) {
415                /* force profile to VAProfileH264High */
416                if (strcmp(ec_disable, "8") == 0) {
417                    drv_debug_msg(VIDEO_DEBUG_INIT, "disabled error concealment by setting profile to VAProfileH264High\n");
418                    profile = VAProfileH264High;
419                }
420            }
421            fclose(ec_fp);
422        }
423    }
424
425    CHECK_INVALID_PARAM(config_id == NULL);
426    CHECK_INVALID_PARAM(num_attribs < 0);
427    CHECK_INVALID_PARAM(attrib_list == NULL);
428
429    if (NULL == format_vtable) {
430        vaStatus = psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint);
431    }
432
433    CHECK_VASTATUS();
434
435    if ((IS_MFLD(driver_data)) &&
436        ((VAEntrypointEncPicture == entrypoint)
437	|| (VAEntrypointEncSlice == entrypoint))) {
438	int active_slc, active_pic;
439        /* Only allow one encoding entrypoint at the sametime.
440	 * But if video encoding request comes when process JPEG encoding,
441	 * it will wait until current JPEG picture encoding finish.
442	 * Further JPEG encoding should fall back to software path.*/
443	active_slc = psb_get_active_entrypoint_number(ctx, VAEntrypointEncSlice);
444	active_pic = psb_get_active_entrypoint_number(ctx, VAEntrypointEncPicture);
445
446	if (active_slc > 0) {
447	    drv_debug_msg(VIDEO_DEBUG_ERROR, "There already is a active video encoding entrypoint."
448		   "Entrypoint %d isn't available.\n", entrypoint);
449	    return VA_STATUS_ERROR_HW_BUSY;
450	}
451	else if (active_pic > 0 && VAEntrypointEncPicture == entrypoint) {
452	    drv_debug_msg(VIDEO_DEBUG_ERROR, "There already is a active picture encoding entrypoint."
453		   "Entrypoint %d isn't available.\n", entrypoint);
454	    return VA_STATUS_ERROR_HW_BUSY;
455	}
456    }
457
458    configID = object_heap_allocate(&driver_data->config_heap);
459    obj_config = CONFIG(configID);
460    CHECK_ALLOCATION(obj_config);
461
462    MEMSET_OBJECT(obj_config, struct object_config_s);
463
464    obj_config->profile = profile;
465    obj_config->format_vtable = format_vtable;
466    obj_config->entrypoint = entrypoint;
467    obj_config->attrib_list[0].type = VAConfigAttribRTFormat;
468    obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420;
469    obj_config->attrib_count = 1;
470
471    for (i = 0; i < num_attribs; i++) {
472        if (attrib_list[i].type > VAConfigAttribRateControl)
473            return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
474
475        vaStatus = psb__update_attribute(obj_config, &(attrib_list[i]));
476        if (VA_STATUS_SUCCESS != vaStatus) {
477            break;
478        }
479    }
480
481    if (VA_STATUS_SUCCESS == vaStatus) {
482        vaStatus = psb__validate_config(obj_config);
483    }
484
485    if (VA_STATUS_SUCCESS == vaStatus) {
486        vaStatus = format_vtable->validateConfig(obj_config);
487    }
488
489    /* Error recovery */
490    if (VA_STATUS_SUCCESS != vaStatus) {
491        object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
492    } else {
493        *config_id = configID;
494    }
495
496#ifdef PSBVIDEO_MSVDX_EC
497    if((getenv("PSB_VIDEO_NOEC") == NULL)
498        && (profile == VAProfileH264ConstrainedBaseline)) {
499        drv_debug_msg(VIDEO_DEBUG_INIT, "profile is VAProfileH264ConstrainedBaseline, error concealment is enabled. \n");
500        driver_data->ec_enabled = 1;
501    } else {
502        driver_data->ec_enabled = 0;
503    }
504
505    if (profile == VAProfileMPEG4Simple ||
506        profile == VAProfileMPEG4AdvancedSimple ||
507        profile == VAProfileMPEG4Main ||
508        profile == VAProfileVP8Version0_3 ||
509	profile == VAProfileH264Baseline ||
510	profile == VAProfileH264Main ||
511	profile == VAProfileH264High ||
512	profile == VAProfileH264ConstrainedBaseline)
513		driver_data->ec_enabled = 1;
514
515#else
516    driver_data->ec_enabled = 0;
517#endif
518
519    DEBUG_FUNC_EXIT
520    return vaStatus;
521}
522
523VAStatus psb_DestroyConfig(
524    VADriverContextP ctx,
525    VAConfigID config_id
526)
527{
528    DEBUG_FUNC_ENTER
529    INIT_DRIVER_DATA
530    VAStatus vaStatus = VA_STATUS_SUCCESS;
531    object_config_p obj_config;
532
533    obj_config = CONFIG(config_id);
534    CHECK_CONFIG(obj_config);
535
536    object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
537    DEBUG_FUNC_EXIT
538    return vaStatus;
539}
540
541VAStatus psb_QueryConfigAttributes(
542    VADriverContextP ctx,
543    VAConfigID config_id,
544    VAProfile *profile,        /* out */
545    VAEntrypoint *entrypoint,     /* out */
546    VAConfigAttrib *attrib_list,    /* out */
547    int *num_attribs        /* out */
548)
549{
550    DEBUG_FUNC_ENTER
551    INIT_DRIVER_DATA
552    VAStatus vaStatus = VA_STATUS_SUCCESS;
553    object_config_p obj_config;
554    int i;
555
556    CHECK_INVALID_PARAM(profile == NULL);
557    CHECK_INVALID_PARAM(entrypoint == NULL);
558    CHECK_INVALID_PARAM(attrib_list == NULL);
559    CHECK_INVALID_PARAM(num_attribs == NULL);
560
561    obj_config = CONFIG(config_id);
562    CHECK_CONFIG(obj_config);
563
564    *profile = obj_config->profile;
565    *entrypoint = obj_config->entrypoint;
566    *num_attribs =  obj_config->attrib_count;
567    for (i = 0; i < obj_config->attrib_count; i++) {
568        attrib_list[i] = obj_config->attrib_list[i];
569    }
570
571    DEBUG_FUNC_EXIT
572    return vaStatus;
573}
574
575void psb__destroy_surface(psb_driver_data_p driver_data, object_surface_p obj_surface)
576{
577    if (NULL != obj_surface) {
578        /* delete subpicture association */
579        psb_SurfaceDeassociateSubpict(driver_data, obj_surface);
580
581	obj_surface->is_ref_surface = 0;
582
583	psb_surface_sync(obj_surface->psb_surface);
584        psb_surface_destroy(obj_surface->psb_surface);
585
586        if (obj_surface->out_loop_surface) {
587            psb_surface_destroy(obj_surface->out_loop_surface);
588        }
589
590        if (obj_surface->scaling_surface) {
591            psb_surface_destroy(obj_surface->scaling_surface);
592        }
593
594        free(obj_surface->psb_surface);
595        object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
596    }
597}
598
599VAStatus psb__checkSurfaceDimensions(psb_driver_data_p driver_data, int width, int height)
600{
601    if (driver_data->video_sd_disabled) {
602        return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
603    }
604    if ((width <= 0) || (width * height > 5120 * 5120) || (height <= 0)) {
605        return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
606    }
607    if (driver_data->video_hd_disabled) {
608        if ((width > 1024) || (height > 576)) {
609            return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
610        }
611    }
612
613    return VA_STATUS_SUCCESS;
614}
615
616VAStatus psb_GetSurfaceAttributes(
617        VADisplay dpy,
618        VAConfigID config,
619        VASurfaceAttrib *attrib_list,
620        unsigned int num_attribs
621        )
622{
623    DEBUG_FUNC_ENTER
624
625    int i;
626    VAStatus vaStatus = VA_STATUS_SUCCESS;
627
628    CHECK_INVALID_PARAM(attrib_list == NULL);
629    CHECK_INVALID_PARAM(num_attribs <= 0);
630
631    /* Generic attributes */
632    for (i = 0; i < num_attribs; i++) {
633        switch (attrib_list[i].type) {
634        case VASurfaceAttribMemoryType:
635            attrib_list[i].flags = VA_SURFACE_ATTRIB_SETTABLE | VA_SURFACE_ATTRIB_GETTABLE;
636            attrib_list[i].value.type = VAGenericValueTypeInteger;
637            attrib_list[i].value.value.i =
638                VA_SURFACE_ATTRIB_MEM_TYPE_VA |
639                VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR |
640                VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
641                VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
642                VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
643            break;
644
645        case VASurfaceAttribExternalBufferDescriptor:
646            attrib_list[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
647            attrib_list[i].value.type = VAGenericValueTypePointer;
648            break;
649
650        default:
651            attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
652            break;
653        }
654    }
655
656    DEBUG_FUNC_EXIT
657    return VA_STATUS_SUCCESS;
658
659}
660
661VAStatus psb_CreateSurfaces(
662        VADriverContextP ctx,
663        int width,
664        int height,
665        int format,
666        int num_surfaces,
667        VASurfaceID *surface_list        /* out */
668)
669{
670    return VA_STATUS_ERROR_UNIMPLEMENTED;
671}
672
673VAStatus psb_CreateSurfaces2(
674    VADriverContextP ctx,
675    int format,
676    int width,
677    int height,
678    VASurfaceID *surface_list,        /* out */
679    int num_surfaces,
680    VASurfaceAttrib *attrib_list,
681    int num_attribs
682)
683{
684    DEBUG_FUNC_ENTER
685    INIT_DRIVER_DATA
686    VAStatus vaStatus = VA_STATUS_SUCCESS;
687    int i, height_origin, buffer_stride = 0;
688    driver_data->protected = (VA_RT_FORMAT_PROTECTED & format);
689    unsigned long fourcc;
690    unsigned int flags = 0;
691    int memory_type = -1;
692    VASurfaceAttribExternalBuffers  *pExternalBufDesc = NULL;
693    VASurfaceAttributeTPI attribute_tpi;
694
695    CHECK_INVALID_PARAM(num_surfaces <= 0);
696    CHECK_SURFACE(surface_list);
697
698    if ((attrib_list != NULL) && (num_attribs > 0)) {
699        for (i = 0; i < num_attribs; i++, attrib_list++) {
700            if (!attrib_list)
701                return VA_STATUS_ERROR_INVALID_PARAMETER;
702            switch (attrib_list->type) {
703            case VASurfaceAttribExternalBufferDescriptor:
704                {
705                    pExternalBufDesc = (VASurfaceAttribExternalBuffers *)attrib_list->value.value.p;
706                    if (pExternalBufDesc == NULL) {
707                        drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid VASurfaceAttribExternalBuffers.\n");
708                        return VA_STATUS_ERROR_INVALID_PARAMETER;
709                    }
710                    attribute_tpi.type = memory_type;
711                    attribute_tpi.buffers = malloc(sizeof(int) * pExternalBufDesc->num_buffers);
712                    attribute_tpi.width = pExternalBufDesc->width;
713                    attribute_tpi.height = pExternalBufDesc->height;
714                    attribute_tpi.count = pExternalBufDesc->num_buffers;
715                    memcpy((void*)attribute_tpi.buffers, (void*)pExternalBufDesc->buffers,
716                            sizeof(pExternalBufDesc->buffers[0]) *
717                            pExternalBufDesc->num_buffers);
718                    attribute_tpi.pixel_format = pExternalBufDesc->pixel_format;
719                    attribute_tpi.size = pExternalBufDesc->data_size;
720                    attribute_tpi.luma_stride = pExternalBufDesc->pitches[0];
721                    attribute_tpi.chroma_u_stride = pExternalBufDesc->pitches[1];
722                    attribute_tpi.chroma_v_stride = pExternalBufDesc->pitches[2];
723                    attribute_tpi.luma_offset = pExternalBufDesc->offsets[0];
724                    attribute_tpi.chroma_u_offset = pExternalBufDesc->offsets[1];
725                    attribute_tpi.chroma_v_offset = pExternalBufDesc->offsets[2];
726                    attribute_tpi.reserved[0] = (unsigned int) pExternalBufDesc->private_data;
727                    if (pExternalBufDesc->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING)
728                        attribute_tpi.tiling = 1;
729                    else
730                        attribute_tpi.tiling = 0;
731                }
732                break;
733            case VASurfaceAttribMemoryType:
734                {
735                    switch (attrib_list->value.value.i) {
736                        case VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR:
737                            memory_type = VAExternalMemoryUserPointer;
738                            break;
739                        case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM:
740                            memory_type = VAExternalMemoryKernelDRMBufffer;
741                            break;
742                        case VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC:
743                            memory_type = VAExternalMemoryAndroidGrallocBuffer;
744                            break;
745                        case VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION:
746                            memory_type = VAExternalMemoryIONSharedFD;
747                            break;
748                        case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
749                            memory_type = VAExternalMemoryNULL;
750                            break;
751                        default:
752                            drv_debug_msg(VIDEO_DEBUG_ERROR, "Unsupported memory type.\n");
753                            return VA_STATUS_ERROR_INVALID_PARAMETER;
754
755                    }
756                }
757                break;
758            default:
759                drv_debug_msg(VIDEO_DEBUG_ERROR, "Unsupported attribute.\n");
760                return VA_STATUS_ERROR_INVALID_PARAMETER;
761            }
762        }
763    }
764
765    if ((memory_type == -1 && pExternalBufDesc != NULL) ||
766            (memory_type != -1 && pExternalBufDesc == NULL)) {
767        return VA_STATUS_ERROR_INVALID_PARAMETER;
768    }
769    else if(memory_type !=-1 && pExternalBufDesc != NULL) {
770        attribute_tpi.type = memory_type;
771        return psb_CreateSurfacesWithAttribute(ctx, width, height, format, num_surfaces, surface_list, &attribute_tpi);
772    }
773
774    format = format & (~VA_RT_FORMAT_PROTECTED);
775
776    /* We only support one format */
777    if ((VA_RT_FORMAT_YUV420 != format)
778        && (VA_RT_FORMAT_YUV422 != format)
779        && (VA_RT_FORMAT_YUV444 != format)) {
780        vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
781        DEBUG_FAILURE;
782        return vaStatus;
783    }
784
785    vaStatus = psb__checkSurfaceDimensions(driver_data, width, height);
786    CHECK_VASTATUS();
787
788    /* Adjust height to be a multiple of 32 (height of macroblock in interlaced mode) */
789    height_origin = height;
790    height = (height + 0x1f) & ~0x1f;
791
792
793    for (i = 0; i < num_surfaces; i++) {
794        int surfaceID;
795        object_surface_p obj_surface;
796        psb_surface_p psb_surface;
797
798        surfaceID = object_heap_allocate(&driver_data->surface_heap);
799        obj_surface = SURFACE(surfaceID);
800        if (NULL == obj_surface) {
801            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
802            DEBUG_FAILURE;
803            break;
804        }
805        MEMSET_OBJECT(obj_surface, struct object_surface_s);
806
807        obj_surface->surface_id = surfaceID;
808        surface_list[i] = surfaceID;
809        obj_surface->context_id = -1;
810        obj_surface->width = width;
811        obj_surface->height = height;
812        obj_surface->width_r = width;
813        obj_surface->height_r = height;
814        obj_surface->height_origin = height_origin;
815        obj_surface->share_info = NULL;
816
817        psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
818        if (NULL == psb_surface) {
819            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
820            obj_surface->surface_id = VA_INVALID_SURFACE;
821            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
822            DEBUG_FAILURE;
823            break;
824        }
825
826        switch (format) {
827        case VA_RT_FORMAT_YUV444:
828            fourcc = VA_FOURCC_YV32; /* allocate 4 planar */
829            break;
830        case VA_RT_FORMAT_YUV422:
831            fourcc = VA_FOURCC_YV16;
832            break;
833        case VA_RT_FORMAT_YUV420:
834        default:
835            fourcc = VA_FOURCC_NV12;
836            break;
837        }
838
839        flags |= driver_data->protected ? IS_PROTECTED : 0;
840        vaStatus = psb_surface_create(driver_data, width, height, fourcc,
841                                      flags, psb_surface);
842
843        if (VA_STATUS_SUCCESS != vaStatus) {
844            free(psb_surface);
845            object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
846            obj_surface->surface_id = VA_INVALID_SURFACE;
847            DEBUG_FAILURE;
848            break;
849        }
850        buffer_stride = psb_surface->stride;
851        /* by default, surface fourcc is NV12 */
852        psb_surface->extra_info[4] = fourcc;
853        obj_surface->psb_surface = psb_surface;
854    }
855
856    /* Error recovery */
857    if (VA_STATUS_SUCCESS != vaStatus) {
858        /* surface_list[i-1] was the last successful allocation */
859        for (; i--;) {
860            object_surface_p obj_surface = SURFACE(surface_list[i]);
861            psb__destroy_surface(driver_data, obj_surface);
862            surface_list[i] = VA_INVALID_SURFACE;
863        }
864        drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateSurfaces failed\n");
865        return vaStatus;
866    }
867    DEBUG_FUNC_EXIT
868    return vaStatus;
869}
870
871VAStatus psb_DestroySurfaces(
872    VADriverContextP ctx,
873    VASurfaceID *surface_list,
874    int num_surfaces
875)
876{
877    INIT_DRIVER_DATA
878    int i;
879    VAStatus vaStatus = VA_STATUS_SUCCESS;
880
881    if (num_surfaces <= 0) {
882        return VA_STATUS_ERROR_INVALID_PARAMETER;
883    }
884
885    CHECK_SURFACE(surface_list);
886
887#if 0
888    /* Free PVR2D buffer wrapped from the surfaces */
889    psb_free_surface_pvr2dbuf(driver_data);
890#endif
891
892    /* Make validation happy */
893    for (i = 0; i < num_surfaces; i++) {
894        object_surface_p obj_surface = SURFACE(surface_list[i]);
895        if (obj_surface == NULL) {
896            return VA_STATUS_ERROR_INVALID_SURFACE;
897        }
898        if (obj_surface->derived_imgcnt > 0) {
899            drv_debug_msg(VIDEO_DEBUG_ERROR, "Some surface is deriving by images\n");
900            return VA_STATUS_ERROR_OPERATION_FAILED;
901        }
902    }
903
904    for (i = 0; i < num_surfaces; i++) {
905        object_surface_p obj_surface = SURFACE(surface_list[i]);
906        if (obj_surface == NULL)
907            return VA_STATUS_ERROR_INVALID_SURFACE;
908
909        if (driver_data->cur_displaying_surface == surface_list[i]) {
910            /* Surface is being displaying. Need to stop overlay here */
911            psb_coverlay_stop(ctx);
912        }
913        drv_debug_msg(VIDEO_DEBUG_INIT, "%s : obj_surface->surface_id = 0x%x\n",__FUNCTION__, obj_surface->surface_id);
914        if (obj_surface->share_info) {
915            psb_DestroySurfaceGralloc(obj_surface);
916        }
917        psb__destroy_surface(driver_data, obj_surface);
918        surface_list[i] = VA_INVALID_SURFACE;
919    }
920
921    DEBUG_FUNC_EXIT
922    return VA_STATUS_SUCCESS;
923}
924
925int psb_new_context(psb_driver_data_p driver_data, int ctx_type)
926{
927    struct drm_lnc_video_getparam_arg arg;
928    int ret = 0;
929    unsigned long ctx_num = 0;
930
931    arg.key = IMG_VIDEO_NEW_CONTEXT;
932    arg.value = (uint64_t)((unsigned long) & ctx_type);
933    ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
934                              &arg, sizeof(arg));
935    if (ret != 0) {
936        drv_debug_msg(VIDEO_DEBUG_ERROR, "Set context %d failed\n", ctx_type);
937	return ret;
938    }
939
940    /* get vp8 encoding context num from arg.value */
941    ctx_num = ctx_type;
942
943    return ctx_num;
944}
945
946#ifdef PSBVIDEO_MSVDX_DEC_TILING
947int psb_update_context(psb_driver_data_p driver_data, unsigned long ctx_type)
948{
949    struct drm_lnc_video_getparam_arg arg;
950    int ret = 0;
951
952    arg.key = IMG_VIDEO_UPDATE_CONTEXT;
953    arg.value = (uint64_t)((unsigned long) & ctx_type);
954    ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
955                              &arg, sizeof(arg));
956    if (ret != 0)
957        drv_debug_msg(VIDEO_DEBUG_ERROR, "Update context %d failed\n", ctx_type);
958
959    return ret;
960}
961#endif
962
963int psb_rm_context(psb_driver_data_p driver_data)
964{
965    struct drm_lnc_video_getparam_arg arg;
966    int tmp;
967    int ret = 0;
968
969    arg.key = IMG_VIDEO_RM_CONTEXT;
970    arg.value = (uint64_t)((unsigned long) & tmp); /* value is ignored */
971    ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
972                              &arg, sizeof(arg));
973    if (ret != 0)
974        drv_debug_msg(VIDEO_DEBUG_ERROR, "Remove context failed\n");
975
976    return ret;
977}
978
979#ifdef PSBVIDEO_MSVDX_DEC_TILING
980unsigned long psb__tile_stride_log2_256(int w)
981{
982    int stride_mode = 0;
983
984    if (512 >= w)
985        stride_mode = 1;
986    else if (1024 >= w)
987        stride_mode = 2;
988    else if (2048 >= w)
989        stride_mode = 3;
990    else if (4096 >= w)
991        stride_mode = 4;
992
993    return stride_mode;
994}
995
996unsigned long psb__tile_stride_log2_512(int w)
997{
998    int stride_mode = 0;
999
1000    if (512 >= w)
1001        stride_mode = 0;
1002    else if (1024 >= w)
1003        stride_mode = 1;
1004    else if (2048 >= w)
1005        stride_mode = 2;
1006    else if (4096 >= w)
1007        stride_mode = 3;
1008
1009    return stride_mode;
1010}
1011#endif
1012
1013VAStatus psb_CreateContext(
1014    VADriverContextP ctx,
1015    VAConfigID config_id,
1016    int picture_width,
1017    int picture_height,
1018    int flag,
1019    VASurfaceID *render_targets,
1020    int num_render_targets,
1021    VAContextID *context        /* out */
1022)
1023{
1024    DEBUG_FUNC_ENTER
1025    INIT_DRIVER_DATA
1026    VAStatus vaStatus = VA_STATUS_SUCCESS;
1027    object_config_p obj_config;
1028    int cmdbuf_num, encode = 0, proc = 0;
1029    int i;
1030    drv_debug_msg(VIDEO_DEBUG_INIT, "CreateContext config_id:%d, pic_w:%d, pic_h:%d, flag:%d, num_render_targets:%d.\n",
1031        config_id, picture_width, picture_height, flag, num_render_targets);
1032
1033    CHECK_INVALID_PARAM(num_render_targets <= 0);
1034
1035    CHECK_SURFACE(render_targets);
1036    CHECK_CONTEXT(context);
1037
1038    vaStatus = psb__checkSurfaceDimensions(driver_data, picture_width, picture_height);
1039    CHECK_VASTATUS();
1040
1041    obj_config = CONFIG(config_id);
1042    CHECK_CONFIG(obj_config);
1043
1044    int contextID = object_heap_allocate(&driver_data->context_heap);
1045    object_context_p obj_context = CONTEXT(contextID);
1046    CHECK_ALLOCATION(obj_context);
1047
1048    *context = contextID;
1049
1050    MEMSET_OBJECT(obj_context, struct object_context_s);
1051
1052    obj_context->driver_data = driver_data;
1053    obj_context->current_render_target = NULL;
1054    obj_context->ec_target = NULL;
1055    obj_context->ec_candidate = NULL;
1056    obj_context->is_oold = driver_data->is_oold;
1057    obj_context->context_id = contextID;
1058    obj_context->config_id = config_id;
1059    obj_context->picture_width = picture_width;
1060    obj_context->picture_height = picture_height;
1061    obj_context->num_render_targets = num_render_targets;
1062    obj_context->video_crop.x = 0;
1063    obj_context->video_crop.y = 0;
1064    obj_context->video_crop.width = picture_width;
1065    obj_context->video_crop.height = picture_height;
1066    obj_context->msvdx_scaling = 0;
1067#ifdef SLICE_HEADER_PARSING
1068    obj_context->msvdx_frame_end = 0;
1069#endif
1070    obj_context->scaling_width = 0;
1071    obj_context->scaling_height = 0;
1072    obj_context->render_targets = (VASurfaceID *) calloc(1, num_render_targets * sizeof(VASurfaceID));
1073    if (obj_context->render_targets == NULL) {
1074        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1075        DEBUG_FAILURE;
1076
1077        object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1078
1079        return vaStatus;
1080    }
1081
1082    /* allocate buffer points for vaRenderPicture */
1083    obj_context->num_buffers = 10;
1084    obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * obj_context->num_buffers);
1085    if (obj_context->buffer_list == NULL) {
1086        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1087        DEBUG_FAILURE;
1088
1089        free(obj_context->render_targets);
1090        object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1091
1092        return vaStatus;
1093    }
1094
1095    memset(obj_context->buffers_unused, 0, sizeof(obj_context->buffers_unused));
1096    memset(obj_context->buffers_unused_count, 0, sizeof(obj_context->buffers_unused_count));
1097    memset(obj_context->buffers_unused_tail, 0, sizeof(obj_context->buffers_unused_tail));
1098    memset(obj_context->buffers_active, 0, sizeof(obj_context->buffers_active));
1099
1100    if (obj_config->entrypoint == VAEntrypointEncSlice
1101        || obj_config->entrypoint == VAEntrypointEncPicture) {
1102        encode = 1;
1103    }
1104#ifdef PSBVIDEO_MRFL_VPP
1105    if (obj_config->entrypoint == VAEntrypointVideoProc)
1106        proc = 1;
1107
1108    //todo: fixme
1109    if (obj_config->entrypoint == VAEntrypointEncSlice && obj_config->profile == VAProfileVP8Version0_3){
1110            proc = 1;
1111            encode = 0;
1112    }
1113#endif
1114
1115    if (encode)
1116        cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE;
1117    else if (proc)
1118        cmdbuf_num = VSP_MAX_CMDBUFS;
1119    else
1120        cmdbuf_num = PSB_MAX_CMDBUFS;
1121
1122    for (i = 0; i < num_render_targets; i++) {
1123        object_surface_p obj_surface = SURFACE(render_targets[i]);
1124        psb_surface_p psb_surface;
1125
1126        if (NULL == obj_surface) {
1127            vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
1128            DEBUG_FAILURE;
1129            break;
1130        }
1131
1132        psb_surface = obj_surface->psb_surface;
1133
1134        /* Clear format specific surface info */
1135        obj_context->render_targets[i] = render_targets[i];
1136        obj_surface->context_id = contextID; /* Claim ownership of surface */
1137#ifdef PSBVIDEO_MSVDX_DEC_TILING
1138        if (GET_SURFACE_INFO_tiling(psb_surface))
1139#ifdef BAYTRAIL
1140            obj_context->msvdx_tile = psb__tile_stride_log2_512(obj_surface->width);
1141#else
1142            if (obj_config->entrypoint == VAEntrypointVideoProc && obj_config->profile == VAProfileNone)
1143                // It's for two pass rotation case
1144                // Need the source surface width for tile stride setting
1145                obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_context->picture_width);
1146            else
1147                obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_surface->width);
1148#endif
1149#endif
1150#if 0
1151        /* for decode, move the surface into |TT */
1152        if ((encode == 0) && /* decode */
1153            ((psb_surface->buf.pl_flags & DRM_PSB_FLAG_MEM_RAR) == 0)) /* surface not in RAR */
1154            psb_buffer_setstatus(&obj_surface->psb_surface->buf,
1155                                 WSBM_PL_FLAG_TT | WSBM_PL_FLAG_SHARED, DRM_PSB_FLAG_MEM_MMU);
1156#endif
1157    }
1158
1159    obj_context->va_flags = flag;
1160    obj_context->format_vtable = obj_config->format_vtable;
1161    obj_context->format_data = NULL;
1162
1163    if (VA_STATUS_SUCCESS == vaStatus) {
1164        vaStatus = obj_context->format_vtable->createContext(obj_context, obj_config);
1165    }
1166
1167    /* Error recovery */
1168    if (VA_STATUS_SUCCESS != vaStatus) {
1169        obj_context->context_id = -1;
1170        obj_context->config_id = -1;
1171        obj_context->picture_width = 0;
1172        obj_context->picture_height = 0;
1173        free(obj_context->render_targets);
1174        free(obj_context->buffer_list);
1175        obj_context->num_buffers = 0;
1176        obj_context->render_targets = NULL;
1177        obj_context->num_render_targets = 0;
1178        obj_context->va_flags = 0;
1179        object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1180
1181        return vaStatus;
1182    }
1183
1184    /* initialize cmdbuf */
1185    for (i = 0; i < PNW_MAX_CMDBUFS_ENCODE; i++) {
1186        obj_context->pnw_cmdbuf_list[i] = NULL;
1187    }
1188
1189#ifdef PSBVIDEO_MRFL
1190    for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) {
1191        obj_context->tng_cmdbuf_list[i] = NULL;
1192    }
1193#endif
1194
1195#ifdef PSBVIDEO_MRFL_VPP
1196    for (i = 0; i < VSP_MAX_CMDBUFS; i++) {
1197        obj_context->vsp_cmdbuf_list[i] = NULL;
1198    }
1199#endif
1200
1201    for (i = 0; i < PSB_MAX_CMDBUFS; i++) {
1202        obj_context->cmdbuf_list[i] = NULL;
1203    }
1204
1205    for (i = 0; i < cmdbuf_num; i++) {
1206        void  *cmdbuf = NULL;
1207#ifndef BAYTRAIL
1208        if (encode) { /* Topaz encode context */
1209#ifdef PSBVIDEO_MRFL
1210            if (IS_MRFL(obj_context->driver_data))
1211                cmdbuf = calloc(1, sizeof(struct tng_cmdbuf_s));
1212#endif
1213#ifdef PSBVIDEO_MFLD
1214            if (IS_MFLD(obj_context->driver_data))
1215                cmdbuf = calloc(1, sizeof(struct pnw_cmdbuf_s));
1216#endif
1217        } else if (proc) { /* VSP VPP context */
1218            /* VED two pass rotation under VPP API */
1219            if (driver_data->ved_vpp)
1220                cmdbuf =  calloc(1, sizeof(struct psb_cmdbuf_s));
1221#ifdef PSBVIDEO_MRFL_VPP
1222            else if (IS_MRFL(obj_context->driver_data))
1223                cmdbuf = calloc(1, sizeof(struct vsp_cmdbuf_s));
1224#endif
1225        } else /* MSVDX decode context */
1226#endif
1227            cmdbuf =  calloc(1, sizeof(struct psb_cmdbuf_s));
1228
1229        if (NULL == cmdbuf) {
1230            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1231            DEBUG_FAILURE;
1232            break;
1233        }
1234
1235#ifndef BAYTRAIL
1236        if (encode) { /* Topaz encode context */
1237
1238#ifdef PSBVIDEO_MRFL
1239            if (IS_MRFL(obj_context->driver_data))
1240                vaStatus = tng_cmdbuf_create(obj_context, driver_data, (tng_cmdbuf_p)cmdbuf);
1241#endif
1242#ifdef PSBVIDEO_MFLD
1243            if (IS_MFLD(obj_context->driver_data))
1244                vaStatus = pnw_cmdbuf_create(obj_context, driver_data, (pnw_cmdbuf_p)cmdbuf);
1245#endif
1246        } else if (proc) { /* VSP VPP context */
1247            if (driver_data->ved_vpp)
1248                vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)cmdbuf);
1249#ifdef PSBVIDEO_MRFL_VPP
1250            else if (IS_MRFL(obj_context->driver_data))
1251                vaStatus = vsp_cmdbuf_create(obj_context, driver_data, (vsp_cmdbuf_p)cmdbuf);
1252#endif
1253        } else /* MSVDX decode context */
1254#endif
1255            vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)cmdbuf);
1256
1257        if (VA_STATUS_SUCCESS != vaStatus) {
1258            free(cmdbuf);
1259            DEBUG_FAILURE;
1260            break;
1261        }
1262
1263#ifndef BAYTRAIL
1264        if (encode) { /* Topaz encode context */
1265            if (i >= LNC_MAX_CMDBUFS_ENCODE) {
1266                free(cmdbuf);
1267                DEBUG_FAILURE;
1268                break;
1269            }
1270
1271#ifdef PSBVIDEO_MRFL
1272            if (IS_MRFL(obj_context->driver_data))
1273                obj_context->tng_cmdbuf_list[i] = (tng_cmdbuf_p)cmdbuf;
1274#endif
1275#ifdef PSBVIDEO_MFLD
1276            if (IS_MFLD(obj_context->driver_data))
1277                obj_context->pnw_cmdbuf_list[i] = (pnw_cmdbuf_p)cmdbuf;
1278#endif
1279        } else if (proc) { /* VSP VPP context */
1280            if (driver_data->ved_vpp)
1281                obj_context->cmdbuf_list[i] = (psb_cmdbuf_p)cmdbuf;
1282#ifdef PSBVIDEO_MRFL_VPP
1283            else if (IS_MRFL(obj_context->driver_data))
1284                obj_context->vsp_cmdbuf_list[i] = (vsp_cmdbuf_p)cmdbuf;
1285#endif
1286        } else /* MSVDX decode context */
1287#endif
1288            obj_context->cmdbuf_list[i] = (psb_cmdbuf_p)cmdbuf;
1289    }
1290
1291    obj_context->cmdbuf_current = -1;
1292    obj_context->cmdbuf = NULL;
1293    obj_context->pnw_cmdbuf = NULL;
1294    obj_context->tng_cmdbuf = NULL;
1295#ifdef PSBVIDEO_MRFL_VPP
1296    obj_context->vsp_cmdbuf = NULL;
1297#endif
1298    obj_context->frame_count = 0;
1299    obj_context->slice_count = 0;
1300    obj_context->msvdx_context = ((driver_data->msvdx_context_base & 0xff0000) >> 16) |
1301                                 ((contextID & 0xff000000) >> 16);
1302#ifdef ANDROID
1303    obj_context->msvdx_context = ((driver_data->drm_fd & 0xf) << 4) |
1304                                 ((unsigned int)gettid() & 0xf);
1305#endif
1306    obj_context->profile = obj_config->profile;
1307    obj_context->entry_point = obj_config->entrypoint;
1308
1309    /* Error recovery */
1310    if (VA_STATUS_SUCCESS != vaStatus) {
1311        if (cmdbuf_num > LNC_MAX_CMDBUFS_ENCODE)
1312            cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE;
1313        for (i = 0; i < cmdbuf_num; i++) {
1314#ifndef BAYTRAIL
1315            if (obj_context->pnw_cmdbuf_list[i]) {
1316                pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]);
1317                free(obj_context->pnw_cmdbuf_list[i]);
1318                obj_context->pnw_cmdbuf_list[i] = NULL;
1319            }
1320#endif
1321#ifdef PSBVIDEO_MRFL
1322            if (obj_context->tng_cmdbuf_list[i]) {
1323                tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]);
1324                free(obj_context->tng_cmdbuf_list[i]);
1325                obj_context->tng_cmdbuf_list[i] = NULL;
1326            }
1327#endif
1328            if (obj_context->cmdbuf_list[i]) {
1329                psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]);
1330                free(obj_context->cmdbuf_list[i]);
1331                obj_context->cmdbuf_list[i] = NULL;
1332            }
1333#ifdef PSBVIDEO_MRFL_VPP
1334            if (obj_context->vsp_cmdbuf_list[i]) {
1335                vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]);
1336                free(obj_context->vsp_cmdbuf_list[i]);
1337                obj_context->vsp_cmdbuf_list[i] = NULL;
1338            }
1339#endif
1340        }
1341
1342        obj_context->cmdbuf = NULL;
1343#ifdef PSBVIDEO_MRFL_VPP
1344        obj_context->vsp_cmdbuf = NULL;
1345#endif
1346
1347        obj_context->context_id = -1;
1348        obj_context->config_id = -1;
1349        obj_context->picture_width = 0;
1350        obj_context->picture_height = 0;
1351        free(obj_context->render_targets);
1352        free(obj_context->buffer_list);
1353        obj_context->num_buffers = 0;
1354        obj_context->render_targets = NULL;
1355        obj_context->num_render_targets = 0;
1356        obj_context->va_flags = 0;
1357        object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1358    }
1359    obj_context->ctp_type = (((obj_config->profile << 8) |
1360                             obj_config->entrypoint | driver_data->protected) & 0xffff);
1361
1362    if (!encode) {
1363        obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16);
1364    }
1365
1366    /* add ctx_num to save vp8 enc context num to support dual vp8 encoding */
1367    int ctx_num = psb_new_context(driver_data, obj_context->ctp_type | driver_data->protected);
1368    if (obj_context->profile == VAProfileVP8Version0_3 &&
1369        obj_context->entry_point == VAEntrypointEncSlice &&
1370	ctx_num > 2) {
1371	    return VA_STATUS_ERROR_UNKNOWN;
1372    }
1373
1374    DEBUG_FUNC_EXIT
1375    return vaStatus;
1376}
1377
1378static VAStatus psb__allocate_malloc_buffer(object_buffer_p obj_buffer, int size)
1379{
1380    VAStatus vaStatus = VA_STATUS_SUCCESS;
1381
1382    obj_buffer->buffer_data = realloc(obj_buffer->buffer_data, size);
1383    CHECK_ALLOCATION(obj_buffer->buffer_data);
1384
1385    return vaStatus;
1386}
1387
1388static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer);
1389
1390static VAStatus psb__allocate_BO_buffer(psb_driver_data_p driver_data, object_context_p obj_context, object_buffer_p obj_buffer, int size, unsigned char *data, VABufferType type)
1391{
1392    VAStatus vaStatus = VA_STATUS_SUCCESS;
1393
1394    ASSERT(NULL == obj_buffer->buffer_data);
1395
1396    if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) {
1397        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Abandoning BO for buffer %08x type %s\n", obj_buffer->base.id,
1398                                 buffer_type_to_string(obj_buffer->type));
1399        /* need to set psb_buffer aside and get another one */
1400        obj_buffer->psb_buffer->status = psb_bs_abandoned;
1401        obj_buffer->psb_buffer = NULL;
1402        obj_buffer->size = 0;
1403        obj_buffer->alloc_size = 0;
1404    }
1405
1406    if (type == VAProtectedSliceDataBufferType) {
1407        if (obj_buffer->psb_buffer) {
1408            drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: old RAR slice buffer with RAR handle 0%08x, current RAR handle 0x%08x\n",
1409                                     obj_buffer->psb_buffer->rar_handle, (uint32_t)data);
1410            drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: force old RAR buffer destroy and new buffer re-allocation by set size=0\n");
1411            obj_buffer->alloc_size = 0;
1412        }
1413    }
1414
1415    if (obj_buffer->alloc_size < (unsigned int)size) {
1416        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Buffer size mismatch: Need %d, currently have %d\n", size, obj_buffer->alloc_size);
1417        if (obj_buffer->psb_buffer) {
1418            if (obj_buffer->buffer_data) {
1419                psb__unmap_buffer(obj_buffer);
1420            }
1421            psb_buffer_destroy(obj_buffer->psb_buffer);
1422            obj_buffer->alloc_size = 0;
1423        } else {
1424            obj_buffer->psb_buffer = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s));
1425            if (NULL == obj_buffer->psb_buffer) {
1426                vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1427                DEBUG_FAILURE;
1428            }
1429        }
1430        if (VA_STATUS_SUCCESS == vaStatus) {
1431            drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new GPU buffers for vaCreateBuffer:type=%s,size=%d.\n",
1432                                     buffer_type_to_string(obj_buffer->type), size);
1433
1434            size = (size + 0x7fff) & ~0x7fff; /* Round up */
1435            if (obj_buffer->type == VAImageBufferType) /* Xserver side PutSurface, Image/subpicture buffer
1436                                                        * should be shared between two process
1437                                                        */
1438                vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu_shared, obj_buffer->psb_buffer);
1439#ifndef BAYTRAIL
1440            else if (obj_buffer->type == VAProtectedSliceDataBufferType) {
1441                vaStatus = psb_buffer_reference_imr(driver_data, (uint32_t)data, obj_buffer->psb_buffer);
1442            }
1443#endif
1444            else if (obj_buffer->type == VAEncCodedBufferType)
1445#ifdef ANDROID
1446               if(obj_context && obj_context->profile == VAProfileVP8Version0_3) /*VP8 Encoder need  uncacheable coded buf*/
1447                  vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer);
1448               else
1449                  vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu_cached, obj_buffer->psb_buffer);
1450#else
1451                vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer);
1452#endif
1453            else
1454                vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer);
1455            if (VA_STATUS_SUCCESS != vaStatus) {
1456                free(obj_buffer->psb_buffer);
1457                obj_buffer->psb_buffer = NULL;
1458                DEBUG_FAILURE;
1459            } else {
1460                obj_buffer->alloc_size = size;
1461            }
1462        }
1463    }
1464    return vaStatus;
1465}
1466
1467static VAStatus psb__map_buffer(object_buffer_p obj_buffer)
1468{
1469    if (obj_buffer->psb_buffer) {
1470        return psb_buffer_map(obj_buffer->psb_buffer, &obj_buffer->buffer_data);
1471    }
1472    return VA_STATUS_SUCCESS;
1473}
1474
1475static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer)
1476{
1477    if (obj_buffer->psb_buffer) {
1478        obj_buffer->buffer_data = NULL;
1479        return psb_buffer_unmap(obj_buffer->psb_buffer);
1480    }
1481    return VA_STATUS_SUCCESS;
1482}
1483
1484static void psb__destroy_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer)
1485{
1486    if (obj_buffer->psb_buffer) {
1487        if (obj_buffer->buffer_data) {
1488            psb__unmap_buffer(obj_buffer);
1489        }
1490        psb_buffer_destroy(obj_buffer->psb_buffer);
1491        free(obj_buffer->psb_buffer);
1492        obj_buffer->psb_buffer = NULL;
1493    }
1494
1495    if (NULL != obj_buffer->buffer_data) {
1496        free(obj_buffer->buffer_data);
1497        obj_buffer->buffer_data = NULL;
1498        obj_buffer->size = 0;
1499    }
1500
1501    object_heap_free(&driver_data->buffer_heap, (object_base_p) obj_buffer);
1502}
1503
1504void psb__suspend_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer)
1505{
1506    if (obj_buffer->context) {
1507        VABufferType type = obj_buffer->type;
1508        object_context_p obj_context = obj_buffer->context;
1509
1510        /* Remove buffer from active list */
1511        *obj_buffer->pptr_prev_next = obj_buffer->ptr_next;
1512
1513        /* Add buffer to tail of unused list */
1514        obj_buffer->ptr_next = NULL;
1515        obj_buffer->last_used = obj_context->frame_count;
1516        if (obj_context->buffers_unused_tail[type]) {
1517            obj_buffer->pptr_prev_next = &(obj_context->buffers_unused_tail[type]->ptr_next);
1518        } else {
1519            obj_buffer->pptr_prev_next = &(obj_context->buffers_unused[type]);
1520        }
1521        *obj_buffer->pptr_prev_next = obj_buffer;
1522        obj_context->buffers_unused_tail[type] = obj_buffer;
1523        obj_context->buffers_unused_count[type]++;
1524
1525        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Adding buffer %08x type %s to unused list. unused count = %d\n", obj_buffer->base.id,
1526                                 buffer_type_to_string(obj_buffer->type), obj_context->buffers_unused_count[type]);
1527
1528        object_heap_suspend_object((object_base_p) obj_buffer, 1); /* suspend */
1529        return;
1530    }
1531
1532    if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) {
1533        /* need to set psb_buffer aside */
1534        obj_buffer->psb_buffer->status = psb_bs_abandoned;
1535        obj_buffer->psb_buffer = NULL;
1536    }
1537
1538    psb__destroy_buffer(driver_data, obj_buffer);
1539}
1540
1541static void psb__destroy_context(psb_driver_data_p driver_data, object_context_p obj_context)
1542{
1543    int encode, i;
1544
1545    if (obj_context->entry_point == VAEntrypointEncSlice)
1546        encode = 1;
1547    else
1548        encode = 0;
1549
1550    obj_context->format_vtable->destroyContext(obj_context);
1551
1552    for (i = 0; i < PSB_MAX_BUFFERTYPES; i++) {
1553        object_buffer_p obj_buffer;
1554        obj_buffer = obj_context->buffers_active[i];
1555        for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) {
1556            drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying active buffer %08x\n", __FUNCTION__, obj_buffer->base.id);
1557            psb__destroy_buffer(driver_data, obj_buffer);
1558        }
1559        obj_buffer = obj_context->buffers_unused[i];
1560        for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) {
1561            drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying unused buffer %08x\n", __FUNCTION__, obj_buffer->base.id);
1562            psb__destroy_buffer(driver_data, obj_buffer);
1563        }
1564        obj_context->buffers_unused_count[i] = 0;
1565    }
1566#ifndef BAYTRAIL
1567    for (i = 0; i < LNC_MAX_CMDBUFS_ENCODE; i++) {
1568        if (obj_context->pnw_cmdbuf_list[i]) {
1569            pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]);
1570            free(obj_context->pnw_cmdbuf_list[i]);
1571            obj_context->pnw_cmdbuf_list[i] = NULL;
1572        }
1573    }
1574#endif
1575#ifdef PSBVIDEO_MRFL
1576    for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) {
1577        if (obj_context->tng_cmdbuf_list[i]) {
1578            tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]);
1579            free(obj_context->tng_cmdbuf_list[i]);
1580            obj_context->tng_cmdbuf_list[i] = NULL;
1581        }
1582    }
1583#endif
1584#ifdef PSBVIDEO_MRFL_VPP
1585    for (i = 0; i < VSP_MAX_CMDBUFS; i++) {
1586        if (obj_context->vsp_cmdbuf_list[i]) {
1587            vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]);
1588            free(obj_context->vsp_cmdbuf_list[i]);
1589            obj_context->vsp_cmdbuf_list[i] = NULL;
1590        }
1591    }
1592#endif
1593
1594    for (i = 0; i < PSB_MAX_CMDBUFS; i++) {
1595        if (obj_context->cmdbuf_list[i]) {
1596            psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]);
1597            free(obj_context->cmdbuf_list[i]);
1598            obj_context->cmdbuf_list[i] = NULL;
1599        }
1600    }
1601    obj_context->cmdbuf = NULL;
1602#ifdef PSBVIDEO_MRFL_VPP
1603    obj_context->vsp_cmdbuf = NULL;
1604#endif
1605
1606    obj_context->context_id = -1;
1607    obj_context->config_id = -1;
1608    obj_context->picture_width = 0;
1609    obj_context->picture_height = 0;
1610    if (obj_context->render_targets)
1611        free(obj_context->render_targets);
1612    obj_context->render_targets = NULL;
1613    obj_context->num_render_targets = 0;
1614    obj_context->va_flags = 0;
1615
1616    obj_context->current_render_target = NULL;
1617    obj_context->ec_target = NULL;
1618    obj_context->ec_candidate = NULL;
1619    if (obj_context->buffer_list)
1620        free(obj_context->buffer_list);
1621    obj_context->num_buffers = 0;
1622
1623    object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1624
1625    psb_rm_context(driver_data);
1626}
1627
1628VAStatus psb_DestroyContext(
1629    VADriverContextP ctx,
1630    VAContextID context
1631)
1632{
1633    DEBUG_FUNC_ENTER
1634    INIT_DRIVER_DATA
1635    VAStatus vaStatus = VA_STATUS_SUCCESS;
1636    object_context_p obj_context = CONTEXT(context);
1637    CHECK_CONTEXT(obj_context);
1638
1639    psb__destroy_context(driver_data, obj_context);
1640
1641    DEBUG_FUNC_EXIT
1642    return vaStatus;
1643}
1644
1645VAStatus psb__CreateBuffer(
1646    psb_driver_data_p driver_data,
1647    object_context_p obj_context,       /* in */
1648    VABufferType type,  /* in */
1649    unsigned int size,          /* in */
1650    unsigned int num_elements, /* in */
1651    unsigned char *data,         /* in */
1652    VABufferID *buf_desc    /* out */
1653)
1654{
1655    DEBUG_FUNC_ENTER
1656    VAStatus vaStatus = VA_STATUS_SUCCESS;
1657    int bufferID;
1658    object_buffer_p obj_buffer = obj_context ? obj_context->buffers_unused[type] : NULL;
1659    int unused_count = obj_context ? obj_context->buffers_unused_count[type] : 0;
1660
1661
1662    /*
1663     * Buffer Management
1664     * For each buffer type, maintain
1665     *   - a LRU sorted list of unused buffers
1666     *   - a list of active buffers
1667     * We only create a new buffer when
1668     *   - no unused buffers are available
1669     *   - the last unused buffer is still queued
1670     *   - the last unused buffer was used very recently and may still be fenced
1671     *      - used recently is defined as within the current frame_count (subject to tweaks)
1672     *
1673     * The buffer that is returned will be moved to the list of active buffers
1674     *   - vaDestroyBuffer and vaRenderPicture will move the active buffer back to the list of unused buffers
1675    */
1676    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Requesting buffer creation, size=%d,elements=%d,type=%s\n", size, num_elements,
1677                             buffer_type_to_string(type));
1678
1679    /* on MFLD, data is IMR offset, and could be 0 */
1680    /*
1681    if ((type == VAProtectedSliceDataBufferType) && (data == NULL)) {
1682        drv_debug_msg(VIDEO_DEBUG_ERROR, "RAR: Create protected slice buffer, but RAR handle is NULL\n");
1683        return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE ;
1684    }
1685    */
1686
1687    if (obj_buffer && obj_buffer->psb_buffer) {
1688        if (psb_bs_queued == obj_buffer->psb_buffer->status) {
1689            /* Buffer is still queued, allocate new buffer instead */
1690            drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, still queued\n", obj_buffer->base.id);
1691            obj_buffer = NULL;
1692        } else if ((obj_buffer->last_used == obj_context->frame_count) && (unused_count < MAX_UNUSED_BUFFERS)) {
1693            /* Buffer was used for this frame, allocate new buffer instead */
1694            drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, recently used. Unused = %d\n", obj_buffer->base.id, unused_count);
1695            obj_buffer = NULL;
1696        } else if (obj_context->frame_count - obj_buffer->last_used < 5) {
1697            /* Buffer was used for previous frame, allocate new buffer instead */
1698            drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x used by frame %d. Unused = %d\n", obj_buffer->base.id, obj_buffer->last_used, unused_count);
1699            obj_buffer = NULL;
1700        }
1701    }
1702
1703    if (obj_buffer) {
1704        bufferID = obj_buffer->base.id;
1705        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Reusing buffer %08x type %s from unused list. Unused = %d\n", bufferID,
1706                                 buffer_type_to_string(type), unused_count);
1707
1708        /* Remove from unused list */
1709        obj_context->buffers_unused[type] = obj_buffer->ptr_next;
1710        if (obj_context->buffers_unused[type]) {
1711            obj_context->buffers_unused[type]->pptr_prev_next = &(obj_context->buffers_unused[type]);
1712            ASSERT(obj_context->buffers_unused_tail[type] != obj_buffer);
1713        } else {
1714            ASSERT(obj_context->buffers_unused_tail[type] == obj_buffer);
1715            obj_context->buffers_unused_tail[type] = 0;
1716        }
1717        obj_context->buffers_unused_count[type]--;
1718
1719        object_heap_suspend_object((object_base_p)obj_buffer, 0); /* Make BufferID valid again */
1720        ASSERT(type == obj_buffer->type);
1721        ASSERT(obj_context == obj_buffer->context);
1722    } else {
1723        bufferID = object_heap_allocate(&driver_data->buffer_heap);
1724        obj_buffer = BUFFER(bufferID);
1725        CHECK_ALLOCATION(obj_buffer);
1726
1727        MEMSET_OBJECT(obj_buffer, struct object_buffer_s);
1728
1729        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocating new buffer %08x type %s.\n", bufferID, buffer_type_to_string(type));
1730        obj_buffer->type = type;
1731        obj_buffer->buffer_data = NULL;
1732        obj_buffer->psb_buffer = NULL;
1733        obj_buffer->size = 0;
1734        obj_buffer->max_num_elements = 0;
1735        obj_buffer->alloc_size = 0;
1736        obj_buffer->context = obj_context;
1737    }
1738    if (obj_context) {
1739        /* Add to front of active list */
1740        obj_buffer->ptr_next = obj_context->buffers_active[type];
1741        if (obj_buffer->ptr_next) {
1742            obj_buffer->ptr_next->pptr_prev_next = &(obj_buffer->ptr_next);
1743        }
1744        obj_buffer->pptr_prev_next = &(obj_context->buffers_active[type]);
1745        *obj_buffer->pptr_prev_next = obj_buffer;
1746    }
1747
1748    switch (obj_buffer->type) {
1749    case VABitPlaneBufferType:
1750    case VASliceDataBufferType:
1751    case VAResidualDataBufferType:
1752    case VAImageBufferType:
1753    case VASliceGroupMapBufferType:
1754    case VAEncCodedBufferType:
1755    case VAProtectedSliceDataBufferType:
1756#ifdef SLICE_HEADER_PARSING
1757    case VAParseSliceHeaderGroupBufferType:
1758#endif
1759        vaStatus = psb__allocate_BO_buffer(driver_data, obj_context,obj_buffer, size * num_elements, data, obj_buffer->type);
1760        DEBUG_FAILURE;
1761        break;
1762    case VAPictureParameterBufferType:
1763    case VAIQMatrixBufferType:
1764    case VASliceParameterBufferType:
1765    case VAMacroblockParameterBufferType:
1766    case VADeblockingParameterBufferType:
1767    case VAEncPackedHeaderParameterBufferType:
1768    case VAEncPackedHeaderDataBufferType:
1769    case VAEncSequenceParameterBufferType:
1770    case VAEncPictureParameterBufferType:
1771    case VAEncSliceParameterBufferType:
1772    case VAQMatrixBufferType:
1773    case VAEncMiscParameterBufferType:
1774    case VAProbabilityBufferType:
1775    case VAHuffmanTableBufferType:
1776    case VAProcPipelineParameterBufferType:
1777    case VAProcFilterParameterBufferType:
1778#ifdef SLICE_HEADER_PARSING
1779    case VAParsePictureParameterBufferType:
1780#endif
1781        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new malloc buffers for vaCreateBuffer:type=%s,size=%d, buffer_data=%p.\n",
1782                                 buffer_type_to_string(type), size, obj_buffer->buffer_data);
1783        vaStatus = psb__allocate_malloc_buffer(obj_buffer, size * num_elements);
1784        DEBUG_FAILURE;
1785        break;
1786
1787    default:
1788        vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1789        DEBUG_FAILURE;
1790        break;;
1791    }
1792
1793    if (VA_STATUS_SUCCESS == vaStatus) {
1794        obj_buffer->size = size;
1795        obj_buffer->max_num_elements = num_elements;
1796        obj_buffer->num_elements = num_elements;
1797        if (data && (obj_buffer->type != VAProtectedSliceDataBufferType)) {
1798            vaStatus = psb__map_buffer(obj_buffer);
1799            if (VA_STATUS_SUCCESS == vaStatus) {
1800                memcpy(obj_buffer->buffer_data, data, size * num_elements);
1801
1802                psb__unmap_buffer(obj_buffer);
1803            }
1804        }
1805    }
1806    if (VA_STATUS_SUCCESS == vaStatus) {
1807        *buf_desc = bufferID;
1808    } else {
1809        psb__destroy_buffer(driver_data, obj_buffer);
1810    }
1811
1812    DEBUG_FUNC_EXIT
1813    return vaStatus;
1814}
1815
1816VAStatus psb_CreateBuffer(
1817    VADriverContextP ctx,
1818    VAContextID context,        /* in */
1819    VABufferType type,  /* in */
1820    unsigned int size,          /* in */
1821    unsigned int num_elements, /* in */
1822    void *data,         /* in */
1823    VABufferID *buf_desc    /* out */
1824)
1825{
1826    DEBUG_FUNC_ENTER
1827    INIT_DRIVER_DATA
1828    VAStatus vaStatus = VA_STATUS_SUCCESS;
1829
1830    CHECK_INVALID_PARAM(num_elements <= 0);
1831
1832    switch (type) {
1833    case VABitPlaneBufferType:
1834    case VASliceDataBufferType:
1835    case VAProtectedSliceDataBufferType:
1836    case VAResidualDataBufferType:
1837    case VASliceGroupMapBufferType:
1838    case VAPictureParameterBufferType:
1839    case VAIQMatrixBufferType:
1840    case VASliceParameterBufferType:
1841    case VAMacroblockParameterBufferType:
1842    case VADeblockingParameterBufferType:
1843    case VAEncCodedBufferType:
1844    case VAEncSequenceParameterBufferType:
1845    case VAEncPictureParameterBufferType:
1846    case VAEncSliceParameterBufferType:
1847    case VAEncPackedHeaderParameterBufferType:
1848    case VAEncPackedHeaderDataBufferType:
1849    case VAQMatrixBufferType:
1850    case VAEncMiscParameterBufferType:
1851    case VAProbabilityBufferType:
1852    case VAHuffmanTableBufferType:
1853    case VAProcPipelineParameterBufferType:
1854    case VAProcFilterParameterBufferType:
1855#ifdef SLICE_HEADER_PARSING
1856    case VAParsePictureParameterBufferType:
1857    case VAParseSliceHeaderGroupBufferType:
1858#endif
1859        break;
1860
1861    default:
1862        vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1863        DEBUG_FAILURE;
1864        return vaStatus;
1865    }
1866
1867    object_context_p obj_context = CONTEXT(context);
1868    CHECK_CONTEXT(obj_context);
1869    CHECK_INVALID_PARAM(buf_desc == NULL);
1870
1871    vaStatus = psb__CreateBuffer(driver_data, obj_context, type, size, num_elements, data, buf_desc);
1872
1873    DEBUG_FUNC_EXIT
1874    return vaStatus;
1875}
1876
1877
1878VAStatus psb_BufferInfo(
1879    VADriverContextP ctx,
1880    VABufferID buf_id,  /* in */
1881    VABufferType *type, /* out */
1882    unsigned int *size,         /* out */
1883    unsigned int *num_elements /* out */
1884)
1885{
1886    DEBUG_FUNC_ENTER
1887    INIT_DRIVER_DATA
1888    VAStatus vaStatus = VA_STATUS_SUCCESS;
1889
1890    object_buffer_p obj_buffer = BUFFER(buf_id);
1891    CHECK_BUFFER(obj_buffer);
1892
1893    *type = obj_buffer->type;
1894    *size = obj_buffer->size;
1895    *num_elements = obj_buffer->num_elements;
1896    DEBUG_FUNC_EXIT
1897    return VA_STATUS_SUCCESS;
1898}
1899
1900
1901VAStatus psb_BufferSetNumElements(
1902    VADriverContextP ctx,
1903    VABufferID buf_id,    /* in */
1904    unsigned int num_elements    /* in */
1905)
1906{
1907    DEBUG_FUNC_ENTER
1908    INIT_DRIVER_DATA
1909    VAStatus vaStatus = VA_STATUS_SUCCESS;
1910    object_buffer_p obj_buffer = BUFFER(buf_id);
1911    CHECK_BUFFER(obj_buffer);
1912
1913    if ((num_elements <= 0) || (num_elements > obj_buffer->max_num_elements)) {
1914        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
1915    }
1916    if (VA_STATUS_SUCCESS == vaStatus) {
1917        obj_buffer->num_elements = num_elements;
1918    }
1919
1920    DEBUG_FUNC_EXIT
1921    return vaStatus;
1922}
1923
1924VAStatus psb_MapBuffer(
1925    VADriverContextP ctx,
1926    VABufferID buf_id,    /* in */
1927    void **pbuf         /* out */
1928)
1929{
1930    DEBUG_FUNC_ENTER
1931    INIT_DRIVER_DATA
1932    VAStatus vaStatus = VA_STATUS_SUCCESS;
1933    object_buffer_p obj_buffer = BUFFER(buf_id);
1934    CHECK_BUFFER(obj_buffer);
1935
1936    CHECK_INVALID_PARAM(pbuf == NULL);
1937
1938    vaStatus = psb__map_buffer(obj_buffer);
1939    CHECK_VASTATUS();
1940
1941    if (NULL != obj_buffer->buffer_data) {
1942        *pbuf = obj_buffer->buffer_data;
1943
1944        /* specifically for Topaz encode
1945         * write validate coded data offset in CodedBuffer
1946         */
1947        if (obj_buffer->type == VAEncCodedBufferType)
1948            psb_codedbuf_map_mangle(ctx, obj_buffer, pbuf);
1949        /* *(IMG_UINT32 *)((unsigned char *)obj_buffer->buffer_data + 4) = 16; */
1950    } else {
1951        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1952    }
1953    DEBUG_FUNC_EXIT
1954    return vaStatus;
1955}
1956
1957VAStatus psb_UnmapBuffer(
1958    VADriverContextP ctx,
1959    VABufferID buf_id    /* in */
1960)
1961{
1962    DEBUG_FUNC_ENTER
1963    INIT_DRIVER_DATA
1964    VAStatus vaStatus = VA_STATUS_SUCCESS;
1965    object_buffer_p obj_buffer = BUFFER(buf_id);
1966    CHECK_BUFFER(obj_buffer);
1967
1968    vaStatus = psb__unmap_buffer(obj_buffer);
1969    DEBUG_FUNC_EXIT
1970    return vaStatus;
1971}
1972
1973
1974VAStatus psb_DestroyBuffer(
1975    VADriverContextP ctx,
1976    VABufferID buffer_id
1977)
1978{
1979    DEBUG_FUNC_ENTER
1980    INIT_DRIVER_DATA
1981    VAStatus vaStatus = VA_STATUS_SUCCESS;
1982    object_buffer_p obj_buffer = BUFFER(buffer_id);
1983    if (NULL == obj_buffer) {
1984        return vaStatus;
1985    }
1986    psb__suspend_buffer(driver_data, obj_buffer);
1987    DEBUG_FUNC_EXIT
1988    return vaStatus;
1989}
1990
1991
1992VAStatus psb_BeginPicture(
1993    VADriverContextP ctx,
1994    VAContextID context,
1995    VASurfaceID render_target
1996)
1997{
1998    DEBUG_FUNC_ENTER
1999    INIT_DRIVER_DATA
2000    VAStatus vaStatus = VA_STATUS_SUCCESS;
2001    object_context_p obj_context;
2002    object_surface_p obj_surface;
2003    object_config_p obj_config;
2004
2005    obj_context = CONTEXT(context);
2006    CHECK_CONTEXT(obj_context);
2007
2008    /* Must not be within BeginPicture / EndPicture already */
2009    ASSERT(obj_context->current_render_target == NULL);
2010
2011    obj_surface = SURFACE(render_target);
2012    CHECK_SURFACE(obj_surface);
2013
2014    obj_context->current_render_surface_id = render_target;
2015    obj_context->current_render_target = obj_surface;
2016    obj_context->slice_count = 0;
2017
2018    obj_config = CONFIG(obj_context->config_id);
2019    if (obj_config == NULL)
2020        return VA_STATUS_ERROR_INVALID_CONFIG;
2021
2022    /* if the surface is decode render target, and in displaying */
2023    if (obj_config &&
2024        (obj_config->entrypoint != VAEntrypointEncSlice) &&
2025        (driver_data->cur_displaying_surface == render_target))
2026        drv_debug_msg(VIDEO_DEBUG_ERROR, "WARNING: rendering a displaying surface, may see tearing\n");
2027
2028    if (VA_STATUS_SUCCESS == vaStatus) {
2029        vaStatus = obj_context->format_vtable->beginPicture(obj_context);
2030    }
2031
2032#ifdef ANDROID
2033    /* want msvdx to do rotate
2034     * but check per-context stream type: interlace or not
2035     */
2036    if ((obj_config->entrypoint != VAEntrypointEncSlice) &&
2037        (obj_config->entrypoint != VAEntrypointEncPicture)) {
2038        psb_RecalcAlternativeOutput(obj_context);
2039    }
2040#endif
2041#ifdef PSBVIDEO_MRFL_VPP_ROTATE
2042    if (driver_data->vpp_on && GET_SURFACE_INFO_tiling(obj_surface->psb_surface))
2043        driver_data->disable_msvdx_rotate = 0;
2044#endif
2045    if (obj_context->interlaced_stream || driver_data->disable_msvdx_rotate) {
2046        int i;
2047        obj_context->msvdx_rotate = 0;
2048        for (i = 0; i < obj_context->num_render_targets; i++) {
2049            object_surface_p obj_surface = SURFACE(obj_context->render_targets[i]);
2050            /*we invalidate all surfaces's rotate buffer share info here.*/
2051            if (obj_surface && obj_surface->share_info) {
2052                obj_surface->share_info->surface_rotate = 0;
2053            }
2054	}
2055    }
2056    else
2057        obj_context->msvdx_rotate = driver_data->msvdx_rotate_want;
2058
2059    /* the main surface track current rotate information
2060     * try to reuse the allocated rotate surfaces and don't destroy them
2061     * thus the rotation info in obj_surface->out_loop_surface may not be updated
2062     */
2063
2064    SET_SURFACE_INFO_rotate(obj_surface->psb_surface, obj_context->msvdx_rotate);
2065
2066     if (CONTEXT_SCALING(obj_context) && obj_config->entrypoint != VAEntrypointEncSlice)
2067          if(VA_STATUS_SUCCESS != psb_CreateScalingSurface(obj_context, obj_surface)) {
2068             obj_context->msvdx_scaling = 0;
2069             ALOGE("%s: fail to allocate scaling surface", __func__);
2070          }
2071
2072    if (CONTEXT_ROTATE(obj_context)) {
2073#ifdef PSBVIDEO_MRFL_VPP_ROTATE
2074        /* The VSP rotation is just for 1080P with tilling */
2075        if (driver_data->vpp_on && GET_SURFACE_INFO_tiling(obj_surface->psb_surface)) {
2076            if (obj_config->entrypoint == VAEntrypointVideoProc)
2077                vaStatus = psb_CreateRotateSurface(obj_context, obj_surface, obj_context->msvdx_rotate);
2078            else {
2079                SET_SURFACE_INFO_rotate(obj_surface->psb_surface, 0);
2080                obj_context->msvdx_rotate = 0;
2081                vaStatus = psb_DestroyRotateBuffer(obj_context, obj_surface);
2082            }
2083        } else
2084#endif
2085	vaStatus = psb_CreateRotateSurface(obj_context, obj_surface, obj_context->msvdx_rotate);
2086        if (VA_STATUS_SUCCESS !=vaStatus)
2087            ALOGE("%s: fail to allocate out loop surface", __func__);
2088    } else {
2089        if (obj_surface && obj_surface->share_info) {
2090            obj_surface->share_info->metadata_rotate = VAROTATION2HAL(driver_data->va_rotate);
2091            obj_surface->share_info->surface_rotate = VAROTATION2HAL(obj_context->msvdx_rotate);
2092        }
2093    }
2094
2095    if (driver_data->is_oold &&  !obj_surface->psb_surface->in_loop_buf) {
2096        psb_surface_p psb_surface = obj_surface->psb_surface;
2097
2098        psb_surface->in_loop_buf = calloc(1, sizeof(struct psb_buffer_s));
2099        CHECK_ALLOCATION(psb_surface->in_loop_buf);
2100
2101        /* FIXME: For RAR surface, need allocate RAR buffer  */
2102        vaStatus = psb_buffer_create(obj_context->driver_data,
2103                                     psb_surface->size,
2104                                     psb_bt_surface,
2105                                     psb_surface->in_loop_buf);
2106    } else if (!driver_data->is_oold && obj_surface->psb_surface->in_loop_buf) {
2107        psb_surface_p psb_surface = obj_surface->psb_surface;
2108
2109        psb_buffer_destroy(psb_surface->in_loop_buf);
2110        free(psb_surface->in_loop_buf);
2111        psb_surface->in_loop_buf = NULL;
2112    }
2113    obj_context->is_oold = driver_data->is_oold;
2114
2115    drv_debug_msg(VIDEO_DEBUG_GENERAL, "---BeginPicture 0x%08x for frame %d --\n",
2116                             render_target, obj_context->frame_count);
2117    psb__trace_message("------Trace frame %d------\n", obj_context->frame_count);
2118
2119    DEBUG_FUNC_EXIT
2120    return vaStatus;
2121}
2122
2123VAStatus psb_RenderPicture(
2124    VADriverContextP ctx,
2125    VAContextID context,
2126    VABufferID *buffers,
2127    int num_buffers
2128)
2129{
2130    DEBUG_FUNC_ENTER
2131    INIT_DRIVER_DATA
2132    VAStatus vaStatus = VA_STATUS_SUCCESS;
2133    object_context_p obj_context;
2134    object_buffer_p *buffer_list;
2135    int i;
2136
2137    obj_context = CONTEXT(context);
2138    CHECK_CONTEXT(obj_context);
2139
2140    CHECK_INVALID_PARAM(num_buffers <= 0);
2141    /* Don't crash on NULL pointers */
2142    CHECK_BUFFER(buffers);
2143    /* Must be within BeginPicture / EndPicture */
2144    ASSERT(obj_context->current_render_target != NULL);
2145
2146    if (num_buffers > obj_context->num_buffers) {
2147        free(obj_context->buffer_list);
2148
2149        obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * num_buffers);
2150        if (obj_context->buffer_list == NULL) {
2151            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
2152            obj_context->num_buffers = 0;
2153        }
2154
2155        obj_context->num_buffers = num_buffers;
2156    }
2157    buffer_list = obj_context->buffer_list;
2158
2159    if (VA_STATUS_SUCCESS == vaStatus) {
2160        /* Lookup buffer references */
2161        for (i = 0; i < num_buffers; i++) {
2162            object_buffer_p obj_buffer = BUFFER(buffers[i]);
2163            CHECK_BUFFER(obj_buffer);
2164
2165            buffer_list[i] = obj_buffer;
2166            drv_debug_msg(VIDEO_DEBUG_GENERAL, "Render buffer %08x type %s\n", obj_buffer->base.id,
2167                                     buffer_type_to_string(obj_buffer->type));
2168        }
2169    }
2170
2171    if (VA_STATUS_SUCCESS == vaStatus) {
2172        vaStatus = obj_context->format_vtable->renderPicture(obj_context, buffer_list, num_buffers);
2173    }
2174
2175    if (buffer_list) {
2176        /* Release buffers */
2177        for (i = 0; i < num_buffers; i++) {
2178            if (buffer_list[i]) {
2179                psb__suspend_buffer(driver_data, buffer_list[i]);
2180            }
2181        }
2182    }
2183
2184    DEBUG_FUNC_EXIT
2185    return vaStatus;
2186}
2187
2188VAStatus psb_EndPicture(
2189    VADriverContextP ctx,
2190    VAContextID context
2191)
2192{
2193    DEBUG_FUNC_ENTER
2194    INIT_DRIVER_DATA
2195    VAStatus vaStatus;
2196    object_context_p obj_context;
2197
2198    obj_context = CONTEXT(context);
2199    CHECK_CONTEXT(obj_context);
2200
2201    vaStatus = obj_context->format_vtable->endPicture(obj_context);
2202
2203    drv_debug_msg(VIDEO_DEBUG_GENERAL, "---EndPicture for frame %d --\n", obj_context->frame_count);
2204
2205    obj_context->current_render_target = NULL;
2206    obj_context->frame_count++;
2207
2208    psb__trace_message("FrameCount = %03d\n", obj_context->frame_count);
2209    drv_debug_msg(VIDEO_DEBUG_GENERAL, "FrameCount = %03d\n", obj_context->frame_count);
2210    psb__trace_message(NULL);
2211
2212
2213    //psb_SyncSurface(ctx, obj_context->current_render_surface_id);
2214    DEBUG_FUNC_EXIT
2215    return vaStatus;
2216}
2217
2218
2219static void psb__surface_usage(
2220    psb_driver_data_p driver_data,
2221    object_surface_p obj_surface,
2222    int *decode, int *encode, int *rc_enable, int *proc
2223)
2224{
2225    object_context_p obj_context;
2226    object_config_p obj_config;
2227    VAEntrypoint tmp;
2228    unsigned int eRCmode;
2229    int i;
2230
2231
2232    *decode = 0;
2233    *encode = 0;
2234    *rc_enable = 0;
2235    *proc = 0;
2236
2237    obj_context = CONTEXT(obj_surface->context_id);
2238    if (NULL == obj_context) /* not associate with a context */
2239        return;
2240
2241    obj_config = CONFIG(obj_context->config_id);
2242    if (NULL == obj_config) /* not have a validate context */
2243        return;
2244
2245    tmp = obj_config->entrypoint;
2246
2247    *encode = (tmp == VAEntrypointEncSlice) || (tmp == VAEntrypointEncPicture);
2248    *decode = (VAEntrypointVLD <= tmp) && (tmp <= VAEntrypointDeblocking);
2249#ifdef PSBVIDEO_MRFL_VPP
2250    *proc = (VAEntrypointVideoProc == tmp);
2251#endif
2252
2253    if (*encode) {
2254        for (i = 0; i < obj_config->attrib_count; i++) {
2255            if (obj_config->attrib_list[i].type == VAConfigAttribRateControl)
2256                break;
2257        }
2258
2259        if (i >= obj_config->attrib_count)
2260            eRCmode = VA_RC_NONE;
2261        else
2262            eRCmode = obj_config->attrib_list[i].value;
2263
2264        if (eRCmode == VA_RC_NONE)
2265            *rc_enable = 0;
2266        else
2267            *rc_enable = 1;
2268    }
2269}
2270
2271VAStatus psb_SyncSurface(
2272    VADriverContextP ctx,
2273    VASurfaceID render_target
2274)
2275{
2276    DEBUG_FUNC_ENTER
2277    INIT_DRIVER_DATA
2278    VAStatus vaStatus = VA_STATUS_SUCCESS;
2279    object_surface_p obj_surface;
2280    int decode = 0, encode = 0, rc_enable = 0, proc = 0;
2281    object_context_p obj_context = NULL;
2282    object_config_p obj_config = NULL;
2283
2284    drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_SyncSurface: 0x%08x\n", render_target);
2285
2286    obj_surface = SURFACE(render_target);
2287    CHECK_SURFACE(obj_surface);
2288
2289    obj_context = CONTEXT(obj_surface->context_id);
2290    if (obj_context) {
2291        obj_config = CONFIG(obj_context->config_id);
2292    }
2293
2294    /* The cur_displaying_surface indicates the surface being displayed by overlay.
2295     * The diaplay_timestamp records the time point of put surface, which would
2296     * be set to zero while using texture blit.*/
2297
2298    /* don't use mutex here for performance concern... */
2299    //pthread_mutex_lock(&output->output_mutex);
2300    if (render_target == driver_data->cur_displaying_surface)
2301        vaStatus = VA_STATUS_ERROR_SURFACE_IN_DISPLAYING;
2302    else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface)    /* use overlay */
2303             && (render_target == driver_data->last_displaying_surface)) {  /* It's the last displaying surface*/
2304        object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface);
2305        /*  The flip operation on current displaying surface could be delayed to
2306         *  next VBlank and hadn't been finished yet. Then, the last displaying
2307         *  surface shouldn't be freed, because the hardware may not
2308         *  complete loading data of it. Any change of the last surface could
2309         *  have a impect on the scrren.*/
2310        if (NULL != cur_obj_surface) {
2311            while ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY)
2312                usleep(PSB_MAX_FLIP_DELAY * 1000);
2313        }
2314    }
2315    //pthread_mutex_unlock(&output->output_mutex);
2316
2317    if (vaStatus != VA_STATUS_ERROR_SURFACE_IN_DISPLAYING) {
2318#ifdef PSBVIDEO_MRFL_VPP_ROTATE
2319        /* For VPP buffer, will sync the rotated buffer */
2320        if (obj_config && obj_config->entrypoint == VAEntrypointVideoProc) {
2321            if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface) &&
2322                (obj_context->msvdx_rotate == VA_ROTATION_90 || obj_context->msvdx_rotate == VA_ROTATION_270) &&
2323                obj_surface->out_loop_surface)
2324                vaStatus = psb_surface_sync(obj_surface->out_loop_surface);
2325            else
2326                vaStatus = psb_surface_sync(obj_surface->psb_surface);
2327	} else
2328#endif
2329        vaStatus = psb_surface_sync(obj_surface->psb_surface);
2330    }
2331
2332    /* report any error of decode for Android */
2333    psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc);
2334#if 0
2335    if (decode && IS_MRST(driver_data)) {
2336        struct drm_lnc_video_getparam_arg arg;
2337        uint32_t ret, handle, fw_status = 0;
2338        handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf));
2339        arg.key = IMG_VIDEO_DECODE_STATUS;
2340        arg.arg = (uint64_t)((unsigned long) & handle);
2341        arg.value = (uint64_t)((unsigned long) & fw_status);
2342        ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
2343                                  &arg, sizeof(arg));
2344        if (ret == 0) {
2345            if (fw_status != 0)
2346                vaStatus = VA_STATUS_ERROR_DECODING_ERROR;
2347        } else {
2348            drv_debug_msg(VIDEO_DEBUG_GENERAL, "IMG_VIDEO_DECODE_STATUS ioctl return failed.\n");
2349            vaStatus = VA_STATUS_ERROR_UNKNOWN;
2350        }
2351    } else if (proc && IS_MRFL(driver_data)) {
2352        /* FIXME: does it need a new surface sync mechanism for FRC? */
2353    }
2354#endif
2355    if (proc && IS_MRFL(driver_data)) {
2356        /* FIXME: does it need a new surface sync mechanism for FRC? */
2357    }
2358
2359    //psb__dump_NV_buffers(obj_surface->psb_surface, 0, 0, obj_surface->width, obj_surface->height);
2360    //psb__dump_NV_buffers(obj_surface->psb_surface_rotate, 0, 0, obj_surface->height, ((obj_surface->width + 0x1f) & (~0x1f)));
2361    if (obj_surface->scaling_surface)
2362        psb__dump_NV12_buffers(obj_surface->scaling_surface, 0, 0, obj_surface->width_s, obj_surface->height_s);
2363    DEBUG_FAILURE;
2364    DEBUG_FUNC_EXIT
2365    return vaStatus;
2366}
2367
2368
2369VAStatus psb_QuerySurfaceStatus(
2370    VADriverContextP ctx,
2371    VASurfaceID render_target,
2372    VASurfaceStatus *status    /* out */
2373)
2374{
2375    DEBUG_FUNC_ENTER
2376    INIT_DRIVER_DATA
2377    VAStatus vaStatus = VA_STATUS_SUCCESS;
2378    object_surface_p obj_surface;
2379    VASurfaceStatus surface_status;
2380    int frame_skip = 0, encode = 0, decode = 0, rc_enable = 0, proc = 0;
2381    object_context_p obj_context = NULL;
2382
2383    obj_surface = SURFACE(render_target);
2384    CHECK_SURFACE(obj_surface);
2385
2386    CHECK_INVALID_PARAM(status == NULL);
2387
2388    psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc);
2389#ifdef PSBVIDEO_MRFL_VPP_ROTATE
2390    /* For VPP 1080P, will query the rotated buffer */
2391    if (proc) {
2392        obj_context = CONTEXT(obj_surface->context_id);
2393        CHECK_CONTEXT(obj_context);
2394        if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface) &&
2395            (obj_context->msvdx_rotate == VA_ROTATION_90 || obj_context->msvdx_rotate == VA_ROTATION_270) &&
2396            obj_surface->out_loop_surface)
2397            vaStatus = psb_surface_query_status(obj_surface->out_loop_surface, &surface_status);
2398        else
2399            vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status);
2400    } else
2401#endif
2402        vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status);
2403
2404    /* The cur_displaying_surface indicates the surface being displayed by overlay.
2405     * The diaplay_timestamp records the time point of put surface, which would
2406     * be set to zero while using texture blit.*/
2407    pthread_mutex_lock(&driver_data->output_mutex);
2408    if (render_target == driver_data->cur_displaying_surface)
2409        surface_status = VASurfaceDisplaying;
2410    else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface)    /* use overlay */
2411             && (render_target == driver_data->last_displaying_surface)) {  /* It's the last displaying surface*/
2412        object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface);
2413        /*The flip operation on current displaying surface could be delayed to
2414         *  next VBlank and hadn't been finished yet. Then, the last displaying
2415         *  surface shouldn't be freed, because the hardware may not
2416         *  complete loading data of it. Any change of the last surface could
2417         *  have a impect on the scrren.*/
2418        if ((NULL != cur_obj_surface)
2419            && ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY)) {
2420            surface_status = VASurfaceDisplaying;
2421        }
2422    }
2423    pthread_mutex_unlock(&driver_data->output_mutex);
2424
2425    /* try to get frameskip flag for encode */
2426#ifndef BAYTRAIL
2427    if (!decode) {
2428        /* The rendering surface may not be associated with any context. So driver should
2429           check the frame skip flag even variable encode is 0 */
2430#ifdef PSBVIDEO_MRFL
2431        if (IS_MRFL(driver_data))
2432            tng_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip);
2433        else
2434#endif
2435            pnw_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip);
2436
2437        if (frame_skip == 1) {
2438            surface_status = surface_status | VASurfaceSkipped;
2439            drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s next frame of 0x%08x is skipped",
2440                    __FUNCTION__, render_target);
2441        }
2442    } else
2443#endif
2444    if (decode) {
2445#ifdef ANDROID
2446        if (obj_surface->psb_surface->buf.handle) {
2447            buffer_handle_t handle = obj_surface->psb_surface->buf.handle;
2448            int display_status;
2449            int err;
2450            err = gralloc_getdisplaystatus(handle, &display_status);
2451            if (!err) {
2452                if (display_status)
2453                    surface_status = VASurfaceDisplaying;
2454                else
2455                    surface_status = VASurfaceReady;
2456            } else {
2457                surface_status = VASurfaceReady;
2458            }
2459
2460            /* if not used by display, then check whether surface used by widi */
2461            if (surface_status == VASurfaceReady && obj_surface->share_info) {
2462                if (obj_surface->share_info->renderStatus == 1) {
2463                    surface_status = VASurfaceDisplaying;
2464                }
2465            }
2466        }
2467#endif
2468    } else if (proc) {
2469        /* FIXME: does it need a new surface sync mechanism for FRC? */
2470    }
2471
2472    *status = surface_status;
2473    DEBUG_FUNC_EXIT
2474    return vaStatus;
2475}
2476
2477VAStatus psb_QuerySurfaceError(
2478    VADriverContextP ctx,
2479    VASurfaceID render_target,
2480    VAStatus error_status,
2481    void **error_info /*out*/
2482)
2483{
2484    DEBUG_FUNC_ENTER
2485    INIT_DRIVER_DATA
2486    VAStatus vaStatus = VA_STATUS_SUCCESS;
2487    object_surface_p obj_surface;
2488    uint32_t i;
2489
2490    obj_surface = SURFACE(render_target);
2491    CHECK_SURFACE(obj_surface);
2492
2493#ifdef PSBVIDEO_MSVDX_EC
2494    if (driver_data->ec_enabled == 0) {
2495#else
2496    {
2497#endif
2498        drv_debug_msg(VIDEO_DEBUG_GENERAL, "error concealment is not supported for this profile.\n");
2499        error_info = NULL;
2500        return VA_STATUS_ERROR_UNKNOWN;
2501    }
2502
2503    if (error_status == VA_STATUS_ERROR_DECODING_ERROR) {
2504        drm_psb_msvdx_decode_status_t *decode_status = driver_data->msvdx_decode_status;
2505        struct drm_lnc_video_getparam_arg arg;
2506        uint32_t ret, handle;
2507        handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf));
2508
2509        arg.key = IMG_VIDEO_MB_ERROR;
2510        arg.arg = (uint64_t)((unsigned long) & handle);
2511        arg.value = (uint64_t)((unsigned long)decode_status);
2512        ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
2513                                  &arg, sizeof(arg));
2514	if (ret != 0) {
2515		drv_debug_msg(VIDEO_DEBUG_GENERAL,"return value is %d drmCommandWriteRead\n",ret);
2516		return VA_STATUS_ERROR_UNKNOWN;
2517	}
2518#ifndef _FOR_FPGA_
2519        if (decode_status->num_region > MAX_MB_ERRORS) {
2520            drv_debug_msg(VIDEO_DEBUG_GENERAL, "too much mb errors are reported.\n");
2521            return VA_STATUS_ERROR_UNKNOWN;
2522        }
2523        i = 0;
2524        for (i = 0; i < decode_status->num_region; ++i) {
2525            driver_data->surface_mb_error[i].status = 1;
2526            driver_data->surface_mb_error[i].start_mb = decode_status->mb_regions[i].start;
2527            driver_data->surface_mb_error[i].end_mb = decode_status->mb_regions[i].end;
2528            //driver_data->surface_mb_error[i].start_mb = decode_status->start_error_mb_list[i];
2529            //driver_data->surface_mb_error[i].end_mb = decode_status->end_error_mb_list[i];
2530            //driver_data->surface_mb_error[i].decode_error_type = decode_status->slice_missing_or_error[i];
2531        }
2532#endif
2533        driver_data->surface_mb_error[i].status = -1;
2534        *error_info = driver_data->surface_mb_error;
2535    } else {
2536        error_info = NULL;
2537        return VA_STATUS_ERROR_UNKNOWN;
2538    }
2539    DEBUG_FUNC_EXIT
2540    return vaStatus;
2541}
2542
2543#define PSB_MAX_SURFACE_ATTRIBUTES 16
2544
2545VAStatus psb_QuerySurfaceAttributes(VADriverContextP ctx,
2546                            VAConfigID config,
2547                            VASurfaceAttrib *attrib_list,
2548                            unsigned int *num_attribs)
2549{
2550    DEBUG_FUNC_ENTER
2551    INIT_DRIVER_DATA
2552
2553    VAStatus vaStatus = VA_STATUS_SUCCESS;
2554    object_config_p obj_config;
2555    unsigned int i = 0;
2556
2557    CHECK_INVALID_PARAM(num_attribs == NULL);
2558
2559    if (attrib_list == NULL) {
2560        *num_attribs = PSB_MAX_SURFACE_ATTRIBUTES;
2561        return VA_STATUS_SUCCESS;
2562    }
2563
2564    obj_config = CONFIG(config);
2565    CHECK_CONFIG(obj_config);
2566
2567    VASurfaceAttrib *attribs = NULL;
2568    attribs = malloc(PSB_MAX_SURFACE_ATTRIBUTES *sizeof(VASurfaceAttrib));
2569    if (attribs == NULL)
2570        return VA_STATUS_ERROR_ALLOCATION_FAILED;
2571
2572    attribs[i].type = VASurfaceAttribPixelFormat;
2573    attribs[i].value.type = VAGenericValueTypeInteger;
2574    attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
2575    attribs[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
2576    i++;
2577
2578    attribs[i].type = VASurfaceAttribMemoryType;
2579    attribs[i].value.type = VAGenericValueTypeInteger;
2580    attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
2581    if (obj_config->entrypoint == VAEntrypointEncSlice && obj_config->profile == VAProfileVP8Version0_3) {
2582        attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
2583            VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
2584	    VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
2585	    VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
2586    } else {
2587        attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
2588            VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
2589            VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR |
2590            VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
2591            VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
2592    }
2593    i++;
2594
2595    attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
2596    attribs[i].value.type = VAGenericValueTypePointer;
2597    attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
2598    attribs[i].value.value.p = NULL;
2599    i++;
2600
2601    //modules have speical formats to support
2602    if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
2603
2604    } else if (obj_config->entrypoint == VAEntrypointEncSlice ||  /* encode */
2605                   obj_config->entrypoint == VAEntrypointEncPicture) {
2606    #ifdef PSBVIDEO_MFLD
2607        if (IS_MFLD(driver_data)) {}
2608    #endif
2609    #ifdef PSBVIDEO_MRFL
2610        if (IS_MRFL(driver_data)) {}
2611    #endif
2612    #ifdef BAYTRAIL
2613        if (IS_BAYTRAIL(driver_data)) {}
2614    #endif
2615    }
2616    else if (obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
2617
2618    }
2619
2620    if (i > *num_attribs) {
2621        *num_attribs = i;
2622        return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
2623    }
2624
2625    *num_attribs = i;
2626    memcpy(attrib_list, attribs, i * sizeof(*attribs));
2627    free(attribs);
2628
2629    DEBUG_FUNC_EXIT
2630    return vaStatus;
2631}
2632
2633VAStatus psb_LockSurface(
2634    VADriverContextP ctx,
2635    VASurfaceID surface,
2636    unsigned int *fourcc, /* following are output argument */
2637    unsigned int *luma_stride,
2638    unsigned int *chroma_u_stride,
2639    unsigned int *chroma_v_stride,
2640    unsigned int *luma_offset,
2641    unsigned int *chroma_u_offset,
2642    unsigned int *chroma_v_offset,
2643    unsigned int *buffer_name,
2644    void **buffer
2645)
2646{
2647    DEBUG_FUNC_ENTER
2648    INIT_DRIVER_DATA
2649    VAStatus vaStatus = VA_STATUS_SUCCESS;
2650    unsigned char *surface_data;
2651    int ret;
2652
2653    object_surface_p obj_surface = SURFACE(surface);
2654    psb_surface_p psb_surface;
2655    CHECK_SURFACE(obj_surface);
2656
2657    psb_surface = obj_surface->psb_surface;
2658    if (buffer_name)
2659        *buffer_name = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf)));
2660
2661    if (buffer) { /* map the surface buffer */
2662        uint32_t srf_buf_ofs = 0;
2663        ret = psb_buffer_map(&psb_surface->buf, &surface_data);
2664        if (ret) {
2665            *buffer = NULL;
2666            vaStatus = VA_STATUS_ERROR_UNKNOWN;
2667            DEBUG_FAILURE;
2668            return vaStatus;
2669        }
2670        srf_buf_ofs = psb_surface->buf.buffer_ofs;
2671        *buffer = surface_data + srf_buf_ofs;
2672    }
2673
2674    *fourcc = VA_FOURCC_NV12;
2675    *luma_stride = psb_surface->stride;
2676    *chroma_u_stride = psb_surface->stride;
2677    *chroma_v_stride = psb_surface->stride;
2678    *luma_offset = 0;
2679    *chroma_u_offset = obj_surface->height * psb_surface->stride;
2680    *chroma_v_offset = obj_surface->height * psb_surface->stride + 1;
2681    DEBUG_FUNC_EXIT
2682    return vaStatus;
2683}
2684
2685
2686VAStatus psb_UnlockSurface(
2687    VADriverContextP ctx,
2688    VASurfaceID surface
2689)
2690{
2691    DEBUG_FUNC_ENTER
2692    INIT_DRIVER_DATA
2693    VAStatus vaStatus = VA_STATUS_SUCCESS;
2694
2695    object_surface_p obj_surface = SURFACE(surface);
2696    CHECK_SURFACE(obj_surface);
2697
2698    psb_surface_p psb_surface = obj_surface->psb_surface;
2699
2700    psb_buffer_unmap(&psb_surface->buf);
2701
2702    DEBUG_FUNC_EXIT
2703    return VA_STATUS_SUCCESS;
2704}
2705
2706VAStatus psb_GetEGLClientBufferFromSurface(
2707    VADriverContextP ctx,
2708    VASurfaceID surface,
2709    void **buffer
2710)
2711{
2712    DEBUG_FUNC_ENTER
2713    INIT_DRIVER_DATA
2714    VAStatus vaStatus = VA_STATUS_SUCCESS;
2715
2716    object_surface_p obj_surface = SURFACE(surface);
2717    CHECK_SURFACE(obj_surface);
2718
2719    psb_surface_p psb_surface = obj_surface->psb_surface;
2720    *buffer = (unsigned char *)psb_surface->bc_buffer;
2721
2722    DEBUG_FUNC_EXIT
2723    return vaStatus;
2724}
2725
2726VAStatus psb_PutSurfaceBuf(
2727    VADriverContextP ctx,
2728    VASurfaceID surface,
2729    unsigned char* data,
2730    int* data_len,
2731    short srcx,
2732    short srcy,
2733    unsigned short srcw,
2734    unsigned short srch,
2735    short destx,
2736    short desty,
2737    unsigned short destw,
2738    unsigned short desth,
2739    VARectangle *cliprects, /* client supplied clip list */
2740    unsigned int number_cliprects, /* number of clip rects in the clip list */
2741    unsigned int flags /* de-interlacing flags */
2742)
2743{
2744    DEBUG_FUNC_ENTER
2745    INIT_DRIVER_DATA;
2746    object_surface_p obj_surface = SURFACE(surface);
2747    psb_surface_p psb_surface;
2748
2749    obj_surface = SURFACE(surface);
2750    if (obj_surface == NULL)
2751        return VA_STATUS_ERROR_INVALID_SURFACE;
2752
2753    psb_surface = obj_surface->psb_surface;
2754
2755#if 0
2756    psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 1, /* check subpicture */
2757                               obj_surface->width, obj_surface->height,
2758                               psb_surface->stride, psb_surface->buf.drm_buf,
2759                               psb_surface->buf.pl_flags, 1 /* wrap dst */);
2760#endif
2761
2762    DEBUG_FUNC_EXIT
2763    return VA_STATUS_SUCCESS;
2764}
2765
2766VAStatus psb_SetTimestampForSurface(
2767    VADriverContextP ctx,
2768    VASurfaceID surface,
2769    long long timestamp
2770)
2771{
2772    INIT_DRIVER_DATA;
2773    VAStatus vaStatus = VA_STATUS_SUCCESS;
2774    object_surface_p obj_surface = SURFACE(surface);
2775
2776    obj_surface = SURFACE(surface);
2777    CHECK_SURFACE(obj_surface);
2778
2779    if (obj_surface->share_info) {
2780        obj_surface->share_info->timestamp = timestamp;
2781        return VA_STATUS_SUCCESS;
2782    } else {
2783        return VA_STATUS_ERROR_UNKNOWN;
2784    }
2785}
2786
2787VAStatus psb_SetVideoCrops(
2788    VADriverContextP ctx,
2789    VAContextID context,
2790    VARectangle *crop
2791)
2792{
2793    INIT_DRIVER_DATA;
2794    VAStatus vaStatus = VA_STATUS_SUCCESS;
2795    object_context_p obj_context = CONTEXT(context);
2796
2797    CHECK_CONTEXT(obj_context);
2798
2799    if (!crop)
2800        return VA_STATUS_ERROR_INVALID_PARAMETER;
2801
2802    if (crop->x < 0 || crop->y < 0 || crop->width > 4096 || crop->height > 4096)
2803        return VA_STATUS_ERROR_INVALID_PARAMETER;
2804
2805    memcpy(&obj_context->video_crop, crop, sizeof(*crop));
2806
2807    return vaStatus;
2808}
2809
2810
2811int  LOCK_HARDWARE(psb_driver_data_p driver_data)
2812{
2813    char ret = 0;
2814
2815    if (driver_data->dri2 || driver_data->dri_dummy)
2816        return 0;
2817
2818    pthread_mutex_lock(&driver_data->drm_mutex);
2819    DRM_CAS(driver_data->drm_lock, driver_data->drm_context,
2820            (DRM_LOCK_HELD | driver_data->drm_context), ret);
2821    if (ret) {
2822        ret = drmGetLock(driver_data->drm_fd, driver_data->drm_context, 0);
2823        /* driver_data->contended_lock=1; */
2824    }
2825
2826    return ret;
2827}
2828
2829int UNLOCK_HARDWARE(psb_driver_data_p driver_data)
2830{
2831    /* driver_data->contended_lock=0; */
2832    if (driver_data->dri2 || driver_data->dri_dummy)
2833        return 0;
2834
2835    DRM_UNLOCK(driver_data->drm_fd, driver_data->drm_lock, driver_data->drm_context);
2836    pthread_mutex_unlock(&driver_data->drm_mutex);
2837
2838    return 0;
2839}
2840
2841
2842static void psb__deinitDRM(VADriverContextP ctx)
2843{
2844    INIT_DRIVER_DATA
2845
2846    if (driver_data->main_pool) {
2847        driver_data->main_pool->takeDown(driver_data->main_pool);
2848        driver_data->main_pool = NULL;
2849    }
2850    if (driver_data->fence_mgr) {
2851        wsbmFenceMgrTTMTakedown(driver_data->fence_mgr);
2852        driver_data->fence_mgr = NULL;
2853    }
2854
2855    if (wsbmIsInitialized())
2856        wsbmTakedown();
2857
2858    driver_data->drm_fd = -1;
2859}
2860
2861
2862static VAStatus psb__initDRI(VADriverContextP ctx)
2863{
2864    INIT_DRIVER_DATA
2865    struct drm_state *drm_state = (struct drm_state *)ctx->drm_state;
2866
2867    assert(dri_state);
2868#ifdef _FOR_FPGA_
2869    dri_state->driConnectedFlag = VA_DUMMY;
2870    /* ON FPGA machine, psb may co-exist with gfx's drm driver */
2871    dri_state->fd = open("/dev/dri/card1", O_RDWR);
2872    if (dri_state->fd < 0)
2873        dri_state->fd = open("/dev/dri/card0", O_RDWR);
2874    assert(dri_state->fd >= 0);
2875#endif
2876    assert(dri_state->driConnectedFlag == VA_DRI2 ||
2877           dri_state->driConnectedFlag == VA_DUMMY);
2878
2879    driver_data->drm_fd = drm_state->fd;
2880    driver_data->dri_dummy = 1;
2881    driver_data->dri2 = 0;
2882    driver_data->ws_priv = NULL;
2883    driver_data->bus_id = NULL;
2884
2885    return VA_STATUS_SUCCESS;
2886}
2887
2888
2889static VAStatus psb__initTTM(VADriverContextP ctx)
2890{
2891    INIT_DRIVER_DATA
2892
2893    const char drm_ext[] = "psb_ttm_placement_alphadrop";
2894    union drm_psb_extension_arg arg;
2895    struct _WsbmBufferPool *pool;
2896    int ret;
2897    const char exec_ext[] = "psb_ttm_execbuf_alphadrop";
2898    union drm_psb_extension_arg exec_arg;
2899    const char lncvideo_getparam_ext[] = "lnc_video_getparam";
2900    union drm_psb_extension_arg lncvideo_getparam_arg;
2901
2902    /* init wsbm
2903     * WSBM node is not used in driver, thus can pass NULL Node callback
2904     */
2905    ret = wsbmInit(wsbmNullThreadFuncs(), NULL/*psbVNodeFuncs()*/);
2906    if (ret) {
2907        drv_debug_msg(VIDEO_DEBUG_ERROR, "failed initializing libwsbm.\n");
2908        return VA_STATUS_ERROR_UNKNOWN;
2909    }
2910
2911    strncpy(arg.extension, drm_ext, sizeof(arg.extension));
2912    /* FIXME: should check dri enabled?
2913     * it seems not init dri here at all
2914     */
2915    ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION,
2916                              &arg, sizeof(arg));
2917    if (ret != 0 || !arg.rep.exists) {
2918        drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\", fd=%d\n",
2919                      drm_ext, driver_data->drm_fd);
2920        drv_debug_msg(VIDEO_DEBUG_ERROR, "found error %s (ret=%d), arg.rep.exists=%d",
2921                      strerror(errno), ret, arg.rep.exists);
2922
2923        driver_data->main_pool = NULL;
2924        return VA_STATUS_ERROR_UNKNOWN;
2925    } else {
2926        pool = wsbmTTMPoolInit(driver_data->drm_fd,
2927                               arg.rep.driver_ioctl_offset);
2928        if (pool == NULL) {
2929            drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get ttm pool\n");
2930            return VA_STATUS_ERROR_UNKNOWN;
2931        }
2932        driver_data->main_pool = pool;
2933    }
2934
2935    strncpy(exec_arg.extension, exec_ext, sizeof(exec_arg.extension));
2936    ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &exec_arg,
2937                              sizeof(exec_arg));
2938    if (ret != 0 || !exec_arg.rep.exists) {
2939        drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\".\n",
2940                           exec_ext);
2941        return FALSE;
2942    }
2943    driver_data->execIoctlOffset = exec_arg.rep.driver_ioctl_offset;
2944
2945    strncpy(lncvideo_getparam_arg.extension, lncvideo_getparam_ext, sizeof(lncvideo_getparam_arg.extension));
2946    ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &lncvideo_getparam_arg,
2947                              sizeof(lncvideo_getparam_arg));
2948    if (ret != 0 || !lncvideo_getparam_arg.rep.exists) {
2949        drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\".\n",
2950                           lncvideo_getparam_ext);
2951        /* return FALSE; */ /* not reture FALSE, so it still can run */
2952    }
2953    driver_data->getParamIoctlOffset = lncvideo_getparam_arg.rep.driver_ioctl_offset;
2954    return VA_STATUS_SUCCESS;
2955}
2956
2957static VAStatus psb__initDRM(VADriverContextP ctx)
2958{
2959    VAStatus vaStatus;
2960
2961    vaStatus = psb__initDRI(ctx);
2962
2963    if (vaStatus == VA_STATUS_SUCCESS)
2964        return psb__initTTM(ctx);
2965    else
2966        return vaStatus;
2967}
2968
2969VAStatus psb_Terminate(VADriverContextP ctx)
2970{
2971    DEBUG_FUNC_ENTER
2972    INIT_DRIVER_DATA
2973    object_subpic_p obj_subpic;
2974    object_image_p obj_image;
2975    object_buffer_p obj_buffer;
2976    object_surface_p obj_surface;
2977    object_context_p obj_context;
2978    object_config_p obj_config;
2979    object_heap_iterator iter;
2980
2981    drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: begin to tear down\n");
2982
2983    /* Clean up left over contexts */
2984    obj_context = (object_context_p) object_heap_first(&driver_data->context_heap, &iter);
2985    while (obj_context) {
2986        drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: contextID %08x still allocated, destroying\n", obj_context->base.id);
2987        psb__destroy_context(driver_data, obj_context);
2988        obj_context = (object_context_p) object_heap_next(&driver_data->context_heap, &iter);
2989    }
2990    object_heap_destroy(&driver_data->context_heap);
2991
2992    /* Clean up SubpicIDs */
2993    obj_subpic = (object_subpic_p) object_heap_first(&driver_data->subpic_heap, &iter);
2994    while (obj_subpic) {
2995        drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: subpictureID %08x still allocated, destroying\n", obj_subpic->base.id);
2996        psb__destroy_subpicture(driver_data, obj_subpic);
2997        obj_subpic = (object_subpic_p) object_heap_next(&driver_data->subpic_heap, &iter);
2998    }
2999    object_heap_destroy(&driver_data->subpic_heap);
3000
3001    /* Clean up ImageIDs */
3002    obj_image = (object_image_p) object_heap_first(&driver_data->image_heap, &iter);
3003    while (obj_image) {
3004        drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: imageID %08x still allocated, destroying\n", obj_image->base.id);
3005        psb__destroy_image(driver_data, obj_image);
3006        obj_image = (object_image_p) object_heap_next(&driver_data->image_heap, &iter);
3007    }
3008    object_heap_destroy(&driver_data->image_heap);
3009
3010    /* Clean up left over buffers */
3011    obj_buffer = (object_buffer_p) object_heap_first(&driver_data->buffer_heap, &iter);
3012    while (obj_buffer) {
3013        drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: bufferID %08x still allocated, destroying\n", obj_buffer->base.id);
3014        psb__destroy_buffer(driver_data, obj_buffer);
3015        obj_buffer = (object_buffer_p) object_heap_next(&driver_data->buffer_heap, &iter);
3016    }
3017    object_heap_destroy(&driver_data->buffer_heap);
3018
3019    /* Clean up left over surfaces */
3020
3021#if 0
3022    /* Free PVR2D buffer wrapped from the surfaces */
3023    psb_free_surface_pvr2dbuf(driver_data);
3024#endif
3025    obj_surface = (object_surface_p) object_heap_first(&driver_data->surface_heap, &iter);
3026    while (obj_surface) {
3027        drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: surfaceID %08x still allocated, destroying\n", obj_surface->base.id);
3028        psb__destroy_surface(driver_data, obj_surface);
3029        obj_surface = (object_surface_p) object_heap_next(&driver_data->surface_heap, &iter);
3030    }
3031    object_heap_destroy(&driver_data->surface_heap);
3032
3033    /* Clean up configIDs */
3034    obj_config = (object_config_p) object_heap_first(&driver_data->config_heap, &iter);
3035    while (obj_config) {
3036        object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
3037        obj_config = (object_config_p) object_heap_next(&driver_data->config_heap, &iter);
3038    }
3039    object_heap_destroy(&driver_data->config_heap);
3040
3041    if (driver_data->camera_bo) {
3042        drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: clearup camera global BO\n");
3043
3044        psb_buffer_destroy((psb_buffer_p)driver_data->camera_bo);
3045        free(driver_data->camera_bo);
3046        driver_data->camera_bo = NULL;
3047    }
3048
3049    if (driver_data->rar_bo) {
3050        drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: clearup RAR global BO\n");
3051
3052        psb_buffer_destroy((psb_buffer_p)driver_data->rar_bo);
3053        free(driver_data->rar_bo);
3054        driver_data->rar_bo = NULL;
3055    }
3056
3057    if (driver_data->ws_priv) {
3058        drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: tear down output portion\n");
3059
3060        psb_deinitOutput(ctx);
3061        driver_data->ws_priv = NULL;
3062    }
3063
3064    drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: de-initialized DRM\n");
3065
3066    psb__deinitDRM(ctx);
3067
3068    if (driver_data->msvdx_decode_status)
3069        free(driver_data->msvdx_decode_status);
3070
3071    if (driver_data->surface_mb_error)
3072        free(driver_data->surface_mb_error);
3073
3074    pthread_mutex_destroy(&driver_data->drm_mutex);
3075    free(ctx->pDriverData);
3076    free(ctx->vtable_egl);
3077    free(ctx->vtable_tpi);
3078
3079    ctx->pDriverData = NULL;
3080    drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: goodbye\n\n");
3081
3082    psb__close_log();
3083    DEBUG_FUNC_EXIT
3084    return VA_STATUS_SUCCESS;
3085}
3086
3087EXPORT VAStatus __vaDriverInit_0_31(VADriverContextP ctx)
3088{
3089    psb_driver_data_p driver_data;
3090    struct VADriverVTableTPI *tpi;
3091    struct VADriverVTableEGL *va_egl;
3092    int result;
3093    if (psb_video_trace_fp) {
3094        /* make gdb always stop here */
3095        signal(SIGUSR1, SIG_IGN);
3096        kill(getpid(), SIGUSR1);
3097    }
3098
3099    psb__open_log();
3100
3101    drv_debug_msg(VIDEO_DEBUG_INIT, "vaInitilize: start the journey\n");
3102
3103    ctx->version_major = 0;
3104    ctx->version_minor = 31;
3105
3106    ctx->max_profiles = PSB_MAX_PROFILES;
3107    ctx->max_entrypoints = PSB_MAX_ENTRYPOINTS;
3108    ctx->max_attributes = PSB_MAX_CONFIG_ATTRIBUTES;
3109    ctx->max_image_formats = PSB_MAX_IMAGE_FORMATS;
3110    ctx->max_subpic_formats = PSB_MAX_SUBPIC_FORMATS;
3111    ctx->max_display_attributes = PSB_MAX_DISPLAY_ATTRIBUTES;
3112
3113    ctx->vtable->vaTerminate = psb_Terminate;
3114    ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints;
3115    ctx->vtable->vaTerminate = psb_Terminate;
3116    ctx->vtable->vaQueryConfigProfiles = psb_QueryConfigProfiles;
3117    ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints;
3118    ctx->vtable->vaQueryConfigAttributes = psb_QueryConfigAttributes;
3119    ctx->vtable->vaCreateConfig = psb_CreateConfig;
3120    ctx->vtable->vaDestroyConfig = psb_DestroyConfig;
3121    ctx->vtable->vaGetConfigAttributes = psb_GetConfigAttributes;
3122    ctx->vtable->vaCreateSurfaces2 = psb_CreateSurfaces2;
3123    ctx->vtable->vaCreateSurfaces = psb_CreateSurfaces;
3124    ctx->vtable->vaGetSurfaceAttributes = psb_GetSurfaceAttributes;
3125    ctx->vtable->vaDestroySurfaces = psb_DestroySurfaces;
3126    ctx->vtable->vaCreateContext = psb_CreateContext;
3127    ctx->vtable->vaDestroyContext = psb_DestroyContext;
3128    ctx->vtable->vaCreateBuffer = psb_CreateBuffer;
3129    ctx->vtable->vaBufferSetNumElements = psb_BufferSetNumElements;
3130    ctx->vtable->vaMapBuffer = psb_MapBuffer;
3131    ctx->vtable->vaUnmapBuffer = psb_UnmapBuffer;
3132    ctx->vtable->vaDestroyBuffer = psb_DestroyBuffer;
3133    ctx->vtable->vaBeginPicture = psb_BeginPicture;
3134    ctx->vtable->vaRenderPicture = psb_RenderPicture;
3135    ctx->vtable->vaEndPicture = psb_EndPicture;
3136    ctx->vtable->vaSyncSurface = psb_SyncSurface;
3137    ctx->vtable->vaQuerySurfaceStatus = psb_QuerySurfaceStatus;
3138    ctx->vtable->vaQuerySurfaceError = psb_QuerySurfaceError;
3139    ctx->vtable->vaPutSurface = psb_PutSurface;
3140    ctx->vtable->vaQueryImageFormats = psb_QueryImageFormats;
3141    ctx->vtable->vaCreateImage = psb_CreateImage;
3142    ctx->vtable->vaDeriveImage = psb_DeriveImage;
3143    ctx->vtable->vaDestroyImage = psb_DestroyImage;
3144    ctx->vtable->vaSetImagePalette = psb_SetImagePalette;
3145    ctx->vtable->vaGetImage = psb_GetImage;
3146    ctx->vtable->vaPutImage = psb_PutImage;
3147    ctx->vtable->vaQuerySubpictureFormats = psb_QuerySubpictureFormats;
3148    ctx->vtable->vaCreateSubpicture = psb_CreateSubpicture;
3149    ctx->vtable->vaDestroySubpicture = psb_DestroySubpicture;
3150    ctx->vtable->vaSetSubpictureImage = psb_SetSubpictureImage;
3151    ctx->vtable->vaSetSubpictureChromakey = psb_SetSubpictureChromakey;
3152    ctx->vtable->vaSetSubpictureGlobalAlpha = psb_SetSubpictureGlobalAlpha;
3153    ctx->vtable->vaAssociateSubpicture = psb_AssociateSubpicture;
3154    ctx->vtable->vaDeassociateSubpicture = psb_DeassociateSubpicture;
3155    ctx->vtable->vaQueryDisplayAttributes = psb_QueryDisplayAttributes;
3156    ctx->vtable->vaGetDisplayAttributes = psb_GetDisplayAttributes;
3157    ctx->vtable->vaSetDisplayAttributes = psb_SetDisplayAttributes;
3158    ctx->vtable->vaQuerySurfaceAttributes = psb_QuerySurfaceAttributes;
3159    ctx->vtable->vaBufferInfo = psb_BufferInfo;
3160    ctx->vtable->vaLockSurface = psb_LockSurface;
3161    ctx->vtable->vaUnlockSurface = psb_UnlockSurface;
3162#ifdef PSBVIDEO_MRFL_VPP
3163    ctx->vtable_vpp->vaQueryVideoProcFilters = vsp_QueryVideoProcFilters;
3164    ctx->vtable_vpp->vaQueryVideoProcFilterCaps = vsp_QueryVideoProcFilterCaps;
3165    ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = vsp_QueryVideoProcPipelineCaps;
3166#endif
3167
3168#ifdef PSBVIDEO_MFLD
3169    ctx->vtable_vpp->vaQueryVideoProcFilters = ved_QueryVideoProcFilters;
3170    ctx->vtable_vpp->vaQueryVideoProcFilterCaps = ved_QueryVideoProcFilterCaps;
3171    ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = ved_QueryVideoProcPipelineCaps;
3172#endif
3173
3174    ctx->vtable_tpi = calloc(1, sizeof(struct VADriverVTableTPI));
3175    if (NULL == ctx->vtable_tpi)
3176        return VA_STATUS_ERROR_ALLOCATION_FAILED;
3177
3178    tpi = (struct VADriverVTableTPI *)ctx->vtable_tpi;
3179    tpi->vaCreateSurfacesWithAttribute = psb_CreateSurfacesWithAttribute;
3180    tpi->vaPutSurfaceBuf = psb_PutSurfaceBuf;
3181	tpi->vaSetTimestampForSurface = psb_SetTimestampForSurface;
3182
3183    ctx->vtable_egl = calloc(1, sizeof(struct VADriverVTableEGL));
3184    if (NULL == ctx->vtable_egl)
3185        return VA_STATUS_ERROR_ALLOCATION_FAILED;
3186
3187    va_egl = (struct VADriverVTableEGL *)ctx->vtable_egl;
3188    va_egl->vaGetEGLClientBufferFromSurface = psb_GetEGLClientBufferFromSurface;
3189
3190    driver_data = (psb_driver_data_p) calloc(1, sizeof(*driver_data));
3191    ctx->pDriverData = (unsigned char *) driver_data;
3192    if (NULL == driver_data) {
3193        if (ctx->vtable_tpi)
3194            free(ctx->vtable_tpi);
3195        if (ctx->vtable_egl)
3196            free(ctx->vtable_egl);
3197        return VA_STATUS_ERROR_ALLOCATION_FAILED;
3198    }
3199
3200    if (VA_STATUS_SUCCESS != psb__initDRM(ctx)) {
3201        free(ctx->pDriverData);
3202        ctx->pDriverData = NULL;
3203        return VA_STATUS_ERROR_UNKNOWN;
3204    }
3205
3206    pthread_mutex_init(&driver_data->drm_mutex, NULL);
3207
3208    /*
3209     * To read PBO.MSR.CCF Mode and Status Register C-Spec -p112
3210     */
3211#define PCI_PORT5_REG80_VIDEO_SD_DISABLE        0x0008
3212#define PCI_PORT5_REG80_VIDEO_HD_DISABLE        0x0010
3213
3214#if 0
3215    struct drm_psb_hw_info hw_info;
3216    do {
3217        result = drmCommandRead(driver_data->drm_fd, DRM_PSB_HW_INFO, &hw_info, sizeof(hw_info));
3218    } while (result == EAGAIN);
3219
3220    if (result != 0) {
3221        psb__deinitDRM(ctx);
3222        free(ctx->pDriverData);
3223        ctx->pDriverData = NULL;
3224        return VA_STATUS_ERROR_UNKNOWN;
3225    }
3226
3227    driver_data->video_sd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_SD_DISABLE);
3228    driver_data->video_hd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_HD_DISABLE);
3229    drv_debug_msg(VIDEO_DEBUG_GENERAL, "hw_info: rev_id = %08x capabilities = %08x\n", hw_info.rev_id, hw_info.caps);
3230    drv_debug_msg(VIDEO_DEBUG_GENERAL, "hw_info: video_sd_disable=%d,video_hd_disable=%d\n",
3231                             driver_data->video_sd_disabled, driver_data->video_hd_disabled);
3232    if (driver_data->video_sd_disabled != 0) {
3233        drv_debug_msg(VIDEO_DEBUG_ERROR, "MRST: hw_info shows video_sd_disable is true,fix it manually\n");
3234        driver_data->video_sd_disabled = 0;
3235    }
3236    if (driver_data->video_hd_disabled != 0) {
3237        drv_debug_msg(VIDEO_DEBUG_ERROR, "MRST: hw_info shows video_hd_disable is true,fix it manually\n");
3238        driver_data->video_hd_disabled = 0;
3239    }
3240#endif
3241
3242    if (0 != psb_get_device_info(ctx)) {
3243        drv_debug_msg(VIDEO_DEBUG_ERROR, "ERROR: failed to get video device info\n");
3244        driver_data->encode_supported = 1;
3245        driver_data->decode_supported = 1;
3246        driver_data->hd_encode_supported = 1;
3247        driver_data->hd_decode_supported = 1;
3248    }
3249
3250#if 0
3251    psb_init_surface_pvr2dbuf(driver_data);
3252#endif
3253
3254    if (VA_STATUS_SUCCESS != psb_initOutput(ctx)) {
3255        pthread_mutex_destroy(&driver_data->drm_mutex);
3256        psb__deinitDRM(ctx);
3257        free(ctx->pDriverData);
3258        ctx->pDriverData = NULL;
3259        return VA_STATUS_ERROR_UNKNOWN;
3260    }
3261
3262    driver_data->msvdx_context_base = (((unsigned int) getpid()) & 0xffff) << 16;
3263#ifdef PSBVIDEO_MRFL
3264    if (IS_MRFL(driver_data)) {
3265        drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield topazhp encoder\n");
3266        driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3267        driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3268        driver_data->profile2Format[VAProfileH264High][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3269        driver_data->profile2Format[VAProfileH264StereoHigh][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3270        driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &tng_H263ES_vtable;
3271        driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &tng_JPEGES_vtable;
3272        driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &tng_MPEG4ES_vtable;
3273        driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &tng_MPEG4ES_vtable;
3274    }
3275#endif
3276#ifdef PSBVIDEO_MRFL_VPP
3277    if (IS_MRFL(driver_data)) {
3278        drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield vsp vpp\n");
3279        driver_data->vpp_profile = &vsp_VPP_vtable;
3280        driver_data->profile2Format[VAProfileVP8Version0_3][VAEntrypointEncSlice] = &vsp_VP8_vtable;
3281    }
3282#endif
3283
3284#ifdef PSBVIDEO_VXD392
3285    if (IS_MRFL(driver_data) || IS_BAYTRAIL(driver_data)) {
3286        drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield VXD392 decoder\n");
3287	driver_data->profile2Format[VAProfileVP8Version0_3][VAEntrypointVLD] = &tng_VP8_vtable;
3288        driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointVLD] = &tng_JPEG_vtable;
3289
3290        driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3291        driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3292
3293        driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3294
3295        driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable;
3296        driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &pnw_H264_vtable;
3297        driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &pnw_H264_vtable;
3298
3299        driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable;
3300        driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable;
3301        driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable;
3302        driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &pnw_H264_vtable;
3303    }
3304#endif
3305
3306#ifdef PSBVIDEO_MRFL
3307    if (IS_MRFL(driver_data)) {
3308        if (*((unsigned int *)ctx->native_dpy) == 0x56454450 /* VEDP */) {
3309
3310            drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield ved vpp\n");
3311            driver_data->vpp_profile = &tng_yuv_processor_vtable;
3312            ctx->vtable_vpp->vaQueryVideoProcFilters = ved_QueryVideoProcFilters;
3313            ctx->vtable_vpp->vaQueryVideoProcFilterCaps = ved_QueryVideoProcFilterCaps;
3314            ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = ved_QueryVideoProcPipelineCaps;
3315            driver_data->ved_vpp = 1;
3316        }
3317    }
3318#endif
3319
3320#ifdef PSBVIDEO_MFLD
3321    if (IS_MFLD(driver_data)) {
3322        driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &pnw_H263ES_vtable;
3323        driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &pnw_H264ES_vtable;
3324        driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &pnw_H264ES_vtable;
3325        driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable;
3326        driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable;
3327        driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &pnw_JPEG_vtable;
3328
3329        driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable;
3330
3331        driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3332        driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3333
3334        driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3335
3336        driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable;
3337        driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &pnw_H264_vtable;
3338        driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &pnw_H264_vtable;
3339
3340        driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable;
3341        driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable;
3342        driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable;
3343        driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &pnw_H264_vtable;
3344
3345        driver_data->vpp_profile = &tng_yuv_processor_vtable;
3346        driver_data->ved_vpp = 1;
3347    }
3348#endif
3349
3350    result = object_heap_init(&driver_data->config_heap, sizeof(struct object_config_s), CONFIG_ID_OFFSET);
3351    ASSERT(result == 0);
3352
3353    result = object_heap_init(&driver_data->context_heap, sizeof(struct object_context_s), CONTEXT_ID_OFFSET);
3354    ASSERT(result == 0);
3355
3356    result = object_heap_init(&driver_data->surface_heap, sizeof(struct object_surface_s), SURFACE_ID_OFFSET);
3357    ASSERT(result == 0);
3358
3359    result = object_heap_init(&driver_data->buffer_heap, sizeof(struct object_buffer_s), BUFFER_ID_OFFSET);
3360    ASSERT(result == 0);
3361
3362    result = object_heap_init(&driver_data->image_heap, sizeof(struct object_image_s), IMAGE_ID_OFFSET);
3363    ASSERT(result == 0);
3364
3365    result = object_heap_init(&driver_data->subpic_heap, sizeof(struct object_subpic_s), SUBPIC_ID_OFFSET);
3366    ASSERT(result == 0);
3367
3368    driver_data->cur_displaying_surface = VA_INVALID_SURFACE;
3369    driver_data->last_displaying_surface = VA_INVALID_SURFACE;
3370
3371    driver_data->clear_color = 0;
3372    driver_data->blend_color = 0;
3373    driver_data->blend_mode = 0;
3374    driver_data->overlay_auto_paint_color_key = 0;
3375
3376    if (IS_BAYTRAIL(driver_data))
3377        ctx->str_vendor = PSB_STR_VENDOR_BAYTRAIL;
3378    if (IS_MRFL(driver_data))
3379        ctx->str_vendor = PSB_STR_VENDOR_MRFL;
3380    else if (IS_MFLD(driver_data))
3381    {
3382        if (IS_LEXINGTON(driver_data))
3383            ctx->str_vendor = PSB_STR_VENDOR_LEXINGTON;
3384        else
3385            ctx->str_vendor = PSB_STR_VENDOR_MFLD;
3386    }
3387    else
3388        ctx->str_vendor = PSB_STR_VENDOR_MRST;
3389
3390    driver_data->msvdx_decode_status = calloc(1, sizeof(drm_psb_msvdx_decode_status_t));
3391    if (NULL == driver_data->msvdx_decode_status) {
3392        pthread_mutex_destroy(&driver_data->drm_mutex);
3393        return VA_STATUS_ERROR_ALLOCATION_FAILED;
3394    }
3395    driver_data->surface_mb_error = calloc(MAX_MB_ERRORS, sizeof(VASurfaceDecodeMBErrors));
3396    if (NULL == driver_data->surface_mb_error) {
3397        pthread_mutex_destroy(&driver_data->drm_mutex);
3398        return VA_STATUS_ERROR_ALLOCATION_FAILED;
3399    }
3400
3401    drv_debug_msg(VIDEO_DEBUG_INIT, "vaInitilize: succeeded!\n\n");
3402
3403#ifdef ANDROID
3404#ifndef PSBVIDEO_VXD392
3405    gralloc_init();
3406#endif
3407#endif
3408
3409    return VA_STATUS_SUCCESS;
3410}
3411
3412
3413EXPORT VAStatus __vaDriverInit_0_32(VADriverContextP ctx)
3414{
3415    return __vaDriverInit_0_31(ctx);
3416}
3417
3418
3419
3420static int psb_get_device_info(VADriverContextP ctx)
3421{
3422    INIT_DRIVER_DATA;
3423    struct drm_lnc_video_getparam_arg arg;
3424    unsigned long device_info;
3425    int ret = 0;
3426    unsigned long video_capability;
3427    unsigned long pci_device;
3428
3429    driver_data->dev_id = 0x4100; /* by default MRST */
3430
3431    arg.key = LNC_VIDEO_DEVICE_INFO;
3432    arg.value = (uint64_t)((unsigned long) & device_info);
3433    ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
3434                              &arg, sizeof(arg));
3435    if (ret != 0) {
3436        drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get video device info\n");
3437        return ret;
3438    }
3439
3440    pci_device = (device_info >> 16) & 0xffff;
3441    video_capability = device_info & 0xffff;
3442
3443    driver_data->dev_id = pci_device;
3444    drv_debug_msg(VIDEO_DEBUG_INIT, "Retrieve Device ID 0x%08x\n", driver_data->dev_id);
3445
3446    if (IS_MFLD(driver_data) || IS_MRFL(driver_data))
3447        driver_data->encode_supported = 1;
3448    else /* 0x4101 or other device hasn't encode support */
3449        driver_data->encode_supported = 0;
3450
3451    driver_data->decode_supported = 1;
3452    driver_data->hd_decode_supported = 1;
3453    driver_data->hd_encode_supported = 1;
3454
3455    return ret;
3456}
3457