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