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