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