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