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