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  *    Elaine Wang <elaine.wang (at) intel.com>
     27  *    Zeng Li <zeng.li (at) intel.com>
     28  *    Edward Lin <edward.lin (at) intel.com>
     29  *
     30  */
     31 
     32 #include "psb_drv_video.h"
     33 //#include "tng_H263ES.h"
     34 #include "tng_hostheader.h"
     35 #include "tng_hostcode.h"
     36 #include "psb_def.h"
     37 #include "psb_drv_debug.h"
     38 #include "psb_cmdbuf.h"
     39 #include "psb_buffer.h"
     40 #include <stdio.h>
     41 #include "psb_output.h"
     42 #include "tng_picmgmt.h"
     43 #include "tng_hostbias.h"
     44 #include "tng_hostair.h"
     45 #ifdef _TOPAZHP_PDUMP_
     46 #include "tng_trace.h"
     47 #endif
     48 #include <wsbm/wsbm_manager.h>
     49 
     50 #include "hwdefs/topazhp_core_regs.h"
     51 #include "hwdefs/topazhp_multicore_regs_old.h"
     52 #include "hwdefs/topaz_db_regs.h"
     53 #include "hwdefs/topaz_vlc_regs.h"
     54 #include "hwdefs/mvea_regs.h"
     55 #include "hwdefs/topazhp_default_params.h"
     56 
     57 #define ALIGN_TO(value, align) ((value + align - 1) & ~(align - 1))
     58 #define PAGE_ALIGN(value) ALIGN_TO(value, 4096)
     59 #define DEFAULT_MVCALC_CONFIG   ((0x00040303)|(MASK_TOPAZHP_CR_MVCALC_JITTER_POINTER_RST))
     60 #define DEFAULT_MVCALC_COLOCATED        (0x00100100)
     61 #define MVEA_MV_PARAM_REGION_SIZE 16
     62 #define MVEA_ABOVE_PARAM_REGION_SIZE 96
     63 #define QUANT_LISTS_SIZE                (224)
     64 #define _1080P_30FPS (((1920*1088)/256)*30)
     65 #define tng_align_64(X)  (((X)+63) &~63)
     66 #define tng_align_4(X)  (((X)+3) &~3)
     67 
     68 /* #define MTX_CONTEXT_ITEM_OFFSET(type, member) (size_t)&(((type*)0)->member) */
     69 
     70 #define DEFAULT_CABAC_DB_MARGIN    (0x190)
     71 #define NOT_USED_BY_TOPAZ 0
     72 /*
     73 #define _TOPAZHP_CMDBUF_
     74 */
     75 #ifdef _TOPAZHP_CMDBUF_
     76 static void tng__trace_cmdbuf_words(tng_cmdbuf_p cmdbuf)
     77 {
     78     int i = 0;
     79     IMG_UINT32 *ptmp = (IMG_UINT32 *)(cmdbuf->cmd_start);
     80     IMG_UINT32 *pend = (IMG_UINT32 *)(cmdbuf->cmd_idx);
     81     do {
     82         drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: command words [%d] = 0x%08x\n", __FUNCTION__, i++, (unsigned int)(*ptmp++));
     83     } while(ptmp < pend);
     84     return ;
     85 }
     86 #endif
     87 
     88 #if 0
     89 static IMG_UINT32 tng__get_codedbuffer_size(
     90     IMG_STANDARD eStandard,
     91     IMG_UINT16 ui16MBWidth,
     92     IMG_UINT16 ui16MBHeight,
     93     IMG_RC_PARAMS * psRCParams
     94 )
     95 {
     96     if (eStandard == IMG_STANDARD_H264) {
     97         // allocate based on worst case qp size
     98         return ((IMG_UINT32)ui16MBWidth * (IMG_UINT32)ui16MBHeight * 400);
     99     }
    100 
    101     if (psRCParams->ui32InitialQp <= 5)
    102         return ((IMG_UINT32)ui16MBWidth * (IMG_UINT32)ui16MBHeight * 1600);
    103 
    104     return ((IMG_UINT32)ui16MBWidth * (IMG_UINT32)ui16MBHeight * 900);
    105 }
    106 
    107 
    108 static IMG_UINT32 tng__get_codedbuf_size_according_bitrate(
    109     IMG_RC_PARAMS * psRCParams
    110 )
    111 {
    112     return ((psRCParams->ui32BitsPerSecond + psRCParams->ui32FrameRate / 2) / psRCParams->ui32FrameRate) * 2;
    113 }
    114 
    115 static IMG_UINT32 tng__get_buffer_size(IMG_UINT32 src_size)
    116 {
    117     return (src_size + 0x1000) & (~0xfff);
    118 }
    119 #endif
    120 
    121 //static inline
    122 VAStatus tng__alloc_init_buffer(
    123     psb_driver_data_p driver_data,
    124     unsigned int size,
    125     psb_buffer_type_t type,
    126     psb_buffer_p buf)
    127 {
    128     unsigned char *pch_virt_addr;
    129     VAStatus vaStatus = VA_STATUS_SUCCESS;
    130     vaStatus = psb_buffer_create(driver_data, size, type, buf);
    131     if (VA_STATUS_SUCCESS != vaStatus) {
    132         drv_debug_msg(VIDEO_DEBUG_ERROR, "alloc mem params buffer");
    133         return vaStatus;
    134     }
    135 
    136     vaStatus = psb_buffer_map(buf, &pch_virt_addr);
    137     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: phy addr 0x%08x, vir addr 0x%08x\n", __FUNCTION__, buf->drm_buf, pch_virt_addr);
    138     if ((vaStatus) || (pch_virt_addr == NULL)) {
    139         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: map buf 0x%08x\n", __FUNCTION__, (IMG_UINT32)pch_virt_addr);
    140         psb_buffer_destroy(buf);
    141     } else {
    142         memset(pch_virt_addr, 0, size);
    143         psb_buffer_unmap(buf);
    144     }
    145 
    146     return vaStatus;
    147 }
    148 
    149 static VAStatus tng__alloc_context_buffer(context_ENC_p ctx, IMG_UINT8 ui8IsJpeg, IMG_UINT32 ui32StreamID)
    150 {
    151     VAStatus vaStatus = VA_STATUS_SUCCESS;
    152     IMG_UINT32 ui32_pic_width, ui32_pic_height;
    153     IMG_UINT32 ui32_mb_per_row, ui32_mb_per_column;
    154     IMG_UINT32 ui32_adj_mb_per_row = 0;
    155     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
    156     psb_driver_data_p ps_driver_data = ctx->obj_context->driver_data;
    157     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamID]);
    158     context_ENC_mem_size *ps_mem_size = &(ctx->ctx_mem_size);
    159 
    160     if (ctx->eStandard == IMG_STANDARD_H264) {
    161         ctx->ui8PipesToUse = tng__min(ctx->ui8PipesToUse, ctx->ui8SlicesPerPicture);
    162     } else {
    163         ctx->ui8PipesToUse = 1;
    164     }
    165 
    166     ctx->i32PicNodes  = (psRCParams->b16Hierarchical ? MAX_REF_B_LEVELS : 0) + 4;
    167     ctx->i32MVStores = (ctx->i32PicNodes * 2);
    168     ctx->i32CodedBuffers = (IMG_INT32)(ctx->ui8PipesToUse) * (ctx->bIsInterlaced ? 3 : 2);
    169     ctx->ui8SlotsInUse = psRCParams->ui16BFrames + 2;
    170 
    171     if (0 != ui8IsJpeg) {
    172         ctx->jpeg_pic_params_size = (sizeof(JPEG_MTX_QUANT_TABLE) + 0x3f) & (~0x3f);
    173         ctx->jpeg_header_mem_size = (sizeof(JPEG_MTX_DMA_SETUP) + 0x3f) & (~0x3f);
    174         ctx->jpeg_header_interface_mem_size = (sizeof(JPEG_MTX_WRITEBACK_MEMORY) + 0x3f) & (~0x3f);
    175 
    176         //write back region
    177         ps_mem_size->writeback = tng_align_KB(COMM_WB_DATA_BUF_SIZE);
    178         tng__alloc_init_buffer(ps_driver_data, WB_FIFO_SIZE * ps_mem_size->writeback, psb_bt_cpu_vpu, &(ctx->bufs_writeback));
    179 
    180         drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end\n", __FUNCTION__);
    181         return vaStatus;
    182     }
    183 
    184     /* width and height should be source surface's w and h or ?? */
    185     ui32_pic_width = ctx->obj_context->picture_width;
    186     ui32_mb_per_row = (ctx->obj_context->picture_width + 15) >> 4;
    187     ui32_pic_height = ctx->obj_context->picture_height;
    188     ui32_mb_per_column = (ctx->obj_context->picture_height + 15) >> 4;
    189     ui32_adj_mb_per_row = ((ui32_mb_per_row + 7)>>3)<<3;  // Ensure multiple of 8 MBs per row
    190 
    191     //command buffer use
    192     ps_mem_size->pic_template = ps_mem_size->slice_template =
    193     ps_mem_size->seq_header = tng_align_KB(TNG_HEADER_SIZE);
    194     tng__alloc_init_buffer(ps_driver_data, ps_mem_size->seq_header,
    195         psb_bt_cpu_vpu, &(ps_mem->bufs_seq_header));
    196 
    197     if (ctx->bEnableMVC)
    198         tng__alloc_init_buffer(ps_driver_data, ps_mem_size->seq_header,
    199             psb_bt_cpu_vpu, &(ps_mem->bufs_sub_seq_header));
    200 
    201     tng__alloc_init_buffer(ps_driver_data, 4 * ps_mem_size->pic_template,
    202         psb_bt_cpu_vpu, &(ps_mem->bufs_pic_template));
    203 
    204     tng__alloc_init_buffer(ps_driver_data, NUM_SLICE_TYPES * ps_mem_size->slice_template,
    205         psb_bt_cpu_vpu, &(ps_mem->bufs_slice_template));
    206 
    207     ps_mem_size->mtx_context = tng_align_KB(MTX_CONTEXT_SIZE);
    208     tng__alloc_init_buffer(ps_driver_data, ps_mem_size->mtx_context,
    209         psb_bt_cpu_vpu, &(ps_mem->bufs_mtx_context));
    210 
    211     //sei header(AUDHeader+SEIBufferPeriodMem+SEIPictureTimingHeaderMem)
    212     ps_mem_size->sei_header = tng_align_KB(64);
    213     tng__alloc_init_buffer(ps_driver_data, 3 * ps_mem_size->sei_header,
    214         psb_bt_cpu_vpu, &(ps_mem->bufs_sei_header));
    215 
    216     //gop header
    217     ps_mem_size->flat_gop = ps_mem_size->hierar_gop = tng_align_KB(64);
    218     tng__alloc_init_buffer(ps_driver_data, ps_mem_size->flat_gop,
    219         psb_bt_cpu_vpu, &(ps_mem->bufs_flat_gop));
    220     tng__alloc_init_buffer(ps_driver_data, ps_mem_size->hierar_gop,
    221         psb_bt_cpu_vpu, &(ps_mem->bufs_hierar_gop));
    222 
    223     //above params
    224     ps_mem_size->above_params = tng_align_KB(MVEA_ABOVE_PARAM_REGION_SIZE * tng_align_64(ui32_mb_per_row));
    225     tng__alloc_init_buffer(ps_driver_data, (IMG_UINT32)(ctx->ui8PipesToUse) * ps_mem_size->above_params,
    226         psb_bt_cpu_vpu, &(ps_mem->bufs_above_params));
    227 
    228     //ctx->mv_setting_btable_size = tng_align_KB(MAX_BFRAMES * (tng_align_64(sizeof(IMG_MV_SETTINGS) * MAX_BFRAMES)));
    229     ps_mem_size->mv_setting_btable = tng_align_KB(MAX_BFRAMES * MV_ROW_STRIDE);
    230     tng__alloc_init_buffer(ps_driver_data, ps_mem_size->mv_setting_btable,
    231         psb_bt_cpu_vpu, &(ps_mem->bufs_mv_setting_btable));
    232 
    233     ps_mem_size->mv_setting_hierar = tng_align_KB(MAX_BFRAMES * sizeof(IMG_MV_SETTINGS));
    234     tng__alloc_init_buffer(ps_driver_data, ps_mem_size->mv_setting_hierar,
    235         psb_bt_cpu_vpu, &(ps_mem->bufs_mv_setting_hierar));
    236 
    237     //colocated params
    238     ps_mem_size->colocated = tng_align_KB(MVEA_MV_PARAM_REGION_SIZE * tng_align_4(ui32_mb_per_row * ui32_mb_per_column));
    239     tng__alloc_init_buffer(ps_driver_data, ctx->i32PicNodes * ps_mem_size->colocated,
    240         psb_bt_cpu_vpu, &(ps_mem->bufs_colocated));
    241 
    242     ps_mem_size->interview_mv = ps_mem_size->mv = ps_mem_size->colocated;
    243     tng__alloc_init_buffer(ps_driver_data, ctx->i32MVStores * ps_mem_size->mv,
    244         psb_bt_cpu_vpu, &(ps_mem->bufs_mv));
    245 
    246     if (ctx->bEnableMVC) {
    247         tng__alloc_init_buffer(ps_driver_data, 2 * ps_mem_size->interview_mv,
    248             psb_bt_cpu_vpu, &(ps_mem->bufs_interview_mv));
    249     }
    250 
    251     //write back region
    252     ps_mem_size->writeback = tng_align_KB(COMM_WB_DATA_BUF_SIZE);
    253     tng__alloc_init_buffer(ps_driver_data, WB_FIFO_SIZE * ps_mem_size->writeback,
    254         psb_bt_cpu_vpu, &(ctx->bufs_writeback));
    255 
    256     ps_mem_size->slice_map = tng_align_KB(0x1500); //(1 + MAX_SLICESPERPIC * 2 + 15) & ~15);
    257     tng__alloc_init_buffer(ps_driver_data, ctx->ui8SlotsInUse * ps_mem_size->slice_map,
    258         psb_bt_cpu_vpu, &(ps_mem->bufs_slice_map));
    259 
    260     ps_mem_size->weighted_prediction = tng_align_KB(sizeof(WEIGHTED_PREDICTION_VALUES));
    261     tng__alloc_init_buffer(ps_driver_data, ctx->ui8SlotsInUse * ps_mem_size->weighted_prediction,
    262         psb_bt_cpu_vpu, &(ps_mem->bufs_weighted_prediction));
    263 
    264 #ifdef LTREFHEADER
    265     ps_mem_size->lt_ref_header = tng_align_KB((sizeof(MTX_HEADER_PARAMS)+63)&~63);
    266     tng__alloc_init_buffer(ps_driver_data, ctx->ui8SlotsInUse * ps_mem_size->lt_ref_header,
    267         psb_bt_cpu_vpu, &(ps_mem->bufs_lt_ref_header));
    268 #endif
    269 
    270     ps_mem_size->recon_pictures = tng_align_KB((tng_align_64(ui32_pic_width)*tng_align_64(ui32_pic_height))*3/2);
    271     tng__alloc_init_buffer(ps_driver_data, ctx->i32PicNodes * ps_mem_size->recon_pictures,
    272         psb_bt_cpu_vpu, &(ps_mem->bufs_recon_pictures));
    273 
    274     ctx->ctx_mem_size.first_pass_out_params = tng_align_KB(sizeof(IMG_FIRST_STAGE_MB_PARAMS) * ui32_mb_per_row *  ui32_mb_per_column);
    275     tng__alloc_init_buffer(ps_driver_data, ctx->ui8SlotsInUse * ctx->ctx_mem_size.first_pass_out_params,
    276         psb_bt_cpu_vpu, &(ps_mem->bufs_first_pass_out_params));
    277 
    278 #ifndef EXCLUDE_BEST_MP_DECISION_DATA
    279     ctx->ctx_mem_size.first_pass_out_best_multipass_param = tng_align_KB(ui32_mb_per_column * (((5*ui32_mb_per_row)+3)>>2) * 64);
    280     tng__alloc_init_buffer(ps_driver_data, ctx->ui8SlotsInUse * ctx->ctx_mem_size.first_pass_out_best_multipass_param,
    281         psb_bt_cpu_vpu, &(ps_mem->bufs_first_pass_out_best_multipass_param));
    282 #endif
    283 
    284     ctx->ctx_mem_size.mb_ctrl_in_params = tng_align_KB(sizeof(IMG_FIRST_STAGE_MB_PARAMS) * ui32_adj_mb_per_row *  ui32_mb_per_column);
    285     tng__alloc_init_buffer(ps_driver_data, ctx->ui8SlotsInUse * ctx->ctx_mem_size.mb_ctrl_in_params,
    286         psb_bt_cpu_vpu, &(ps_mem->bufs_mb_ctrl_in_params));
    287 
    288     ctx->ctx_mem_size.lowpower_params = tng_align_KB(TNG_HEADER_SIZE);
    289     tng__alloc_init_buffer(ps_driver_data, ps_mem_size->lowpower_params,
    290         psb_bt_cpu_vpu, &(ps_mem->bufs_lowpower_params));
    291 
    292     ctx->ctx_mem_size.lowpower_data = tng_align_KB(0x10000);
    293 
    294     return vaStatus;
    295 }
    296 
    297 static void tng__free_context_buffer(context_ENC_p ctx, unsigned char is_JPEG, unsigned int stream_id)
    298 {
    299     context_ENC_mem *ps_mem = &(ctx->ctx_mem[stream_id]);
    300 
    301     if (0 != is_JPEG) {
    302         psb_buffer_destroy(&(ctx->bufs_writeback));
    303         return;
    304     }
    305     psb_buffer_destroy(&(ps_mem->bufs_seq_header));
    306     if (ctx->bEnableMVC)
    307         psb_buffer_destroy(&(ps_mem->bufs_sub_seq_header));
    308     psb_buffer_destroy(&(ps_mem->bufs_pic_template));
    309     psb_buffer_destroy(&(ps_mem->bufs_slice_template));
    310     psb_buffer_destroy(&(ps_mem->bufs_mtx_context));
    311     psb_buffer_destroy(&(ps_mem->bufs_sei_header));
    312 
    313     psb_buffer_destroy(&(ps_mem->bufs_flat_gop));
    314     psb_buffer_destroy(&(ps_mem->bufs_hierar_gop));
    315     psb_buffer_destroy(&(ps_mem->bufs_above_params));
    316     psb_buffer_destroy(&(ps_mem->bufs_mv_setting_btable));
    317     psb_buffer_destroy(&(ps_mem->bufs_mv_setting_hierar));
    318     psb_buffer_destroy(&(ps_mem->bufs_colocated));
    319     psb_buffer_destroy(&(ps_mem->bufs_mv));
    320     if (ctx->bEnableMVC)
    321         psb_buffer_destroy(&(ps_mem->bufs_interview_mv));
    322 
    323     psb_buffer_destroy(&(ctx->bufs_writeback));
    324     psb_buffer_destroy(&(ps_mem->bufs_slice_map));
    325     psb_buffer_destroy(&(ps_mem->bufs_weighted_prediction));
    326 #ifdef LTREFHEADER
    327     psb_buffer_destroy(&(ps_mem->bufs_lt_ref_header));
    328 #endif
    329     psb_buffer_destroy(&(ps_mem->bufs_recon_pictures));
    330     psb_buffer_destroy(&(ps_mem->bufs_first_pass_out_params));
    331 #ifndef EXCLUDE_BEST_MP_DECISION_DATA
    332     psb_buffer_destroy(&(ps_mem->bufs_first_pass_out_best_multipass_param));
    333 #endif
    334     psb_buffer_destroy(&(ps_mem->bufs_mb_ctrl_in_params));
    335     psb_buffer_destroy(&(ps_mem->bufs_lowpower_params));
    336 
    337     return ;
    338 }
    339 
    340 unsigned int tng__get_ipe_control(IMG_CODEC  eEncodingFormat)
    341 {
    342     unsigned int RegVal = 0;
    343 
    344     RegVal = F_ENCODE(2, MVEA_CR_IPE_GRID_FINE_SEARCH) |
    345     F_ENCODE(0, MVEA_CR_IPE_GRID_SEARCH_SIZE) |
    346     F_ENCODE(1, MVEA_CR_IPE_Y_FINE_SEARCH);
    347 
    348     switch (eEncodingFormat) {
    349         case IMG_CODEC_H263_NO_RC:
    350         case IMG_CODEC_H263_VBR:
    351         case IMG_CODEC_H263_CBR:
    352             RegVal |= F_ENCODE(0, MVEA_CR_IPE_BLOCKSIZE) | F_ENCODE(0, MVEA_CR_IPE_ENCODING_FORMAT);
    353         break;
    354         case IMG_CODEC_MPEG4_NO_RC:
    355         case IMG_CODEC_MPEG4_VBR:
    356         case IMG_CODEC_MPEG4_CBR:
    357             RegVal |= F_ENCODE(1, MVEA_CR_IPE_BLOCKSIZE) | F_ENCODE(1, MVEA_CR_IPE_ENCODING_FORMAT);
    358         default:
    359         break;
    360         case IMG_CODEC_H264_NO_RC:
    361         case IMG_CODEC_H264_VBR:
    362         case IMG_CODEC_H264_CBR:
    363         case IMG_CODEC_H264_VCM:
    364             RegVal |= F_ENCODE(2, MVEA_CR_IPE_BLOCKSIZE) | F_ENCODE(2, MVEA_CR_IPE_ENCODING_FORMAT);
    365         break;
    366     }
    367     RegVal |= F_ENCODE(6, MVEA_CR_IPE_Y_CANDIDATE_NUM);
    368     return RegVal;
    369 }
    370 
    371 void tng__setup_enc_profile_features(context_ENC_p ctx, IMG_UINT32 ui32EncProfile)
    372 {
    373     IMG_ENCODE_FEATURES * pEncFeatures = &ctx->sEncFeatures;
    374     /* Set the default values first */
    375     pEncFeatures->bDisableBPicRef_0 = IMG_FALSE;
    376     pEncFeatures->bDisableBPicRef_1 = IMG_FALSE;
    377 
    378     pEncFeatures->bDisableInter8x8 = IMG_FALSE;
    379     pEncFeatures->bRestrictInter4x4 = IMG_FALSE;
    380 
    381     pEncFeatures->bDisableIntra4x4  = IMG_FALSE;
    382     pEncFeatures->bDisableIntra8x8  = IMG_FALSE;
    383     pEncFeatures->bDisableIntra16x16 = IMG_FALSE;
    384 
    385     pEncFeatures->bEnable8x16MVDetect   = IMG_TRUE;
    386     pEncFeatures->bEnable16x8MVDetect   = IMG_TRUE;
    387     pEncFeatures->bDisableBFrames       = IMG_FALSE;
    388 
    389     pEncFeatures->eMinBlkSz = BLK_SZ_DEFAULT;
    390 
    391     switch (ui32EncProfile) {
    392         case ENC_PROFILE_LOWCOMPLEXITY:
    393             pEncFeatures->bDisableInter8x8  = IMG_TRUE;
    394             pEncFeatures->bRestrictInter4x4 = IMG_TRUE;
    395             pEncFeatures->bDisableIntra4x4  = IMG_TRUE;
    396             pEncFeatures->bDisableIntra8x8  = IMG_TRUE;
    397             pEncFeatures->bRestrictInter4x4 = IMG_TRUE;
    398             pEncFeatures->eMinBlkSz         = BLK_SZ_16x16;
    399             pEncFeatures->bDisableBFrames   = IMG_TRUE;
    400             break;
    401 
    402         case ENC_PROFILE_HIGHCOMPLEXITY:
    403             pEncFeatures->bDisableBPicRef_0 = IMG_FALSE;
    404             pEncFeatures->bDisableBPicRef_1 = IMG_FALSE;
    405 
    406             pEncFeatures->bDisableInter8x8 = IMG_FALSE;
    407             pEncFeatures->bRestrictInter4x4 = IMG_FALSE;
    408 
    409             pEncFeatures->bDisableIntra4x4  = IMG_FALSE;
    410             pEncFeatures->bDisableIntra8x8  = IMG_FALSE;
    411             pEncFeatures->bDisableIntra16x16 = IMG_FALSE;
    412 
    413             pEncFeatures->bEnable8x16MVDetect   = IMG_TRUE;
    414             pEncFeatures->bEnable16x8MVDetect   = IMG_TRUE;
    415             break;
    416     }
    417 
    418     if (ctx->eStandard != IMG_STANDARD_H264) {
    419 	pEncFeatures->bEnable8x16MVDetect = IMG_FALSE;
    420 	pEncFeatures->bEnable16x8MVDetect = IMG_FALSE;
    421     }
    422 
    423     return;
    424 }
    425 
    426 VAStatus tng__patch_hw_profile(context_ENC_p ctx)
    427 {
    428     IMG_UINT32 ui32IPEControl = 0;
    429     IMG_UINT32 ui32PredCombControl = 0;
    430     IMG_ENCODE_FEATURES * psEncFeatures = &(ctx->sEncFeatures);
    431 
    432     // bDisableIntra4x4
    433     if (psEncFeatures->bDisableIntra4x4)
    434         ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTRA4X4_DISABLE);
    435 
    436     //bDisableIntra8x8
    437     if (psEncFeatures->bDisableIntra8x8)
    438         ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTRA8X8_DISABLE);
    439 
    440     //bDisableIntra16x16, check if atleast one of the other Intra mode is enabled
    441     if ((psEncFeatures->bDisableIntra16x16) &&
    442         (!(psEncFeatures->bDisableIntra8x8) || !(psEncFeatures->bDisableIntra4x4))) {
    443         ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTRA16X16_DISABLE);
    444     }
    445 
    446     if (psEncFeatures->bRestrictInter4x4) {
    447 //        ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTER4X4_RESTRICT);
    448         ui32IPEControl |= F_ENCODE(1, TOPAZHP_CR_IPE_MV_NUMBER_RESTRICTION);
    449     }
    450 
    451     if (psEncFeatures->bDisableInter8x8)
    452         ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTER8X8_DISABLE);
    453 
    454     if (psEncFeatures->bDisableBPicRef_1)
    455         ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_B_PIC1_DISABLE);
    456     else if (psEncFeatures->bDisableBPicRef_0)
    457         ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_B_PIC0_DISABLE);
    458 
    459     // save predictor combiner control in video encode parameter set
    460     ctx->ui32PredCombControl = ui32PredCombControl;
    461 
    462     // set blocksize
    463     ui32IPEControl |= F_ENCODE(psEncFeatures->eMinBlkSz, TOPAZHP_CR_IPE_BLOCKSIZE);
    464 
    465     if (psEncFeatures->bEnable8x16MVDetect)
    466         ui32IPEControl |= F_ENCODE(1, TOPAZHP_CR_IPE_8X16_ENABLE);
    467 
    468     if (psEncFeatures->bEnable16x8MVDetect)
    469         ui32IPEControl |= F_ENCODE(1, TOPAZHP_CR_IPE_16X8_ENABLE);
    470 
    471     if (psEncFeatures->bDisableBFrames)
    472         ctx->sRCParams.ui16BFrames = 0;
    473 
    474     //save IPE-control register
    475     ctx->ui32IPEControl = ui32IPEControl;
    476 
    477     return VA_STATUS_SUCCESS;
    478 }
    479 
    480 #ifdef _TOPAZHP_CMDBUF_
    481 static void tng__trace_cmdbuf(tng_cmdbuf_p cmdbuf, int idx)
    482 {
    483     IMG_UINT32 ui32CmdTmp[4];
    484     IMG_UINT32 *ptmp = (IMG_UINT32 *)(cmdbuf->cmd_start);
    485     IMG_UINT32 *pend = (IMG_UINT32 *)(cmdbuf->cmd_idx);
    486     IMG_UINT32 ui32Len;
    487 
    488     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: start, stream (%d), ptmp (0x%08x), pend (0x%08x}\n", __FUNCTION__, idx, (unsigned int)ptmp, (unsigned int)pend);
    489 
    490     if (idx)
    491         return ;
    492 
    493     while (ptmp < pend) {
    494         drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: ptmp (0x%08x}\n", __FUNCTION__, *ptmp);
    495         if ((*ptmp & 0x7f) == MTX_CMDID_SW_NEW_CODEC) {
    496             ptmp += 4;
    497         } else if ((*ptmp & 0x7f) == MTX_CMDID_SW_LEAVE_LOWPOWER) {
    498             ptmp += 2;
    499         } else if ((*ptmp & 0x7f) == MTX_CMDID_SW_WRITEREG) {
    500             ui32Len = *(++ptmp);
    501             drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: len = %d\n", __FUNCTION__, ui32Len);
    502             ptmp += (ui32Len * 3) + 1;
    503             drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: reg ptmp (0x%08x}\n", __FUNCTION__, *ptmp);
    504         } else if ((*ptmp & 0x7f) == MTX_CMDID_DO_HEADER) {
    505             ui32CmdTmp[0] = *ptmp++;
    506             ui32CmdTmp[1] = *ptmp++;
    507             ui32CmdTmp[2] = *ptmp++;
    508             ui32CmdTmp[3] = 0;
    509             //topazhp_dump_command((unsigned int*)ui32CmdTmp);
    510             ptmp += 2;
    511         } else if (
    512             ((*ptmp & 0x7f) == MTX_CMDID_SETVIDEO)||
    513             ((*ptmp & 0x7f) == MTX_CMDID_SHUTDOWN)) {
    514             ui32CmdTmp[0] = *ptmp++;
    515             ui32CmdTmp[1] = *ptmp++;
    516             ui32CmdTmp[2] = *ptmp++;
    517             ui32CmdTmp[3] = *ptmp++;
    518             //topazhp_dump_command((unsigned int*)ui32CmdTmp);
    519         } else if (
    520             ((*ptmp & 0x7f) == MTX_CMDID_PROVIDE_SOURCE_BUFFER) ||
    521             ((*ptmp & 0x7f) == MTX_CMDID_PROVIDE_REF_BUFFER) ||
    522             ((*ptmp & 0x7f) == MTX_CMDID_PROVIDE_CODED_BUFFER) ||
    523             ((*ptmp & 0x7f) == MTX_CMDID_PICMGMT) ||
    524             ((*ptmp & 0x7f) == MTX_CMDID_ENCODE_FRAME)) {
    525             ui32CmdTmp[0] = *ptmp++;
    526             ui32CmdTmp[1] = *ptmp++;
    527             ui32CmdTmp[2] = *ptmp++;
    528             ui32CmdTmp[3] = 0;
    529             //topazhp_dump_command((unsigned int*)ui32CmdTmp);
    530         } else {
    531             drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: error leave lowpower = 0x%08x\n", __FUNCTION__, *ptmp++);
    532         }
    533     }
    534 
    535     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end\n", __FUNCTION__);
    536 
    537     return ;
    538 }
    539 #endif
    540 
    541 void tng_DestroyContext(object_context_p obj_context, unsigned char is_JPEG)
    542 {
    543     context_ENC_p ctx;
    544 //    tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
    545     ctx = (context_ENC_p)obj_context->format_data;
    546     FRAME_ORDER_INFO *psFrameInfo = &(ctx->sFrameOrderInfo);
    547 
    548     if (psFrameInfo->slot_consume_dpy_order != NULL)
    549         free(psFrameInfo->slot_consume_dpy_order);
    550     if (psFrameInfo->slot_consume_enc_order != NULL)
    551         free(psFrameInfo->slot_consume_enc_order);
    552 
    553     tng_air_buf_free(ctx);
    554 
    555     tng__free_context_buffer(ctx, is_JPEG, 0);
    556 
    557     if (ctx->bEnableMVC)
    558         tng__free_context_buffer(ctx, is_JPEG, 1);
    559 
    560     free(obj_context->format_data);
    561     obj_context->format_data = NULL;
    562 }
    563 
    564 static VAStatus tng__init_rc_params(context_ENC_p ctx, object_config_p obj_config)
    565 {
    566     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
    567     unsigned int eRCmode = 0;
    568     memset(psRCParams, 0, sizeof(IMG_RC_PARAMS));
    569     IMG_INT32 i;
    570 
    571     //set RC mode
    572     for (i = 0; i < obj_config->attrib_count; i++) {
    573         if (obj_config->attrib_list[i].type == VAConfigAttribRateControl)
    574             break;
    575     }
    576 
    577     if (i >= obj_config->attrib_count) {
    578         eRCmode = VA_RC_NONE;
    579     } else {
    580         eRCmode = obj_config->attrib_list[i].value;
    581     }
    582 
    583     ctx->sRCParams.bRCEnable = IMG_TRUE;
    584     ctx->sRCParams.bDisableBitStuffing = IMG_FALSE;
    585 
    586     if (eRCmode == VA_RC_NONE) {
    587         ctx->sRCParams.bRCEnable = IMG_FALSE;
    588         ctx->sRCParams.eRCMode = IMG_RCMODE_NONE;
    589     } else if (eRCmode == VA_RC_CBR) {
    590         ctx->sRCParams.eRCMode = IMG_RCMODE_CBR;
    591     } else if (eRCmode == VA_RC_VBR) {
    592         ctx->sRCParams.eRCMode = IMG_RCMODE_VBR;
    593     } else if (eRCmode == VA_RC_VCM) {
    594         ctx->sRCParams.eRCMode = IMG_RCMODE_VCM;
    595     } else {
    596         ctx->sRCParams.bRCEnable = IMG_FALSE;
    597         drv_debug_msg(VIDEO_DEBUG_ERROR, "not support this RT Format\n");
    598         return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
    599     }
    600 
    601     psRCParams->bScDetectDisable = IMG_FALSE;
    602     psRCParams->ui32SliceByteLimit = 0;
    603     psRCParams->ui32SliceMBLimit = 0;
    604     psRCParams->bIsH264Codec = (ctx->eStandard == IMG_STANDARD_H264) ? IMG_TRUE : IMG_FALSE;
    605     return VA_STATUS_SUCCESS;
    606 }
    607 
    608 /**************************************************************************************************
    609 * Function:             IMG_C_GetEncoderCaps
    610 * Description:  Get the capabilities of the encoder for the given codec
    611 *
    612 ***************************************************************************************************/
    613 //FIXME
    614 static const IMG_UINT32 g_ui32PipesAvailable = TOPAZHP_PIPE_NUM;
    615 static const IMG_UINT32 g_ui32CoreDes1 = TOPAZHP_PIPE_NUM;
    616 static const IMG_UINT32 g_ui32CoreRev = 0x00030401;
    617 
    618 static IMG_UINT32 tng__get_num_pipes()
    619 {
    620     return g_ui32PipesAvailable;
    621 }
    622 
    623 static IMG_UINT32 tng__get_core_des1()
    624 {
    625     return g_ui32CoreDes1;
    626 }
    627 
    628 static IMG_UINT32 tng__get_core_rev()
    629 {
    630     return g_ui32CoreRev;
    631 }
    632 
    633 static VAStatus tng__get_encoder_caps(context_ENC_p ctx)
    634 {
    635     IMG_ENC_CAPS *psCaps = &(ctx->sCapsParams);
    636     IMG_UINT16 ui16Height = ctx->ui16FrameHeight;
    637     IMG_UINT32 ui32NumCores = 0;
    638     IMG_UINT16 ui16MBRows = 0; //MB Rows in a GOB(slice);
    639 
    640     ctx->ui32CoreRev = tng__get_core_rev();
    641     psCaps->ui32CoreFeatures = tng__get_core_des1();
    642 
    643     /* get the actual number of cores */
    644     ui32NumCores = tng__get_num_pipes();
    645 
    646     switch (ctx->eStandard) {
    647         case IMG_STANDARD_JPEG:
    648             psCaps->ui16MaxSlices = ui16Height / 8;
    649             psCaps->ui16MinSlices = 1;
    650             psCaps->ui16RecommendedSlices = ui32NumCores;
    651             break;
    652         case IMG_STANDARD_H264:
    653             psCaps->ui16MaxSlices = ui16Height / 16;
    654             psCaps->ui16MinSlices = 1;
    655             psCaps->ui16RecommendedSlices = ui32NumCores;
    656             break;
    657         case IMG_STANDARD_MPEG2:
    658             psCaps->ui16MaxSlices = 174; // Slice labelling dictates a maximum of 174 slices
    659             psCaps->ui16MinSlices = 1;
    660             psCaps->ui16RecommendedSlices = (ui16Height + 15) / 16;
    661             break;
    662         case IMG_STANDARD_H263:
    663             // if the original height of the pic is less than 400 , k is 1. refer standard.
    664             if (ui16Height <= 400) {
    665                 ui16MBRows = 1;
    666             } else if (ui16Height < 800) { // if between 400 and 800 it's 2.
    667                 ui16MBRows = 2;
    668             } else {
    669                 ui16MBRows = 4;
    670             }
    671             // before rounding is done for the height.
    672             // get the GOB's based on this MB Rows and not vice-versa.
    673             psCaps->ui16RecommendedSlices = (ui16Height + 15) >> (4 + (ui16MBRows >> 1));
    674             psCaps->ui16MaxSlices = psCaps->ui16MinSlices = psCaps->ui16RecommendedSlices;
    675             break;
    676         case IMG_STANDARD_MPEG4:
    677             psCaps->ui16MaxSlices = 1;
    678             psCaps->ui16MinSlices = 1;
    679             psCaps->ui16RecommendedSlices = 1;
    680             break;
    681         default:
    682             break;
    683     }
    684     return VA_STATUS_SUCCESS;
    685 }
    686 
    687 static VAStatus tng__init_context(context_ENC_p ctx)
    688 {
    689     VAStatus vaStatus = 0;
    690 
    691     /* Mostly sure about the following video parameters */
    692     //ctx->ui32HWProfile = pParams->ui32HWProfile;
    693     ctx->ui32FrameCount[0] = ctx->ui32FrameCount[1] = 0;
    694     /* Using Extended parameters */
    695     ctx->ui8PipesToUse = (IMG_UINT8)(tng__get_num_pipes() & (IMG_UINT32)0xff);
    696     //carc params
    697     ctx->sCARCParams.bCARC             = 0;
    698     ctx->sCARCParams.i32CARCBaseline   = 0;
    699     ctx->sCARCParams.ui32CARCThreshold = TOPAZHP_DEFAULT_uCARCThreshold;
    700     ctx->sCARCParams.ui32CARCCutoff    = TOPAZHP_DEFAULT_uCARCCutoff;
    701     ctx->sCARCParams.ui32CARCNegRange  = TOPAZHP_DEFAULT_uCARCNegRange;
    702     ctx->sCARCParams.ui32CARCNegScale  = TOPAZHP_DEFAULT_uCARCNegScale;
    703     ctx->sCARCParams.ui32CARCPosRange  = TOPAZHP_DEFAULT_uCARCPosRange;
    704     ctx->sCARCParams.ui32CARCPosScale  = TOPAZHP_DEFAULT_uCARCPosScale;
    705     ctx->sCARCParams.ui32CARCShift     = TOPAZHP_DEFAULT_uCARCShift;
    706 
    707     ctx->bUseDefaultScalingList = IMG_FALSE;
    708     ctx->ui32CabacBinLimit = TOPAZHP_DEFAULT_uCABACBinLimit; //This parameter need not be exposed
    709     if (ctx->ui32CabacBinLimit == 0)
    710         ctx->ui32CabacBinFlex = 0;//This parameter need not be exposed
    711     else
    712         ctx->ui32CabacBinFlex = TOPAZHP_DEFAULT_uCABACBinFlex;//This parameter need not be exposed
    713 
    714     ctx->ui32FCode = 4;                     //This parameter need not be exposed
    715     ctx->iFineYSearchSize = 2;//This parameter need not be exposed
    716     ctx->ui32VopTimeResolution = 15;//This parameter need not be exposed
    717 //    ctx->bEnabledDynamicBPic = IMG_FALSE;//Related to Rate Control,which is no longer needed.
    718     ctx->bH264IntraConstrained = IMG_FALSE;//This parameter need not be exposed
    719     ctx->bEnableInpCtrl     = IMG_FALSE;//This parameter need not be exposed
    720     ctx->bEnableAIR = 0;
    721     ctx->bEnableCIR = 0;
    722     ctx->bEnableHostBias = (ctx->bEnableAIR != 0);//This parameter need not be exposed
    723     ctx->bEnableHostQP = IMG_FALSE; //This parameter need not be exposed
    724     ctx->ui8CodedSkippedIndex = 3;//This parameter need not be exposed
    725     ctx->ui8InterIntraIndex         = 3;//This parameter need not be exposed
    726     ctx->uMaxChunks = 0xA0;//This parameter need not be exposed
    727     ctx->uChunksPerMb = 0x40;//This parameter need not be exposed
    728     ctx->uPriorityChunks = (0xA0 - 0x60);//This parameter need not be exposed
    729     ctx->bWeightedPrediction = IMG_FALSE;//Weighted Prediction is not supported in TopazHP Version 3.0
    730     ctx->ui8VPWeightedImplicitBiPred = 0;//Weighted Prediction is not supported in TopazHP Version 3.0
    731     ctx->bSkipDuplicateVectors = IMG_FALSE;//By default false Newly Added
    732     ctx->bEnableCumulativeBiases = IMG_FALSE;//By default false Newly Added
    733     ctx->ui16UseCustomScalingLists = 0;//By default false Newly Added
    734     ctx->bPpsScaling = IMG_FALSE;//By default false Newly Added
    735     ctx->ui8MPEG2IntraDCPrecision = 0;//By default 0 Newly Added
    736     ctx->uMBspS = 0;//By default 0 Newly Added
    737     ctx->bMultiReferenceP = IMG_FALSE;//By default false Newly Added
    738     ctx->ui8RefSpacing=0;//By default 0 Newly Added
    739     ctx->bSpatialDirect = 0;//By default 0 Newly Added
    740     ctx->ui32DebugCRCs = 0;//By default false Newly Added
    741     ctx->bEnableMVC = IMG_FALSE;//By default false Newly Added
    742     ctx->ui16MVCViewIdx = (IMG_UINT16)(NON_MVC_VIEW);//Newly Added
    743     ctx->bSrcAllocInternally = IMG_FALSE;//By default false Newly Added
    744     ctx->bCodedAllocInternally = IMG_FALSE;//By default true Newly Added
    745     ctx->bHighLatency = IMG_TRUE;//Newly Added
    746     ctx->i32NumAIRMBs = -1;
    747     ctx->i32AIRThreshold = -1;
    748     ctx->i16AIRSkipCnt = -1;
    749     ctx->i32LastCIRIndex = -1;
    750     //Need to check on the following parameters
    751     ctx->ui8EnableSelStatsFlags  = IMG_FALSE;//Default Value ?? Extended Parameter ??
    752     ctx->bH2648x8Transform = IMG_FALSE;//Default Value ?? Extended Parameter or OMX_VIDEO_PARAM_AVCTYPE -> bDirect8x8Inference??
    753     //FIXME: Zhaohan, eStandard is always 0 here.
    754     ctx->bNoOffscreenMv = (ctx->eStandard == IMG_STANDARD_H263) ? IMG_TRUE : IMG_FALSE; //Default Value ?? Extended Parameter and bUseOffScreenMVUserSetting
    755     ctx->bNoSequenceHeaders = IMG_FALSE;
    756     ctx->bTopFieldFirst = IMG_TRUE;
    757     ctx->sBiasTables.ui32FCode = ctx->ui32FCode;
    758     ctx->ui32pseudo_rand_seed = UNINIT_PARAM;
    759     ctx->bVPAdaptiveRoundingDisable = IMG_TRUE;
    760 
    761     //Default fcode is 4
    762     if (!ctx->sBiasTables.ui32FCode)
    763 	ctx->sBiasTables.ui32FCode = 4;
    764 
    765     ctx->uiCbrBufferTenths = TOPAZHP_DEFAULT_uiCbrBufferTenths;
    766 
    767     tng__setup_enc_profile_features(ctx, ENC_PROFILE_DEFAULT);
    768 
    769     vaStatus = tng__patch_hw_profile(ctx);
    770     if (vaStatus != VA_STATUS_SUCCESS) {
    771         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: tng__patch_hw_profile\n", __FUNCTION__);
    772     }
    773 
    774     return VA_STATUS_SUCCESS;
    775 }
    776 
    777 VAStatus tng_CreateContext(
    778     object_context_p obj_context,
    779     object_config_p obj_config,
    780     unsigned char is_JPEG)
    781 {
    782     VAStatus vaStatus = 0;
    783     unsigned short ui16Width, ui16Height;
    784     context_ENC_p ctx;
    785 
    786     ui16Width = obj_context->picture_width;
    787     ui16Height = obj_context->picture_height;
    788     ctx = (context_ENC_p) calloc(1, sizeof(struct context_ENC_s));
    789     if (NULL == ctx) {
    790         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
    791         DEBUG_FAILURE;
    792         return vaStatus;
    793     }
    794 
    795     memset((void*)ctx, 0, sizeof(struct context_ENC_s));
    796 
    797     obj_context->format_data = (void*) ctx;
    798     ctx->obj_context = obj_context;
    799 
    800     if (is_JPEG == 0) {
    801         ctx->ui16Width = (unsigned short)(~0xf & (ui16Width + 0xf));
    802         ctx->ui16FrameHeight = (unsigned short)(~0xf & (ui16Height + 0xf));
    803 
    804         vaStatus = tng__init_context(ctx);
    805         if (vaStatus != VA_STATUS_SUCCESS) {
    806             drv_debug_msg(VIDEO_DEBUG_ERROR, "init Context params");
    807         }
    808 
    809         vaStatus = tng__init_rc_params(ctx, obj_config);
    810         if (vaStatus != VA_STATUS_SUCCESS) {
    811             drv_debug_msg(VIDEO_DEBUG_ERROR, "init rc params");
    812         }
    813     } else {
    814         /*JPEG only require them are even*/
    815         ctx->ui16Width = (unsigned short)(~0x1 & (ui16Width + 0x1));
    816         ctx->ui16FrameHeight = (unsigned short)(~0x1 & (ui16Height + 0x1));
    817     }
    818 
    819     ctx->eFormat = IMG_CODEC_PL12;     // use default
    820 
    821     tng__setup_enc_profile_features(ctx, ENC_PROFILE_DEFAULT);
    822 
    823     if (is_JPEG) {
    824         vaStatus = tng__alloc_context_buffer(ctx, is_JPEG, 0);
    825         if (vaStatus != VA_STATUS_SUCCESS) {
    826             drv_debug_msg(VIDEO_DEBUG_ERROR, "setup enc profile");
    827         }
    828     }
    829 
    830     return vaStatus;
    831 }
    832 
    833 VAStatus tng_BeginPicture(context_ENC_p ctx)
    834 {
    835     VAStatus vaStatus = VA_STATUS_SUCCESS;
    836     context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
    837     tng_cmdbuf_p cmdbuf;
    838     int ret;
    839 
    840     ctx->ui32StreamID = 0;
    841 
    842     if (ctx->ui32RawFrameCount != 0)
    843         ps_buf->previous_src_surface = ps_buf->src_surface;
    844     ps_buf->src_surface = ctx->obj_context->current_render_target;
    845 
    846     vaStatus = tng__get_encoder_caps(ctx);
    847     if (vaStatus != VA_STATUS_SUCCESS) {
    848         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: tng__get_encoder_caps\n", __FUNCTION__);
    849     }
    850 
    851     /* clear frameskip flag to 0 */
    852     CLEAR_SURFACE_INFO_skipped_flag(ps_buf->src_surface->psb_surface);
    853 
    854     /* Initialise the command buffer */
    855     ret = tng_context_get_next_cmdbuf(ctx->obj_context);
    856     if (ret) {
    857         drv_debug_msg(VIDEO_DEBUG_ERROR, "get next cmdbuf fail\n");
    858         vaStatus = VA_STATUS_ERROR_UNKNOWN;
    859         return vaStatus;
    860     }
    861     cmdbuf = ctx->obj_context->tng_cmdbuf;
    862 
    863     //FIXME
    864     /* only map topaz param when necessary */
    865     cmdbuf->topaz_in_params_I_p = NULL;
    866     cmdbuf->topaz_in_params_P_p = NULL;
    867     ctx->obj_context->slice_count = 0;
    868 
    869     tng_cmdbuf_buffer_ref(cmdbuf, &(ctx->obj_context->current_render_target->psb_surface->buf));
    870 
    871     return vaStatus;
    872 }
    873 
    874 static VAStatus tng__provide_buffer_BFrames(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
    875 {
    876     IMG_RC_PARAMS * psRCParams = &(ctx->sRCParams);
    877     FRAME_ORDER_INFO *psFrameInfo = &(ctx->sFrameOrderInfo);
    878     int slot_index = 0;
    879     unsigned long long display_order = 0;
    880     IMG_INT32  i32SlotBuf  = (IMG_INT32)(psRCParams->ui16BFrames + 2);
    881     IMG_UINT32 ui32SlotBuf = (IMG_UINT32)(psRCParams->ui16BFrames + 2);
    882     IMG_UINT32 ui32FrameIdx = ctx->ui32FrameCount[ui32StreamIndex];
    883 
    884     if (ui32StreamIndex == 0)
    885         getFrameDpyOrder(ui32FrameIdx, psRCParams->ui16BFrames, ctx->ui32IntraCnt,
    886              ctx->ui32IdrPeriod, psFrameInfo, &display_order);
    887 
    888     slot_index = psFrameInfo->last_slot;
    889 
    890     drv_debug_msg(VIDEO_DEBUG_GENERAL,
    891         "%s: (int)ui32FrameIdx = %d, psRCParams->ui16BFrames = %d, psRCParams->ui32IntraFreq = %d, ctx->ui32IdrPeriod = %d\n",
    892         __FUNCTION__, (int)ui32FrameIdx, (int)psRCParams->ui16BFrames, (int)psRCParams->ui32IntraFreq, ctx->ui32IdrPeriod);
    893 
    894     drv_debug_msg(VIDEO_DEBUG_GENERAL,
    895         "%s: last_slot = %d, last_frame_type = %d, display_order = %d\n",
    896         __FUNCTION__, psFrameInfo->last_slot, psFrameInfo->last_frame_type, display_order);
    897 
    898     if (ui32FrameIdx < ui32SlotBuf) {
    899         if (ui32FrameIdx == 0) {
    900             tng_send_source_frame(ctx, 0, 0);
    901         } else if (ui32FrameIdx == 1) {
    902             slot_index = 1;
    903             do {
    904                 tng_send_source_frame(ctx, slot_index, slot_index);
    905                 ++slot_index;
    906             } while(slot_index < i32SlotBuf);
    907         } else {
    908             slot_index = ui32FrameIdx - 1;
    909             tng_send_source_frame(ctx, slot_index, slot_index);
    910         }
    911     } else {
    912         tng_send_source_frame(ctx, slot_index , display_order);
    913     }
    914 
    915     return VA_STATUS_SUCCESS;
    916 }
    917 
    918 VAStatus tng__provide_buffer_PFrames(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
    919 {
    920     IMG_UINT32 ui32FrameIdx = ctx->ui32FrameCount[ui32StreamIndex];
    921 
    922     drv_debug_msg(VIDEO_DEBUG_GENERAL,
    923         "%s: frame count = %d, SlotsInUse = %d, ui32FrameIdx = %d\n",
    924         __FUNCTION__, (int)ui32FrameIdx, ctx->ui8SlotsInUse, ui32FrameIdx);
    925 
    926     tng_send_source_frame(ctx, ctx->ui8SlotsCoded, ui32FrameIdx);
    927 /*
    928     if (ctx->ui32IntraCnt == 0)
    929         ctx->eFrameType = IMG_INTRA_FRAME;
    930     else
    931         if (ui32FrameIdx % ctx->ui32IntraCnt == 0)
    932             ctx->eFrameType = IMG_INTRA_FRAME;
    933         else
    934             ctx->eFrameType = IMG_INTER_P;
    935 
    936     if (ctx->ui32IdrPeriod == 0) {
    937         if (ui32FrameIdx == 0)
    938             ctx->eFrameType = IMG_INTRA_IDR;
    939     } else {
    940         if (ctx->ui32IntraCnt == 0) {
    941             if (ui32FrameIdx % ctx->ui32IdrPeriod == 0)
    942                 ctx->eFrameType = IMG_INTRA_IDR;
    943         } else {
    944             if (ui32FrameIdx % (ctx->ui32IntraCnt * ctx->ui32IdrPeriod) == 0)
    945                 ctx->eFrameType = IMG_INTRA_IDR;
    946         }
    947     }
    948 */
    949     ctx->eFrameType = IMG_INTER_P;
    950 
    951     if (ui32FrameIdx % ctx->ui32IntraCnt == 0)
    952         ctx->eFrameType = IMG_INTRA_FRAME;
    953 
    954     if (ui32FrameIdx % (ctx->ui32IdrPeriod * ctx->ui32IntraCnt) == 0)
    955         ctx->eFrameType = IMG_INTRA_IDR;
    956 
    957     drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: ctx->eFrameType = %d\n", __FUNCTION__, ctx->eFrameType);
    958 
    959     return VA_STATUS_SUCCESS;
    960 }
    961 
    962 static IMG_UINT16 H264_ROUNDING_OFFSETS[18][4] = {
    963     {  683, 683, 683, 683 },   /* 0  I-Slice - INTRA4  LUMA */
    964     {  683, 683, 683, 683 },   /* 1  P-Slice - INTRA4  LUMA */
    965     {  683, 683, 683, 683 },   /* 2  B-Slice - INTRA4  LUMA */
    966 
    967     {  683, 683, 683, 683 },   /* 3  I-Slice - INTRA8  LUMA */
    968     {  683, 683, 683, 683 },   /* 4  P-Slice - INTRA8  LUMA */
    969     {  683, 683, 683, 683 },   /* 5  B-Slice - INTRA8  LUMA */
    970     {  341, 341, 341, 341 },   /* 6  P-Slice - INTER8  LUMA */
    971     {  341, 341, 341, 341 },   /* 7  B-Slice - INTER8  LUMA */
    972 
    973     {  683, 683, 683, 000 },   /* 8  I-Slice - INTRA16 LUMA */
    974     {  683, 683, 683, 000 },   /* 9  P-Slice - INTRA16 LUMA */
    975     {  683, 683, 683, 000 },   /* 10 B-Slice - INTRA16 LUMA */
    976     {  341, 341, 341, 341 },   /* 11 P-Slice - INTER16 LUMA */
    977     {  341, 341, 341, 341 },   /* 12 B-Slice - INTER16 LUMA */
    978 
    979     {  683, 683, 683, 000 },   /* 13 I-Slice - INTRA16 CHROMA */
    980     {  683, 683, 683, 000 },   /* 14 P-Slice - INTRA16 CHROMA */
    981     {  683, 683, 683, 000 },   /* 15 B-Slice - INTRA16 CHROMA */
    982     {  341, 341, 341, 000 },   /* 16 P-Slice - INTER16 CHROMA */
    983     {  341, 341, 341, 000 } /* 17 B-Slice - INTER16 CHROMA */
    984 };
    985 
    986 static IMG_UINT16 tng__create_gop_frame(
    987     IMG_UINT8 * pui8Level, IMG_BOOL bReference,
    988     IMG_UINT8 ui8Pos, IMG_UINT8 ui8Ref0Level,
    989     IMG_UINT8 ui8Ref1Level, IMG_FRAME_TYPE eFrameType)
    990 {
    991     *pui8Level = ((ui8Ref0Level > ui8Ref1Level) ? ui8Ref0Level : ui8Ref1Level)  + 1;
    992 
    993     return F_ENCODE(bReference, GOP_REFERENCE) |
    994            F_ENCODE(ui8Pos, GOP_POS) |
    995            F_ENCODE(ui8Ref0Level, GOP_REF0) |
    996            F_ENCODE(ui8Ref1Level, GOP_REF1) |
    997            F_ENCODE(eFrameType, GOP_FRAMETYPE);
    998 }
    999 
   1000 static void tng__minigop_generate_flat(void* buffer_p, IMG_UINT32 ui32BFrameCount, IMG_UINT32 ui32RefSpacing, IMG_UINT8 aui8PicOnLevel[])
   1001 {
   1002     /* B B B B P */
   1003     IMG_UINT8 ui8EncodeOrderPos;
   1004     IMG_UINT8 ui8Level;
   1005     IMG_UINT16 * psGopStructure = (IMG_UINT16 *)buffer_p;
   1006 
   1007     psGopStructure[0] = tng__create_gop_frame(&ui8Level, IMG_TRUE, MAX_BFRAMES, ui32RefSpacing, 0, IMG_INTER_P);
   1008     aui8PicOnLevel[ui8Level]++;
   1009 
   1010     for (ui8EncodeOrderPos = 1; ui8EncodeOrderPos < MAX_GOP_SIZE; ui8EncodeOrderPos++) {
   1011         psGopStructure[ui8EncodeOrderPos] = tng__create_gop_frame(&ui8Level, IMG_FALSE,
   1012                                             ui8EncodeOrderPos - 1, ui32RefSpacing, ui32RefSpacing + 1, IMG_INTER_B);
   1013         aui8PicOnLevel[ui8Level] = ui32BFrameCount;
   1014     }
   1015 
   1016     for( ui8EncodeOrderPos = 0; ui8EncodeOrderPos < MAX_GOP_SIZE; ui8EncodeOrderPos++) {
   1017         drv_debug_msg(VIDEO_DEBUG_GENERAL,
   1018             "%s: psGopStructure = 0x%06x\n", __FUNCTION__, psGopStructure[ui8EncodeOrderPos]);
   1019     }
   1020 
   1021     return ;
   1022 }
   1023 
   1024 static void tng__gop_split(IMG_UINT16 ** pasGopStructure, IMG_INT8 i8Ref0, IMG_INT8 i8Ref1,
   1025                            IMG_UINT8 ui8Ref0Level, IMG_UINT8 ui8Ref1Level, IMG_UINT8 aui8PicOnLevel[])
   1026 {
   1027     IMG_UINT8 ui8Distance = i8Ref1 - i8Ref0;
   1028     IMG_UINT8 ui8Position = i8Ref0 + (ui8Distance >> 1);
   1029     IMG_UINT8 ui8Level;
   1030 
   1031     if (ui8Distance == 1)
   1032         return;
   1033 
   1034     /* mark middle as this level */
   1035 
   1036     (*pasGopStructure)++;
   1037     **pasGopStructure = tng__create_gop_frame(&ui8Level, ui8Distance >= 3, ui8Position, ui8Ref0Level, ui8Ref1Level, IMG_INTER_B);
   1038     aui8PicOnLevel[ui8Level]++;
   1039 
   1040     if (ui8Distance >= 4)
   1041         tng__gop_split(pasGopStructure, i8Ref0, ui8Position, ui8Ref0Level, ui8Level, aui8PicOnLevel);
   1042 
   1043     if (ui8Distance >= 3)
   1044         tng__gop_split(pasGopStructure, ui8Position, i8Ref1, ui8Level, ui8Ref1Level, aui8PicOnLevel);
   1045 }
   1046 
   1047 static void tng_minigop_generate_hierarchical(void* buffer_p, IMG_UINT32 ui32BFrameCount,
   1048         IMG_UINT32 ui32RefSpacing, IMG_UINT8 aui8PicOnLevel[])
   1049 {
   1050     IMG_UINT8 ui8Level;
   1051     IMG_UINT16 * psGopStructure = (IMG_UINT16 *)buffer_p;
   1052 
   1053     psGopStructure[0] = tng__create_gop_frame(&ui8Level, IMG_TRUE, ui32BFrameCount, ui32RefSpacing, 0, IMG_INTER_P);
   1054     aui8PicOnLevel[ui8Level]++;
   1055 
   1056     tng__gop_split(&psGopStructure, -1, ui32BFrameCount, ui32RefSpacing, ui32RefSpacing + 1, aui8PicOnLevel);
   1057 }
   1058 
   1059 static void tng__generate_scale_tables(IMG_MTX_VIDEO_CONTEXT* psMtxEncCtx)
   1060 {
   1061     psMtxEncCtx->ui32InterIntraScale[0] = 0x0004;  // Force intra by scaling its cost by 0
   1062     psMtxEncCtx->ui32InterIntraScale[1] = 0x0103;  // favour intra by a factor 3
   1063     psMtxEncCtx->ui32InterIntraScale[2] = 0x0102;  // favour intra by a factor 2
   1064     psMtxEncCtx->ui32InterIntraScale[3] = 0x0101;  // no bias
   1065     psMtxEncCtx->ui32InterIntraScale[4] = 0x0101;  // no bias
   1066     psMtxEncCtx->ui32InterIntraScale[5] = 0x0201;  // favour inter by a factor 2
   1067     psMtxEncCtx->ui32InterIntraScale[6] = 0x0301;  // favour inter by a factor 3
   1068     psMtxEncCtx->ui32InterIntraScale[7] = 0x0400;  // Force inter by scaling it's cost by 0
   1069 
   1070     psMtxEncCtx->ui32SkippedCodedScale[0] = 0x0004;  // Force coded by scaling its cost by 0
   1071     psMtxEncCtx->ui32SkippedCodedScale[1] = 0x0103;  // favour coded by a factor 3
   1072     psMtxEncCtx->ui32SkippedCodedScale[2] = 0x0102;  // favour coded by a factor 2
   1073     psMtxEncCtx->ui32SkippedCodedScale[3] = 0x0101;  // no bias
   1074     psMtxEncCtx->ui32SkippedCodedScale[4] = 0x0101;  // no bias
   1075     psMtxEncCtx->ui32SkippedCodedScale[5] = 0x0201;  // favour skipped by a factor 2
   1076     psMtxEncCtx->ui32SkippedCodedScale[6] = 0x0301;  // favour skipped by a factor 3
   1077     psMtxEncCtx->ui32SkippedCodedScale[7] = 0x0400;  // Force skipped by scaling it's cost by 0
   1078     return ;
   1079 }
   1080 
   1081 /*!
   1082 ******************************************************************************
   1083  @Function      tng_update_driver_mv_scaling
   1084  @details
   1085         Setup the registers for scaling candidate motion vectors to take into account
   1086         how far away (temporally) the reference pictures are
   1087 ******************************************************************************/
   1088 
   1089 static IMG_INT tng__abs(IMG_INT a)
   1090 {
   1091     if (a < 0)
   1092         return -a;
   1093     else
   1094         return a;
   1095 }
   1096 
   1097 static IMG_INT tng__abs32(IMG_INT32 a)
   1098 {
   1099     if (a < 0)
   1100         return -a;
   1101     else
   1102         return a;
   1103 }
   1104 
   1105 void tng_update_driver_mv_scaling(
   1106     IMG_UINT32 uFrameNum,
   1107     IMG_UINT32 uRef0Num,
   1108     IMG_UINT32 uRef1Num,
   1109     IMG_UINT32 ui32PicFlags,
   1110     IMG_BOOL   bSkipDuplicateVectors,
   1111     IMG_UINT32 * pui32MVCalc_Below,
   1112     IMG_UINT32 * pui32MVCalc_Colocated,
   1113     IMG_UINT32 * pui32MVCalc_Config)
   1114 {
   1115     IMG_UINT32 uMvCalcConfig = 0;
   1116     IMG_UINT32 uMvCalcColocated = F_ENCODE(0x10, TOPAZHP_CR_TEMPORAL_BLEND);
   1117     IMG_UINT32 uMvCalcBelow = 0;
   1118 
   1119     //If b picture calculate scaling factor for colocated motion vectors
   1120     if (ui32PicFlags & ISINTERB_FLAGS) {
   1121         IMG_INT tb, td, tx;
   1122         IMG_INT iDistScale;
   1123 
   1124         //calculation taken from H264 spec
   1125         tb = (uFrameNum * 2) - (uRef1Num * 2);
   1126         td = (uRef0Num  * 2) - (uRef1Num * 2);
   1127         tx = (16384 + tng__abs(td / 2)) / td;
   1128         iDistScale = (tb * tx + 32) >> 6;
   1129         if (iDistScale > 1023) iDistScale = 1023;
   1130         if (iDistScale < -1024) iDistScale = -1024;
   1131         uMvCalcColocated |= F_ENCODE(iDistScale, TOPAZHP_CR_COL_DIST_SCALE_FACT);
   1132 
   1133         //We assume the below temporal mvs are from the latest reference frame
   1134         //rather then the most recently encoded B frame (as Bs aren't reference)
   1135 
   1136         //Fwd temporal is same as colocated mv scale
   1137         uMvCalcBelow     |= F_ENCODE(iDistScale, TOPAZHP_CR_PIC0_DIST_SCALE_FACTOR);
   1138 
   1139         //Bkwd temporal needs to be scaled by the recipricol amount in the other direction
   1140         tb = (uFrameNum * 2) - (uRef0Num * 2);
   1141         td = (uRef0Num  * 2) - (uRef1Num * 2);
   1142         tx = (16384 + tng__abs(td / 2)) / td;
   1143         iDistScale = (tb * tx + 32) >> 6;
   1144         if (iDistScale > 1023) iDistScale = 1023;
   1145         if (iDistScale < -1024) iDistScale = -1024;
   1146         uMvCalcBelow |= F_ENCODE(iDistScale, TOPAZHP_CR_PIC1_DIST_SCALE_FACTOR);
   1147     } else {
   1148         //Don't scale the temporal below mvs
   1149         uMvCalcBelow |= F_ENCODE(1 << 8, TOPAZHP_CR_PIC0_DIST_SCALE_FACTOR);
   1150 
   1151         if (uRef0Num != uRef1Num) {
   1152             IMG_INT iRef0Dist, iRef1Dist;
   1153             IMG_INT iScale;
   1154 
   1155             //Distance to second reference picture may be different when
   1156             //using multiple reference frames on P. Scale based on difference
   1157             //in temporal distance to ref pic 1 compared to distance to ref pic 0
   1158             iRef0Dist = (uFrameNum - uRef0Num);
   1159             iRef1Dist = (uFrameNum - uRef1Num);
   1160             iScale    = (iRef1Dist << 8) / iRef0Dist;
   1161 
   1162             if (iScale > 1023) iScale = 1023;
   1163             if (iScale < -1024) iScale = -1024;
   1164 
   1165             uMvCalcBelow |= F_ENCODE(iScale, TOPAZHP_CR_PIC1_DIST_SCALE_FACTOR);
   1166         } else
   1167             uMvCalcBelow |= F_ENCODE(1 << 8, TOPAZHP_CR_PIC1_DIST_SCALE_FACTOR);
   1168     }
   1169 
   1170     if (uFrameNum > 0) {
   1171         IMG_INT ref0_distance, ref1_distance;
   1172         IMG_INT jitter0, jitter1;
   1173 
   1174         ref0_distance = tng__abs32((IMG_INT32)uFrameNum - (IMG_INT32)uRef0Num);
   1175         ref1_distance = tng__abs32((IMG_INT32)uFrameNum - (IMG_INT32)uRef1Num);
   1176 
   1177         if (!(ui32PicFlags & ISINTERB_FLAGS)) {
   1178             jitter0 = ref0_distance * 1;
   1179             jitter1 = jitter0 > 1 ? 1 : 2;
   1180         } else {
   1181             jitter0 = ref1_distance * 1;
   1182             jitter1 = ref0_distance * 1;
   1183         }
   1184 
   1185         //Hardware can only cope with 1 - 4 jitter factors
   1186         jitter0 = (jitter0 > 4) ? 4 : (jitter0 < 1) ? 1 : jitter0;
   1187         jitter1 = (jitter1 > 4) ? 4 : (jitter1 < 1) ? 1 : jitter1;
   1188 
   1189         //Hardware can only cope with 1 - 4 jitter factors
   1190         assert(jitter0 > 0 && jitter0 <= 4 && jitter1 > 0 && jitter1 <= 4);
   1191 
   1192         uMvCalcConfig |= F_ENCODE(jitter0 - 1, TOPAZHP_CR_MVCALC_IPE0_JITTER_FACTOR) |
   1193                          F_ENCODE(jitter1 - 1, TOPAZHP_CR_MVCALC_IPE1_JITTER_FACTOR);
   1194     }
   1195 
   1196     uMvCalcConfig |= F_ENCODE(1, TOPAZHP_CR_MVCALC_DUP_VEC_MARGIN);
   1197     uMvCalcConfig |= F_ENCODE(7, TOPAZHP_CR_MVCALC_GRID_MB_X_STEP);
   1198     uMvCalcConfig |= F_ENCODE(13, TOPAZHP_CR_MVCALC_GRID_MB_Y_STEP);
   1199     uMvCalcConfig |= F_ENCODE(3, TOPAZHP_CR_MVCALC_GRID_SUB_STEP);
   1200     uMvCalcConfig |= F_ENCODE(1, TOPAZHP_CR_MVCALC_GRID_DISABLE);
   1201 
   1202     if (bSkipDuplicateVectors)
   1203         uMvCalcConfig |= F_ENCODE(1, TOPAZHP_CR_MVCALC_NO_PSEUDO_DUPLICATES);
   1204 
   1205     * pui32MVCalc_Below =   uMvCalcBelow;
   1206     * pui32MVCalc_Colocated = uMvCalcColocated;
   1207     * pui32MVCalc_Config = uMvCalcConfig;
   1208 }
   1209 
   1210 static void tng__prepare_mv_estimates(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
   1211 {
   1212     context_ENC_mem* ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
   1213     IMG_MTX_VIDEO_CONTEXT* psMtxEncCtx = NULL;
   1214     IMG_UINT32 ui32Distance;
   1215 
   1216     psb_buffer_map(&(ps_mem->bufs_mtx_context), &(ps_mem->bufs_mtx_context.virtual_addr));
   1217     if (ps_mem->bufs_mtx_context.virtual_addr == NULL) {
   1218         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping mtx context\n", __FUNCTION__);
   1219         return ;
   1220     }
   1221 
   1222     psMtxEncCtx = (IMG_MTX_VIDEO_CONTEXT*)(ps_mem->bufs_mtx_context.virtual_addr);
   1223 
   1224     /* IDR */
   1225     psMtxEncCtx->sMVSettingsIdr.ui32MVCalc_Config = DEFAULT_MVCALC_CONFIG;  // default based on TRM
   1226     psMtxEncCtx->sMVSettingsIdr.ui32MVCalc_Colocated = 0x00100100;// default based on TRM
   1227     psMtxEncCtx->sMVSettingsIdr.ui32MVCalc_Below = 0x01000100;      // default based on TRM
   1228 
   1229     tng_update_driver_mv_scaling(
   1230         0, 0, 0, 0, IMG_FALSE, //psMtxEncCtx->bSkipDuplicateVectors, //By default false Newly Added
   1231         &psMtxEncCtx->sMVSettingsIdr.ui32MVCalc_Below,
   1232         &psMtxEncCtx->sMVSettingsIdr.ui32MVCalc_Colocated,
   1233         &psMtxEncCtx->sMVSettingsIdr.ui32MVCalc_Config);
   1234 
   1235     /* NonB (I or P) */
   1236     for (ui32Distance = 1; ui32Distance <= MAX_BFRAMES + 1; ui32Distance++) {
   1237         psMtxEncCtx->sMVSettingsNonB[ui32Distance - 1].ui32MVCalc_Config = DEFAULT_MVCALC_CONFIG;       // default based on TRM
   1238         psMtxEncCtx->sMVSettingsNonB[ui32Distance - 1].ui32MVCalc_Colocated = 0x00100100;// default based on TRM
   1239         psMtxEncCtx->sMVSettingsNonB[ui32Distance - 1].ui32MVCalc_Below = 0x01000100;   // default based on TRM
   1240 
   1241 
   1242         tng_update_driver_mv_scaling(ui32Distance, 0, 0, 0, IMG_FALSE, //psMtxEncCtx->bSkipDuplicateVectors,
   1243                                      &psMtxEncCtx->sMVSettingsNonB[ui32Distance - 1].ui32MVCalc_Below,
   1244                                      &psMtxEncCtx->sMVSettingsNonB[ui32Distance - 1].ui32MVCalc_Colocated,
   1245                                      &psMtxEncCtx->sMVSettingsNonB[ui32Distance - 1].ui32MVCalc_Config);
   1246     }
   1247 
   1248     {
   1249         IMG_UINT32 ui32DistanceB;
   1250         IMG_UINT32 ui32Position;
   1251         context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
   1252         IMG_MV_SETTINGS *pHostMVSettingsHierarchical = NULL;
   1253         IMG_MV_SETTINGS *pMvElement = NULL;
   1254         IMG_MV_SETTINGS *pHostMVSettingsBTable = NULL;
   1255 
   1256         psb_buffer_map(&(ps_mem->bufs_mv_setting_btable), &(ps_mem->bufs_mv_setting_btable.virtual_addr));
   1257         if (ps_mem->bufs_mv_setting_btable.virtual_addr == NULL) {
   1258             drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping mv setting btable\n", __FUNCTION__);
   1259             return ;
   1260         }
   1261 
   1262         pHostMVSettingsBTable = (IMG_MV_SETTINGS *)(ps_mem->bufs_mv_setting_btable.virtual_addr);
   1263 
   1264         for (ui32DistanceB = 0; ui32DistanceB < MAX_BFRAMES; ui32DistanceB++) {
   1265             for (ui32Position = 1; ui32Position <= ui32DistanceB + 1; ui32Position++) {
   1266                 pMvElement = (IMG_MV_SETTINGS * ) ((IMG_UINT8 *) pHostMVSettingsBTable + MV_OFFSET_IN_TABLE(ui32DistanceB, ui32Position - 1));
   1267                 pMvElement->ui32MVCalc_Config= (DEFAULT_MVCALC_CONFIG|MASK_TOPAZHP_CR_MVCALC_GRID_DISABLE);    // default based on TRM
   1268                 pMvElement->ui32MVCalc_Colocated=0x00100100;// default based on TRM
   1269                 pMvElement->ui32MVCalc_Below=0x01000100;	// default based on TRM
   1270 
   1271                 tng_update_driver_mv_scaling(
   1272                     ui32Position, ui32DistanceB + 2, 0, ISINTERB_FLAGS, IMG_FALSE,
   1273                     &pMvElement->ui32MVCalc_Below,
   1274                     &pMvElement->ui32MVCalc_Colocated,
   1275                     &pMvElement->ui32MVCalc_Config);
   1276             }
   1277         }
   1278 
   1279         if (ctx->b_is_mv_setting_hierar){
   1280             pHostMVSettingsHierarchical = (IMG_MV_SETTINGS *)(ps_mem->bufs_mv_setting_hierar.virtual_addr);
   1281 
   1282             for (ui32DistanceB = 0; ui32DistanceB < MAX_BFRAMES; ui32DistanceB++) {
   1283                 pMvElement = (IMG_MV_SETTINGS * ) ((IMG_UINT8 *)pHostMVSettingsBTable + MV_OFFSET_IN_TABLE(ui32DistanceB, ui32DistanceB >> 1));
   1284                 //memcpy(pHostMVSettingsHierarchical + ui32DistanceB, , sizeof(IMG_MV_SETTINGS));
   1285                 pHostMVSettingsHierarchical[ui32DistanceB].ui32MVCalc_Config    = pMvElement->ui32MVCalc_Config;
   1286                 pHostMVSettingsHierarchical[ui32DistanceB].ui32MVCalc_Colocated = pMvElement->ui32MVCalc_Colocated;
   1287                 pHostMVSettingsHierarchical[ui32DistanceB].ui32MVCalc_Below     = pMvElement->ui32MVCalc_Below;
   1288             }
   1289         }
   1290         psb_buffer_unmap(&(ps_mem->bufs_mv_setting_btable));
   1291     }
   1292 
   1293     psb_buffer_unmap(&(ps_mem->bufs_mtx_context));
   1294 
   1295     return ;
   1296 }
   1297 
   1298 static void tng__adjust_picflags(
   1299     context_ENC_p ctx,
   1300     IMG_RC_PARAMS * psRCParams,
   1301     IMG_BOOL bFirstPic,
   1302     IMG_UINT32 * pui32Flags)
   1303 {
   1304     IMG_UINT32 ui32Flags;
   1305     PIC_PARAMS * psPicParams = &ctx->sPicParams;
   1306     ui32Flags = psPicParams->ui32Flags;
   1307 
   1308     if (!psRCParams->bRCEnable || (!bFirstPic))
   1309         ui32Flags = 0;
   1310 
   1311     switch (ctx->eStandard) {
   1312     case IMG_STANDARD_NONE:
   1313         break;
   1314     case IMG_STANDARD_H264:
   1315         break;
   1316     case IMG_STANDARD_H263:
   1317         ui32Flags |= ISH263_FLAGS;
   1318         break;
   1319     case IMG_STANDARD_MPEG4:
   1320         ui32Flags |= ISMPEG4_FLAGS;
   1321         break;
   1322     case IMG_STANDARD_MPEG2:
   1323         ui32Flags |= ISMPEG2_FLAGS;
   1324         break;
   1325     default:
   1326         break;
   1327     }
   1328     * pui32Flags = ui32Flags;
   1329 }
   1330 
   1331 #define gbLowLatency 0
   1332 
   1333 static void tng__setup_rcdata(context_ENC_p ctx)
   1334 {
   1335     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
   1336     PIC_PARAMS    *psPicParams = &(ctx->sPicParams);
   1337 
   1338     IMG_INT32 i32FrameRate, i32TmpQp;
   1339     double        L1, L2, L3,L4, L5, L6, flBpp;
   1340     IMG_INT32 i32BufferSizeInFrames;
   1341 
   1342     if (ctx->bInsertHRDParams &&
   1343        (ctx->eStandard == IMG_STANDARD_H264)) {
   1344        psRCParams->ui32BufferSize = ctx->buffer_size;
   1345        psRCParams->i32InitialLevel = ctx->buffer_size - ctx->initial_buffer_fullness;
   1346        psRCParams->i32InitialDelay = ctx->initial_buffer_fullness;
   1347     }
   1348 
   1349     // If Bit Rate and Basic Units are not specified then set to default values.
   1350     if (psRCParams->ui32BitsPerSecond == 0 && !ctx->bEnableMVC) {
   1351         psRCParams->ui32BitsPerSecond = 640000;     // kbps
   1352     }
   1353 
   1354     if (!psRCParams->ui32BUSize) {
   1355         psRCParams->ui32BUSize = (ctx->ui16PictureHeight>>4) * (ctx->ui16Width>>4);		// BU = 1 Frame
   1356     }
   1357 
   1358     if (!psRCParams->ui32FrameRate) {
   1359         psRCParams->ui32FrameRate = 30;		// fps
   1360     }
   1361 
   1362     // Calculate Bits Per Pixel
   1363     if (ctx->ui16Width <= 176 ) {
   1364         i32FrameRate    = 30;
   1365     } else {
   1366         i32FrameRate	= psRCParams->ui32FrameRate;
   1367     }
   1368 
   1369     flBpp = 1.0 * psRCParams->ui32BitsPerSecond / (i32FrameRate * ctx->ui16Width * ctx->ui16FrameHeight);
   1370 
   1371     psPicParams->sInParams.ui8SeInitQP          = psRCParams->ui32InitialQp;
   1372     psPicParams->sInParams.ui8MBPerRow      = (ctx->ui16Width>>4);
   1373     psPicParams->sInParams.ui16MBPerBU       = psRCParams->ui32BUSize;
   1374     psPicParams->sInParams.ui16MBPerFrm     = (ctx->ui16Width>>4) * (ctx->ui16PictureHeight>>4);
   1375     psPicParams->sInParams.ui16BUPerFrm      = (psPicParams->sInParams.ui16MBPerFrm) / psRCParams->ui32BUSize;
   1376 
   1377     psPicParams->sInParams.ui16IntraPeriod      = psRCParams->ui32IntraFreq;
   1378     psPicParams->sInParams.ui16BFrames         = psRCParams->ui16BFrames;
   1379     psPicParams->sInParams.i32BitRate             = psRCParams->ui32BitsPerSecond;
   1380 
   1381     psPicParams->sInParams.bFrmSkipDisable   = psRCParams->bDisableFrameSkipping;
   1382     psPicParams->sInParams.i32BitsPerFrm       = (psRCParams->ui32BitsPerSecond + psRCParams->ui32FrameRate/2) / psRCParams->ui32FrameRate;
   1383     psPicParams->sInParams.i32BitsPerBU         = psPicParams->sInParams.i32BitsPerFrm / (4 * psPicParams->sInParams.ui16BUPerFrm);
   1384 
   1385     // Codec-dependant fields
   1386     if (ctx->eStandard == IMG_STANDARD_H264) {
   1387         psPicParams->sInParams.mode.h264.i32TransferRate = (psRCParams->ui32TransferBitsPerSecond + psRCParams->ui32FrameRate/2) / psRCParams->ui32FrameRate;
   1388         psPicParams->sInParams.mode.h264.bHierarchicalMode =   psRCParams->b16Hierarchical;
   1389     } else {
   1390         psPicParams->sInParams.mode.other.i32BitsPerGOP      = (psRCParams->ui32BitsPerSecond / psRCParams->ui32FrameRate) * psRCParams->ui32IntraFreq;
   1391         psPicParams->sInParams.mode.other.ui16AvQPVal         = psRCParams->ui32InitialQp;
   1392         psPicParams->sInParams.mode.other.ui16MyInitQP         = psRCParams->ui32InitialQp;
   1393     }
   1394 
   1395 
   1396     if (psPicParams->sInParams.i32BitsPerFrm) {
   1397         i32BufferSizeInFrames = (psRCParams->ui32BufferSize + (psPicParams->sInParams.i32BitsPerFrm/2))/psPicParams->sInParams.i32BitsPerFrm;
   1398     } else {
   1399         IMG_ASSERT(ctx->bEnableMvc && "Can happen only in MVC mode");
   1400         /* Asigning more or less `normal` value. To be overriden by MVC RC module */
   1401         i32BufferSizeInFrames = 30;
   1402     }
   1403 
   1404     // select thresholds and initial Qps etc that are codec dependent
   1405     switch (ctx->eStandard) {
   1406         case IMG_STANDARD_H264:
   1407             L1 = 0.1;	L2 = 0.15;	L3 = 0.2;
   1408             psPicParams->sInParams.ui8MaxQPVal = 51;
   1409             ctx->ui32KickSize = psPicParams->sInParams.ui16MBPerBU;
   1410 
   1411             // Setup MAX and MIN Quant Values
   1412             if (psRCParams->iMinQP == 0) {
   1413                 if (flBpp >= 0.50)
   1414                     i32TmpQp = 4;
   1415                 else if (flBpp > 0.133)
   1416                     i32TmpQp = (IMG_INT32)(22 - (40*flBpp));
   1417                 else
   1418                     i32TmpQp = (IMG_INT32)(30 - (100 * flBpp));
   1419 
   1420                 /* Adjust minQp up for small buffer size and down for large buffer size */
   1421                 if (i32BufferSizeInFrames < 5) {
   1422                     i32TmpQp += 2;
   1423                 }
   1424 
   1425                 if (i32BufferSizeInFrames > 40) {
   1426                     if(i32TmpQp>=1)
   1427                         i32TmpQp -= 1;
   1428                 }
   1429                 /* for HD content allow a lower minQp as bitrate is more easily controlled in this case */
   1430                 if (psPicParams->sInParams.ui16MBPerFrm > 2000) {
   1431                         i32TmpQp -= 6;
   1432                 }
   1433             } else
   1434                 i32TmpQp = psRCParams->iMinQP;
   1435 
   1436             if (i32TmpQp < 2) {
   1437                 psPicParams->sInParams.ui8MinQPVal = 2;
   1438             } else {
   1439                 psPicParams->sInParams.ui8MinQPVal = i32TmpQp;
   1440             }
   1441 
   1442             // Calculate Initial QP if it has not been specified
   1443             i32TmpQp = psPicParams->sInParams.ui8SeInitQP;
   1444             if (psPicParams->sInParams.ui8SeInitQP==0) {
   1445                 L1 = 0.050568;
   1446                 L2 = 0.202272;
   1447                 L3 = 0.40454321;
   1448                 L4 = 0.80908642;
   1449                 L5 = 1.011358025;
   1450 
   1451                 if (flBpp < L1)
   1452                     i32TmpQp = (IMG_INT32)(45 - 78.10*flBpp);
   1453                 else if (flBpp>=L1 && flBpp<L2)
   1454                     i32TmpQp = (IMG_INT32)(44 - 72.51*flBpp);
   1455                 else if (flBpp>=L2 && flBpp<L3)
   1456                     i32TmpQp = (IMG_INT32)(34 - 24.72*flBpp);
   1457                 else if (flBpp>=L3 && flBpp<L4)
   1458                     i32TmpQp = (IMG_INT32)(32 - 19.78*flBpp);
   1459                 else if (flBpp>=L4 && flBpp<L5)
   1460                     i32TmpQp = (IMG_INT32)(25 - 9.89*flBpp);
   1461                 else if (flBpp>=L5)
   1462                     i32TmpQp = (IMG_INT32)(18 - 4.95*flBpp);
   1463 
   1464                 /* Adjust ui8SeInitQP up for small buffer size or small fps */
   1465                 /* Adjust ui8SeInitQP up for small gop size */
   1466                 if ((i32BufferSizeInFrames < 20) || (psRCParams->ui32IntraFreq < 20)) {
   1467                     i32TmpQp += 2;
   1468                 }
   1469 
   1470 		/* for very small buffers increase initial Qp even more */
   1471 		if(i32BufferSizeInFrames < 5)
   1472 		{
   1473 			i32TmpQp += 8;
   1474 		}
   1475 
   1476                 /* start on a lower initial Qp for HD content as the coding is more efficient */
   1477                 if (psPicParams->sInParams.ui16MBPerFrm > 2000) {
   1478                     i32TmpQp -= 2;
   1479                 }
   1480 
   1481 		if(psPicParams->sInParams.ui16IntraPeriod ==1)
   1482 		{
   1483 		    /* for very small GOPS start with a much higher initial Qp */
   1484 		    i32TmpQp += 12;
   1485 		} else if (psPicParams->sInParams.ui16IntraPeriod<5) {
   1486 		    /* for very small GOPS start with a much higher initial Qp */
   1487 		    i32TmpQp += 6;
   1488 		}
   1489             }
   1490             if (i32TmpQp>49) {
   1491                 i32TmpQp = 49;
   1492             }
   1493             if (i32TmpQp < psPicParams->sInParams.ui8MinQPVal) {
   1494                 i32TmpQp = psPicParams->sInParams.ui8MinQPVal;
   1495             }
   1496             psPicParams->sInParams.ui8SeInitQP = i32TmpQp;
   1497 
   1498             if(flBpp <= 0.3)
   1499                 psPicParams->ui32Flags |= ISRC_I16BIAS;
   1500 
   1501             break;
   1502 
   1503         case IMG_STANDARD_MPEG4:
   1504         case IMG_STANDARD_MPEG2:
   1505         case IMG_STANDARD_H263:
   1506             psPicParams->sInParams.ui8MaxQPVal	 = 31;
   1507             if (ctx->ui16Width == 176) {
   1508                 L1 = 0.042;    L2 = 0.084;    L3 = 0.126;    L4 = 0.168;    L5 = 0.336;    L6=0.505;
   1509             } else if (ctx->ui16Width == 352) {
   1510                 L1 = 0.064;    L2 = 0.084;    L3 = 0.106;    L4 = 0.126;    L5 = 0.168;    L6=0.210;
   1511             } else {
   1512                 L1 = 0.050;    L2 = 0.0760;    L3 = 0.096;   L4 = 0.145;    L5 = 0.193;    L6=0.289;
   1513             }
   1514 
   1515             if (psPicParams->sInParams.ui8SeInitQP==0) {
   1516                 if (flBpp < L1)
   1517                     psPicParams->sInParams.ui8SeInitQP = 31;
   1518                 else if (flBpp>=L1 && flBpp<L2)
   1519                     psPicParams->sInParams.ui8SeInitQP = 26;
   1520                 else if (flBpp>=L2 && flBpp<L3)
   1521                     psPicParams->sInParams.ui8SeInitQP = 22;
   1522                 else if (flBpp>=L3 && flBpp<L4)
   1523                     psPicParams->sInParams.ui8SeInitQP = 18;
   1524                 else if (flBpp>=L4 && flBpp<L5)
   1525                     psPicParams->sInParams.ui8SeInitQP = 14;
   1526                 else if (flBpp>=L5 && flBpp<L6)
   1527                     psPicParams->sInParams.ui8SeInitQP = 10;
   1528                 else
   1529                     psPicParams->sInParams.ui8SeInitQP = 8;
   1530 
   1531                 /* Adjust ui8SeInitQP up for small buffer size or small fps */
   1532                 /* Adjust ui8SeInitQP up for small gop size */
   1533                 if ((i32BufferSizeInFrames < 20) || (psRCParams->ui32IntraFreq < 20)) {
   1534                     psPicParams->sInParams.ui8SeInitQP += 2;
   1535                 }
   1536 
   1537                 if (psPicParams->sInParams.ui8SeInitQP > psPicParams->sInParams.ui8MaxQPVal) {
   1538                     psPicParams->sInParams.ui8SeInitQP = psPicParams->sInParams.ui8MaxQPVal;
   1539                 }
   1540                 psPicParams->sInParams.mode.other.ui16AvQPVal =  psPicParams->sInParams.ui8SeInitQP;
   1541             }
   1542             psPicParams->sInParams.ui8MinQPVal = 2;
   1543 
   1544             /* Adjust minQp up for small buffer size and down for large buffer size */
   1545             if (i32BufferSizeInFrames < 20) {
   1546                 psPicParams->sInParams.ui8MinQPVal += 1;
   1547             }
   1548             break;
   1549 
   1550         default:
   1551             /* the NO RC cases will fall here */
   1552             break;
   1553     }
   1554 
   1555     if (ctx->sRCParams.eRCMode == IMG_RCMODE_VBR) {
   1556         psPicParams->sInParams.ui16MBPerBU  = psPicParams->sInParams.ui16MBPerFrm;
   1557         psPicParams->sInParams.ui16BUPerFrm = 1;
   1558 
   1559         // Initialize the parameters of fluid flow traffic model.
   1560         psPicParams->sInParams.i32BufferSize   = psRCParams->ui32BufferSize;
   1561 
   1562 
   1563         // These scale factor are used only for rate control to avoid overflow
   1564         // in fixed-point calculation these scale factors are decided by bit rate
   1565         if (psRCParams->ui32BitsPerSecond < 640000) {
   1566             psPicParams->sInParams.ui8ScaleFactor  = 2;						// related to complexity
   1567         }
   1568         else if (psRCParams->ui32BitsPerSecond < 2000000) {
   1569             // 2 Mbits
   1570             psPicParams->sInParams.ui8ScaleFactor  = 4;
   1571         }
   1572         else if(psRCParams->ui32BitsPerSecond < 8000000) {
   1573             // 8 Mbits
   1574             psPicParams->sInParams.ui8ScaleFactor  = 6;
   1575         } else
   1576             psPicParams->sInParams.ui8ScaleFactor  = 8;
   1577     } else {
   1578         // Set up Input Parameters that are mode dependent
   1579         switch (ctx->eStandard) {
   1580             case IMG_STANDARD_H264:
   1581                 // ------------------- H264 CBR RC ------------------- //
   1582                 // Initialize the parameters of fluid flow traffic model.
   1583                 psPicParams->sInParams.i32BufferSize = psRCParams->ui32BufferSize;
   1584 
   1585                 // HRD consideration - These values are used by H.264 reference code.
   1586                 if (psRCParams->ui32BitsPerSecond < 1000000) {
   1587                 // 1 Mbits/s
   1588                     psPicParams->sInParams.ui8ScaleFactor = 0;
   1589                 } else if (psRCParams->ui32BitsPerSecond < 2000000) {
   1590                 // 2 Mbits/s
   1591                     psPicParams->sInParams.ui8ScaleFactor = 1;
   1592                 } else if (psRCParams->ui32BitsPerSecond < 4000000) {
   1593                 // 4 Mbits/s
   1594                     psPicParams->sInParams.ui8ScaleFactor = 2;
   1595                 } else if (psRCParams->ui32BitsPerSecond < 8000000) {
   1596                 // 8 Mbits/s
   1597                     psPicParams->sInParams.ui8ScaleFactor = 3;
   1598                 } else  {
   1599                     psPicParams->sInParams.ui8ScaleFactor = 4;
   1600                 }
   1601 
   1602                 if (ctx->sRCParams.eRCMode == IMG_RCMODE_VCM) {
   1603                     psPicParams->sInParams.i32BufferSize = i32BufferSizeInFrames;
   1604                 }
   1605                 break;
   1606             case IMG_STANDARD_MPEG4:
   1607             case IMG_STANDARD_MPEG2:
   1608             case IMG_STANDARD_H263:
   1609                 flBpp  = 256 * (psRCParams->ui32BitsPerSecond/ctx->ui16Width);
   1610                 flBpp /= (ctx->ui16FrameHeight * psRCParams->ui32FrameRate);
   1611 
   1612                 if ((psPicParams->sInParams.ui16MBPerFrm > 1024 && flBpp < 16) || (psPicParams->sInParams.ui16MBPerFrm <= 1024 && flBpp < 24))
   1613                     psPicParams->sInParams.mode.other.ui8HalfFrameRate = 1;
   1614                 else
   1615                     psPicParams->sInParams.mode.other.ui8HalfFrameRate = 0;
   1616 
   1617                 if (psPicParams->sInParams.mode.other.ui8HalfFrameRate >= 1) {
   1618                     psPicParams->sInParams.ui8SeInitQP = 31;
   1619                     psPicParams->sInParams.mode.other.ui16AvQPVal = 31;
   1620                     psPicParams->sInParams.mode.other.ui16MyInitQP = 31;
   1621                 }
   1622 
   1623                 psPicParams->sInParams.i32BufferSize = psRCParams->ui32BufferSize;
   1624                 break;
   1625             default:
   1626                 break;
   1627         }
   1628     }
   1629 
   1630     if (psRCParams->bScDetectDisable)
   1631         psPicParams->ui32Flags  |= ISSCENE_DISABLED;
   1632 
   1633     psPicParams->sInParams.i32InitialDelay	= psRCParams->i32InitialDelay;
   1634     psPicParams->sInParams.i32InitialLevel	= psRCParams->i32InitialLevel;
   1635     psRCParams->ui32InitialQp = psPicParams->sInParams.ui8SeInitQP;
   1636 
   1637     /* The rate control uses this value to adjust the reaction rate to larger than expected frames */
   1638     if (ctx->eStandard == IMG_STANDARD_H264) {
   1639         if (psPicParams->sInParams.i32BitsPerFrm) {
   1640             const IMG_INT32 bitsPerGop = (psRCParams->ui32BitsPerSecond / psRCParams->ui32FrameRate) * psRCParams->ui32IntraFreq;
   1641             psPicParams->sInParams.mode.h264.ui32RCScaleFactor = (bitsPerGop * 256) /
   1642                 (psPicParams->sInParams.i32BufferSize - psPicParams->sInParams.i32InitialLevel);
   1643         } else {
   1644             psPicParams->sInParams.mode.h264.ui32RCScaleFactor = 0;
   1645         }
   1646     } else {
   1647         psPicParams->sInParams.mode.other.ui16MyInitQP		= psPicParams->sInParams.ui8SeInitQP;
   1648     }
   1649 
   1650     return ;
   1651 }
   1652 
   1653 static void tng__save_slice_params_template(
   1654     context_ENC_p ctx,
   1655     IMG_UINT32  ui32SliceBufIdx,
   1656     IMG_UINT32  ui32SliceType,
   1657     IMG_UINT32  ui32IPEControl,
   1658     IMG_UINT32  ui32Flags,
   1659     IMG_UINT32  ui32SliceConfig,
   1660     IMG_UINT32  ui32SeqConfig,
   1661     IMG_UINT32  ui32StreamIndex
   1662 )
   1663 {
   1664     IMG_FRAME_TEMPLATE_TYPE eSliceType = (IMG_FRAME_TEMPLATE_TYPE)ui32SliceType;
   1665     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
   1666     SLICE_PARAMS *slice_temp_p = NULL;
   1667 
   1668     psb_buffer_map(&(ps_mem->bufs_slice_template), &(ps_mem->bufs_slice_template.virtual_addr));
   1669     if (ps_mem->bufs_slice_template.virtual_addr == NULL) {
   1670         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping slice template\n", __FUNCTION__);
   1671         return ;
   1672     }
   1673 
   1674     slice_temp_p = (SLICE_PARAMS*)(ps_mem->bufs_slice_template.virtual_addr + (ctx->ctx_mem_size.slice_template * ui32SliceBufIdx));
   1675 
   1676     slice_temp_p->eTemplateType = eSliceType;
   1677     slice_temp_p->ui32Flags = ui32Flags;
   1678     slice_temp_p->ui32IPEControl = ui32IPEControl;
   1679     slice_temp_p->ui32SliceConfig = ui32SliceConfig;
   1680     slice_temp_p->ui32SeqConfig = ui32SeqConfig;
   1681 
   1682     psb_buffer_unmap(&(ps_mem->bufs_slice_template));
   1683 
   1684     return ;
   1685 }
   1686 
   1687 
   1688 /*****************************************************************************
   1689  * Function Name        :       PrepareEncodeSliceParams
   1690  *
   1691  ****************************************************************************/
   1692 static IMG_UINT32 tng__prepare_encode_sliceparams(
   1693     context_ENC_p ctx,
   1694     IMG_UINT32  ui32SliceBufIdx,
   1695     IMG_UINT32  ui32SliceType,
   1696     IMG_UINT16  __maybe_unused ui16CurrentRow,
   1697     IMG_UINT16  ui16SliceHeight,
   1698     IMG_UINT8   uiDeblockIDC,
   1699     IMG_BOOL    bFieldMode,
   1700     IMG_INT     iFineYSearchSize,
   1701     IMG_UINT32  ui32StreamIndex
   1702 )
   1703 {
   1704     IMG_UINT32      ui32FrameStoreFormat;
   1705     IMG_UINT8       ui8SwapChromas;
   1706     IMG_UINT32      ui32MBsPerKick, ui32KicksPerSlice;
   1707     IMG_UINT32      ui32IPEControl;
   1708     IMG_UINT32      ui32Flags = 0;
   1709     IMG_UINT32      ui32SliceConfig = 0;
   1710     IMG_UINT32      ui32SeqConfig = 0;
   1711     IMG_BOOL bIsIntra = IMG_FALSE;
   1712     IMG_BOOL bIsBPicture = IMG_FALSE;
   1713     IMG_BOOL bIsIDR = IMG_FALSE;
   1714     IMG_IPE_MINBLOCKSIZE blkSz;
   1715     IMG_FRAME_TEMPLATE_TYPE eSliceType = (IMG_FRAME_TEMPLATE_TYPE)ui32SliceType;
   1716 
   1717     if (!ctx) {
   1718         return VA_STATUS_ERROR_INVALID_CONTEXT;
   1719     }
   1720 
   1721     /* We want multiple ones of these so we can submit multiple slices without having to wait for the next*/
   1722     ui32IPEControl = ctx->ui32IPEControl;
   1723     bIsIntra = ((eSliceType == IMG_FRAME_IDR) || (eSliceType == IMG_FRAME_INTRA));
   1724     bIsBPicture = (eSliceType == IMG_FRAME_INTER_B);
   1725     bIsIDR = ((eSliceType == IMG_FRAME_IDR) || (eSliceType == IMG_FRAME_INTER_P_IDR));
   1726 
   1727     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bIsIntra  = %x\n", __FUNCTION__, bIsIntra);
   1728     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bIsBFrame = %x\n", __FUNCTION__, bIsBPicture);
   1729     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bIsIDR    = %x\n", __FUNCTION__, bIsIDR);
   1730     /* extract block size */
   1731     blkSz = F_EXTRACT(ui32IPEControl, TOPAZHP_CR_IPE_BLOCKSIZE);
   1732     /* mask-out the block size bits from ui32IPEControl */
   1733     ui32IPEControl &= ~(F_MASK(TOPAZHP_CR_IPE_BLOCKSIZE));
   1734     switch (ctx->eStandard) {
   1735     case IMG_STANDARD_NONE:
   1736     case IMG_STANDARD_JPEG:
   1737         break;
   1738 
   1739     case IMG_STANDARD_H264:
   1740         if (blkSz > 2) blkSz = 2;
   1741         if (bIsBPicture) {
   1742             if (blkSz > 1) blkSz = 1;
   1743         }
   1744 #ifdef BRN_30322
   1745         else if (bIsIntra) {
   1746             if (blkSz == 0) blkSz = 1; // Workaround for BRN 30322
   1747         }
   1748 #endif
   1749 
   1750 #ifdef BRN_30550
   1751         if (ctx->bCabacEnabled)
   1752             if (blkSz == 0) blkSz = 1;
   1753 #endif
   1754         if (ctx->uMBspS >= _1080P_30FPS) {
   1755             ui32IPEControl |= F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
   1756                               F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH);
   1757         } else {
   1758             ui32IPEControl |= F_ENCODE(iFineYSearchSize + 1, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
   1759                               F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH);
   1760 
   1761         }
   1762         if (ctx->bLimitNumVectors)
   1763             ui32IPEControl |= F_ENCODE(1, TOPAZHP_CR_IPE_MV_NUMBER_RESTRICTION);
   1764         break;
   1765 
   1766     case IMG_STANDARD_H263:
   1767         blkSz = 0;
   1768         ui32IPEControl = F_ENCODE(iFineYSearchSize + 1, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
   1769                          F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH) |
   1770                          F_ENCODE(0, TOPAZHP_CR_IPE_4X4_SEARCH);
   1771         //We only support a maxium vector of 15.5 pixels in H263
   1772         break;
   1773 
   1774     case IMG_STANDARD_MPEG4:
   1775         if (blkSz > BLK_SZ_8x8) blkSz = BLK_SZ_8x8;
   1776         ui32IPEControl |= F_ENCODE(iFineYSearchSize + 1, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
   1777                           F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH) |
   1778                           F_ENCODE(0, TOPAZHP_CR_IPE_4X4_SEARCH);
   1779         // FIXME Should be 1, set to zero for hardware testing.
   1780         break;
   1781     case IMG_STANDARD_MPEG2:
   1782         if (blkSz != BLK_SZ_16x16) blkSz = BLK_SZ_16x16;
   1783         ui32IPEControl |= F_ENCODE(iFineYSearchSize + 1, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
   1784                           F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH) |
   1785                           F_ENCODE(0, TOPAZHP_CR_IPE_4X4_SEARCH);
   1786         // FIXME Should be 1, set to zero for hardware testing.
   1787         break;
   1788     }
   1789 
   1790     {
   1791         IMG_BOOL bRestrict4x4SearchSize;
   1792         IMG_UINT32 uLritcBoundary;
   1793 
   1794         if (ctx->uMBspS >= _1080P_30FPS)
   1795             bRestrict4x4SearchSize = 1;
   1796         else
   1797             bRestrict4x4SearchSize = 0;
   1798 
   1799         ui32IPEControl |= F_ENCODE(blkSz, TOPAZHP_CR_IPE_BLOCKSIZE);
   1800         uLritcBoundary = (blkSz != BLK_SZ_16x16) ? (iFineYSearchSize + (bRestrict4x4SearchSize ? 0 : 1)) : 1;
   1801         if (uLritcBoundary > 3) {
   1802             return VA_STATUS_ERROR_UNKNOWN;
   1803         }
   1804 
   1805         /* Minium sub block size to calculate motion vectors for. 0=16x16, 1=8x8, 2=4x4 */
   1806         ui32IPEControl = F_INSERT(ui32IPEControl, blkSz, TOPAZHP_CR_IPE_BLOCKSIZE);
   1807         ui32IPEControl = F_INSERT(ui32IPEControl, iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH);
   1808         ui32IPEControl = F_INSERT(ui32IPEControl, ctx->bLimitNumVectors, TOPAZHP_CR_IPE_MV_NUMBER_RESTRICTION);
   1809 
   1810         ui32IPEControl = F_INSERT(ui32IPEControl, uLritcBoundary, TOPAZHP_CR_IPE_LRITC_BOUNDARY);  // 8x8 search
   1811         ui32IPEControl = F_INSERT(ui32IPEControl, bRestrict4x4SearchSize ? 0 : 1, TOPAZHP_CR_IPE_4X4_SEARCH);
   1812 
   1813     }
   1814     ui32IPEControl = F_INSERT(ui32IPEControl, ctx->bHighLatency, TOPAZHP_CR_IPE_HIGH_LATENCY);
   1815 //              psSliceParams->ui32IPEControl = ui32IPEControl;
   1816 
   1817     if (!bIsIntra) {
   1818         if (bIsBPicture)
   1819             ui32Flags |= ISINTERB_FLAGS;
   1820         else
   1821             ui32Flags |= ISINTERP_FLAGS;
   1822     }
   1823     switch (ctx->eStandard)  {
   1824     case IMG_STANDARD_NONE:
   1825         break;
   1826     case IMG_STANDARD_H263:
   1827         ui32Flags |= ISH263_FLAGS;
   1828         break;
   1829     case IMG_STANDARD_MPEG4:
   1830         ui32Flags |= ISMPEG4_FLAGS;
   1831         break;
   1832     case IMG_STANDARD_MPEG2:
   1833         ui32Flags |= ISMPEG2_FLAGS;
   1834         break;
   1835     default:
   1836         break;
   1837     }
   1838 
   1839     if (ctx->bMultiReferenceP && !(bIsIntra || bIsBPicture))
   1840         ui32Flags |= ISMULTIREF_FLAGS;
   1841     if (ctx->bSpatialDirect && bIsBPicture)
   1842         ui32Flags |= SPATIALDIRECT_FLAGS;
   1843 
   1844     if (bIsIntra) {
   1845         ui32SliceConfig = F_ENCODE(TOPAZHP_CR_SLICE_TYPE_I_SLICE, TOPAZHP_CR_SLICE_TYPE);
   1846     } else {
   1847         if (bIsBPicture) {
   1848             ui32SliceConfig = F_ENCODE(TOPAZHP_CR_SLICE_TYPE_B_SLICE, TOPAZHP_CR_SLICE_TYPE);
   1849         } else {
   1850             // p frame
   1851             ui32SliceConfig = F_ENCODE(TOPAZHP_CR_SLICE_TYPE_P_SLICE, TOPAZHP_CR_SLICE_TYPE);
   1852         }
   1853     }
   1854 
   1855     ui32MBsPerKick = ctx->ui32KickSize;
   1856     // we need to figure out the number of kicks and mb's per kick to use.
   1857     // on H.264 we will use a MB's per kick of basic unit
   1858     // on other rc varients we will use mb's per kick of width
   1859     ui32KicksPerSlice = ((ui16SliceHeight / 16) * (ctx->ui16Width / 16)) / ui32MBsPerKick;
   1860     assert((ui32KicksPerSlice * ui32MBsPerKick) == ((ui16SliceHeight / 16)*(ctx->ui16Width / 16)));
   1861 
   1862     // need some sensible ones don't look to be implemented yet...
   1863     // change per stream
   1864 
   1865     if ((ctx->eFormat == IMG_CODEC_UY0VY1_8888) || (ctx->eFormat == IMG_CODEC_VY0UY1_8888))
   1866         ui32FrameStoreFormat = 3;
   1867     else if ((ctx->eFormat == IMG_CODEC_Y0UY1V_8888) || (ctx->eFormat == IMG_CODEC_Y0VY1U_8888))
   1868         ui32FrameStoreFormat = 2;
   1869     else if ((ctx->eFormat == IMG_CODEC_PL12) || (ctx->eFormat == IMG_CODEC_422_PL12))
   1870         ui32FrameStoreFormat = 1;
   1871     else
   1872         ui32FrameStoreFormat = 0;
   1873 
   1874     if ((ctx->eFormat == IMG_CODEC_VY0UY1_8888) || (ctx->eFormat == IMG_CODEC_Y0VY1U_8888))
   1875         ui8SwapChromas = 1;
   1876     else
   1877         ui8SwapChromas = 0;
   1878 
   1879     switch (ctx->eStandard) {
   1880     case IMG_STANDARD_NONE:
   1881     case IMG_STANDARD_JPEG:
   1882         break;
   1883     case IMG_STANDARD_H264:
   1884         /* H264 */
   1885 
   1886         ui32SeqConfig = F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC0_BELOW_IN_VALID)
   1887                         | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
   1888                         | F_ENCODE(0, TOPAZHP_CR_ABOVE_OUT_OF_SLICE_VALID)
   1889                         | F_ENCODE(1, TOPAZHP_CR_WRITE_TEMPORAL_PIC0_BELOW_VALID)
   1890                         | F_ENCODE(0, TOPAZHP_CR_REF_PIC0_VALID)
   1891                         | F_ENCODE(0, TOPAZHP_CR_REF_PIC1_VALID)
   1892                         | F_ENCODE(!bIsBPicture, TOPAZHP_CR_REF_PIC1_EQUAL_PIC0)
   1893                         | F_ENCODE(bFieldMode ? 1 : 0 , TOPAZHP_CR_FIELD_MODE)
   1894                         | F_ENCODE(ui8SwapChromas, TOPAZHP_CR_FRAME_STORE_CHROMA_SWAP)
   1895                         | F_ENCODE(ui32FrameStoreFormat, TOPAZHP_CR_FRAME_STORE_FORMAT)
   1896                         | F_ENCODE(TOPAZHP_CR_ENCODER_STANDARD_H264, TOPAZHP_CR_ENCODER_STANDARD)
   1897                         | F_ENCODE(uiDeblockIDC == 1 ? 0 : 1, TOPAZHP_CR_DEBLOCK_ENABLE);
   1898 
   1899         if (ctx->sRCParams.ui16BFrames) {
   1900             ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_WRITE_TEMPORAL_COL_VALID);
   1901             if ((ui32Flags & ISINTERB_FLAGS) == ISINTERB_FLAGS)
   1902                 ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_TEMPORAL_COL_IN_VALID);
   1903         }
   1904 
   1905         if (!bIsBPicture) {
   1906             ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_WRITE_TEMPORAL_COL_VALID);
   1907         }
   1908 
   1909         break;
   1910     case IMG_STANDARD_MPEG4:
   1911         /* MPEG4 */
   1912         ui32SeqConfig = F_ENCODE(1, TOPAZHP_CR_WRITE_RECON_PIC)
   1913                         | F_ENCODE(0, TOPAZHP_CR_DEBLOCK_ENABLE)
   1914                         | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC0_BELOW_IN_VALID)
   1915                         | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
   1916                         | F_ENCODE(0, TOPAZHP_CR_ABOVE_OUT_OF_SLICE_VALID)
   1917                         | F_ENCODE(((ui32Flags & ISINTERP_FLAGS) == ISINTERP_FLAGS), TOPAZHP_CR_WRITE_TEMPORAL_PIC0_BELOW_VALID)
   1918                         | F_ENCODE(0, TOPAZHP_CR_REF_PIC0_VALID)
   1919                         | F_ENCODE(0, TOPAZHP_CR_REF_PIC1_VALID)
   1920                         | F_ENCODE(1, TOPAZHP_CR_REF_PIC1_EQUAL_PIC0)
   1921                         | F_ENCODE(0, TOPAZHP_CR_FIELD_MODE)
   1922                         | F_ENCODE(ui8SwapChromas, TOPAZHP_CR_FRAME_STORE_CHROMA_SWAP)
   1923                         | F_ENCODE(ui32FrameStoreFormat, TOPAZHP_CR_FRAME_STORE_FORMAT)
   1924                         | F_ENCODE(TOPAZHP_CR_ENCODER_STANDARD_MPEG4, TOPAZHP_CR_ENCODER_STANDARD);
   1925         break;
   1926     case IMG_STANDARD_MPEG2:
   1927         /* MPEG2 */
   1928         ui32SeqConfig = F_ENCODE(1, TOPAZHP_CR_WRITE_RECON_PIC)
   1929                         | F_ENCODE(0, TOPAZHP_CR_DEBLOCK_ENABLE)
   1930                         | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC0_BELOW_IN_VALID)
   1931                         | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
   1932                         | F_ENCODE(0, TOPAZHP_CR_ABOVE_OUT_OF_SLICE_VALID)
   1933                         | F_ENCODE(((ui32Flags & ISINTERP_FLAGS) == ISINTERP_FLAGS), TOPAZHP_CR_WRITE_TEMPORAL_PIC0_BELOW_VALID)
   1934                         | F_ENCODE(1, TOPAZHP_CR_REF_PIC0_VALID)
   1935                         | F_ENCODE(0, TOPAZHP_CR_REF_PIC1_VALID)
   1936                         | F_ENCODE(1, TOPAZHP_CR_REF_PIC1_EQUAL_PIC0)
   1937                         | F_ENCODE(bFieldMode ? 1 : 0 , TOPAZHP_CR_FIELD_MODE)
   1938                         | F_ENCODE(ui8SwapChromas, TOPAZHP_CR_FRAME_STORE_CHROMA_SWAP)
   1939                         | F_ENCODE(ui32FrameStoreFormat, TOPAZHP_CR_FRAME_STORE_FORMAT)
   1940                         | F_ENCODE(TOPAZHP_CR_ENCODER_STANDARD_MPEG2, TOPAZHP_CR_ENCODER_STANDARD);
   1941         break;
   1942     case IMG_STANDARD_H263:
   1943         /* H263 */
   1944         ui32SeqConfig = F_ENCODE(1, TOPAZHP_CR_WRITE_RECON_PIC)
   1945                         | F_ENCODE(0, TOPAZHP_CR_DEBLOCK_ENABLE)
   1946                         | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC0_BELOW_IN_VALID)
   1947                         | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
   1948                         | F_ENCODE(0, TOPAZHP_CR_ABOVE_OUT_OF_SLICE_VALID)
   1949                         | F_ENCODE(((ui32Flags & ISINTERP_FLAGS) == ISINTERP_FLAGS), TOPAZHP_CR_WRITE_TEMPORAL_PIC0_BELOW_VALID)
   1950                         | F_ENCODE(0, TOPAZHP_CR_REF_PIC0_VALID)
   1951                         | F_ENCODE(0, TOPAZHP_CR_REF_PIC1_VALID)
   1952                         | F_ENCODE(1, TOPAZHP_CR_REF_PIC1_EQUAL_PIC0)
   1953                         | F_ENCODE(0, TOPAZHP_CR_FIELD_MODE)
   1954                         | F_ENCODE(ui8SwapChromas, TOPAZHP_CR_FRAME_STORE_CHROMA_SWAP)
   1955                         | F_ENCODE(ui32FrameStoreFormat, TOPAZHP_CR_FRAME_STORE_FORMAT)
   1956                         | F_ENCODE(TOPAZHP_CR_ENCODER_STANDARD_H263, TOPAZHP_CR_ENCODER_STANDARD);
   1957         break;
   1958     }
   1959 
   1960     if (bIsBPicture)        {
   1961         ui32SeqConfig |= F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
   1962                          | F_ENCODE(0, TOPAZHP_CR_WRITE_TEMPORAL_PIC1_BELOW_VALID)
   1963                          | F_ENCODE(1, TOPAZHP_CR_REF_PIC1_VALID)
   1964                          | F_ENCODE(1, TOPAZHP_CR_TEMPORAL_COL_IN_VALID);
   1965     }
   1966 
   1967     if (ctx->ui8EnableSelStatsFlags & ESF_FIRST_STAGE_STATS)        {
   1968         ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_WRITE_MB_FIRST_STAGE_VALID);
   1969     }
   1970 
   1971     if (ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MB_DECISION_STATS ||
   1972         ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MOTION_VECTOR_STATS)  {
   1973         ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_BEST_MULTIPASS_OUT_VALID);
   1974 
   1975         if (!(ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MOTION_VECTOR_STATS)) {
   1976             ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_BEST_MVS_OUT_DISABLE);// 64 Byte Best Multipass Motion Vector output disabled by default
   1977         }
   1978     }
   1979 
   1980     if (ctx->bEnableInpCtrl) {
   1981         ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_MB_CONTROL_IN_VALID);
   1982     }
   1983 
   1984     if (eSliceType == IMG_FRAME_IDR) {
   1985         ctx->sBiasTables.ui32SeqConfigInit = ui32SeqConfig;
   1986     }
   1987 
   1988     tng__save_slice_params_template(ctx, ui32SliceBufIdx, eSliceType,
   1989         ui32IPEControl, ui32Flags, ui32SliceConfig, ui32SeqConfig, ui32StreamIndex);
   1990 
   1991     return 0;
   1992 }
   1993 
   1994 void tng__mpeg4_generate_pic_hdr_template(
   1995     context_ENC_p ctx,
   1996     IMG_FRAME_TEMPLATE_TYPE ui8SliceType,
   1997     IMG_UINT8 ui8Search_range)
   1998 {
   1999     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
   2000     MTX_HEADER_PARAMS * pPicHeaderMem;
   2001     VOP_CODING_TYPE eVop_Coding_Type;
   2002     IMG_BOOL8 b8IsVopCoded;
   2003     IMG_UINT8 ui8OriginalSliceType = ui8SliceType;
   2004 
   2005     /* MPEG4: We do not support B-frames at the moment, so we use a spare slot, to store a template for the skipped frame */
   2006     if (ui8SliceType == IMG_FRAME_INTER_B)
   2007     {
   2008 	ui8SliceType = IMG_FRAME_INTER_P;
   2009 	b8IsVopCoded = IMG_FALSE;
   2010     } else {
   2011 	b8IsVopCoded = IMG_TRUE;
   2012     }
   2013 
   2014     eVop_Coding_Type = (ui8SliceType == IMG_FRAME_INTER_P) ? P_FRAME : I_FRAME;
   2015 
   2016     psb_buffer_map(&(ps_mem->bufs_pic_template), &(ps_mem->bufs_pic_template.virtual_addr));
   2017     if (ps_mem->bufs_pic_template.virtual_addr == NULL) {
   2018         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping pic template\n", __FUNCTION__);
   2019         return ;
   2020     }
   2021 
   2022     pPicHeaderMem = (MTX_HEADER_PARAMS *)((IMG_UINT8*)(ps_mem->bufs_pic_template.virtual_addr + (ctx->ctx_mem_size.pic_template * ui8OriginalSliceType)));
   2023     //todo fix time resolution
   2024     tng__MPEG4_notforsims_prepare_vop_header(pPicHeaderMem, b8IsVopCoded, ui8Search_range, eVop_Coding_Type);
   2025     psb_buffer_unmap(&(ps_mem->bufs_pic_template));
   2026 
   2027 }
   2028 
   2029 void tng__h263_generate_pic_hdr_template(
   2030     context_ENC_p ctx,
   2031     IMG_FRAME_TEMPLATE_TYPE eFrameType,
   2032     IMG_UINT16 ui16Width,
   2033     IMG_UINT16 ui16Heigh)
   2034 
   2035 {
   2036     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
   2037     MTX_HEADER_PARAMS * pPicHeaderMem = NULL;
   2038     H263_PICTURE_CODING_TYPE ePictureCodingType = ((eFrameType == IMG_FRAME_INTRA)|| (eFrameType == IMG_FRAME_IDR)) ? I_FRAME : P_FRAME;
   2039 
   2040     psb_buffer_map(&(ps_mem->bufs_pic_template), &(ps_mem->bufs_pic_template.virtual_addr));
   2041     if (ps_mem->bufs_pic_template.virtual_addr == NULL) {
   2042         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping pic template\n", __FUNCTION__);
   2043         return ;
   2044     }
   2045 
   2046     pPicHeaderMem = (MTX_HEADER_PARAMS *)((IMG_UINT8*)(ps_mem->bufs_pic_template.virtual_addr + (ctx->ctx_mem_size.pic_template * eFrameType)));
   2047 
   2048     IMG_UINT8 ui8FrameRate = (IMG_UINT8)ctx->sRCParams.ui32FrameRate;
   2049 
   2050     // Get a pointer to the memory the header will be written to
   2051     tng__H263_notforsims_prepare_video_pictureheader(
   2052         pPicHeaderMem,
   2053         ePictureCodingType,
   2054         ctx->ui8H263SourceFormat,
   2055         ui8FrameRate,
   2056         ui16Width,
   2057         ui16Heigh);
   2058 
   2059     psb_buffer_unmap(&(ps_mem->bufs_pic_template));
   2060 
   2061 }
   2062 
   2063 
   2064 static void tng__MPEG4ES_send_seq_header(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
   2065 {
   2066     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
   2067     tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
   2068 
   2069     psb_buffer_map(&(ps_mem->bufs_seq_header), &(ps_mem->bufs_seq_header.virtual_addr));
   2070     if (ps_mem->bufs_seq_header.virtual_addr == NULL) {
   2071         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping seq template\n", __FUNCTION__);
   2072         return ;
   2073     }
   2074 
   2075     tng__MPEG4_prepare_sequence_header(ps_mem->bufs_seq_header.virtual_addr,
   2076                                        IMG_FALSE,//FIXME: Zhaohan bFrame
   2077                                        ctx->ui8ProfileIdc,//profile
   2078                                        ctx->ui8LevelIdc,//ui8Profile_lvl_indication
   2079                                        3,//ui8Fixed_vop_time_increment
   2080                                        ctx->obj_context->picture_width,//ui8Fixed_vop_time_increment
   2081                                        ctx->obj_context->picture_height,//ui32Picture_Height_Pixels
   2082                                        NULL,//VBVPARAMS
   2083                                        ctx->ui32VopTimeResolution);
   2084     psb_buffer_unmap(&(ps_mem->bufs_seq_header));
   2085 
   2086     cmdbuf->cmd_idx_saved[TNG_CMDBUF_SEQ_HEADER_IDX] = cmdbuf->cmd_idx;
   2087 }
   2088 
   2089 static void tng__H264ES_send_seq_header(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
   2090 {
   2091     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
   2092     tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
   2093     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
   2094     H264_VUI_PARAMS *psVuiParams = &(ctx->sVuiParams);
   2095 
   2096 //    memset(psVuiParams, 0, sizeof(H264_VUI_PARAMS));
   2097 
   2098     if (psRCParams->eRCMode != IMG_RCMODE_NONE) {
   2099         psVuiParams->vui_flag = 1;
   2100         if (psVuiParams->num_units_in_tick == 0 || psVuiParams->Time_Scale == 0) {
   2101             psVuiParams->num_units_in_tick = 1;
   2102             psVuiParams->Time_Scale = psRCParams->ui32FrameRate * 2;
   2103         }
   2104         psVuiParams->bit_rate_value_minus1 = psRCParams->ui32BitsPerSecond / 64 - 1;
   2105         psVuiParams->cbp_size_value_minus1 = psRCParams->ui32BufferSize / 64 - 1;
   2106         psVuiParams->CBR = ((psRCParams->eRCMode == IMG_RCMODE_CBR) && (!psRCParams->bDisableBitStuffing)) ? 1 : 0;
   2107         psVuiParams->initial_cpb_removal_delay_length_minus1 = BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY_SIZE - 1;
   2108         psVuiParams->cpb_removal_delay_length_minus1 = PTH_SEI_NAL_CPB_REMOVAL_DELAY_SIZE - 1;
   2109         psVuiParams->dpb_output_delay_length_minus1 = PTH_SEI_NAL_DPB_OUTPUT_DELAY_SIZE - 1;
   2110         psVuiParams->time_offset_length = 24;
   2111     }
   2112     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s psVuiParams->vui_flag = %d\n", __FUNCTION__, psVuiParams->vui_flag);
   2113 
   2114     psb_buffer_map(&(ps_mem->bufs_seq_header), &(ps_mem->bufs_seq_header.virtual_addr));
   2115     if (ps_mem->bufs_seq_header.virtual_addr == NULL) {
   2116         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping seq header\n", __FUNCTION__);
   2117         return ;
   2118     }
   2119 
   2120     tng__H264ES_prepare_sequence_header(
   2121         ps_mem->bufs_seq_header.virtual_addr,
   2122         &(ctx->sVuiParams),
   2123         &(ctx->sCropParams),
   2124         ctx->ui16Width,         //ui8_picture_width_in_mbs
   2125         ctx->ui16PictureHeight, //ui8_picture_height_in_mbs
   2126         ctx->ui32CustomQuantMask,    //0,  ui8_custom_quant_mask
   2127         ctx->ui8ProfileIdc,          //ui8_profile
   2128         ctx->ui8LevelIdc,            //ui8_level
   2129         ctx->ui8FieldCount,          //1,  ui8_field_count
   2130         ctx->ui8MaxNumRefFrames,     //1,  ui8_max_num_ref_frames
   2131         ctx->bPpsScaling,            //0   ui8_pps_scaling_cnt
   2132         ctx->bUseDefaultScalingList, //0,  b_use_default_scaling_list
   2133         ctx->bEnableLossless,        //0,  blossless
   2134         ctx->bArbitrarySO
   2135     );
   2136     psb_buffer_unmap(&(ps_mem->bufs_seq_header));
   2137 
   2138     if (ctx->bEnableMVC) {
   2139         psb_buffer_map(&(ps_mem->bufs_sub_seq_header), &(ps_mem->bufs_sub_seq_header.virtual_addr));
   2140         if (ps_mem->bufs_sub_seq_header.virtual_addr == NULL) {
   2141             drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping sub seq header\n", __FUNCTION__);
   2142             return ;
   2143         }
   2144         tng__H264ES_prepare_mvc_sequence_header(
   2145             ps_mem->bufs_sub_seq_header.virtual_addr,
   2146             &(ctx->sCropParams),
   2147             ctx->ui16Width,         //ui8_picture_width_in_mbs
   2148             ctx->ui16PictureHeight, //ui8_picture_height_in_mbs
   2149             ctx->ui32CustomQuantMask,    //0,  ui8_custom_quant_mask
   2150             ctx->ui8ProfileIdc,          //ui8_profile
   2151             ctx->ui8LevelIdc,            //ui8_level
   2152             ctx->ui8FieldCount,          //1,  ui8_field_count
   2153             ctx->ui8MaxNumRefFrames,     //1,  ui8_max_num_ref_frames
   2154             ctx->bPpsScaling,            //0   ui8_pps_scaling_cnt
   2155             ctx->bUseDefaultScalingList, //0,  b_use_default_scaling_list
   2156             ctx->bEnableLossless,        //0,  blossless
   2157             ctx->bArbitrarySO
   2158         );
   2159         psb_buffer_unmap(&(ps_mem->bufs_sub_seq_header));
   2160     }
   2161 
   2162     cmdbuf->cmd_idx_saved[TNG_CMDBUF_SEQ_HEADER_IDX] = cmdbuf->cmd_idx;
   2163 
   2164     return ;
   2165 }
   2166 
   2167 static void tng__H264ES_send_pic_header(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
   2168 {
   2169     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
   2170     IMG_BOOL bDepViewPPS = IMG_FALSE;
   2171 
   2172     if ((ctx->bEnableMVC) && (ctx->ui16MVCViewIdx != 0) &&
   2173         (ctx->ui16MVCViewIdx != (IMG_UINT16)(NON_MVC_VIEW))) {
   2174         bDepViewPPS = IMG_TRUE;
   2175     }
   2176 
   2177     psb_buffer_map(&(ps_mem->bufs_pic_template), &(ps_mem->bufs_pic_template.virtual_addr));
   2178     if (ps_mem->bufs_pic_template.virtual_addr == NULL) {
   2179         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping pic template\n", __FUNCTION__);
   2180         return ;
   2181     }
   2182 
   2183     tng__H264ES_prepare_picture_header(
   2184         ps_mem->bufs_pic_template.virtual_addr,
   2185         ctx->bCabacEnabled,
   2186         ctx->bH2648x8Transform,     //IMG_BOOL    b_8x8transform,
   2187         ctx->bH264IntraConstrained, //IMG_BOOL    bIntraConstrained,
   2188         0, //IMG_INT8    i8CQPOffset,
   2189         0, //IMG_BOOL    bWeightedPrediction,
   2190         0, //IMG_UINT8   ui8WeightedBiPred,
   2191         bDepViewPPS, //IMG_BOOL    bMvcPPS,
   2192         0, //IMG_BOOL    bScalingMatrix,
   2193         0  //IMG_BOOL    bScalingLists
   2194     );
   2195 
   2196     psb_buffer_unmap(&(ps_mem->bufs_pic_template));
   2197     return ;
   2198 }
   2199 
   2200 static void tng__H264ES_send_hrd_header(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
   2201 {
   2202     unsigned int ui32nal_initial_cpb_removal_delay;
   2203     unsigned int ui32nal_initial_cpb_removal_delay_offset;
   2204     uint32_t ui32cpb_removal_delay;
   2205     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
   2206     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
   2207     H264_VUI_PARAMS *psVuiParams = &(ctx->sVuiParams);
   2208     IMG_UINT8 aui8clocktimestampflag[1];
   2209     aui8clocktimestampflag[0] = IMG_FALSE;
   2210 
   2211     ui32nal_initial_cpb_removal_delay =
   2212         90000 * (1.0 * psRCParams->i32InitialDelay / psRCParams->ui32BitsPerSecond);
   2213     ui32nal_initial_cpb_removal_delay_offset =
   2214         90000 * (1.0 * ctx->buffer_size / psRCParams->ui32BitsPerSecond)
   2215         - ui32nal_initial_cpb_removal_delay;
   2216 
   2217     drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert SEI buffer period message with "
   2218             "ui32nal_initial_cpb_removal_delay(%d) and "
   2219             "ui32nal_initial_cpb_removal_delay_offset(%d)\n",
   2220             ui32nal_initial_cpb_removal_delay,
   2221             ui32nal_initial_cpb_removal_delay_offset);
   2222 
   2223     psb_buffer_map(&(ps_mem->bufs_sei_header), &(ps_mem->bufs_sei_header.virtual_addr));
   2224     if (ps_mem->bufs_sei_header.virtual_addr == NULL) {
   2225         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping sei header\n", __FUNCTION__);
   2226         return ;
   2227     }
   2228 
   2229     if ((!ctx->bEnableMVC) || (ctx->ui16MVCViewIdx == 0)) {
   2230         tng__H264ES_prepare_AUD_header(ps_mem->bufs_sei_header.virtual_addr);
   2231     }
   2232 
   2233     tng__H264ES_prepare_SEI_buffering_period_header(
   2234         ps_mem->bufs_sei_header.virtual_addr + (ctx->ctx_mem_size.sei_header),
   2235         0,// ui8cpb_cnt_minus1,
   2236         psVuiParams->initial_cpb_removal_delay_length_minus1+1, //ui8initial_cpb_removal_delay_length,
   2237         1, //ui8NalHrdBpPresentFlag,
   2238         ui32nal_initial_cpb_removal_delay, // ui32nal_initial_cpb_removal_delay,
   2239         ui32nal_initial_cpb_removal_delay_offset, //ui32nal_initial_cpb_removal_delay_offset,
   2240         0, //ui8VclHrdBpPresentFlag - CURRENTLY HARD CODED TO ZERO IN TOPAZ
   2241         NOT_USED_BY_TOPAZ, // ui32vcl_initial_cpb_removal_delay, (not used when ui8VclHrdBpPresentFlag = 0)
   2242         NOT_USED_BY_TOPAZ); // ui32vcl_initial_cpb_removal_delay_offset (not used when ui8VclHrdBpPresentFlag = 0)
   2243 
   2244     /* ui32cpb_removal_delay is zero for 1st frame and will be reset
   2245      * after a IDR frame */
   2246     if (ctx->ui32FrameCount[ui32StreamIndex] == 0) {
   2247         if (ctx->ui32RawFrameCount == 0)
   2248             ui32cpb_removal_delay = 0;
   2249         else
   2250             ui32cpb_removal_delay =
   2251                 ctx->ui32IdrPeriod * ctx->ui32IntraCnt * 2;
   2252     } else
   2253         ui32cpb_removal_delay = 2 * ctx->ui32FrameCount[ui32StreamIndex];
   2254 
   2255     tng__H264ES_prepare_SEI_picture_timing_header(
   2256         ps_mem->bufs_sei_header.virtual_addr + (ctx->ctx_mem_size.sei_header * 2),
   2257         1, //ui8CpbDpbDelaysPresentFlag,
   2258         psVuiParams->cpb_removal_delay_length_minus1, //cpb_removal_delay_length_minus1,
   2259         psVuiParams->dpb_output_delay_length_minus1, //dpb_output_delay_length_minus1,
   2260         ui32cpb_removal_delay, //ui32cpb_removal_delay,
   2261         2, //ui32dpb_output_delay,
   2262         0, //ui8pic_struct_present_flag (contained in the sequence header, Topaz hard-coded default to 0)
   2263         NOT_USED_BY_TOPAZ, //ui8pic_struct, (not used when ui8pic_struct_present_flag = 0)
   2264         NOT_USED_BY_TOPAZ, //NumClockTS, (not used when ui8pic_struct_present_flag = 0)
   2265         aui8clocktimestampflag, //abclock_timestamp_flag, (not used when ui8pic_struct_present_flag = 0)
   2266         NOT_USED_BY_TOPAZ, //ui8full_timestamp_flag, (not used when ui8pic_struct_present_flag = 0)
   2267         NOT_USED_BY_TOPAZ, //ui8seconds_flag, (not used when ui8pic_struct_present_flag = 0)
   2268         NOT_USED_BY_TOPAZ, //ui8minutes_flag, (not used when ui8pic_struct_present_flag = 0)
   2269         NOT_USED_BY_TOPAZ, //ui8hours_flag, (not used when ui8pic_struct_present_flag = 0)
   2270         NOT_USED_BY_TOPAZ, //seconds_value, (not used when ui8pic_struct_present_flag = 0)
   2271         NOT_USED_BY_TOPAZ, //minutes_value, (not used when ui8pic_struct_present_flag = 0)
   2272         NOT_USED_BY_TOPAZ, //hours_value, (not used when ui8pic_struct_present_flag = 0)
   2273         NOT_USED_BY_TOPAZ, //ct_type (2=Unknown) See TRM Table D 2 ?Mapping of ct_type to source picture scan  (not used when ui8pic_struct_present_flag = 0)
   2274         NOT_USED_BY_TOPAZ, //nuit_field_based_flag, (not used when ui8pic_struct_present_flag = 0)
   2275         NOT_USED_BY_TOPAZ, //counting_type (See TRM Table D 3 ?Definition of counting_type values)  (not used when ui8pic_struct_present_flag = 0)
   2276         NOT_USED_BY_TOPAZ, //ui8discontinuity_flag, (not used when ui8pic_struct_present_flag = 0)
   2277         NOT_USED_BY_TOPAZ, //ui8cnt_dropped_flag, (not used when ui8pic_struct_present_flag = 0)
   2278         NOT_USED_BY_TOPAZ, //n_frames, (not used when ui8pic_struct_present_flag = 0)
   2279         NOT_USED_BY_TOPAZ, //time_offset_length, (not used when ui8pic_struct_present_flag = 0)
   2280         NOT_USED_BY_TOPAZ); //time_offset (not used when ui8pic_struct_present_flag = 0)
   2281     psb_buffer_unmap(&(ps_mem->bufs_sei_header));
   2282 
   2283     return ;
   2284 }
   2285 
   2286 static void tng__generate_slice_params_template(
   2287     context_ENC_p ctx,
   2288     IMG_UINT32 slice_buf_idx,
   2289     IMG_UINT32 slice_type,
   2290     IMG_UINT32 ui32StreamIndex
   2291 )
   2292 {
   2293     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
   2294     IMG_UINT8  *slice_mem_temp_p = NULL;
   2295     IMG_UINT32 ui32SliceHeight = 0;
   2296     IMG_FRAME_TEMPLATE_TYPE slice_temp_type = (IMG_FRAME_TEMPLATE_TYPE)slice_type;
   2297     IMG_FRAME_TEMPLATE_TYPE buf_idx = (IMG_FRAME_TEMPLATE_TYPE)slice_buf_idx;
   2298 
   2299     if (ctx->ui8SlicesPerPicture != 0)
   2300         ui32SliceHeight = ctx->ui16PictureHeight / ctx->ui8SlicesPerPicture;
   2301     else
   2302         drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s slice height\n", __FUNCTION__);
   2303 
   2304     ui32SliceHeight &= ~15;
   2305 
   2306     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG ui8DeblockIDC    = %x\n", __FUNCTION__, ctx->ui8DeblockIDC   );
   2307     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG ui32SliceHeight  = %x\n", __FUNCTION__, ui32SliceHeight );
   2308     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bIsInterlaced    = %x\n", __FUNCTION__, ctx->bIsInterlaced   );
   2309     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG iFineYSearchSize = %x\n", __FUNCTION__, ctx->iFineYSearchSize);
   2310 
   2311     tng__prepare_encode_sliceparams(
   2312         ctx,
   2313         slice_buf_idx,
   2314         slice_temp_type,
   2315         0,                        // ui16CurrentRow,
   2316         ui32SliceHeight,
   2317         ctx->ui8DeblockIDC,       // uiDeblockIDC
   2318         ctx->bIsInterlaced,       // bFieldMode
   2319         ctx->iFineYSearchSize,
   2320         ui32StreamIndex
   2321     );
   2322 
   2323     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bCabacEnabled  = %x\n", __FUNCTION__, ctx->bCabacEnabled );
   2324     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG ui16MVCViewIdx = %x\n", __FUNCTION__, ctx->ui16MVCViewIdx);
   2325 
   2326     if(ctx->bEnableMVC)
   2327         ctx->ui16MVCViewIdx = (IMG_UINT16)ui32StreamIndex;
   2328 
   2329     if (ps_mem->bufs_slice_template.virtual_addr == NULL) {
   2330         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping slice template\n", __FUNCTION__);
   2331         return ;
   2332     }
   2333 
   2334     slice_mem_temp_p = (IMG_UINT8*)(ps_mem->bufs_slice_template.virtual_addr + (ctx->ctx_mem_size.slice_template * buf_idx));
   2335     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: addr 0x%08x, virtual 0x%08x, size = 0x%08x, buf_idx = %x\n",
   2336         __FUNCTION__, slice_mem_temp_p, ps_mem->bufs_slice_template.virtual_addr, ctx->ctx_mem_size.slice_template, buf_idx);
   2337 
   2338     /* Prepare Slice Header Template */
   2339     switch (ctx->eStandard) {
   2340     case IMG_STANDARD_NONE:
   2341     case IMG_STANDARD_JPEG:
   2342     case IMG_STANDARD_MPEG4:
   2343         break;
   2344     case IMG_STANDARD_H264:
   2345         //H264_NOTFORSIMS_PrepareSliceHeader
   2346         tng__H264ES_notforsims_prepare_sliceheader(
   2347             slice_mem_temp_p,
   2348             slice_temp_type,
   2349             ctx->ui8DeblockIDC,
   2350             0,                   // ui32FirstMBAddress
   2351             0,                   // uiMBSkipRun
   2352             ctx->bCabacEnabled,
   2353             ctx->bIsInterlaced,
   2354             ctx->ui16MVCViewIdx, //(IMG_UINT16)(NON_MVC_VIEW);
   2355             IMG_FALSE            // bIsLongTermRef
   2356         );
   2357         break;
   2358 
   2359     case IMG_STANDARD_H263:
   2360         tng__H263ES_notforsims_prepare_gobsliceheader(slice_mem_temp_p);
   2361         break;
   2362 
   2363     case IMG_STANDARD_MPEG2:
   2364         tng__MPEG2_prepare_sliceheader(slice_mem_temp_p);
   2365         break;
   2366     }
   2367 
   2368     psb_buffer_unmap(&(ps_mem->bufs_slice_template));
   2369 
   2370     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end \n", __FUNCTION__);
   2371 
   2372     return ;
   2373 }
   2374 
   2375 //H264_PrepareTemplates
   2376 static VAStatus tng__prepare_templates(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
   2377 {
   2378     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
   2379     PIC_PARAMS *psPicParams = &(ctx->sPicParams);
   2380     IN_RC_PARAMS* psInParams = &(psPicParams->sInParams);
   2381     psPicParams->ui32Flags = 0;
   2382 
   2383     tng__prepare_mv_estimates(ctx, ui32StreamIndex);
   2384 
   2385     switch (ctx->eStandard) {
   2386         case IMG_STANDARD_H263:
   2387             psPicParams->ui32Flags |= ISH263_FLAGS;
   2388             break;
   2389         case IMG_STANDARD_MPEG4:
   2390             psPicParams->ui32Flags |= ISMPEG4_FLAGS;
   2391             break;
   2392         case IMG_STANDARD_MPEG2:
   2393             psPicParams->ui32Flags |= ISMPEG2_FLAGS;
   2394             break;
   2395         default:
   2396             break;
   2397     }
   2398 
   2399     if (psRCParams->eRCMode) {
   2400         psPicParams->ui32Flags |= ISRC_FLAGS;
   2401         tng__setup_rcdata(ctx);
   2402     } else {
   2403         psInParams->ui8SeInitQP  = psRCParams->ui32InitialQp;
   2404         psInParams->ui8MBPerRow  = (ctx->ui16Width >> 4);
   2405         psInParams->ui16MBPerFrm = (ctx->ui16Width >> 4) * (ctx->ui16PictureHeight >> 4);
   2406         psInParams->ui16MBPerBU  = psRCParams->ui32BUSize;
   2407         psInParams->ui16BUPerFrm = (psInParams->ui16MBPerFrm) / psRCParams->ui32BUSize;
   2408         ctx->ui32KickSize = psInParams->ui16MBPerBU;
   2409     }
   2410 
   2411     // Prepare Slice header templates
   2412     tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_IDR, (IMG_UINT32)IMG_FRAME_IDR, ui32StreamIndex);
   2413     tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTRA, (IMG_UINT32)IMG_FRAME_INTRA, ui32StreamIndex);
   2414     tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_P, (IMG_UINT32)IMG_FRAME_INTER_P, ui32StreamIndex);
   2415     switch(ctx->eStandard) {
   2416 	case IMG_STANDARD_H264:
   2417 	    tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_B, (IMG_UINT32)IMG_FRAME_INTER_B, ui32StreamIndex);
   2418 	    if (ctx->bEnableMVC)
   2419 		tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_P_IDR, (IMG_UINT32)IMG_FRAME_INTER_P_IDR, ui32StreamIndex);
   2420             tng__H264ES_send_seq_header(ctx, 0);
   2421             tng__H264ES_send_pic_header(ctx, 0);
   2422             if (ctx->bInsertHRDParams)
   2423                 tng__H264ES_send_hrd_header(ctx, 0);
   2424 	    break;
   2425 	case IMG_STANDARD_H263:
   2426 	    tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_B, (IMG_UINT32)IMG_FRAME_INTER_B, ui32StreamIndex);
   2427 	    /* Here H263 uses the actual width and height */
   2428 	    tng__h263_generate_pic_hdr_template(ctx, IMG_FRAME_IDR, ctx->h263_actual_width, ctx->h263_actual_height);
   2429             tng__h263_generate_pic_hdr_template(ctx, IMG_FRAME_INTRA, ctx->h263_actual_width, ctx->h263_actual_height);
   2430             tng__h263_generate_pic_hdr_template(ctx, IMG_FRAME_INTER_P, ctx->h263_actual_width, ctx->h263_actual_height);
   2431 	    break;
   2432 	case IMG_STANDARD_MPEG4:
   2433 	    tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_B, (IMG_UINT32)IMG_FRAME_INTER_P, ui32StreamIndex);
   2434 	    tng__mpeg4_generate_pic_hdr_template(ctx, IMG_FRAME_IDR, 4);
   2435             tng__mpeg4_generate_pic_hdr_template(ctx, IMG_FRAME_INTRA, 4);
   2436             tng__mpeg4_generate_pic_hdr_template(ctx, IMG_FRAME_INTER_P, 4);
   2437 	    tng__mpeg4_generate_pic_hdr_template(ctx, IMG_FRAME_INTER_B, 4);
   2438 	    break;
   2439 	default:
   2440 	    break;
   2441     }
   2442 
   2443     //FIXME: Zhaohan tng__mpeg2/mpeg4_generate_pic_hdr_template(IMG_FRAME_IDR\IMG_FRAME_INTRA\IMG_FRAME_INTER_P\IMG_FRAME_INTER_B);
   2444 
   2445 /*
   2446     else {
   2447         slice_mem_temp_p = (IMG_UINT8*)cmdbuf->slice_mem_p + (((IMG_UINT32)IMG_FRAME_INTER_P_IDR) * cmdbuf->mem_size);
   2448         memset(slice_mem_temp_p, 0, 128);
   2449     }
   2450 */
   2451     // Prepare Pic Params Templates
   2452     tng__adjust_picflags(ctx, psRCParams, IMG_TRUE, &(ctx->ui32FirstPicFlags));
   2453     tng__adjust_picflags(ctx, psRCParams, IMG_FALSE, &(ctx->ui32NonFirstPicFlags));
   2454 
   2455     return VA_STATUS_SUCCESS;
   2456 }
   2457 
   2458 #if INPUT_SCALER_SUPPORTED
   2459 static IMG_FLOAT VIDEO_CalculateBessel0 (IMG_FLOAT fX)
   2460 {
   2461     IMG_FLOAT fAX, fY;
   2462 
   2463     fAX = (IMG_FLOAT)IMG_FABS(fX);
   2464 
   2465     if (fAX < 3.75) 	{
   2466         fY = (IMG_FLOAT)(fX / 3.75);
   2467         fY *= fY;
   2468 
   2469         return (IMG_FLOAT)(1.0 + fY *
   2470             (3.5156229 + fY *
   2471             (3.0899424 + fY *
   2472             (1.2067492 + fY *
   2473             (0.2659732 + fY *
   2474             (0.360768e-1 + fY * 0.45813e-2))))));
   2475     }
   2476 
   2477     fY = (IMG_FLOAT)(3.75 / fAX);
   2478 
   2479     return (IMG_FLOAT)((IMG_EXP(fAX) / IMG_SQRT(fAX)) *
   2480         (0.39894228 + fY *
   2481         (0.1328592e-1 + fY *
   2482         (0.225319e-2 + fY *
   2483         (-0.157565e-2 + fY *
   2484         (0.916281e-2 + fY *
   2485         (-0.2057706e-1 + fY *
   2486         (0.2635537e-1 + fY *
   2487         (-0.1647633e-1 + fY * 0.392377e-2)))))))));
   2488 }
   2489 
   2490 static IMG_FLOAT VIDEO_SincFunc (IMG_FLOAT fInput, IMG_FLOAT fScale)
   2491 {
   2492     IMG_FLOAT fX;
   2493     IMG_FLOAT fKaiser;
   2494 
   2495     /* Kaiser window */
   2496     fX = fInput / (4.0f / 2.0f) - 1.0f;
   2497     fX = (IMG_FLOAT)IMG_SQRT(1.0f - fX * fX);
   2498     fKaiser = VIDEO_CalculateBessel0(2.0f * fX) / VIDEO_CalculateBessel0(2.0f);
   2499 
   2500     /* Sinc function */
   2501     fX = 4.0f / 2.0f - fInput;
   2502     if (fX == 0) {
   2503         return fKaiser;
   2504     }
   2505 
   2506     fX *= 0.9f * fScale * 3.1415926535897f;
   2507 
   2508     return fKaiser * (IMG_FLOAT)(IMG_SIN(fX) / fX);
   2509 }
   2510 
   2511 static void VIDEO_CalcCoefs_FromPitch (IMG_FLOAT	fPitch, IMG_UINT8 aui8Table[4][16])
   2512 {
   2513     /* Based on sim code */
   2514     /* The function is symmetrical, so we only need to calculate the first half of the taps, and the middle value. */
   2515 
   2516     IMG_FLOAT	fScale;
   2517     IMG_UINT32	ui32I, ui32Tap;
   2518     IMG_FLOAT	afTable[4][16];
   2519     IMG_INT32	i32Total;
   2520     IMG_FLOAT	fTotal;
   2521     IMG_INT32	i32MiddleTap, i32MiddleI;		/* Mirrored / middle Values for I and T */
   2522 
   2523     if (fPitch < 1.0f) {
   2524         fScale = 1.0f;
   2525     } else {
   2526         fScale = 1.0f / fPitch;
   2527     }
   2528 
   2529     for (ui32I = 0; ui32I < 16; ui32I++) {
   2530         for (ui32Tap = 0; ui32Tap < 4; ui32Tap++) {
   2531             afTable[ui32Tap][ui32I] = VIDEO_SincFunc(((IMG_FLOAT)ui32Tap) + ((IMG_FLOAT)ui32I) / 16.0f, fScale);
   2532         }
   2533     }
   2534 
   2535     for (ui32Tap = 0; ui32Tap < 2; ui32Tap++) {
   2536         for (ui32I = 0; ui32I < 16; ui32I++) {
   2537             /* Copy the table around the centre point */
   2538             i32MiddleTap = (3 - ui32Tap) + (16 - ui32I) / 16;
   2539             i32MiddleI = (16 - ui32I) & 15;
   2540             if ((IMG_UINT32)i32MiddleTap < 4) {
   2541                 afTable[i32MiddleTap][i32MiddleI] = afTable[ui32Tap][ui32I];
   2542             }
   2543         }
   2544     }
   2545 
   2546     /* The middle value */
   2547     afTable[2][0] = VIDEO_SincFunc(2.0f, fScale);
   2548 
   2549     /* Normalize this interpolation point, and convert to 2.6 format, truncating the result	*/
   2550     for (ui32I = 0; ui32I < 16; ui32I++) {
   2551         fTotal = 0.0f;
   2552         i32Total = 0;
   2553 
   2554         for (ui32Tap = 0; ui32Tap < 4; ui32Tap++) {
   2555             fTotal += afTable[ui32Tap][ui32I];
   2556         }
   2557 
   2558         for (ui32Tap = 0; ui32Tap < 4; ui32Tap++) {
   2559             aui8Table[ui32Tap][ui32I] = (IMG_UINT8)((afTable[ui32Tap][ui32I] * 64.0f) / fTotal);
   2560             i32Total += aui8Table[ui32Tap][ui32I];
   2561         }
   2562 
   2563         if (ui32I <= 8) { /* normalize any floating point errors */
   2564             i32Total -= 64;
   2565             if (ui32I == 8) {
   2566                 i32Total /= 2;
   2567             }
   2568             /* Subtract the error from the I Point in the first tap ( this will not get
   2569             mirrored, as it would go off the end). */
   2570             aui8Table[0][ui32I] = (IMG_UINT8)(aui8Table[0][ui32I] - (IMG_UINT8)i32Total);
   2571         }
   2572     }
   2573 
   2574     /* Copy the normalised table around the centre point */
   2575     for (ui32Tap = 0; ui32Tap < 2; ui32Tap++) {
   2576         for (ui32I = 0; ui32I < 16; ui32I++) {
   2577             i32MiddleTap = (3 - ui32Tap) + (16 - ui32I) / 16;
   2578             i32MiddleI = (16 - ui32I) & 15;
   2579             if ((IMG_UINT32)i32MiddleTap < 4) {
   2580                 aui8Table[i32MiddleTap][i32MiddleI] = aui8Table[ui32Tap][ui32I];
   2581             }
   2582         }
   2583     }
   2584     return ;
   2585 }
   2586 #endif
   2587 
   2588 static void tng__setvideo_params(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
   2589 {
   2590     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
   2591     context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
   2592     IMG_MTX_VIDEO_CONTEXT* psMtxEncContext = NULL;
   2593     IMG_RC_PARAMS * psRCParams = &(ctx->sRCParams);
   2594     //IMG_UINT16 ui16WidthInMbs = (ctx->ui16Width + 15) >> 4;
   2595     //IMG_UINT16 ui16FrameHeightInMbs = (ctx->ui16FrameHeight + 15) >> 4;
   2596     IMG_INT nIndex;
   2597     IMG_UINT8 ui8Flag;
   2598 #ifndef EXCLUDE_ADAPTIVE_ROUNDING
   2599     IMG_INT32 i, j;
   2600 #endif
   2601 
   2602     psb_buffer_map(&(ps_mem->bufs_mtx_context), &(ps_mem->bufs_mtx_context.virtual_addr));
   2603     if (ps_mem->bufs_mtx_context.virtual_addr == NULL) {
   2604         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping slice template\n", __FUNCTION__);
   2605         return ;
   2606     }
   2607 
   2608     psMtxEncContext = (IMG_MTX_VIDEO_CONTEXT*)(ps_mem->bufs_mtx_context.virtual_addr);
   2609 
   2610     ctx->i32PicNodes = (psRCParams->b16Hierarchical ? MAX_REF_B_LEVELS : 0) + ctx->ui8RefSpacing + 4;
   2611     ctx->i32MVStores = (ctx->i32PicNodes * 2);
   2612     ctx->ui8SlotsInUse = psRCParams->ui16BFrames + 2;
   2613 
   2614     psMtxEncContext->ui32InitialQp = ctx->sRCParams.ui32InitialQp;
   2615     psMtxEncContext->ui32BUSize = ctx->sRCParams.ui32BUSize;
   2616     psMtxEncContext->ui16CQPOffset = (ctx->sRCParams.i8QCPOffset & 0x1f) | ((ctx->sRCParams.i8QCPOffset & 0x1f) << 8);
   2617     psMtxEncContext->eStandard = ctx->eStandard;
   2618     psMtxEncContext->ui32WidthInMbs = ctx->ui16Width >> 4;
   2619     psMtxEncContext->ui32PictureHeightInMbs = ctx->ui16PictureHeight >> 4;
   2620     psMtxEncContext->bOutputReconstructed = (ps_buf->rec_surface != NULL) ? IMG_TRUE : IMG_FALSE;
   2621     psMtxEncContext->ui32VopTimeResolution = ctx->ui32VopTimeResolution;
   2622     psMtxEncContext->ui8MaxSlicesPerPicture = ctx->ui8SlicesPerPicture;
   2623     psMtxEncContext->ui8NumPipes = ctx->ui8PipesToUse;
   2624     psMtxEncContext->eFormat = ctx->eFormat;
   2625 
   2626     psMtxEncContext->b8IsInterlaced = ctx->bIsInterlaced;
   2627     psMtxEncContext->b8TopFieldFirst = ctx->bTopFieldFirst;
   2628     psMtxEncContext->b8ArbitrarySO = ctx->bArbitrarySO;
   2629 
   2630     psMtxEncContext->ui32IdrPeriod = ctx->ui32IdrPeriod * ctx->ui32IntraCnt;
   2631     psMtxEncContext->ui32BFrameCount = ctx->sRCParams.ui16BFrames;
   2632     psMtxEncContext->b8Hierarchical = (IMG_BOOL8) ctx->sRCParams.b16Hierarchical;
   2633     psMtxEncContext->ui32IntraLoopCnt = ctx->ui32IntraCnt;
   2634     psMtxEncContext->ui8RefSpacing = ctx->ui8RefSpacing;
   2635     psMtxEncContext->ui32DebugCRCs = ctx->ui32DebugCRCs;
   2636 
   2637     psMtxEncContext->ui8FirstPipe = ctx->ui8BasePipe;
   2638     psMtxEncContext->ui8LastPipe = ctx->ui8BasePipe + ctx->ui8PipesToUse - 1;
   2639     psMtxEncContext->ui8PipesToUseFlags = 0;
   2640     ui8Flag = 0x1 << psMtxEncContext->ui8FirstPipe;
   2641     for (nIndex = 0; nIndex < psMtxEncContext->ui8NumPipes; nIndex++, ui8Flag<<=1)
   2642         psMtxEncContext->ui8PipesToUseFlags |= ui8Flag; //Pipes used MUST be contiguous from the BasePipe offset
   2643 
   2644     // Only used in MPEG2, 2 bit field (0 = 8 bit, 1 = 9 bit, 2 = 10 bit and 3=11 bit precision)
   2645     if (ctx->eStandard == IMG_STANDARD_MPEG2)
   2646         psMtxEncContext->ui8MPEG2IntraDCPrecision = ctx->ui8MPEG2IntraDCPrecision;
   2647 
   2648     psMtxEncContext->b16EnableMvc = ctx->bEnableMVC;
   2649     psMtxEncContext->ui16MvcViewIdx = ctx->ui16MVCViewIdx;
   2650     if (ctx->eStandard == IMG_STANDARD_H264)
   2651         psMtxEncContext->b16NoSequenceHeaders = ctx->bNoSequenceHeaders;
   2652 
   2653     {
   2654         IMG_UINT16 ui16SrcYStride = 0, ui16SrcUVStride = 0;
   2655         // 3 Components: Y, U, V
   2656         ctx->ui16BufferStride = ps_buf->src_surface->psb_surface->stride;
   2657         ui16SrcUVStride = ui16SrcYStride = ctx->ui16BufferStride;
   2658         ctx->ui16BufferHeight = ctx->ui16FrameHeight;
   2659         switch (ctx->eFormat) {
   2660         case IMG_CODEC_YUV:
   2661         case IMG_CODEC_PL8:
   2662         case IMG_CODEC_YV12:
   2663             ui16SrcUVStride = ui16SrcYStride / 2;
   2664             break;
   2665 
   2666         case IMG_CODEC_PL12:            // Interleaved chroma pixels
   2667         case IMG_CODEC_IMC2:            // Interleaved chroma rows
   2668         case IMG_CODEC_422_YUV:         // Odd-numbered chroma rows unused
   2669         case IMG_CODEC_422_YV12:        // Odd-numbered chroma rows unused
   2670         case IMG_CODEC_422_PL8:         // Odd-numbered chroma rows unused
   2671         case IMG_CODEC_Y0UY1V_8888: // Interleaved luma and chroma pixels
   2672         case IMG_CODEC_Y0VY1U_8888: // Interleaved luma and chroma pixels
   2673         case IMG_CODEC_UY0VY1_8888: // Interleaved luma and chroma pixels
   2674         case IMG_CODEC_VY0UY1_8888: // Interleaved luma and chroma pixels
   2675             ui16SrcUVStride = ui16SrcYStride;
   2676             break;
   2677 
   2678         case IMG_CODEC_422_IMC2:        // Interleaved chroma pixels and unused odd-numbered chroma rows
   2679         case IMG_CODEC_422_PL12:        // Interleaved chroma rows and unused odd-numbered chroma rows
   2680             ui16SrcUVStride = ui16SrcYStride * 2;
   2681             break;
   2682 
   2683         default:
   2684             break;
   2685         }
   2686 
   2687         if ((ctx->bIsInterlaced) && (ctx->bIsInterleaved)) {
   2688             ui16SrcYStride *= 2;                    // ui16SrcYStride
   2689             ui16SrcUVStride *= 2;           // ui16SrcUStride
   2690         }
   2691 
   2692         psMtxEncContext->ui32PicRowStride = F_ENCODE(ui16SrcYStride >> 6, TOPAZHP_CR_CUR_PIC_LUMA_STRIDE) |
   2693                                             F_ENCODE(ui16SrcUVStride >> 6, TOPAZHP_CR_CUR_PIC_CHROMA_STRIDE);
   2694     }
   2695 
   2696     psMtxEncContext->eRCMode = ctx->sRCParams.eRCMode;
   2697     psMtxEncContext->b8DisableBitStuffing = ctx->sRCParams.bDisableBitStuffing;
   2698     psMtxEncContext->b8FirstPic = IMG_TRUE;
   2699 
   2700     /*Contents Adaptive Rate Control Parameters*/
   2701     psMtxEncContext->bCARC          =  ctx->sCARCParams.bCARC;
   2702     psMtxEncContext->iCARCBaseline  =  ctx->sCARCParams.i32CARCBaseline;
   2703     psMtxEncContext->uCARCThreshold =  ctx->sCARCParams.ui32CARCThreshold;
   2704     psMtxEncContext->uCARCCutoff    =  ctx->sCARCParams.ui32CARCCutoff;
   2705     psMtxEncContext->uCARCNegRange  =  ctx->sCARCParams.ui32CARCNegRange;
   2706     psMtxEncContext->uCARCNegScale  =  ctx->sCARCParams.ui32CARCNegScale;
   2707     psMtxEncContext->uCARCPosRange  =  ctx->sCARCParams.ui32CARCPosRange;
   2708     psMtxEncContext->uCARCPosScale  =  ctx->sCARCParams.ui32CARCPosScale;
   2709     psMtxEncContext->uCARCShift     =  ctx->sCARCParams.ui32CARCShift;
   2710     psMtxEncContext->ui32MVClip_Config =  F_ENCODE(ctx->bNoOffscreenMv, TOPAZHP_CR_MVCALC_RESTRICT_PICTURE);
   2711     psMtxEncContext->ui32LRITC_Tile_Use_Config = 0;
   2712     psMtxEncContext->ui32LRITC_Cache_Chunk_Config = 0;
   2713 
   2714     psMtxEncContext->ui32IPCM_0_Config = F_ENCODE(ctx->ui32CabacBinFlex, TOPAZ_VLC_CR_CABAC_BIN_FLEX) |
   2715         F_ENCODE(DEFAULT_CABAC_DB_MARGIN, TOPAZ_VLC_CR_CABAC_DB_MARGIN);
   2716 
   2717     psMtxEncContext->ui32IPCM_1_Config = F_ENCODE(3200, TOPAZ_VLC_CR_IPCM_THRESHOLD) |
   2718         F_ENCODE(ctx->ui32CabacBinLimit, TOPAZ_VLC_CR_CABAC_BIN_LIMIT);
   2719 
   2720     // leave alone until high profile and constrained modes are defined.
   2721     psMtxEncContext->ui32H264CompControl  = F_ENCODE((ctx->bCabacEnabled ? 0 : 1), TOPAZHP_CR_H264COMP_8X8_CAVLC);
   2722 
   2723     psMtxEncContext->ui32H264CompControl |= F_ENCODE(ctx->bUseDefaultScalingList ? 1 : 0, TOPAZHP_CR_H264COMP_DEFAULT_SCALING_LIST);
   2724 
   2725     psMtxEncContext->ui32H264CompControl |= F_ENCODE(ctx->bH2648x8Transform ? 1 : 0, TOPAZHP_CR_H264COMP_8X8_TRANSFORM);
   2726 
   2727     psMtxEncContext->ui32H264CompControl |= F_ENCODE(ctx->bH264IntraConstrained ? 1 : 0, TOPAZHP_CR_H264COMP_CONSTRAINED_INTRA);
   2728 
   2729 
   2730 #ifndef EXCLUDE_ADAPTIVE_ROUNDING
   2731     psMtxEncContext->bMCAdaptiveRoundingDisable = ctx->bVPAdaptiveRoundingDisable;
   2732     psMtxEncContext->ui32H264CompControl |= F_ENCODE(psMtxEncContext->bMCAdaptiveRoundingDisable ? 0 : 1, TOPAZHP_CR_H264COMP_ADAPT_ROUND_ENABLE);
   2733 
   2734     if (!psMtxEncContext->bMCAdaptiveRoundingDisable)
   2735         for (i = 0; i < 4; i++)
   2736             for (j = 0; j < 18; j++)
   2737                 psMtxEncContext->ui16MCAdaptiveRoundingOffsets[j][i] = H264_ROUNDING_OFFSETS[j][i];
   2738 #endif
   2739 
   2740     if ((ctx->eStandard == IMG_STANDARD_H264) && (ctx->ui32CoreRev >= MIN_34_REV)) {
   2741         psMtxEncContext->ui32H264CompControl |= F_ENCODE(USE_VCM_HW_SUPPORT, TOPAZHP_CR_H264COMP_VIDEO_CONF_ENABLE);
   2742     }
   2743 
   2744     psMtxEncContext->ui32H264CompControl |=
   2745            F_ENCODE(ctx->ui16UseCustomScalingLists & 0x01 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTRA_LUMA_ENABLE)
   2746         | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x02 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTRA_CB_ENABLE)
   2747         | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x04 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTRA_CR_ENABLE)
   2748         | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x08 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTER_LUMA_ENABLE)
   2749         | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x10 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTER_CB_ENABLE)
   2750         | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x20 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTER_CR_ENABLE)
   2751         | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x40 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_8X8_INTRA_LUMA_ENABLE)
   2752         | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x80 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_8X8_INTER_LUMA_ENABLE);
   2753 
   2754     psMtxEncContext->ui32H264CompControl |=
   2755            F_ENCODE(ctx->bEnableLossless ? 1 : 0, INTEL_H264_LL)
   2756         | F_ENCODE(ctx->bLossless8x8Prefilter ? 1 : 0, INTEL_H264_LL8X8P);
   2757 
   2758     psMtxEncContext->ui32H264CompIntraPredModes = 0x3ffff;// leave at default for now.
   2759     psMtxEncContext->ui32PredCombControl = ctx->ui32PredCombControl;
   2760     psMtxEncContext->ui32SkipCodedInterIntra = F_ENCODE(ctx->ui8InterIntraIndex, TOPAZHP_CR_INTER_INTRA_SCALE_IDX)
   2761         |F_ENCODE(ctx->ui8CodedSkippedIndex, TOPAZHP_CR_SKIPPED_CODED_SCALE_IDX);
   2762 
   2763     if (ctx->bEnableInpCtrl) {
   2764         psMtxEncContext->ui32MBHostCtrl = F_ENCODE(ctx->bEnableHostQP, TOPAZHP_CR_MB_HOST_QP)
   2765             |F_ENCODE(ctx->bEnableHostBias, TOPAZHP_CR_MB_HOST_SKIPPED_CODED_SCALE)
   2766             |F_ENCODE(ctx->bEnableHostBias, TOPAZHP_CR_MB_HOST_INTER_INTRA_SCALE);
   2767         psMtxEncContext->ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTER_INTRA_SCALE_ENABLE)
   2768             |F_ENCODE(1, TOPAZHP_CR_SKIPPED_CODED_SCALE_ENABLE);
   2769     }
   2770 
   2771     if (ctx->bEnableCumulativeBiases)
   2772         psMtxEncContext->ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_CUMULATIVE_BIASES_ENABLE);
   2773 
   2774     psMtxEncContext->ui32PredCombControl |=
   2775         F_ENCODE((((ctx->ui8InterIntraIndex == 3) && (ctx->ui8CodedSkippedIndex == 3)) ? 0 : 1), TOPAZHP_CR_INTER_INTRA_SCALE_ENABLE) |
   2776         F_ENCODE((ctx->ui8CodedSkippedIndex == 3 ? 0 : 1), TOPAZHP_CR_SKIPPED_CODED_SCALE_ENABLE);
   2777     // workaround for BRN 33252, if the Skip coded scale is set then we also have to set the inter/inter enable. We set it enabled and rely on the default value of 3 (unbiased) to keep things behaving.
   2778     //      psMtxEncContext->ui32PredCombControl |= F_ENCODE((ctx->ui8InterIntraIndex==3?0:1), TOPAZHP_CR_INTER_INTRA_SCALE_ENABLE) | F_ENCODE((ctx->ui8CodedSkippedIndex==3?0:1), TOPAZHP_CR_SKIPPED_CODED_SCALE_ENABLE);
   2779     //psMtxEncContext->ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTER_INTRA_SCALE_ENABLE) | F_ENCODE(1, TOPAZHP_CR_SKIPPED_CODED_SCALE_ENABLE);
   2780     psMtxEncContext->ui32DeblockCtrl = F_ENCODE(ctx->ui8DeblockIDC, TOPAZ_DB_CR_DISABLE_DEBLOCK_IDC);
   2781     psMtxEncContext->ui32VLCControl = 0;
   2782 
   2783     switch (ctx->eStandard) {
   2784     case IMG_STANDARD_H264:
   2785         psMtxEncContext->ui32VLCControl |= F_ENCODE(1, TOPAZ_VLC_CR_CODEC); // 1 for H.264 note this is inconsistant with the sequencer value
   2786         psMtxEncContext->ui32VLCControl |= F_ENCODE(0, TOPAZ_VLC_CR_CODEC_EXTEND);
   2787 
   2788         break;
   2789     case IMG_STANDARD_H263:
   2790         psMtxEncContext->ui32VLCControl |= F_ENCODE(3, TOPAZ_VLC_CR_CODEC); // 3 for H.263 note this is inconsistant with the sequencer value
   2791         psMtxEncContext->ui32VLCControl |= F_ENCODE(0, TOPAZ_VLC_CR_CODEC_EXTEND);
   2792 
   2793         break;
   2794     case IMG_STANDARD_MPEG4:
   2795         psMtxEncContext->ui32VLCControl |= F_ENCODE(2, TOPAZ_VLC_CR_CODEC); // 2 for Mpeg4 note this is inconsistant with the sequencer value
   2796         psMtxEncContext->ui32VLCControl |= F_ENCODE(0, TOPAZ_VLC_CR_CODEC_EXTEND);
   2797         break;
   2798     case IMG_STANDARD_MPEG2:
   2799         psMtxEncContext->ui32VLCControl |= F_ENCODE(0, TOPAZ_VLC_CR_CODEC);
   2800         psMtxEncContext->ui32VLCControl |= F_ENCODE(1, TOPAZ_VLC_CR_CODEC_EXTEND);
   2801         break;
   2802     default:
   2803         break;
   2804     }
   2805 
   2806     if (ctx->bCabacEnabled) {
   2807         psMtxEncContext->ui32VLCControl |= F_ENCODE(1, TOPAZ_VLC_CR_CABAC_ENABLE); // 2 for Mpeg4 note this is inconsistant with the sequencer value
   2808     }
   2809 
   2810     psMtxEncContext->ui32VLCControl |= F_ENCODE(ctx->bIsInterlaced ? 1 : 0, TOPAZ_VLC_CR_VLC_FIELD_CODED);
   2811     psMtxEncContext->ui32VLCControl |= F_ENCODE(ctx->bH2648x8Transform ? 1 : 0, TOPAZ_VLC_CR_VLC_8X8_TRANSFORM);
   2812     psMtxEncContext->ui32VLCControl |= F_ENCODE(ctx->bH264IntraConstrained ? 1 : 0, TOPAZ_VLC_CR_VLC_CONSTRAINED_INTRA);
   2813 
   2814     psMtxEncContext->ui32VLCSliceControl = F_ENCODE(ctx->sRCParams.ui32SliceByteLimit, TOPAZ_VLC_CR_SLICE_SIZE_LIMIT);
   2815     psMtxEncContext->ui32VLCSliceMBControl = F_ENCODE(ctx->sRCParams.ui32SliceMBLimit, TOPAZ_VLC_CR_SLICE_MBS_LIMIT);
   2816 
   2817         switch (ctx->eStandard) {
   2818             case IMG_STANDARD_H264: {
   2819                 IMG_UINT32 ui32VertMVLimit = 255; // default to no clipping
   2820                 if (ctx->ui32VertMVLimit)
   2821                     ui32VertMVLimit = ctx->ui32VertMVLimit;
   2822                 // as topaz can only cope with at most 255 (in the register field)
   2823                 ui32VertMVLimit = tng__min(255,ui32VertMVLimit);
   2824                 // workaround for BRN 29973 and 30032
   2825                 {
   2826 #if defined(BRN_29973) || defined(BRN_30032)
   2827                     if (ctx->ui32CoreRev <= 0x30006) {
   2828                         if ((ctx->ui16Width / 16) & 1) // BRN 30032, if odd number of macroblocks we need to limit vector to +-112
   2829                             psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
   2830                                 |F_ENCODE(112, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
   2831                                 |F_ENCODE(ui32VertMVLimit, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
   2832                         else // for 29973 we need to limit vector to +-120
   2833                             if (ctx->ui16Width >= 1920)
   2834                                 psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
   2835                                 |F_ENCODE(120, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
   2836                                 |F_ENCODE(ui32VertMVLimit, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
   2837                             else
   2838                                 psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
   2839                                 |F_ENCODE(255, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
   2840                                 |F_ENCODE(ui32VertMVLimit, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
   2841                     } else
   2842 #endif
   2843                         {
   2844                             psMtxEncContext->ui32IPEVectorClipping =
   2845                             F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED) |
   2846                             F_ENCODE(255, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X) |
   2847                             F_ENCODE(ui32VertMVLimit, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
   2848                         }
   2849                     }
   2850                     psMtxEncContext->ui32SPEMvdClipRange = F_ENCODE(0, TOPAZHP_CR_SPE_MVD_CLIP_ENABLE);
   2851             }
   2852             break;
   2853             case IMG_STANDARD_H263:
   2854                 {
   2855                     psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
   2856                         | F_ENCODE(16 - 1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
   2857                         | F_ENCODE(16 - 1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
   2858 
   2859                     psMtxEncContext->ui32SPEMvdClipRange = F_ENCODE(1, TOPAZHP_CR_SPE_MVD_CLIP_ENABLE)
   2860                         | F_ENCODE( 62, TOPAZHP_CR_SPE_MVD_POS_CLIP)
   2861                         | F_ENCODE((uint32_t)(-64), TOPAZHP_CR_SPE_MVD_NEG_CLIP);
   2862                 }
   2863                 break;
   2864             case IMG_STANDARD_MPEG4:
   2865             case IMG_STANDARD_MPEG2:
   2866                 {
   2867                     IMG_UINT8 uX, uY, uResidualSize;
   2868                     //The maximum MPEG4 and MPEG2 motion vector differential in 1/2 pixels is
   2869                     //calculated as 1 << (fcode - 1) * 32 or *16 in MPEG2
   2870 
   2871                     uResidualSize=(ctx->eStandard == IMG_STANDARD_MPEG4 ? 32 : 16);
   2872 
   2873                     uX = tng__min(128 - 1, (((1<<(ctx->sBiasTables.ui32FCode - 1)) * uResidualSize)/4) - 1);
   2874                     uY = tng__min(104 - 1, (((1<<(ctx->sBiasTables.ui32FCode - 1)) * uResidualSize)/4) - 1);
   2875 
   2876                     //Write to register
   2877                     psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
   2878                         | F_ENCODE(uX, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
   2879                         | F_ENCODE(uY, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
   2880 
   2881                     psMtxEncContext->ui32SPEMvdClipRange = F_ENCODE(0, TOPAZHP_CR_SPE_MVD_CLIP_ENABLE);
   2882                 }
   2883                 break;
   2884             case IMG_STANDARD_JPEG:
   2885 			case IMG_STANDARD_NONE:
   2886 			default:
   2887 			    break;
   2888         }
   2889 #ifdef FIRMWARE_BIAS
   2890     //copy the bias tables
   2891     {
   2892         int n;
   2893         for (n = 52; n >= 0; n -= 2)    {
   2894             psMtxEncContext->aui32DirectBias_P[n >> 1] = ctx->sBiasTables.aui32DirectBias_P[n];
   2895             psMtxEncContext->aui32InterBias_P[n >> 1] = ctx->sBiasTables.aui32InterBias_P[n];
   2896             psMtxEncContext->aui32DirectBias_B[n >> 1] = ctx->sBiasTables.aui32DirectBias_B[n];
   2897             psMtxEncContext->aui32InterBias_B[n >> 1] = ctx->sBiasTables.aui32InterBias_B[n];
   2898         }
   2899     }
   2900 #endif
   2901 
   2902     //copy the scale-tables
   2903     tng__generate_scale_tables(psMtxEncContext);
   2904 //      memcpy(psMtxEncContext->ui32InterIntraScale, ctx->ui32InterIntraScale, sizeof(IMG_UINT32)*SCALE_TBL_SZ);
   2905 //      memcpy(psMtxEncContext->ui32SkippedCodedScale, ctx->ui32SkippedCodedScale, sizeof(IMG_UINT32)*SCALE_TBL_SZ);
   2906 
   2907     // WEIGHTED PREDICTION
   2908     psMtxEncContext->b8WeightedPredictionEnabled = ctx->bWeightedPrediction;
   2909     psMtxEncContext->ui8MTXWeightedImplicitBiPred = ctx->ui8VPWeightedImplicitBiPred;
   2910 
   2911     // SEI_INSERTION
   2912     psMtxEncContext->b8InsertHRDparams = ctx->bInsertHRDParams;
   2913     if (psMtxEncContext->b8InsertHRDparams & !ctx->sRCParams.ui32BitsPerSecond) {   //ctx->uBitRate
   2914         /* HRD parameters are meaningless without a bitrate */
   2915         psMtxEncContext->b8InsertHRDparams = IMG_FALSE;
   2916     }
   2917     if (psMtxEncContext->b8InsertHRDparams) {
   2918         psMtxEncContext->ui64ClockDivBitrate = (90000 * 0x100000000LL);
   2919         psMtxEncContext->ui64ClockDivBitrate /= ctx->sRCParams.ui32BitsPerSecond;                       //ctx->uBitRate;
   2920         psMtxEncContext->ui32MaxBufferMultClockDivBitrate = (IMG_UINT32)(((IMG_UINT64)(ctx->sRCParams.ui32BufferSize) *
   2921                 (IMG_UINT64) 90000) / (IMG_UINT64) ctx->sRCParams.ui32BitsPerSecond);
   2922     }
   2923 
   2924     memcpy(&psMtxEncContext->sInParams, &ctx->sPicParams.sInParams, sizeof(IN_RC_PARAMS));
   2925     // Update MV Scaling settings
   2926     // IDR
   2927     //      memcpy(&psMtxEncContext->sMVSettingsIdr, &ctx->sMVSettingsIdr, sizeof(IMG_MV_SETTINGS));
   2928     // NonB (I or P)
   2929     //      for (i = 0; i <= MAX_BFRAMES; i++)
   2930     //              memcpy(&psMtxEncContext->sMVSettingsNonB[i], &ctx->sMVSettingsNonB[i], sizeof(IMG_MV_SETTINGS));
   2931 
   2932     psMtxEncContext->ui32LRITC_Cache_Chunk_Config =
   2933         F_ENCODE(ctx->uChunksPerMb, INTEL_CH_PM) |
   2934         F_ENCODE(ctx->uMaxChunks, INTEL_CH_MX) |
   2935         F_ENCODE(ctx->uMaxChunks - ctx->uPriorityChunks, INTEL_CH_PY);
   2936 
   2937 
   2938     //they would be set in function tng__prepare_templates()
   2939     psMtxEncContext->ui32FirstPicFlags = ctx->ui32FirstPicFlags;
   2940     psMtxEncContext->ui32NonFirstPicFlags = ctx->ui32NonFirstPicFlags;
   2941 
   2942 #ifdef LTREFHEADER
   2943     psMtxEncContext->i8SliceHeaderSlotNum = -1;
   2944 #endif
   2945 
   2946     {
   2947         memset(psMtxEncContext->aui8PicOnLevel, 0, sizeof(psMtxEncContext->aui8PicOnLevel));
   2948         psb_buffer_map(&(ps_mem->bufs_flat_gop), &(ps_mem->bufs_flat_gop.virtual_addr));
   2949         if (ps_mem->bufs_flat_gop.virtual_addr == NULL) {
   2950            drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping flat gop\n", __FUNCTION__);
   2951            return ;
   2952         }
   2953         tng__minigop_generate_flat(ps_mem->bufs_flat_gop.virtual_addr, psMtxEncContext->ui32BFrameCount,
   2954             psMtxEncContext->ui8RefSpacing, psMtxEncContext->aui8PicOnLevel);
   2955         psb_buffer_unmap(&(ps_mem->bufs_flat_gop));
   2956 
   2957         if (ctx->sRCParams.b16Hierarchical) {
   2958             memset(psMtxEncContext->aui8PicOnLevel, 0, sizeof(psMtxEncContext->aui8PicOnLevel));
   2959             psb_buffer_map(&(ps_mem->bufs_hierar_gop), &(ps_mem->bufs_hierar_gop.virtual_addr));
   2960             if (ps_mem->bufs_hierar_gop.virtual_addr == NULL) {
   2961                 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping sei header\n", __FUNCTION__);
   2962                 return ;
   2963             }
   2964             tng_minigop_generate_hierarchical(ps_mem->bufs_hierar_gop.virtual_addr, psMtxEncContext->ui32BFrameCount,
   2965                 psMtxEncContext->ui8RefSpacing, psMtxEncContext->aui8PicOnLevel);
   2966             psb_buffer_unmap(&(ps_mem->bufs_hierar_gop));
   2967         }
   2968     }
   2969 
   2970 #if INPUT_SCALER_SUPPORTED
   2971     if (ctx->bEnableScaler) {
   2972         IMG_UINT8 sccCoeffs[4][16];
   2973         IMG_UINT32 ui32PitchX, ui32PitchY;
   2974         IMG_INT32 i32Phase, i32Tap;
   2975 
   2976         ui32PitchX = (((IMG_UINT32)(psVideoParams->ui16SourceWidth - psVideoParams->ui8CropLeft - psVideoParams->ui8CropRight)) << 12) / psVideoParams->ui16Width;
   2977         ui32PitchY = (((IMG_UINT32)(psVideoParams->ui16SourceFrameHeight - psVideoParams->ui8CropTop - psVideoParams->ui8CropBottom)) << 12) / psVideoParams->ui16FrameHeight;
   2978 
   2979         // Input size
   2980         psMtxEncContext->ui32ScalerInputSizeReg = F_ENCODE(psVideoParams->ui16SourceWidth - 1, TOPAZHP_EXT_CR_SCALER_INPUT_WIDTH_MIN1) |
   2981             F_ENCODE((psVideoParams->ui16SourceFrameHeight >> (psVideo->bIsInterlaced ? 1 : 0)) - 1, TOPAZHP_EXT_CR_SCALER_INPUT_HEIGHT_MIN1);
   2982 
   2983         psMtxEncContext->ui32ScalerCropReg = F_ENCODE(psVideoParams->ui8CropLeft, TOPAZHP_EXT_CR_SCALER_INPUT_CROP_HOR) |
   2984             F_ENCODE(psVideoParams->ui8CropTop, TOPAZHP_EXT_CR_SCALER_INPUT_CROP_VER);
   2985 
   2986         // Scale factors
   2987         psMtxEncContext->ui32ScalerPitchReg = 0;
   2988 
   2989         if (ui32PitchX > 0x3FFF) {
   2990             psMtxEncContext->ui32ScalerPitchReg |= F_ENCODE(1, TOPAZHP_EXT_CR_SCALER_HOR_BILINEAR_FILTER);
   2991             ui32PitchX >>= 1;
   2992         }
   2993 
   2994         if (ui32PitchX > 0x3FFF) {
   2995             ui32PitchX = 0x3FFF;
   2996         }
   2997 
   2998         if (ui32PitchY > 0x3FFF) {
   2999             psMtxEncContext->ui32ScalerPitchReg |= F_ENCODE(1, TOPAZHP_EXT_CR_SCALER_VER_BILINEAR_FILTER);
   3000             ui32PitchY >>= 1;
   3001         }
   3002 
   3003         if (ui32PitchY > 0x3FFF) {
   3004             ui32PitchY = 0x3FFF;
   3005         }
   3006 
   3007         psMtxEncContext->ui32ScalerPitchReg |= F_ENCODE(ui32PitchX, TOPAZHP_EXT_CR_SCALER_INPUT_HOR_PITCH) |
   3008             F_ENCODE(ui32PitchY, TOPAZHP_EXT_CR_SCALER_INPUT_VER_PITCH);
   3009 
   3010 
   3011         // Coefficients
   3012         VIDEO_CalcCoefs_FromPitch(((IMG_FLOAT)ui32PitchX) / 4096.0f, sccCoeffs);
   3013 
   3014         for (i32Phase = 0; i32Phase < 4; i32Phase++) {
   3015             psMtxEncContext->asHorScalerCoeffRegs[i32Phase] = 0;
   3016             for (i32Tap = 0; i32Tap < 4; i32Tap++) 	{
   3017                 psMtxEncContext->asHorScalerCoeffRegs[i32Phase] |= F_ENCODE(sccCoeffs[3 - i32Tap][(i32Phase * 2) + 1], TOPAZHP_EXT_CR_SCALER_HOR_LUMA_COEFF(i32Tap));
   3018             }
   3019         }
   3020 
   3021         VIDEO_CalcCoefs_FromPitch(((IMG_FLOAT)ui32PitchY) / 4096.0f, sccCoeffs);
   3022 
   3023         for (i32Phase = 0; i32Phase < 4; i32Phase++) {
   3024             psMtxEncContext->asVerScalerCoeffRegs[i32Phase] = 0;
   3025             for (i32Tap = 0; i32Tap < 4; i32Tap++) {
   3026                 psMtxEncContext->asVerScalerCoeffRegs[i32Phase] |= F_ENCODE(sccCoeffs[3 - i32Tap][(i32Phase * 2) + 1], TOPAZHP_EXT_CR_SCALER_VER_LUMA_COEFF(i32Tap));
   3027             }
   3028         }
   3029     } else {
   3030         // Disable scaling
   3031         psMtxEncContext->ui32ScalerInputSizeReg = 0;
   3032     }
   3033 #endif // INPUT_SCALER_SUPPORTED
   3034 
   3035     psb_buffer_unmap(&(ps_mem->bufs_mtx_context));
   3036 
   3037     return ;
   3038 }
   3039 
   3040 static void tng__setvideo_cmdbuf(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
   3041 {
   3042     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
   3043     context_ENC_mem_size *ps_mem_size = &(ctx->ctx_mem_size);
   3044 #ifndef _TNG_FRAMES_
   3045     context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
   3046 #endif
   3047     IMG_MTX_VIDEO_CONTEXT* psMtxEncContext = NULL;
   3048     IMG_INT32 i;
   3049 
   3050     psb_buffer_map(&(ps_mem->bufs_mtx_context), &(ps_mem->bufs_mtx_context.virtual_addr));
   3051     if (ps_mem->bufs_mtx_context.virtual_addr == NULL) {
   3052         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping sei header\n", __FUNCTION__);
   3053         return ;
   3054     }
   3055     psMtxEncContext = (IMG_MTX_VIDEO_CONTEXT*)(ps_mem->bufs_mtx_context.virtual_addr);
   3056 
   3057     tng_cmdbuf_set_phys(&(psMtxEncContext->ui32MVSettingsBTable), 0,
   3058         &(ps_mem->bufs_mv_setting_btable), 0, 0);
   3059     if (ctx->sRCParams.b16Hierarchical)
   3060         tng_cmdbuf_set_phys(&psMtxEncContext->ui32MVSettingsHierarchical, 0,
   3061             &(ps_mem->bufs_mv_setting_hierar), 0, 0);
   3062 #ifdef _TNG_FRAMES_
   3063     tng_cmdbuf_set_phys(psMtxEncContext->apReconstructured, ctx->i32PicNodes,
   3064         &(ps_mem->bufs_recon_pictures), 0, ps_mem_size->recon_pictures);
   3065 #else
   3066     for (i = 0; i < ctx->i32PicNodes; i++) {
   3067         tng_cmdbuf_set_phys(&(psMtxEncContext->apReconstructured[i]), 0,
   3068             &(ps_buf->ref_surface[i]->psb_surface->buf), 0, 0);
   3069     }
   3070 #endif
   3071 
   3072     tng_cmdbuf_set_phys(psMtxEncContext->apColocated, ctx->i32PicNodes,
   3073         &(ps_mem->bufs_colocated), 0, ps_mem_size->colocated);
   3074 
   3075     tng_cmdbuf_set_phys(psMtxEncContext->apMV, ctx->i32MVStores,
   3076         &(ps_mem->bufs_mv), 0, ps_mem_size->mv);
   3077 
   3078     if (ctx->bEnableMVC) {
   3079         tng_cmdbuf_set_phys(psMtxEncContext->apInterViewMV, 2,
   3080             &(ps_mem->bufs_interview_mv), 0, ps_mem_size->interview_mv);
   3081     }
   3082 
   3083     tng_cmdbuf_set_phys(psMtxEncContext->apWritebackRegions, WB_FIFO_SIZE,
   3084         &(ctx->bufs_writeback), 0, ps_mem_size->writeback);
   3085 
   3086     tng_cmdbuf_set_phys(psMtxEncContext->apAboveParams, (IMG_UINT32)(ctx->ui8PipesToUse),
   3087         &(ps_mem->bufs_above_params), 0, ps_mem_size->above_params);
   3088 
   3089     // SEI_INSERTION
   3090     if (ctx->bInsertHRDParams) {
   3091         tng_cmdbuf_set_phys(&psMtxEncContext->pSEIBufferingPeriodTemplate, 0,
   3092             &(ps_mem->bufs_sei_header), ps_mem_size->sei_header, ps_mem_size->sei_header);
   3093         tng_cmdbuf_set_phys(&psMtxEncContext->pSEIPictureTimingTemplate, 0,
   3094             &(ps_mem->bufs_sei_header), ps_mem_size->sei_header * 2, ps_mem_size->sei_header);
   3095     }
   3096 
   3097     tng_cmdbuf_set_phys(psMtxEncContext->apSliceParamsTemplates, NUM_SLICE_TYPES,
   3098         &(ps_mem->bufs_slice_template), 0, ps_mem_size->slice_template);
   3099 
   3100     tng_cmdbuf_set_phys(psMtxEncContext->aui32SliceMap, ctx->ui8SlotsInUse,
   3101         &(ps_mem->bufs_slice_map), 0, ps_mem_size->slice_map);
   3102 
   3103     // WEIGHTED PREDICTION
   3104     if (ctx->bWeightedPrediction || (ctx->ui8VPWeightedImplicitBiPred == WBI_EXPLICIT)) {
   3105         tng_cmdbuf_set_phys(psMtxEncContext->aui32WeightedPredictionVirtAddr, ctx->ui8SlotsInUse,
   3106             &(ps_mem->bufs_weighted_prediction), 0, ps_mem_size->weighted_prediction);
   3107     }
   3108 
   3109     tng_cmdbuf_set_phys(&psMtxEncContext->ui32FlatGopStruct, 0, &(ps_mem->bufs_flat_gop), 0, 0);
   3110     if (psMtxEncContext->b8Hierarchical)
   3111         tng_cmdbuf_set_phys(&psMtxEncContext->ui32HierarGopStruct, 0, &(ps_mem->bufs_hierar_gop), 0, 0);
   3112 
   3113 #ifdef LTREFHEADER
   3114     tng_cmdbuf_set_phys(psMtxEncContext->aui32LTRefHeader, ctx->ui8SlotsInUse,
   3115         &(ps_mem->bufs_lt_ref_header), 0, ps_mem_size->lt_ref_header);
   3116 #endif
   3117 
   3118     tng_cmdbuf_set_phys(psMtxEncContext->apPicHdrTemplates, 4,
   3119         &(ps_mem->bufs_pic_template), 0, ps_mem_size->pic_template);
   3120 
   3121     if (ctx->eStandard == IMG_STANDARD_H264) {
   3122         tng_cmdbuf_set_phys(&(psMtxEncContext->apSeqHeader), 0,
   3123             &(ps_mem->bufs_seq_header), 0, ps_mem_size->seq_header);
   3124         if (ctx->bEnableMVC)
   3125             tng_cmdbuf_set_phys(&(psMtxEncContext->apSubSetSeqHeader), 0,
   3126                 &(ps_mem->bufs_sub_seq_header), 0, ps_mem_size->seq_header);
   3127     }
   3128 
   3129     if (ctx->ui8EnableSelStatsFlags & ESF_FIRST_STAGE_STATS) {
   3130         tng_cmdbuf_set_phys(psMtxEncContext->pFirstPassOutParamAddr, ctx->ui8SlotsInUse,
   3131             &(ps_mem->bufs_first_pass_out_params), 0, ps_mem_size->first_pass_out_params);
   3132     }
   3133 
   3134 #ifndef EXCLUDE_BEST_MP_DECISION_DATA
   3135     // Store the feedback memory address for all "5" slots in the context
   3136     if (ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MB_DECISION_STATS
   3137         || ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MOTION_VECTOR_STATS) {
   3138         tng_cmdbuf_set_phys(psMtxEncContext->pFirstPassOutBestMultipassParamAddr, ctx->ui8SlotsInUse,
   3139             &(ps_mem->bufs_first_pass_out_best_multipass_param), 0, ps_mem_size->first_pass_out_best_multipass_param);
   3140     }
   3141 #endif
   3142 
   3143     //Store the MB-Input control parameter memory for all the 5-slots in the context
   3144     if (ctx->bEnableInpCtrl) {
   3145         tng_cmdbuf_set_phys(psMtxEncContext->pMBCtrlInParamsAddr, ctx->ui8SlotsInUse,
   3146             &(ps_mem->bufs_mb_ctrl_in_params), 0, ps_mem_size->mb_ctrl_in_params);
   3147     }
   3148 
   3149     psb_buffer_unmap(&(ps_mem->bufs_mtx_context));
   3150 
   3151     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s end\n", __FUNCTION__);
   3152 
   3153     return ;
   3154 }
   3155 
   3156 static VAStatus tng__validate_params(context_ENC_p ctx)
   3157 {
   3158     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3159     IMG_UINT16 ui16WidthInMbs = (ctx->ui16Width + 15) >> 4;
   3160     IMG_UINT16 ui16PictureHeight = ((ctx->ui16FrameHeight >> (ctx->bIsInterlaced ? 1 : 0)) + 15) & ~15;
   3161     IMG_UINT16 ui16FrameHeightInMbs = (ctx->ui16FrameHeight + 15) >> 4;
   3162 
   3163     if ((ctx->ui16Width & 0xf) != 0) {
   3164         return VA_STATUS_ERROR_INVALID_PARAMETER;
   3165     }
   3166 
   3167     if ((ctx->ui16FrameHeight & 0xf) != 0) {
   3168         return VA_STATUS_ERROR_INVALID_PARAMETER;
   3169     }
   3170 
   3171     ctx->uMBspS = ui16WidthInMbs * ui16FrameHeightInMbs * ctx->sRCParams.ui32FrameRate;
   3172 
   3173     if (ctx->ui32CoreRev >= MIN_36_REV) {
   3174         if ((ctx->ui16Width > 4096) || (ctx->ui16PictureHeight > 4096)) {
   3175             return VA_STATUS_ERROR_INVALID_PARAMETER;
   3176         }
   3177         if ((ui16WidthInMbs << 4) * ui16PictureHeight > 2048 * 2048) {
   3178             return VA_STATUS_ERROR_INVALID_PARAMETER;
   3179         }
   3180     } else {
   3181         if ((ctx->ui16Width > 2048) || (ui16PictureHeight > 2048)) {
   3182             return VA_STATUS_ERROR_INVALID_PARAMETER;
   3183         }
   3184     }
   3185 
   3186     if (ctx->eStandard == IMG_STANDARD_H264) {
   3187         if ((ctx->ui8DeblockIDC == 0) && (ctx->bArbitrarySO))
   3188             ctx->ui8DeblockIDC = 2;
   3189 
   3190         if ((ctx->ui8DeblockIDC == 0) && ((IMG_UINT32)(ctx->ui8PipesToUse) > 1) && (ctx->ui8SlicesPerPicture > 1)) {
   3191             drv_debug_msg(VIDEO_DEBUG_GENERAL, "WARNING: Full deblocking with multiple pipes will cause a mismatch between reconstructed and encoded video\n");
   3192             drv_debug_msg(VIDEO_DEBUG_GENERAL, "Consider using -deblockIDC 2 or -deblockIDC 1 instead if matching reconstructed video is required.\n");
   3193             drv_debug_msg(VIDEO_DEBUG_GENERAL, "WARNING: Forcing -deblockIDC = 2 for HW verification.\n");
   3194             ctx->ui8DeblockIDC = 2;
   3195         }
   3196     } else if (ctx->eStandard == IMG_STANDARD_H263) {
   3197 		ctx->bArbitrarySO = IMG_FALSE;
   3198 		ctx->ui8DeblockIDC = 1;
   3199     } else {
   3200         ctx->ui8DeblockIDC = 1;
   3201     }
   3202 
   3203     //ctx->sRCParams.ui32SliceByteLimit = 0;
   3204     ctx->sRCParams.ui32SliceMBLimit = 0;
   3205     //slice params
   3206     if (ctx->ui8SlicesPerPicture == 0)
   3207         ctx->ui8SlicesPerPicture = ctx->sCapsParams.ui16RecommendedSlices;
   3208     else {
   3209         if (ctx->ui8SlicesPerPicture > ctx->sCapsParams.ui16MaxSlices)
   3210             ctx->ui8SlicesPerPicture = ctx->sCapsParams.ui16MaxSlices;
   3211         else if (ctx->ui8SlicesPerPicture < ctx->sCapsParams.ui16MinSlices)
   3212             ctx->ui8SlicesPerPicture = ctx->sCapsParams.ui16MinSlices;
   3213     }
   3214 
   3215     if (ctx->ui32pseudo_rand_seed == UNINIT_PARAM) {
   3216         // When -randseed is uninitialised, initialise seed using other commandline values
   3217         ctx->ui32pseudo_rand_seed = (IMG_UINT32) ((ctx->sRCParams.ui32InitialQp +
   3218             ctx->ui16PictureHeight + ctx->ui16Width + ctx->sRCParams.ui32BitsPerSecond) & 0xffffffff);
   3219         // iQP_Luma + pParams->uHeight + pParams->uWidth + pParams->uBitRate) & 0xffffffff);
   3220     }
   3221 
   3222     if (ctx->eStandard == IMG_STANDARD_H264) {
   3223         ctx->ui8PipesToUse = tng__min(ctx->ui8PipesToUse, ctx->ui8SlicesPerPicture);
   3224     } else {
   3225         ctx->ui8PipesToUse = 1;
   3226     }
   3227 
   3228     return vaStatus;
   3229 }
   3230 
   3231 static VAStatus tng__validate_busize(context_ENC_p ctx)
   3232 {
   3233     //IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
   3234     // if no BU size is given then pick one ourselves, if doing arbitrary slice order then make BU = width in bu's
   3235     // forces slice boundaries to no be mid-row
   3236     if (ctx->bArbitrarySO || (ctx->ui32BasicUnit == 0)) {
   3237         ctx->ui32BasicUnit = (ctx->ui16Width / 16);
   3238         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Patched Basic unit to %d\n", ctx->ui32BasicUnit);
   3239     } else {
   3240         IMG_UINT32 ui32MBs, ui32MBsperSlice, ui32MBsLastSlice;
   3241         IMG_UINT32 ui32BUs;
   3242         IMG_INT32  i32SliceHeight;
   3243         IMG_UINT32 ui32MaxSlicesPerPipe, ui32MaxMBsPerPipe, ui32MaxBUsPerPipe;
   3244 
   3245         ui32MBs  = ctx->ui16PictureHeight * ctx->ui16Width / (16 * 16);
   3246 
   3247         i32SliceHeight = ctx->ui16PictureHeight / ctx->ui8SlicesPerPicture;
   3248         i32SliceHeight &= ~15;
   3249 
   3250         ui32MBsperSlice = (i32SliceHeight * ctx->ui16Width) / (16 * 16);
   3251         ui32MBsLastSlice = ui32MBs - (ui32MBsperSlice * (ctx->ui8SlicesPerPicture - 1));
   3252 
   3253         // they have given us a basic unit so validate it
   3254         if (ctx->ui32BasicUnit < 6) {
   3255             drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size too small, must be greater than 6\n");
   3256             return VA_STATUS_ERROR_UNKNOWN;
   3257         }
   3258 
   3259         if (ctx->ui32BasicUnit > ui32MBsperSlice) {
   3260             drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size(%d) too large", ctx->ui32BasicUnit);
   3261             drv_debug_msg(VIDEO_DEBUG_GENERAL, " must not be greater than the number of macroblocks in a slice (%d)\n", ui32MBsperSlice);
   3262             return VA_STATUS_ERROR_UNKNOWN;
   3263         }
   3264         if (ctx->ui32BasicUnit > ui32MBsLastSlice) {
   3265             drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size(%d) too large", ctx->ui32BasicUnit);
   3266             drv_debug_msg(VIDEO_DEBUG_GENERAL, " must not be greater than the number of macroblocks in a slice (%d)\n", ui32MBsLastSlice);
   3267             return VA_STATUS_ERROR_UNKNOWN;
   3268         }
   3269 
   3270         ui32BUs = ui32MBsperSlice / ctx->ui32BasicUnit;
   3271         if ((ui32BUs * ctx->ui32BasicUnit) != ui32MBsperSlice) {
   3272             drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size(%d) not an integer divisor of MB's in a slice(%d)",
   3273                                      ctx->ui32BasicUnit, ui32MBsperSlice);
   3274             return VA_STATUS_ERROR_UNKNOWN;
   3275         }
   3276 
   3277         ui32BUs = ui32MBsLastSlice / ctx->ui32BasicUnit;
   3278         if ((ui32BUs * ctx->ui32BasicUnit) != ui32MBsLastSlice) {
   3279             drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size(%d) not an integer divisor of MB's in the last slice(%d)",
   3280                                      ctx->ui32BasicUnit, ui32MBsLastSlice);
   3281             return VA_STATUS_ERROR_UNKNOWN;
   3282         }
   3283 
   3284         // check if the number of BUs per pipe is greater than 200
   3285         ui32MaxSlicesPerPipe = (IMG_UINT32)(ctx->ui8SlicesPerPicture + ctx->ui8PipesToUse - 1) / (IMG_UINT32)(ctx->ui8PipesToUse);
   3286         ui32MaxMBsPerPipe = (ui32MBsperSlice * (ui32MaxSlicesPerPipe - 1)) + ui32MBsLastSlice;
   3287         ui32MaxBUsPerPipe = (ui32MaxMBsPerPipe + ctx->ui32BasicUnit - 1) / ctx->ui32BasicUnit;
   3288         if (ui32MaxBUsPerPipe > 200) {
   3289             drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size too small. There must be less than 201 basic units per slice");
   3290             return VA_STATUS_ERROR_UNKNOWN;
   3291         }
   3292     }
   3293 
   3294     ctx->sRCParams.ui32BUSize = ctx->ui32BasicUnit;
   3295     return VA_STATUS_SUCCESS;
   3296 }
   3297 
   3298 static VAStatus tng__cmdbuf_new_codec(context_ENC_p ctx)
   3299 {
   3300      VAStatus vaStatus = VA_STATUS_SUCCESS;
   3301      tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
   3302      psb_driver_data_p driver_data = ctx->obj_context->driver_data;
   3303      context_ENC_mem *ps_mem = &(ctx->ctx_mem[0]);
   3304 
   3305      *cmdbuf->cmd_idx++ =
   3306         ((MTX_CMDID_SW_NEW_CODEC & MTX_CMDWORD_ID_MASK) << MTX_CMDWORD_ID_SHIFT) |
   3307         ((ctx->eCodec        & MTX_CMDWORD_CORE_MASK) << MTX_CMDWORD_CORE_SHIFT) |
   3308         (((driver_data->context_id & MTX_CMDWORD_COUNT_MASK) << MTX_CMDWORD_COUNT_SHIFT));
   3309  //       (((driver_data->drm_context & MTX_CMDWORD_COUNT_MASK) << MTX_CMDWORD_COUNT_SHIFT));
   3310 
   3311      tng_cmdbuf_insert_command_param((ctx->ui16Width << 16) | ctx->ui16PictureHeight);
   3312 
   3313     return vaStatus;
   3314 }
   3315 
   3316 static VAStatus tng__cmdbuf_doheader(context_ENC_p ctx)
   3317 {
   3318     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3319     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
   3320      tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
   3321 
   3322     cmdbuf->cmd_idx_saved[TNG_CMDBUF_PIC_HEADER_IDX] = cmdbuf->cmd_idx;
   3323     tng_cmdbuf_insert_command(ctx->obj_context, 0,
   3324                                       MTX_CMDID_DO_HEADER,
   3325                                       0,
   3326                                       &(ps_mem->bufs_seq_header),
   3327                                       0);
   3328     return vaStatus;
   3329 }
   3330 
   3331 static VAStatus tng__cmdbuf_lowpower(context_ENC_p ctx)
   3332 {
   3333     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3334     tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
   3335     psb_driver_data_p driver_data = ctx->obj_context->driver_data;
   3336 
   3337     *cmdbuf->cmd_idx++ =
   3338         ((MTX_CMDID_SW_LEAVE_LOWPOWER & MTX_CMDWORD_ID_MASK) << MTX_CMDWORD_ID_SHIFT) |
   3339         (((ctx->ui32RawFrameCount == 0 ? 1 : 0)  & MTX_CMDWORD_CORE_MASK) << MTX_CMDWORD_CORE_SHIFT) |
   3340         (((driver_data->context_id & MTX_CMDWORD_COUNT_MASK) << MTX_CMDWORD_COUNT_SHIFT));
   3341 
   3342     tng_cmdbuf_insert_command_param(ctx->eCodec);
   3343 
   3344     return vaStatus;
   3345 }
   3346 
   3347 static VAStatus tng__cmdbuf_load_bias(context_ENC_p ctx)
   3348 {
   3349     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3350 
   3351     //init bias parameters
   3352      tng_init_bias_params(ctx);
   3353 
   3354      vaStatus = tng__generate_bias(ctx);
   3355      if (vaStatus != VA_STATUS_SUCCESS) {
   3356          drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: generate bias params\n", __FUNCTION__, vaStatus);
   3357      }
   3358 
   3359      vaStatus = tng_load_bias(ctx, IMG_INTER_P);
   3360      if (vaStatus != VA_STATUS_SUCCESS) {
   3361          drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: load bias params\n", __FUNCTION__, vaStatus);
   3362      }
   3363     return vaStatus;
   3364 }
   3365 
   3366 static VAStatus tng__cmdbuf_setvideo(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
   3367 {
   3368     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3369     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
   3370 
   3371     tng__setvideo_params(ctx, ui32StreamIndex);
   3372     tng__setvideo_cmdbuf(ctx, ui32StreamIndex);
   3373 
   3374     tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
   3375         MTX_CMDID_SETVIDEO, 0, &(ps_mem->bufs_mtx_context), 0);
   3376 
   3377     return vaStatus;
   3378 }
   3379 
   3380 static void tng__rc_update(
   3381     context_ENC_p ctx,
   3382     IMG_UINT32 ui32NewBitrate,
   3383     IMG_UINT8 ui8NewFrameQP,
   3384     IMG_UINT8 ui8NewFrameMinQP,
   3385     IMG_UINT8 ui8NewFrameMaxQP,
   3386     IMG_UINT16 ui16NewIntraPeriod)
   3387 {
   3388     psb_buffer_p buf = (psb_buffer_p)(F_ENCODE(ui8NewFrameMinQP, MTX_MSG_RC_UPDATE_MIN_QP) |
   3389                         F_ENCODE(ui8NewFrameMaxQP, MTX_MSG_RC_UPDATE_MAX_QP) |
   3390                         F_ENCODE(ui16NewIntraPeriod, MTX_MSG_RC_UPDATE_INTRA));
   3391     tng_cmdbuf_insert_command(
   3392                         ctx->obj_context,
   3393                         ctx->ui32StreamID,
   3394                         MTX_CMDID_RC_UPDATE,
   3395                         F_ENCODE(ui8NewFrameQP, MTX_MSG_RC_UPDATE_QP) |
   3396                             F_ENCODE(ui32NewBitrate, MTX_MSG_RC_UPDATE_BITRATE),
   3397                         buf,
   3398                         0);
   3399 }
   3400 
   3401 static VAStatus tng__update_ratecontrol(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
   3402 {
   3403     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3404     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
   3405     IMG_UINT32 ui32CmdData = 0;
   3406     IMG_UINT32 ui32NewBitsPerFrame = 0;
   3407     IMG_UINT8 ui8NewVCMIFrameQP = 0;
   3408 
   3409     if (!(ctx->rc_update_flag))
   3410         return vaStatus;
   3411 
   3412     tng__setup_rcdata(ctx);
   3413 
   3414     drv_debug_msg(VIDEO_DEBUG_GENERAL,
   3415         "%s: frame[%d] bits_per_second = %d, min_qp = %d, max_qp = %d, initial_qp = %d\n",
   3416         __FUNCTION__, ctx->ui32FrameCount[ui32StreamIndex], psRCParams->ui32BitsPerSecond,
   3417         psRCParams->iMinQP, ctx->max_qp, psRCParams->ui32InitialQp);
   3418 
   3419     if (ctx->rc_update_flag & RC_MASK_frame_rate) {
   3420 	tng__rc_update(ctx, psRCParams->ui32BitsPerSecond, -1, -1, -1, -1);
   3421 	ctx->rc_update_flag &= ~RC_MASK_frame_rate;
   3422     }
   3423 
   3424     if (ctx->rc_update_flag & RC_MASK_bits_per_second) {
   3425 	tng__rc_update(ctx, psRCParams->ui32BitsPerSecond, -1, -1, -1, -1);
   3426 	ctx->rc_update_flag &= ~RC_MASK_bits_per_second;
   3427     }
   3428 
   3429     if (ctx->rc_update_flag & RC_MASK_min_qp) {
   3430 	tng__rc_update(ctx, -1, -1, psRCParams->iMinQP, -1, -1);
   3431 	ctx->rc_update_flag &= ~RC_MASK_min_qp;
   3432     }
   3433 
   3434     if (ctx->rc_update_flag & RC_MASK_max_qp) {
   3435 	tng__rc_update(ctx, -1, -1, -1, ctx->max_qp, -1);
   3436 	ctx->rc_update_flag &= ~RC_MASK_max_qp;
   3437     }
   3438 
   3439     if (ctx->rc_update_flag & RC_MASK_initial_qp) {
   3440 	tng__rc_update(ctx, -1, psRCParams->ui32InitialQp, -1, -1, -1);
   3441 	ctx->rc_update_flag &= ~RC_MASK_initial_qp;
   3442     }
   3443 
   3444     if (ctx->rc_update_flag & RC_MASK_intra_period) {
   3445 	tng__rc_update(ctx, -1, -1, -1, -1, ctx->ui32IntraCnt);
   3446 	ctx->rc_update_flag &= ~RC_MASK_intra_period;
   3447     }
   3448 
   3449     return vaStatus;
   3450 }
   3451 
   3452 static VAStatus tng__update_frametype(context_ENC_p ctx, IMG_FRAME_TYPE eFrameType)
   3453 {
   3454     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3455     IMG_UINT32 ui32CmdData = 0;
   3456 
   3457     ui32CmdData = F_ENCODE(IMG_PICMGMT_REF_TYPE, MTX_MSG_PICMGMT_SUBTYPE) |
   3458                 F_ENCODE(eFrameType, MTX_MSG_PICMGMT_DATA);
   3459 
   3460     tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
   3461         MTX_CMDID_PICMGMT ,
   3462         ui32CmdData, 0, 0);
   3463 
   3464     return vaStatus;
   3465 }
   3466 
   3467 static VAStatus tng__cmdbuf_send_picmgmt(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
   3468 {
   3469     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3470     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
   3471 
   3472     if (!(ctx->rc_update_flag))
   3473         return vaStatus;
   3474 
   3475     //tng__setup_rcdata(ctx);
   3476     drv_debug_msg(VIDEO_DEBUG_GENERAL,
   3477         "%s: ui32BitsPerSecond = %d, ui32FrameRate = %d, ui32InitialQp = %d\n",
   3478         __FUNCTION__, psRCParams->ui32BitsPerSecond,
   3479         psRCParams->ui32FrameRate, psRCParams->ui32InitialQp);
   3480     drv_debug_msg(VIDEO_DEBUG_GENERAL,
   3481         "%s: frame_count[%d] = %d\n", __FUNCTION__,
   3482         ui32StreamIndex, ctx->ui32FrameCount[ui32StreamIndex]);
   3483 
   3484     return vaStatus;
   3485 }
   3486 
   3487 
   3488 static VAStatus tng__cmdbuf_provide_buffer(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
   3489 {
   3490     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3491 
   3492     if (ctx->ui8PipesToUse == 1) {
   3493         tng_send_codedbuf(ctx, ctx->ui8SlotsCoded);
   3494     } else {
   3495         /*Make sure DMA start is 128bits alignment*/
   3496         tng_send_codedbuf(ctx, ctx->ui8SlotsCoded * 2);
   3497         tng_send_codedbuf(ctx, ctx->ui8SlotsCoded * 2 + 1);
   3498     }
   3499 
   3500     if (ctx->sRCParams.ui16BFrames > 0)
   3501         tng__provide_buffer_BFrames(ctx, ui32StreamIndex);
   3502     else
   3503         tng__provide_buffer_PFrames(ctx, ui32StreamIndex);
   3504 /*
   3505     if (ctx->ui32LastPicture != 0) {
   3506         drv_debug_msg(VIDEO_DEBUG_GENERAL,
   3507             "%s: frame_count[%d] = %d\n", __FUNCTION__,
   3508             ui32StreamIndex, ctx->ui32FrameCount[ui32StreamIndex]);
   3509         tng_picmgmt_update(ctx,IMG_PICMGMT_EOS, ctx->ui32LastPicture);
   3510     }
   3511 */
   3512 #ifdef _TOPAZHP_REC_
   3513     tng_send_rec_frames(ctx, -1, 0);
   3514     tng_send_ref_frames(ctx, 0, 0);
   3515     tng_send_ref_frames(ctx, 1, 0);
   3516 #endif
   3517 
   3518     ctx->ui8SlotsCoded = (ctx->ui8SlotsCoded + 1) & 1;
   3519 
   3520     return vaStatus;
   3521 }
   3522 
   3523 VAStatus tng__set_ctx_buf(context_ENC_p ctx, IMG_UINT32 __maybe_unused ui32StreamID)
   3524 {
   3525     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3526     IMG_UINT8 ui8IsJpeg;
   3527 
   3528     vaStatus = tng__validate_params(ctx);
   3529     if (vaStatus != VA_STATUS_SUCCESS) {
   3530         drv_debug_msg(VIDEO_DEBUG_ERROR, "validate params");
   3531     }
   3532 
   3533     vaStatus = tng__validate_busize(ctx);
   3534     if (vaStatus != VA_STATUS_SUCCESS) {
   3535         drv_debug_msg(VIDEO_DEBUG_ERROR, "validate busize");
   3536     }
   3537     ctx->ctx_cmdbuf[0].ui32LowCmdCount = 0xa5a5a5a5 %  MAX_TOPAZ_CMD_COUNT;
   3538     ctx->ctx_cmdbuf[0].ui32HighCmdCount = 0;
   3539     ctx->ctx_cmdbuf[0].ui32HighWBReceived = 0;
   3540 
   3541     ui8IsJpeg = (ctx->eStandard == IMG_STANDARD_JPEG) ? 1 : 0;
   3542     vaStatus = tng__alloc_context_buffer(ctx, ui8IsJpeg, 0);
   3543     if (vaStatus != VA_STATUS_SUCCESS) {
   3544         drv_debug_msg(VIDEO_DEBUG_ERROR, "setup enc profile");
   3545     }
   3546     return vaStatus;
   3547 }
   3548 
   3549 static VAStatus tng__set_headers (context_ENC_p ctx, IMG_UINT32 __maybe_unused ui32StreamID)
   3550 {
   3551     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3552     IMG_UINT8 ui8SlotIdx = 0;
   3553 
   3554     vaStatus = tng__prepare_templates(ctx, 0);
   3555     if (vaStatus != VA_STATUS_SUCCESS) {
   3556         drv_debug_msg(VIDEO_DEBUG_ERROR, "prepare_templates\n");
   3557     }
   3558 
   3559     for (ui8SlotIdx = 0; ui8SlotIdx < ctx->ui8SlotsInUse; ui8SlotIdx++)
   3560         tng_fill_slice_map(ctx, (IMG_UINT32)ui8SlotIdx, 0);
   3561 
   3562     return vaStatus;
   3563 }
   3564 
   3565 static VAStatus tng__set_cmd_buf(context_ENC_p ctx, IMG_UINT32 __maybe_unused ui32StreamID)
   3566 {
   3567     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3568 
   3569     vaStatus = tng__cmdbuf_new_codec(ctx);
   3570     if (vaStatus != VA_STATUS_SUCCESS) {
   3571         drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf new codec\n");
   3572     }
   3573 
   3574     vaStatus = tng__cmdbuf_lowpower(ctx);
   3575     if (vaStatus != VA_STATUS_SUCCESS) {
   3576         drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf lowpower\n");
   3577     }
   3578 
   3579     vaStatus = tng__cmdbuf_load_bias(ctx);
   3580     if (vaStatus != VA_STATUS_SUCCESS) {
   3581         drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf load bias\n");
   3582     }
   3583 
   3584     vaStatus = tng__cmdbuf_setvideo(ctx, 0);
   3585     if (vaStatus != VA_STATUS_SUCCESS) {
   3586         drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf setvideo\n");
   3587     }
   3588     return vaStatus;
   3589 }
   3590 
   3591 VAStatus tng__end_one_frame(context_ENC_p ctx, IMG_UINT32 ui32StreamID)
   3592 {
   3593     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3594     context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
   3595 
   3596     drv_debug_msg(VIDEO_DEBUG_GENERAL, "ui32StreamID is %d.\n", ui32StreamID);
   3597 
   3598     /* save current settings */
   3599     ps_buf->previous_src_surface = ps_buf->src_surface;
   3600 #ifdef _TNG_FRAMES_
   3601     ps_buf->previous_ref_surface = ps_buf->ref_surface;
   3602 #else
   3603     ps_buf->previous_ref_surface = ps_buf->ref_surface[0];
   3604 #endif
   3605 
   3606     /*Frame Skip flag in Coded Buffer of frame N determines if frame N+2
   3607     * should be skipped, which means sending encoding commands of frame N+1 doesn't
   3608     * have to wait until frame N is completed encoded. It reduces the precision of
   3609     * rate control but improves HD encoding performance a lot.*/
   3610     ps_buf->pprevious_coded_buf = ps_buf->previous_coded_buf;
   3611     ps_buf->previous_coded_buf = ps_buf->coded_buf;
   3612 
   3613     ctx->ePreFrameType = ctx->eFrameType;
   3614 
   3615     return vaStatus;
   3616 }
   3617 
   3618 VAStatus tng_EndPicture(context_ENC_p ctx)
   3619 {
   3620     VAStatus vaStatus = VA_STATUS_SUCCESS;
   3621     tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
   3622     context_ENC_mem *ps_mem = &(ctx->ctx_mem[0]);
   3623     unsigned int offset;
   3624     int value;
   3625 
   3626     drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: ctx->ui8SlicesPerPicture = %d, ctx->ui32FrameCount[0] = %d\n",
   3627          __FUNCTION__, ctx->ui8SlicesPerPicture, ctx->ui32FrameCount[0]);
   3628 
   3629     if (ctx->ui32FrameCount[0] == 0) {
   3630         vaStatus = tng__set_ctx_buf(ctx, 0);
   3631         if (vaStatus != VA_STATUS_SUCCESS) {
   3632             drv_debug_msg(VIDEO_DEBUG_ERROR, "set ctx buf \n");
   3633         }
   3634         vaStatus = tng__set_headers(ctx, 0);
   3635         if (vaStatus != VA_STATUS_SUCCESS) {
   3636             drv_debug_msg(VIDEO_DEBUG_ERROR, "set headers \n");
   3637         }
   3638 
   3639         vaStatus = tng__set_cmd_buf(ctx, 0);
   3640         if (vaStatus != VA_STATUS_SUCCESS) {
   3641            drv_debug_msg(VIDEO_DEBUG_ERROR, "set cmd buf \n");
   3642         }
   3643 
   3644 #ifdef _TOPAZHP_PDUMP_
   3645 	tng_trace_setvideo(ctx, 0);
   3646 #endif
   3647     } else {
   3648         vaStatus = tng__cmdbuf_lowpower(ctx);
   3649         if (vaStatus != VA_STATUS_SUCCESS) {
   3650             drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf lowpower\n");
   3651         }
   3652     }
   3653 
   3654     if (ctx->sRCParams.eRCMode != IMG_RCMODE_NONE ||
   3655 	ctx->rc_update_flag) {
   3656         vaStatus = tng__update_ratecontrol(ctx, ctx->ui32StreamID);
   3657         if (vaStatus != VA_STATUS_SUCCESS) {
   3658             drv_debug_msg(VIDEO_DEBUG_ERROR, "send picmgmt");
   3659         }
   3660     }
   3661 
   3662     if ((ctx->idr_force_flag == 1) && (ctx->sRCParams.ui16BFrames == 0)){
   3663         vaStatus = tng__update_frametype(ctx, IMG_FRAME_IDR);
   3664         if (vaStatus != VA_STATUS_SUCCESS) {
   3665             drv_debug_msg(VIDEO_DEBUG_ERROR, "send picmgmt IDR");
   3666         }
   3667         ctx->idr_force_flag =0;
   3668     }
   3669 
   3670     vaStatus = tng__cmdbuf_provide_buffer(ctx, ctx->ui32StreamID);
   3671     if (vaStatus != VA_STATUS_SUCCESS) {
   3672         drv_debug_msg(VIDEO_DEBUG_ERROR, "provide buffer");
   3673     }
   3674 
   3675     if (ctx->bEnableAIR == IMG_TRUE ||
   3676 	ctx->bEnableCIR == IMG_TRUE) {
   3677 	tng_air_set_input_control(ctx, 0);
   3678 
   3679 	if (ctx->bEnableAIR == IMG_TRUE)
   3680 	    tng_air_set_output_control(ctx, 0);
   3681     }
   3682 
   3683     if (ctx->eStandard == IMG_STANDARD_MPEG4) {
   3684         if (ctx->ui32FrameCount[0] == 0) {
   3685             vaStatus = tng__cmdbuf_doheader(ctx);
   3686             if (vaStatus != VA_STATUS_SUCCESS) {
   3687                 drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf doheader\n");
   3688             }
   3689         }
   3690         tng__MPEG4ES_send_seq_header(ctx, ctx->ui32StreamID);
   3691     }
   3692 
   3693     if (ctx->bInsertHRDParams)
   3694 	tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
   3695 	    MTX_CMDID_DO_HEADER, 0, &(ps_mem->bufs_sei_header), 0);
   3696 
   3697     tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
   3698         MTX_CMDID_ENCODE_FRAME, 0, 0, 0);
   3699 
   3700 #ifdef _TOPAZHP_CMDBUF_
   3701     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s addr = 0x%08x \n", __FUNCTION__, cmdbuf);
   3702     tng__trace_cmdbuf_words(cmdbuf);
   3703     tng__trace_cmdbuf(cmdbuf, ctx->ui32StreamID);
   3704 #endif
   3705 
   3706     //    tng_buffer_unmap(ctx, ctx->ui32StreamID);
   3707     tng_cmdbuf_mem_unmap(cmdbuf);
   3708 
   3709     vaStatus = tng__end_one_frame(ctx, 0);
   3710     if (vaStatus != VA_STATUS_SUCCESS) {
   3711        drv_debug_msg(VIDEO_DEBUG_ERROR, "setting when one frame ends\n");
   3712     }
   3713 
   3714     if (tng_context_flush_cmdbuf(ctx->obj_context)) {
   3715         vaStatus = VA_STATUS_ERROR_UNKNOWN;
   3716     }
   3717 
   3718 
   3719     ++(ctx->ui32FrameCount[ctx->ui32StreamID]);
   3720     ++(ctx->ui32RawFrameCount);
   3721     return vaStatus;
   3722 }
   3723