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