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