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