ihevcd_parse_slice.c revision 0d8951cef4b1a1dbf4ff5ba3e8796cf1d4503098
1/****************************************************************************** 2* 3* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore 4* 5* Licensed under the Apache License, Version 2.0 (the "License"); 6* you may not use this file except in compliance with the License. 7* You may obtain a copy of the License at: 8* 9* http://www.apache.org/licenses/LICENSE-2.0 10* 11* Unless required by applicable law or agreed to in writing, software 12* distributed under the License is distributed on an "AS IS" BASIS, 13* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14* See the License for the specific language governing permissions and 15* limitations under the License. 16* 17******************************************************************************/ 18/** 19 ******************************************************************************* 20 * @file 21 * ihevcd_parse_slice.c 22 * 23 * @brief 24 * Contains functions for parsing slice data 25 * 26 * @author 27 * Harish 28 * 29 * @par List of Functions: 30 * 31 * @remarks 32 * None 33 * 34 ******************************************************************************* 35 */ 36/*****************************************************************************/ 37/* File Includes */ 38/*****************************************************************************/ 39#include <stdio.h> 40#include <stddef.h> 41#include <stdlib.h> 42#include <string.h> 43#include <assert.h> 44 45#include "ihevc_typedefs.h" 46#include "iv.h" 47#include "ivd.h" 48#include "ihevcd_cxa.h" 49#include "ithread.h" 50 51#include "ihevc_defs.h" 52#include "ihevc_debug.h" 53#include "ihevc_structs.h" 54#include "ihevc_macros.h" 55#include "ihevc_mem_fns.h" 56#include "ihevc_platform_macros.h" 57 58#include "ihevc_common_tables.h" 59#include "ihevc_error.h" 60#include "ihevc_cabac_tables.h" 61 62#include "ihevcd_trace.h" 63#include "ihevcd_defs.h" 64#include "ihevcd_function_selector.h" 65#include "ihevcd_structs.h" 66#include "ihevcd_error.h" 67#include "ihevcd_nal.h" 68#include "ihevcd_bitstream.h" 69#include "ihevcd_utils.h" 70#include "ihevcd_parse_slice.h" 71#include "ihevcd_parse_residual.h" 72#include "ihevcd_cabac.h" 73#include "ihevcd_job_queue.h" 74#include "ihevcd_intra_pred_mode_prediction.h" 75#include "ihevcd_common_tables.h" 76#include "ihevcd_process_slice.h" 77#ifdef GPU_BUILD 78#include "ihevcd_opencl_mc_interface.h" 79#endif 80#include "ihevcd_debug.h" 81#include "ihevcd_get_mv.h" 82#include "ihevcd_boundary_strength.h" 83#include "ihevcd_ilf_padding.h" 84#include "ihevcd_statistics.h" 85/* Bit stream offset threshold */ 86#define BITSTRM_OFF_THRS 8 87 88/** 89 * Table used to decode part_mode if AMP is enabled and current CU is not min CU 90 */ 91const UWORD8 gau1_part_mode_amp[] = { PART_nLx2N, PART_nRx2N, PART_Nx2N, 0xFF, PART_2NxnU, PART_2NxnD, PART_2NxN, 0xFF }; 92 93const UWORD32 gau4_ct_depth_mask[] = { 0x0, 0x55555555, 0xAAAAAAAA, 0xFFFFFFFF }; 94 95 96 97/** 98 ******************************************************************************* 99 * 100 * @brief 101 * Parses Transform tree syntax 102 * 103 * @par Description: 104 * Parses Transform tree syntax as per Section:7.3.9.8 105 * 106 * @param[in] ps_codec 107 * Pointer to codec context 108 * 109 * @returns Status 110 * 111 * @remarks 112 * 113 * 114 ******************************************************************************* 115 */ 116 117WORD32 ihevcd_parse_transform_tree(codec_t *ps_codec, 118 WORD32 x0, WORD32 y0, 119 WORD32 cu_x_base, WORD32 cu_y_base, 120 WORD32 log2_trafo_size, 121 WORD32 trafo_depth, 122 WORD32 blk_idx, 123 WORD32 intra_pred_mode) 124{ 125 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 126 sps_t *ps_sps; 127 pps_t *ps_pps; 128 WORD32 value; 129 WORD32 x1, y1; 130 WORD32 max_trafo_depth; 131 132 bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm; 133 WORD32 intra_split_flag; 134 WORD32 split_transform_flag; 135 WORD32 ctxt_idx; 136 cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac; 137 138 max_trafo_depth = ps_codec->s_parse.s_cu.i4_max_trafo_depth; 139 ps_sps = ps_codec->s_parse.ps_sps; 140 ps_pps = ps_codec->s_parse.ps_pps; 141 intra_split_flag = ps_codec->s_parse.s_cu.i4_intra_split_flag; 142 143 { 144 split_transform_flag = 0; 145 if((log2_trafo_size <= ps_sps->i1_log2_max_transform_block_size) && 146 (log2_trafo_size > ps_sps->i1_log2_min_transform_block_size) && 147 (trafo_depth < max_trafo_depth) && 148 !(intra_split_flag && (trafo_depth == 0))) 149 { 150 /* encode the split transform flag, context derived as per Table9-37 */ 151 ctxt_idx = IHEVC_CAB_SPLIT_TFM + (5 - log2_trafo_size); 152 153 TRACE_CABAC_CTXT("split_transform_flag", ps_cabac->u4_range, ctxt_idx); 154 split_transform_flag = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 155 AEV_TRACE("split_transform_flag", split_transform_flag, 156 ps_cabac->u4_range); 157 158 } 159 else 160 { 161 WORD32 inter_split_flag = 0; 162 163 if((0 == ps_sps->i1_max_transform_hierarchy_depth_inter) && 164 (PRED_MODE_INTER == ps_codec->s_parse.s_cu.i4_pred_mode) && 165 (PART_2Nx2N != ps_codec->s_parse.s_cu.i4_part_mode) && 166 (0 == trafo_depth)) 167 { 168 inter_split_flag = 1; 169 } 170 171 if((log2_trafo_size > ps_sps->i1_log2_max_transform_block_size) || 172 ((1 == intra_split_flag) && (0 == trafo_depth)) || 173 (1 == inter_split_flag)) 174 { 175 split_transform_flag = 1; 176 } 177 } 178 179 if(0 == trafo_depth) 180 { 181 ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth] = 0; 182 ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth] = 0; 183 } 184 else 185 { 186 ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth] = ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth - 1]; 187 ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth] = ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth - 1]; 188 } 189 if(trafo_depth == 0 || log2_trafo_size > 2) 190 { 191 ctxt_idx = IHEVC_CAB_CBCR_IDX + trafo_depth; 192 /* CBF for Cb/Cr is sent only if the parent CBF for Cb/Cr is non-zero */ 193 if((trafo_depth == 0) || ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth - 1]) 194 { 195 TRACE_CABAC_CTXT("cbf_cb", ps_cabac->u4_range, ctxt_idx); 196 value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 197 AEV_TRACE("cbf_cb", value, ps_cabac->u4_range); 198 ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth] = value; 199 } 200 201 if((trafo_depth == 0) || ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth - 1]) 202 { 203 TRACE_CABAC_CTXT("cbf_cr", ps_cabac->u4_range, ctxt_idx); 204 value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 205 AEV_TRACE("cbf_cr", value, ps_cabac->u4_range); 206 ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth] = value; 207 } 208 } 209 if(split_transform_flag) 210 { 211 WORD32 intra_pred_mode_tmp; 212 x1 = x0 + ((1 << log2_trafo_size) >> 1); 213 y1 = y0 + ((1 << log2_trafo_size) >> 1); 214 215 /* For transform depth of zero, intra pred mode as decoded at CU */ 216 /* level is sent to the transform tree nodes */ 217 /* When depth is non-zero intra pred mode of parent node is sent */ 218 /* This takes care of passing correct mode to all the child nodes */ 219 intra_pred_mode_tmp = trafo_depth ? intra_pred_mode : ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[0]; 220 ihevcd_parse_transform_tree(ps_codec, x0, y0, x0, y0, log2_trafo_size - 1, trafo_depth + 1, 0, intra_pred_mode_tmp); 221 222 intra_pred_mode_tmp = trafo_depth ? intra_pred_mode : ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[1]; 223 ihevcd_parse_transform_tree(ps_codec, x1, y0, x0, y0, log2_trafo_size - 1, trafo_depth + 1, 1, intra_pred_mode_tmp); 224 225 intra_pred_mode_tmp = trafo_depth ? intra_pred_mode : ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[2]; 226 ihevcd_parse_transform_tree(ps_codec, x0, y1, x0, y0, log2_trafo_size - 1, trafo_depth + 1, 2, intra_pred_mode_tmp); 227 228 intra_pred_mode_tmp = trafo_depth ? intra_pred_mode : ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[3]; 229 ihevcd_parse_transform_tree(ps_codec, x1, y1, x0, y0, log2_trafo_size - 1, trafo_depth + 1, 3, intra_pred_mode_tmp); 230 231 } 232 else 233 { 234 WORD32 ctb_x_base; 235 WORD32 ctb_y_base; 236 WORD32 cu_qp_delta_abs; 237 238 239 240 tu_t *ps_tu = ps_codec->s_parse.ps_tu; 241 cu_qp_delta_abs = 0; 242 ctb_x_base = ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size; 243 ctb_y_base = ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size; 244 245 if((ps_codec->s_parse.s_cu.i4_pred_mode == PRED_MODE_INTRA) || 246 (trafo_depth != 0) || 247 (ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth]) || 248 (ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth])) 249 { 250 ctxt_idx = IHEVC_CAB_CBF_LUMA_IDX; 251 ctxt_idx += (trafo_depth == 0) ? 1 : 0; 252 253 TRACE_CABAC_CTXT("cbf_luma", ps_cabac->u4_range, ctxt_idx); 254 value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 255 AEV_TRACE("cbf_luma", value, ps_cabac->u4_range); 256 257 ps_codec->s_parse.s_cu.i1_cbf_luma = value; 258 } 259 else 260 { 261 ps_codec->s_parse.s_cu.i1_cbf_luma = 1; 262 } 263 264 /* Initialize ps_tu to default values */ 265 /* If required change this to WORD32 packed write */ 266 ps_tu->b1_cb_cbf = 0; 267 ps_tu->b1_cr_cbf = 0; 268 ps_tu->b1_y_cbf = 0; 269 ps_tu->b4_pos_x = ((x0 - ctb_x_base) >> 2); 270 ps_tu->b4_pos_y = ((y0 - ctb_y_base) >> 2); 271 ps_tu->b1_transquant_bypass = ps_codec->s_parse.s_cu.i4_cu_transquant_bypass; 272 ps_tu->b3_size = (log2_trafo_size - 2); 273 ps_tu->b7_qp = ps_codec->s_parse.u4_qp; 274 275 ps_tu->b6_luma_intra_mode = intra_pred_mode; 276 ps_tu->b3_chroma_intra_mode_idx = ps_codec->s_parse.s_cu.i4_intra_chroma_pred_mode_idx; 277 278 /* Section:7.3.12 Transform unit syntax inlined here */ 279 if(ps_codec->s_parse.s_cu.i1_cbf_luma || 280 ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth] || 281 ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth]) 282 { 283 WORD32 intra_pred_mode_chroma; 284 if(ps_pps->i1_cu_qp_delta_enabled_flag && !ps_codec->s_parse.i4_is_cu_qp_delta_coded) 285 { 286 287 288 WORD32 c_max = TU_MAX_QP_DELTA_ABS; 289 WORD32 ctxt_inc = IHEVC_CAB_QP_DELTA_ABS; 290 WORD32 ctxt_inc_max = CTXT_MAX_QP_DELTA_ABS; 291 292 TRACE_CABAC_CTXT("cu_qp_delta_abs", ps_cabac->u4_range, ctxt_inc); 293 /* qp_delta_abs is coded as combination of tunary and eg0 code */ 294 /* See Table 9-32 and Table 9-37 for details on cu_qp_delta_abs */ 295 cu_qp_delta_abs = ihevcd_cabac_decode_bins_tunary(ps_cabac, 296 ps_bitstrm, 297 c_max, 298 ctxt_inc, 299 0, 300 ctxt_inc_max); 301 if(cu_qp_delta_abs >= c_max) 302 { 303 value = ihevcd_cabac_decode_bypass_bins_egk(ps_cabac, ps_bitstrm, 0); 304 cu_qp_delta_abs += value; 305 } 306 AEV_TRACE("cu_qp_delta_abs", cu_qp_delta_abs, ps_cabac->u4_range); 307 308 309 ps_codec->s_parse.i4_is_cu_qp_delta_coded = 1; 310 311 312 if(cu_qp_delta_abs) 313 { 314 value = ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm); 315 AEV_TRACE("cu_qp_delta_sign", value, ps_cabac->u4_range); 316 317 if(value) 318 cu_qp_delta_abs = -cu_qp_delta_abs; 319 320 } 321 ps_codec->s_parse.s_cu.i4_cu_qp_delta = cu_qp_delta_abs; 322 323 } 324 325 if(ps_codec->s_parse.s_cu.i1_cbf_luma) 326 { 327 ps_tu->b1_y_cbf = 1; 328 ihevcd_parse_residual_coding(ps_codec, x0, y0, log2_trafo_size, 0, intra_pred_mode); 329 } 330 331 if(4 == ps_codec->s_parse.s_cu.i4_intra_chroma_pred_mode_idx) 332 intra_pred_mode_chroma = ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[0]; 333 else 334 { 335 intra_pred_mode_chroma = gau1_intra_pred_chroma_modes[ps_codec->s_parse.s_cu.i4_intra_chroma_pred_mode_idx]; 336 337 if(intra_pred_mode_chroma == 338 ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[0]) 339 { 340 intra_pred_mode_chroma = INTRA_ANGULAR(34); 341 } 342 343 } 344 if(log2_trafo_size > 2) 345 { 346 if(ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth]) 347 { 348 ps_tu->b1_cb_cbf = 1; 349 ihevcd_parse_residual_coding(ps_codec, x0, y0, log2_trafo_size - 1, 1, intra_pred_mode_chroma); 350 } 351 352 if(ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth]) 353 { 354 ps_tu->b1_cr_cbf = 1; 355 ihevcd_parse_residual_coding(ps_codec, x0, y0, log2_trafo_size - 1, 2, intra_pred_mode_chroma); 356 } 357 } 358 else if(blk_idx == 3) 359 { 360 if(ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth]) 361 { 362 ps_tu->b1_cb_cbf = 1; 363 ihevcd_parse_residual_coding(ps_codec, cu_x_base, cu_y_base, log2_trafo_size, 1, intra_pred_mode_chroma); 364 } 365 366 if(ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth]) 367 { 368 ps_tu->b1_cr_cbf = 1; 369 ihevcd_parse_residual_coding(ps_codec, cu_x_base, cu_y_base, log2_trafo_size, 2, intra_pred_mode_chroma); 370 } 371 } 372 else 373 { 374 //ps_tu->b1_chroma_present = 0; 375 ps_tu->b3_chroma_intra_mode_idx = INTRA_PRED_CHROMA_IDX_NONE; 376 } 377 } 378 else 379 { 380 if((3 != blk_idx) && (2 == log2_trafo_size)) 381 { 382 ps_tu->b3_chroma_intra_mode_idx = INTRA_PRED_CHROMA_IDX_NONE; 383 } 384 } 385 386 /* Set the first TU in CU flag */ 387 { 388 if((ps_codec->s_parse.s_cu.i4_pos_x << 3) == (ps_tu->b4_pos_x << 2) && 389 (ps_codec->s_parse.s_cu.i4_pos_y << 3) == (ps_tu->b4_pos_y << 2)) 390 { 391 ps_tu->b1_first_tu_in_cu = 1; 392 } 393 else 394 { 395 ps_tu->b1_first_tu_in_cu = 0; 396 } 397 } 398 ps_codec->s_parse.ps_tu++; 399 ps_codec->s_parse.s_cu.i4_tu_cnt++; 400 ps_codec->s_parse.i4_pic_tu_idx++; 401 } 402 } 403 return ret; 404} 405/** 406 ******************************************************************************* 407 * 408 * @brief 409 * Parses Motion vector difference 410 * 411 * @par Description: 412 * Parses Motion vector difference as per Section:7.3.9.9 413 * 414 * @param[in] ps_codec 415 * Pointer to codec context 416 * 417 * @returns Error from IHEVCD_ERROR_T 418 * 419 * @remarks 420 * 421 * 422 ******************************************************************************* 423 */ 424IHEVCD_ERROR_T ihevcd_parse_mvd(codec_t *ps_codec, mv_t *ps_mv) 425{ 426 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 427 WORD32 value; 428 WORD32 abs_mvd; 429 bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm; 430 WORD32 abs_mvd_greater0_flag[2]; 431 WORD32 abs_mvd_greater1_flag[2]; 432 WORD32 ctxt_idx; 433 cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac; 434 435 436 ctxt_idx = IHEVC_CAB_MVD_GRT0; 437 /* encode absmvd_x > 0 */ 438 TRACE_CABAC_CTXT("abs_mvd_greater0_flag[0]", ps_cabac->u4_range, ctxt_idx); 439 abs_mvd_greater0_flag[0] = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 440 AEV_TRACE("abs_mvd_greater0_flag[0]", abs_mvd_greater0_flag[0], ps_cabac->u4_range); 441 442 /* encode absmvd_y > 0 */ 443 TRACE_CABAC_CTXT("abs_mvd_greater0_flag[1]", ps_cabac->u4_range, ctxt_idx); 444 abs_mvd_greater0_flag[1] = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 445 AEV_TRACE("abs_mvd_greater0_flag[1]", abs_mvd_greater0_flag[1], ps_cabac->u4_range); 446 447 ctxt_idx = IHEVC_CAB_MVD_GRT1; 448 abs_mvd_greater1_flag[0] = 0; 449 abs_mvd_greater1_flag[1] = 0; 450 451 if(abs_mvd_greater0_flag[0]) 452 { 453 TRACE_CABAC_CTXT("abs_mvd_greater1_flag[0]", ps_cabac->u4_range, ctxt_idx); 454 abs_mvd_greater1_flag[0] = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 455 AEV_TRACE("abs_mvd_greater1_flag[0]", abs_mvd_greater1_flag[0], ps_cabac->u4_range); 456 } 457 if(abs_mvd_greater0_flag[1]) 458 { 459 TRACE_CABAC_CTXT("abs_mvd_greater1_flag[1]", ps_cabac->u4_range, ctxt_idx); 460 abs_mvd_greater1_flag[1] = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 461 AEV_TRACE("abs_mvd_greater1_flag[1]", abs_mvd_greater1_flag[1], ps_cabac->u4_range); 462 } 463 abs_mvd = 0; 464 if(abs_mvd_greater0_flag[0]) 465 { 466 abs_mvd = 1; 467 if(abs_mvd_greater1_flag[0]) 468 { 469 value = ihevcd_cabac_decode_bypass_bins_egk(ps_cabac, ps_bitstrm, 1); 470 AEV_TRACE("abs_mvd_minus2[0]", value, ps_cabac->u4_range); 471 abs_mvd = value + 2; 472 } 473 value = ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm); 474 AEV_TRACE("mvd_sign_flag[0]", value, ps_cabac->u4_range); 475 if(value) 476 { 477 abs_mvd = -abs_mvd; 478 } 479 480 } 481 ps_mv->i2_mvx = abs_mvd; 482 abs_mvd = 0; 483 if(abs_mvd_greater0_flag[1]) 484 { 485 abs_mvd = 1; 486 if(abs_mvd_greater1_flag[1]) 487 { 488 value = ihevcd_cabac_decode_bypass_bins_egk(ps_cabac, ps_bitstrm, 1); 489 AEV_TRACE("abs_mvd_minus2[1]", value, ps_cabac->u4_range); 490 abs_mvd = value + 2; 491 492 } 493 value = ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm); 494 AEV_TRACE("mvd_sign_flag[1]", value, ps_cabac->u4_range); 495 496 if(value) 497 { 498 abs_mvd = -abs_mvd; 499 } 500 } 501 ps_mv->i2_mvy = abs_mvd; 502 503 return ret; 504} 505 506/** 507 ******************************************************************************* 508 * 509 * @brief 510 * Parses PCM sample 511 * 512 * 513 * @par Description: 514 * Parses PCM sample as per Section:7.3.9.7 Pcm sample syntax 515 * 516 * @param[in] ps_codec 517 * Pointer to codec context 518 * 519 * @returns Error from IHEVCD_ERROR_T 520 * 521 * @remarks 522 * 523 * 524 ******************************************************************************* 525 */ 526 527IHEVCD_ERROR_T ihevcd_parse_pcm_sample(codec_t *ps_codec, 528 WORD32 x0, 529 WORD32 y0, 530 WORD32 log2_cb_size) 531{ 532 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 533 cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac; 534 sps_t *ps_sps; 535 536 WORD32 value; 537 WORD32 i; 538 539 WORD32 num_bits; 540 UWORD32 u4_sig_coeff_map; 541 bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm; 542 tu_t *ps_tu = ps_codec->s_parse.ps_tu; 543 tu_sblk_coeff_data_t *ps_tu_sblk_coeff_data; 544 UWORD8 *pu1_coeff_data; 545 ps_sps = ps_codec->s_parse.ps_sps; 546 547 UNUSED(value); 548 UNUSED(ps_tu); 549 UNUSED(ps_cabac); 550 UNUSED(x0); 551 UNUSED(y0); 552 553 { 554 WORD8 *pi1_scan_idx; 555 WORD8 *pi1_buf = (WORD8 *)ps_codec->s_parse.pv_tu_coeff_data; 556 WORD8 *pi1_num_coded_subblks; 557 558 /* First WORD8 gives number of coded subblocks */ 559 pi1_num_coded_subblks = pi1_buf++; 560 561 /* Set number of coded subblocks in the current TU to zero */ 562 /* For PCM there will be only one subblock which is the same size as CU */ 563 *pi1_num_coded_subblks = 1; 564 565 /* Second WORD8 gives (scan idx << 1) | trans_skip */ 566 pi1_scan_idx = pi1_buf++; 567 *pi1_scan_idx = (0 << 1) | 1; 568 569 /* Store the incremented pointer in pv_tu_coeff_data */ 570 ps_codec->s_parse.pv_tu_coeff_data = pi1_buf; 571 572 } 573 574 u4_sig_coeff_map = 0xFFFFFFFF; 575 ps_tu_sblk_coeff_data = (tu_sblk_coeff_data_t *)ps_codec->s_parse.pv_tu_coeff_data; 576 ps_tu_sblk_coeff_data->u2_sig_coeff_map = u4_sig_coeff_map; 577 ps_tu_sblk_coeff_data->u2_subblk_pos = 0; 578 579 pu1_coeff_data = (UWORD8 *)&ps_tu_sblk_coeff_data->ai2_level[0]; 580 581 num_bits = ps_sps->i1_pcm_sample_bit_depth_luma; 582 583 for(i = 0; i < 1 << (log2_cb_size << 1); i++) 584 { 585 TRACE_CABAC_CTXT("pcm_sample_luma", ps_cabac->u4_range, 0); 586 BITS_PARSE("pcm_sample_luma", value, ps_bitstrm, num_bits); 587 588 //ps_pcmsample_t->i1_pcm_sample_luma[i] = value; 589 *pu1_coeff_data++ = value << (BIT_DEPTH_LUMA - num_bits); 590 } 591 592 num_bits = ps_sps->i1_pcm_sample_bit_depth_chroma; 593 594 for(i = 0; i < (1 << (log2_cb_size << 1)) >> 1; i++) 595 { 596 TRACE_CABAC_CTXT("pcm_sample_chroma", ps_cabac->u4_range, 0); 597 BITS_PARSE("pcm_sample_chroma", value, ps_bitstrm, num_bits); 598 599 // ps_pcmsample_t->i1_pcm_sample_chroma[i] = value; 600 *pu1_coeff_data++ = value << (BIT_DEPTH_CHROMA - num_bits); 601 } 602 603 ps_codec->s_parse.pv_tu_coeff_data = pu1_coeff_data; 604 605 return ret; 606} 607/** 608 ******************************************************************************* 609 * 610 * @brief 611 * Parses Prediction unit 612 * 613 * @par Description: 614 * Parses Prediction unit as per Section:7.3.9.6 615 * 616 * @param[in] ps_codec 617 * Pointer to codec context 618 * 619 * @returns Error from IHEVCD_ERROR_T 620 * 621 * @remarks 622 * 623 * 624 ******************************************************************************* 625 */ 626 627IHEVCD_ERROR_T ihevcd_parse_pu_mvp(codec_t *ps_codec, pu_t *ps_pu) 628{ 629 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 630 WORD32 value; 631 slice_header_t *ps_slice_hdr; 632 bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm; 633 cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac; 634 WORD32 inter_pred_idc; 635 636 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 637 638 if(ps_slice_hdr->i1_slice_type == BSLICE) 639 { 640 WORD32 pu_w_plus_pu_h; 641 WORD32 ctxt_idx; 642 /* required to check if w+h==12 case */ 643 pu_w_plus_pu_h = ((ps_pu->b4_wd + 1) << 2) + ((ps_pu->b4_ht + 1) << 2); 644 if(12 == pu_w_plus_pu_h) 645 { 646 ctxt_idx = IHEVC_CAB_INTER_PRED_IDC + 4; 647 TRACE_CABAC_CTXT("inter_pred_idc", ps_cabac->u4_range, ctxt_idx); 648 inter_pred_idc = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, 649 ctxt_idx); 650 } 651 else 652 { 653 /* larger PUs can be encoded as bi_pred/l0/l1 inter_pred_idc */ 654 WORD32 is_bipred; 655 656 ctxt_idx = IHEVC_CAB_INTER_PRED_IDC + ps_codec->s_parse.i4_ct_depth; 657 TRACE_CABAC_CTXT("inter_pred_idc", ps_cabac->u4_range, ctxt_idx); 658 is_bipred = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 659 inter_pred_idc = PRED_BI; 660 if(!is_bipred) 661 { 662 ctxt_idx = IHEVC_CAB_INTER_PRED_IDC + 4; 663 inter_pred_idc = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, 664 ctxt_idx); 665 } 666 } 667 668 AEV_TRACE("inter_pred_idc", inter_pred_idc, ps_cabac->u4_range); 669 } 670 else 671 inter_pred_idc = PRED_L0; 672 ps_pu->mv.i1_l0_ref_idx = 0; 673 ps_pu->mv.i1_l1_ref_idx = 0; 674 /* Decode MVD for L0 for PRED_L0 or PRED_BI */ 675 if(inter_pred_idc != PRED_L1) 676 { 677 WORD32 active_refs = ps_slice_hdr->i1_num_ref_idx_l0_active; 678 WORD32 ref_idx = 0; 679 WORD32 ctxt_idx; 680 681 if(active_refs > 1) 682 { 683 ctxt_idx = IHEVC_CAB_INTER_REF_IDX; 684 /* encode the context modelled first bin */ 685 TRACE_CABAC_CTXT("ref_idx", ps_cabac->u4_range, ctxt_idx); 686 ref_idx = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 687 688 if((active_refs > 2) && ref_idx) 689 { 690 WORD32 value; 691 /* encode the context modelled second bin */ 692 ctxt_idx++; 693 value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 694 ref_idx += value; 695 if((active_refs > 3) && value) 696 { 697 /* encode remaining bypass bins */ 698 ref_idx = ihevcd_cabac_decode_bypass_bins_tunary(ps_cabac, 699 ps_bitstrm, 700 (active_refs - 3) 701 ); 702 ref_idx += 2; 703 } 704 } 705 AEV_TRACE("ref_idx", ref_idx, ps_cabac->u4_range); 706 } 707 708 ref_idx = CLIP3(ref_idx, 0, MAX_DPB_SIZE - 1); 709 ps_pu->mv.i1_l0_ref_idx = ref_idx; 710 711 ihevcd_parse_mvd(ps_codec, &ps_pu->mv.s_l0_mv); 712 713 ctxt_idx = IHEVC_CAB_MVP_L0L1; 714 value = ihevcd_cabac_decode_bin(ps_cabac, 715 ps_bitstrm, 716 ctxt_idx); 717 718 AEV_TRACE("mvp_l0/l1_flag", value, ps_cabac->u4_range); 719 720 ps_pu->b1_l0_mvp_idx = value; 721 722 } 723 /* Decode MVD for L1 for PRED_L1 or PRED_BI */ 724 if(inter_pred_idc != PRED_L0) 725 { 726 WORD32 active_refs = ps_slice_hdr->i1_num_ref_idx_l1_active; 727 WORD32 ref_idx = 0; 728 WORD32 ctxt_idx; 729 730 if(active_refs > 1) 731 { 732 733 ctxt_idx = IHEVC_CAB_INTER_REF_IDX; 734 TRACE_CABAC_CTXT("ref_idx", ps_cabac->u4_range, ctxt_idx); 735 /* encode the context modelled first bin */ 736 ref_idx = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 737 738 if((active_refs > 2) && ref_idx) 739 { 740 WORD32 value; 741 /* encode the context modelled second bin */ 742 ctxt_idx++; 743 value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 744 ref_idx += value; 745 if((active_refs > 3) && value) 746 { 747 /* encode remaining bypass bins */ 748 ref_idx = ihevcd_cabac_decode_bypass_bins_tunary(ps_cabac, 749 ps_bitstrm, 750 (active_refs - 3) 751 ); 752 ref_idx += 2; 753 } 754 } 755 756 AEV_TRACE("ref_idx", ref_idx, ps_cabac->u4_range); 757 } 758 759 ref_idx = CLIP3(ref_idx, 0, MAX_DPB_SIZE - 1); 760 ps_pu->mv.i1_l1_ref_idx = ref_idx; 761 762 if(ps_slice_hdr->i1_mvd_l1_zero_flag && inter_pred_idc == PRED_BI) 763 { 764 ps_pu->mv.s_l1_mv.i2_mvx = 0; 765 ps_pu->mv.s_l1_mv.i2_mvy = 0; 766 } 767 else 768 { 769 ihevcd_parse_mvd(ps_codec, &ps_pu->mv.s_l1_mv); 770 } 771 772 ctxt_idx = IHEVC_CAB_MVP_L0L1; 773 value = ihevcd_cabac_decode_bin(ps_cabac, 774 ps_bitstrm, 775 ctxt_idx); 776 777 AEV_TRACE("mvp_l0/l1_flag", value, ps_cabac->u4_range); 778 ps_pu->b1_l1_mvp_idx = value; 779 780 } 781 782 ps_pu->b2_pred_mode = inter_pred_idc; 783 return ret; 784} 785/** 786 ******************************************************************************* 787 * 788 * @brief 789 * Parses Prediction unit 790 * 791 * @par Description: 792 * Parses Prediction unit as per Section:7.3.9.6 793 * 794 * @param[in] ps_codec 795 * Pointer to codec context 796 * 797 * @returns Error from IHEVCD_ERROR_T 798 * 799 * @remarks 800 * 801 * 802 ******************************************************************************* 803 */ 804 805IHEVCD_ERROR_T ihevcd_parse_prediction_unit(codec_t *ps_codec, 806 WORD32 x0, 807 WORD32 y0, 808 WORD32 wd, 809 WORD32 ht) 810{ 811 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 812 slice_header_t *ps_slice_hdr; 813 sps_t *ps_sps; 814 bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm; 815 WORD32 ctb_x_base; 816 WORD32 ctb_y_base; 817 818 pu_t *ps_pu = ps_codec->s_parse.ps_pu; 819 cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac; 820 821 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 822 823 /* Set PU structure to default values */ 824 memset(ps_pu, 0, sizeof(pu_t)); 825 826 ps_sps = ps_codec->s_parse.ps_sps; 827 ctb_x_base = ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size; 828 ctb_y_base = ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size; 829 830 ps_pu->b4_pos_x = (x0 - ctb_x_base) >> 2; 831 ps_pu->b4_pos_y = (y0 - ctb_y_base) >> 2; 832 ps_pu->b4_wd = (wd >> 2) - 1; 833 ps_pu->b4_ht = (ht >> 2) - 1; 834 835 ps_pu->b1_intra_flag = 0; 836 ps_pu->b3_part_mode = ps_codec->s_parse.s_cu.i4_part_mode; 837 838 if(PRED_MODE_SKIP == ps_codec->s_parse.s_cu.i4_pred_mode) 839 { 840 WORD32 merge_idx = 0; 841 if(ps_slice_hdr->i1_max_num_merge_cand > 1) 842 { 843 WORD32 ctxt_idx = IHEVC_CAB_MERGE_IDX_EXT; 844 WORD32 bin; 845 846 TRACE_CABAC_CTXT("merge_idx", ps_cabac->u4_range, ctxt_idx); 847 bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 848 if(bin) 849 { 850 if(ps_slice_hdr->i1_max_num_merge_cand > 2) 851 { 852 merge_idx = ihevcd_cabac_decode_bypass_bins_tunary( 853 ps_cabac, ps_bitstrm, 854 (ps_slice_hdr->i1_max_num_merge_cand - 2)); 855 } 856 merge_idx++; 857 } 858 AEV_TRACE("merge_idx", merge_idx, ps_cabac->u4_range); 859 } 860 ps_pu->b1_merge_flag = 1; 861 ps_pu->b3_merge_idx = merge_idx; 862 863 } 864 else 865 { 866 /* MODE_INTER */ 867 WORD32 merge_flag; 868 WORD32 ctxt_idx = IHEVC_CAB_MERGE_FLAG_EXT; 869 TRACE_CABAC_CTXT("merge_flag", ps_cabac->u4_range, ctxt_idx); 870 merge_flag = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 871 AEV_TRACE("merge_flag", merge_flag, ps_cabac->u4_range); 872 873 ps_pu->b1_merge_flag = merge_flag; 874 875 if(merge_flag) 876 { 877 WORD32 merge_idx = 0; 878 if(ps_slice_hdr->i1_max_num_merge_cand > 1) 879 { 880 WORD32 ctxt_idx = IHEVC_CAB_MERGE_IDX_EXT; 881 WORD32 bin; 882 TRACE_CABAC_CTXT("merge_idx", ps_cabac->u4_range, ctxt_idx); 883 bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 884 if(bin) 885 { 886 if(ps_slice_hdr->i1_max_num_merge_cand > 2) 887 { 888 merge_idx = ihevcd_cabac_decode_bypass_bins_tunary( 889 ps_cabac, ps_bitstrm, 890 (ps_slice_hdr->i1_max_num_merge_cand - 2)); 891 } 892 merge_idx++; 893 } 894 AEV_TRACE("merge_idx", merge_idx, ps_cabac->u4_range); 895 } 896 897 ps_pu->b3_merge_idx = merge_idx; 898 } 899 else 900 { 901 ihevcd_parse_pu_mvp(ps_codec, ps_pu); 902 } 903 904 } 905 STATS_UPDATE_PU_SIZE(ps_pu); 906 /* Increment PU pointer */ 907 ps_codec->s_parse.ps_pu++; 908 ps_codec->s_parse.i4_pic_pu_idx++; 909 return ret; 910} 911 912 913WORD32 ihevcd_parse_part_mode_amp(cab_ctxt_t *ps_cabac, bitstrm_t *ps_bitstrm) 914{ 915 WORD32 ctxt_idx = IHEVC_CAB_PART_MODE; 916 WORD32 part_mode_idx; 917 WORD32 part_mode; 918 WORD32 bin; 919 920 part_mode = 0; 921 TRACE_CABAC_CTXT("part_mode", ps_cabac->u4_range, ctxt_idx); 922 bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx++); 923 924 if(!bin) 925 { 926 bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx++); 927 part_mode_idx = bin; 928 part_mode_idx <<= 1; 929 930 /* Following takes of handling context increment for 3rd bin in part_mode */ 931 /* When AMP is enabled and the current is not min CB */ 932 /* Context for 3rd bin is 3 and not 2 */ 933 ctxt_idx += 1; 934 935 bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 936 part_mode_idx |= bin; 937 938 part_mode_idx <<= 1; 939 if(!bin) 940 { 941 942 bin = ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm); 943 part_mode_idx |= bin; 944 } 945 part_mode = gau1_part_mode_amp[part_mode_idx]; 946 } 947 return part_mode; 948} 949IHEVCD_ERROR_T ihevcd_parse_coding_unit_intra(codec_t *ps_codec, 950 WORD32 x0, 951 WORD32 y0, 952 WORD32 log2_cb_size) 953{ 954 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 955 sps_t *ps_sps; 956 cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac; 957 bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm; 958 WORD32 pcm_flag; 959 WORD32 value; 960 WORD32 cb_size = 1 << log2_cb_size; 961 WORD32 part_mode = ps_codec->s_parse.s_cu.i4_part_mode; 962 tu_t *ps_tu = ps_codec->s_parse.ps_tu; 963 pu_t *ps_pu = ps_codec->s_parse.ps_pu; 964 WORD32 ctb_x_base; 965 WORD32 ctb_y_base; 966 ps_sps = ps_codec->s_parse.ps_sps; 967 ctb_x_base = ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size; 968 ctb_y_base = ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size; 969 970 memset(ps_pu, 0, sizeof(pu_t)); 971 ps_pu->b1_intra_flag = 1; 972 ps_pu->b4_wd = (cb_size >> 2) - 1; 973 ps_pu->b4_ht = (cb_size >> 2) - 1; 974 ps_pu->b4_pos_x = (x0 - ctb_x_base) >> 2; 975 ps_pu->b4_pos_y = (y0 - ctb_y_base) >> 2; 976 977 pcm_flag = 0; 978 if((PART_2Nx2N == part_mode) && (ps_sps->i1_pcm_enabled_flag) 979 && (log2_cb_size 980 >= ps_sps->i1_log2_min_pcm_coding_block_size) 981 && (log2_cb_size 982 <= (ps_sps->i1_log2_min_pcm_coding_block_size + ps_sps->i1_log2_diff_max_min_pcm_coding_block_size))) 983 { 984 TRACE_CABAC_CTXT("pcm_flag", ps_cabac->u4_range, 0); 985 pcm_flag = ihevcd_cabac_decode_terminate(ps_cabac, ps_bitstrm); 986 AEV_TRACE("pcm_flag", pcm_flag, ps_cabac->u4_range); 987 } 988 989 ps_codec->s_parse.i4_cu_pcm_flag = pcm_flag; 990 if(pcm_flag) 991 { 992 UWORD8 *pu1_luma_intra_pred_mode_top, *pu1_luma_intra_pred_mode_left; 993 WORD32 i, num_pred_blocks; 994 995 if(ps_codec->s_parse.s_bitstrm.u4_bit_ofst % 8) 996 { 997 TRACE_CABAC_CTXT("pcm_alignment_zero_bit", ps_cabac->u4_range, 0); 998 ihevcd_bits_flush_to_byte_boundary(&ps_codec->s_parse.s_bitstrm); 999 AEV_TRACE("pcm_alignment_zero_bit", 0, ps_cabac->u4_range); 1000 } 1001 1002 ihevcd_parse_pcm_sample(ps_codec, x0, y0, log2_cb_size); 1003 1004 ihevcd_cabac_reset(&ps_codec->s_parse.s_cabac, 1005 &ps_codec->s_parse.s_bitstrm); 1006 1007 ps_tu = ps_codec->s_parse.ps_tu; 1008 ps_tu->b1_cb_cbf = 1; 1009 ps_tu->b1_cr_cbf = 1; 1010 ps_tu->b1_y_cbf = 1; 1011 ps_tu->b4_pos_x = ((x0 - ctb_x_base) >> 2); 1012 ps_tu->b4_pos_y = ((y0 - ctb_y_base) >> 2); 1013 ps_tu->b1_transquant_bypass = 1; 1014 ps_tu->b3_size = (log2_cb_size - 2); 1015 ps_tu->b7_qp = ps_codec->s_parse.u4_qp; 1016 ps_tu->b3_chroma_intra_mode_idx = INTRA_PRED_CHROMA_IDX_NONE; 1017 ps_tu->b6_luma_intra_mode = INTRA_PRED_NONE; 1018 1019 /* Set the first TU in CU flag */ 1020 { 1021 if((ps_codec->s_parse.s_cu.i4_pos_x << 3) == (ps_tu->b4_pos_x << 2) && 1022 (ps_codec->s_parse.s_cu.i4_pos_y << 3) == (ps_tu->b4_pos_y << 2)) 1023 { 1024 ps_tu->b1_first_tu_in_cu = 1; 1025 } 1026 else 1027 { 1028 ps_tu->b1_first_tu_in_cu = 0; 1029 } 1030 } 1031 1032 /* Update the intra pred mode for PCM to INTRA_DC(default mode) */ 1033 pu1_luma_intra_pred_mode_top = ps_codec->s_parse.pu1_luma_intra_pred_mode_top 1034 + (ps_codec->s_parse.s_cu.i4_pos_x * 2); 1035 1036 pu1_luma_intra_pred_mode_left = ps_codec->s_parse.pu1_luma_intra_pred_mode_left 1037 + (ps_codec->s_parse.s_cu.i4_pos_y * 2); 1038 1039 num_pred_blocks = 1; /* Because PCM part mode will be 2Nx2N */ 1040 1041 ps_codec->s_func_selector.ihevc_memset_fptr(pu1_luma_intra_pred_mode_left, INTRA_DC, (cb_size / num_pred_blocks) / MIN_PU_SIZE); 1042 ps_codec->s_func_selector.ihevc_memset_fptr(pu1_luma_intra_pred_mode_top, INTRA_DC, (cb_size / num_pred_blocks) / MIN_PU_SIZE); 1043 1044 1045 /* Set no_loop_filter appropriately */ 1046 if(1 == ps_sps->i1_pcm_loop_filter_disable_flag) 1047 { 1048 UWORD8 *pu1_pic_no_loop_filter_flag; 1049 WORD32 numbytes_row; 1050 UWORD32 u4_mask; 1051 1052 pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1053 numbytes_row = (ps_sps->i2_pic_width_in_luma_samples + 63) / 64; 1054 pu1_pic_no_loop_filter_flag += (y0 / 8) * numbytes_row; 1055 pu1_pic_no_loop_filter_flag += (x0 / 64); 1056 /* Generate (cb_size / 8) number of 1s */ 1057 /* i.e (log2_cb_size - 2) number of 1s */ 1058 u4_mask = LSB_ONES((cb_size >> 3)); 1059 for(i = 0; i < (cb_size / 8); i++) 1060 { 1061 *pu1_pic_no_loop_filter_flag |= (u4_mask << (((x0) / 8) % 8)); 1062 pu1_pic_no_loop_filter_flag += numbytes_row; 1063 } 1064 } 1065 /* Increment ps_tu and tu_idx */ 1066 ps_codec->s_parse.ps_tu++; 1067 ps_codec->s_parse.s_cu.i4_tu_cnt++; 1068 ps_codec->s_parse.i4_pic_tu_idx++; 1069 1070 } 1071 else 1072 { 1073 WORD32 cnt = 0; 1074 WORD32 i; 1075 WORD32 part_cnt; 1076 1077 part_cnt = (part_mode == PART_NxN) ? 4 : 1; 1078 1079 for(i = 0; i < part_cnt; i++) 1080 { 1081 TRACE_CABAC_CTXT("prev_intra_pred_luma_flag", ps_cabac->u4_range, IHEVC_CAB_INTRA_LUMA_PRED_FLAG); 1082 value = ihevcd_cabac_decode_bin(ps_cabac, 1083 ps_bitstrm, 1084 IHEVC_CAB_INTRA_LUMA_PRED_FLAG); 1085 1086 ps_codec->s_parse.s_cu.ai4_prev_intra_luma_pred_flag[i] = 1087 value; 1088 AEV_TRACE("prev_intra_pred_luma_flag", value, ps_cabac->u4_range); 1089 } 1090 1091 for(i = 0; i < part_cnt; i++) 1092 { 1093 if(ps_codec->s_parse.s_cu.ai4_prev_intra_luma_pred_flag[cnt]) 1094 { 1095 value = ihevcd_cabac_decode_bypass_bins_tunary(ps_cabac, ps_bitstrm, 2); 1096 AEV_TRACE("mpm_idx", value, ps_cabac->u4_range); 1097 ps_codec->s_parse.s_cu.ai4_mpm_idx[cnt] = value; 1098 } 1099 else 1100 { 1101 value = ihevcd_cabac_decode_bypass_bins(ps_cabac, ps_bitstrm, 5); 1102 AEV_TRACE("rem_intra_luma_pred_mode", value, 1103 ps_cabac->u4_range); 1104 ps_codec->s_parse.s_cu.ai4_rem_intra_luma_pred_mode[cnt] = 1105 value; 1106 } 1107 cnt++; 1108 } 1109 TRACE_CABAC_CTXT("intra_chroma_pred_mode", ps_cabac->u4_range, IHEVC_CAB_CHROMA_PRED_MODE); 1110 value = ihevcd_cabac_decode_bin(ps_cabac, 1111 ps_bitstrm, 1112 IHEVC_CAB_CHROMA_PRED_MODE); 1113 ps_codec->s_parse.s_cu.i4_intra_chroma_pred_mode_idx = 4; 1114 if(value) 1115 { 1116 ps_codec->s_parse.s_cu.i4_intra_chroma_pred_mode_idx = 1117 ihevcd_cabac_decode_bypass_bins(ps_cabac, 1118 ps_bitstrm, 2); 1119 } 1120 AEV_TRACE("intra_chroma_pred_mode", 1121 ps_codec->s_parse.s_cu.i4_intra_chroma_pred_mode_idx, 1122 ps_cabac->u4_range); 1123 1124 1125 ihevcd_intra_pred_mode_prediction(ps_codec, log2_cb_size, x0, y0); 1126 } 1127 STATS_UPDATE_PU_SIZE(ps_pu); 1128 /* Increment PU pointer */ 1129 ps_codec->s_parse.ps_pu++; 1130 ps_codec->s_parse.i4_pic_pu_idx++; 1131 1132 return ret; 1133} 1134/** 1135 ******************************************************************************* 1136 * 1137 * @brief 1138 * Parses coding unit 1139 * 1140 * @par Description: 1141 * Parses coding unit as per Section:7.3.9.5 1142 * 1143 * @param[in] ps_codec 1144 * Pointer to codec context 1145 * 1146 * @returns Error from IHEVCD_ERROR_T 1147 * 1148 * @remarks 1149 * 1150 * 1151 ******************************************************************************* 1152 */ 1153 1154IHEVCD_ERROR_T ihevcd_parse_coding_unit(codec_t *ps_codec, 1155 WORD32 x0, 1156 WORD32 y0, 1157 WORD32 log2_cb_size) 1158{ 1159 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 1160 sps_t *ps_sps; 1161 pps_t *ps_pps; 1162 WORD32 cb_size; 1163 slice_header_t *ps_slice_hdr; 1164 WORD32 skip_flag; 1165 WORD32 pcm_flag; 1166 UWORD32 *pu4_skip_top = ps_codec->s_parse.pu4_skip_cu_top; 1167 UWORD32 u4_skip_left = ps_codec->s_parse.u4_skip_cu_left; 1168 bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm; 1169 tu_t *ps_tu = ps_codec->s_parse.ps_tu; 1170 1171 WORD32 cu_pos_x; 1172 WORD32 cu_pos_y; 1173 cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac; 1174 1175 ASSERT(0 == (x0 % 8)); 1176 ASSERT(0 == (y0 % 8)); 1177 1178 ps_codec->s_parse.s_cu.i4_tu_cnt = 0; 1179 ps_sps = ps_codec->s_parse.ps_sps; 1180 ps_pps = ps_codec->s_parse.ps_pps; 1181 1182 cu_pos_x = ps_codec->s_parse.s_cu.i4_pos_x; 1183 cu_pos_y = ps_codec->s_parse.s_cu.i4_pos_y; 1184 1185 1186 1187 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 1188 1189 1190 cb_size = 1 << log2_cb_size; 1191 1192 ps_codec->s_parse.s_cu.i4_cu_transquant_bypass = 0; 1193 1194 if(ps_pps->i1_transquant_bypass_enable_flag) 1195 { 1196 TRACE_CABAC_CTXT("cu_transquant_bypass_flag", ps_cabac->u4_range, IHEVC_CAB_CU_TQ_BYPASS_FLAG); 1197 ps_codec->s_parse.s_cu.i4_cu_transquant_bypass = 1198 ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, 1199 IHEVC_CAB_CU_TQ_BYPASS_FLAG); 1200 /* Update transquant_bypass in ps_tu */ 1201 1202 AEV_TRACE("cu_transquant_bypass_flag", ps_codec->s_parse.s_cu.i4_cu_transquant_bypass, 1203 ps_cabac->u4_range); 1204 1205 if(ps_codec->s_parse.s_cu.i4_cu_transquant_bypass) 1206 { 1207 UWORD8 *pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1208 UWORD32 u4_mask; 1209 WORD32 i; 1210 WORD32 numbytes_row; 1211 numbytes_row = (ps_sps->i2_pic_width_in_luma_samples + 63) / 64; 1212 pu1_pic_no_loop_filter_flag += (y0 / 8) * numbytes_row; 1213 pu1_pic_no_loop_filter_flag += (x0 / 64); 1214 1215 /* Generate (cb_size / 8) number of 1s */ 1216 /* i.e (log2_cb_size - 2) number of 1s */ 1217 u4_mask = LSB_ONES((cb_size >> 3)); 1218 for(i = 0; i < (cb_size / 8); i++) 1219 { 1220 *pu1_pic_no_loop_filter_flag |= (u4_mask << (((x0) / 8) % 8)); 1221 pu1_pic_no_loop_filter_flag += numbytes_row; 1222 } 1223 } 1224 } 1225 1226 { 1227 UWORD32 u4_skip_top = 0; 1228 UWORD32 u4_mask; 1229 UWORD32 u4_top_mask, u4_left_mask; 1230 UWORD32 u4_min_cu_x = x0 / 8; 1231 UWORD32 u4_min_cu_y = y0 / 8; 1232 1233 pu4_skip_top += (u4_min_cu_x / 32); 1234 1235 1236 if(ps_slice_hdr->i1_slice_type != ISLICE) 1237 { 1238 WORD32 ctx_idx_inc; 1239 ctx_idx_inc = 0; 1240 1241 if((0 != cu_pos_y) || 1242 ((0 != ps_codec->s_parse.i4_ctb_slice_y) && 1243 (0 != ps_codec->s_parse.i4_ctb_tile_y))) 1244 { 1245 u4_skip_top = *pu4_skip_top; 1246 u4_skip_top >>= (u4_min_cu_x % 32); 1247 if(u4_skip_top & 1) 1248 ctx_idx_inc++; 1249 } 1250 1251 /*****************************************************************/ 1252 /* If cu_pos_x is non-zero then left is available */ 1253 /* If cu_pos_x is zero then ensure both the following are true */ 1254 /* Current CTB is not the first CTB in a tile row */ 1255 /* Current CTB is not the first CTB in a slice */ 1256 /*****************************************************************/ 1257 if((0 != cu_pos_x) || 1258 (((0 != ps_codec->s_parse.i4_ctb_slice_x) || (0 != ps_codec->s_parse.i4_ctb_slice_y)) && 1259 (0 != ps_codec->s_parse.i4_ctb_tile_x))) 1260 { 1261 u4_skip_left >>= (u4_min_cu_y % 32); 1262 if(u4_skip_left & 1) 1263 ctx_idx_inc++; 1264 } 1265 TRACE_CABAC_CTXT("cu_skip_flag", ps_cabac->u4_range, (IHEVC_CAB_SKIP_FLAG + ctx_idx_inc)); 1266 skip_flag = ihevcd_cabac_decode_bin(ps_cabac, 1267 ps_bitstrm, 1268 (IHEVC_CAB_SKIP_FLAG + ctx_idx_inc)); 1269 1270 AEV_TRACE("cu_skip_flag", skip_flag, ps_cabac->u4_range); 1271 } 1272 else 1273 skip_flag = 0; 1274 1275 /* Update top skip_flag */ 1276 u4_skip_top = *pu4_skip_top; 1277 /* Since Max cb_size is 64, maximum of 8 bits will be set or reset */ 1278 /* Also since Coding block will be within 64x64 grid, only 8bits within a WORD32 1279 * need to be updated. These 8 bits will not cross 8 bit boundaries 1280 */ 1281 u4_mask = LSB_ONES(cb_size / 8); 1282 u4_top_mask = u4_mask << (u4_min_cu_x % 32); 1283 1284 1285 if(skip_flag) 1286 { 1287 u4_skip_top |= u4_top_mask; 1288 } 1289 else 1290 { 1291 u4_skip_top &= ~u4_top_mask; 1292 } 1293 *pu4_skip_top = u4_skip_top; 1294 1295 /* Update left skip_flag */ 1296 u4_skip_left = ps_codec->s_parse.u4_skip_cu_left; 1297 u4_mask = LSB_ONES(cb_size / 8); 1298 u4_left_mask = u4_mask << (u4_min_cu_y % 32); 1299 1300 if(skip_flag) 1301 { 1302 u4_skip_left |= u4_left_mask; 1303 } 1304 else 1305 { 1306 u4_skip_left &= ~u4_left_mask; 1307 } 1308 ps_codec->s_parse.u4_skip_cu_left = u4_skip_left; 1309 } 1310 ps_codec->s_parse.i4_cu_pcm_flag = 0; 1311 1312 if(skip_flag) 1313 { 1314 WORD32 ctb_x_base; 1315 WORD32 ctb_y_base; 1316 1317 ctb_x_base = ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size; 1318 ctb_y_base = ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size; 1319 1320 ps_tu->b1_cb_cbf = 0; 1321 ps_tu->b1_cr_cbf = 0; 1322 ps_tu->b1_y_cbf = 0; 1323 ps_tu->b4_pos_x = ((x0 - ctb_x_base) >> 2); 1324 ps_tu->b4_pos_y = ((y0 - ctb_y_base) >> 2); 1325 ps_tu->b1_transquant_bypass = 0; 1326 ps_tu->b3_size = (log2_cb_size - 2); 1327 ps_tu->b7_qp = ps_codec->s_parse.u4_qp; 1328 ps_tu->b3_chroma_intra_mode_idx = INTRA_PRED_CHROMA_IDX_NONE; 1329 ps_tu->b6_luma_intra_mode = INTRA_PRED_NONE; 1330 1331 /* Set the first TU in CU flag */ 1332 { 1333 if((ps_codec->s_parse.s_cu.i4_pos_x << 3) == (ps_tu->b4_pos_x << 2) && 1334 (ps_codec->s_parse.s_cu.i4_pos_y << 3) == (ps_tu->b4_pos_y << 2)) 1335 { 1336 ps_tu->b1_first_tu_in_cu = 1; 1337 } 1338 else 1339 { 1340 ps_tu->b1_first_tu_in_cu = 0; 1341 } 1342 } 1343 1344 ps_codec->s_parse.ps_tu++; 1345 ps_codec->s_parse.s_cu.i4_tu_cnt++; 1346 ps_codec->s_parse.i4_pic_tu_idx++; 1347 1348 ps_codec->s_parse.s_cu.i4_pred_mode = PRED_MODE_SKIP; 1349 ps_codec->s_parse.s_cu.i4_part_mode = PART_2Nx2N; 1350 { 1351 pu_t *ps_pu = ps_codec->s_parse.ps_pu; 1352 ps_pu->b2_part_idx = 0; 1353 ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size, cb_size); 1354 STATS_UPDATE_PU_SKIP_SIZE(ps_pu); 1355 } 1356 } 1357 else 1358 { 1359 WORD32 pred_mode; 1360 WORD32 part_mode; 1361 WORD32 intra_split_flag; 1362 WORD32 is_mincb; 1363 cb_size = (1 << log2_cb_size); 1364 is_mincb = (cb_size == (1 << ps_sps->i1_log2_min_coding_block_size)); 1365 pcm_flag = 0; 1366 if(ps_slice_hdr->i1_slice_type != ISLICE) 1367 { 1368 TRACE_CABAC_CTXT("pred_mode_flag", ps_cabac->u4_range, IHEVC_CAB_PRED_MODE); 1369 pred_mode = ihevcd_cabac_decode_bin(ps_cabac, 1370 ps_bitstrm, 1371 IHEVC_CAB_PRED_MODE); 1372 1373 AEV_TRACE("pred_mode_flag", pred_mode, ps_cabac->u4_range); 1374 } 1375 else 1376 { 1377 pred_mode = PRED_MODE_INTRA; 1378 } 1379 1380 /* If current CU is intra then set corresponging bit in picture level intra map */ 1381 if(PRED_MODE_INTRA == pred_mode) 1382 { 1383 UWORD8 *pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag; 1384 UWORD32 u4_mask; 1385 WORD32 i; 1386 WORD32 numbytes_row; 1387 numbytes_row = (ps_sps->i2_pic_width_in_luma_samples + 63) / 64; 1388 pu1_pic_intra_flag += (y0 / 8) * numbytes_row; 1389 pu1_pic_intra_flag += (x0 / 64); 1390 1391 /* Generate (cb_size / 8) number of 1s */ 1392 /* i.e (log2_cb_size - 2) number of 1s */ 1393 u4_mask = LSB_ONES((cb_size >> 3)); 1394 for(i = 0; i < (cb_size / 8); i++) 1395 { 1396 *pu1_pic_intra_flag |= (u4_mask << (((x0) / 8) % 8)); 1397 pu1_pic_intra_flag += numbytes_row; 1398 } 1399 } 1400 1401 ps_codec->s_parse.s_cu.i4_pred_mode = pred_mode; 1402 intra_split_flag = 0; 1403 if((PRED_MODE_INTRA != pred_mode) || 1404 is_mincb) 1405 { 1406 UWORD32 bin; 1407 if(PRED_MODE_INTRA == pred_mode) 1408 { 1409 TRACE_CABAC_CTXT("part_mode", ps_cabac->u4_range, IHEVC_CAB_PART_MODE); 1410 bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, IHEVC_CAB_PART_MODE); 1411 part_mode = (bin) ? PART_2Nx2N : PART_NxN; 1412 } 1413 else 1414 { 1415 WORD32 amp_enabled = ps_sps->i1_amp_enabled_flag; 1416 1417 UWORD32 u4_max_bin_cnt = 0; 1418 1419 1420 1421 if(amp_enabled && !is_mincb) 1422 { 1423 part_mode = ihevcd_parse_part_mode_amp(ps_cabac, ps_bitstrm); 1424 } 1425 else 1426 { 1427 WORD32 ctxt_inc = IHEVC_CAB_PART_MODE; 1428 1429 u4_max_bin_cnt = 2; 1430 if((is_mincb) && (cb_size > 8)) 1431 { 1432 u4_max_bin_cnt++; 1433 } 1434 1435 part_mode = -1; 1436 TRACE_CABAC_CTXT("part_mode", ps_cabac->u4_range, IHEVC_CAB_PART_MODE); 1437 do 1438 { 1439 bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, 1440 ctxt_inc++); 1441 part_mode++; 1442 }while(--u4_max_bin_cnt && !bin); 1443 1444 /* If the last bin was zero, then increment part mode by 1 */ 1445 if(!bin) 1446 part_mode++; 1447 } 1448 1449 1450 } 1451 1452 AEV_TRACE("part_mode", part_mode, ps_cabac->u4_range); 1453 1454 } 1455 else 1456 { 1457 part_mode = 0; 1458 intra_split_flag = 0; 1459 } 1460 ps_codec->s_parse.s_cu.i4_part_mode = part_mode; 1461 1462 if((PRED_MODE_INTRA == ps_codec->s_parse.s_cu.i4_pred_mode) && 1463 (PART_NxN == ps_codec->s_parse.s_cu.i4_part_mode)) 1464 { 1465 intra_split_flag = 1; 1466 } 1467 ps_codec->s_parse.s_cu.i4_part_mode = part_mode; 1468 ps_codec->s_parse.s_cu.i4_intra_split_flag = intra_split_flag; 1469 if(pred_mode == PRED_MODE_INTRA) 1470 { 1471 ps_codec->s_parse.i4_cu_pcm_flag = 0; 1472 ihevcd_parse_coding_unit_intra(ps_codec, x0, y0, log2_cb_size); 1473 pcm_flag = ps_codec->s_parse.i4_cu_pcm_flag; 1474 1475 } 1476 else 1477 { 1478 if(part_mode == PART_2Nx2N) 1479 { 1480 pu_t *ps_pu = ps_codec->s_parse.ps_pu; 1481 ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size, cb_size); 1482 ps_pu->b2_part_idx = 0; 1483 } 1484 else if(part_mode == PART_2NxN) 1485 { 1486 pu_t *ps_pu = ps_codec->s_parse.ps_pu; 1487 1488 ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size, cb_size / 2); 1489 ps_pu->b2_part_idx = 0; 1490 1491 ps_pu = ps_codec->s_parse.ps_pu; 1492 ihevcd_parse_prediction_unit(ps_codec, x0, y0 + (cb_size / 2), cb_size, cb_size / 2); 1493 1494 ps_pu->b2_part_idx = 1; 1495 } 1496 else if(part_mode == PART_Nx2N) 1497 { 1498 pu_t *ps_pu = ps_codec->s_parse.ps_pu; 1499 ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size / 2, cb_size); 1500 ps_pu->b2_part_idx = 0; 1501 ps_pu = ps_codec->s_parse.ps_pu; 1502 ihevcd_parse_prediction_unit(ps_codec, x0 + (cb_size / 2), y0, cb_size / 2, cb_size); 1503 1504 ps_pu->b2_part_idx = 1; 1505 } 1506 else if(part_mode == PART_2NxnU) 1507 { 1508 pu_t *ps_pu = ps_codec->s_parse.ps_pu; 1509 ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size, cb_size / 4); 1510 ps_pu->b2_part_idx = 0; 1511 ps_pu = ps_codec->s_parse.ps_pu; 1512 ihevcd_parse_prediction_unit(ps_codec, x0, y0 + (cb_size / 4), cb_size, cb_size * 3 / 4); 1513 1514 ps_pu->b2_part_idx = 1; 1515 } 1516 else if(part_mode == PART_2NxnD) 1517 { 1518 pu_t *ps_pu = ps_codec->s_parse.ps_pu; 1519 ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size, cb_size * 3 / 4); 1520 ps_pu->b2_part_idx = 0; 1521 ps_pu = ps_codec->s_parse.ps_pu; 1522 ihevcd_parse_prediction_unit(ps_codec, x0, y0 + (cb_size * 3 / 4), cb_size, cb_size / 4); 1523 1524 ps_pu->b2_part_idx = 1; 1525 } 1526 else if(part_mode == PART_nLx2N) 1527 { 1528 pu_t *ps_pu = ps_codec->s_parse.ps_pu; 1529 ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size / 4, cb_size); 1530 ps_pu->b2_part_idx = 0; 1531 ps_pu = ps_codec->s_parse.ps_pu; 1532 ihevcd_parse_prediction_unit(ps_codec, x0 + (cb_size / 4), y0, cb_size * 3 / 4, cb_size); 1533 1534 ps_pu->b2_part_idx = 1; 1535 } 1536 else if(part_mode == PART_nRx2N) 1537 { 1538 pu_t *ps_pu = ps_codec->s_parse.ps_pu; 1539 ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size * 3 / 4, cb_size); 1540 ps_pu->b2_part_idx = 0; 1541 ps_pu = ps_codec->s_parse.ps_pu; 1542 ihevcd_parse_prediction_unit(ps_codec, x0 + (cb_size * 3 / 4), y0, cb_size / 4, cb_size); 1543 ps_pu->b2_part_idx = 1; 1544 } 1545 else 1546 { /* PART_NxN */ 1547 pu_t *ps_pu = ps_codec->s_parse.ps_pu; 1548 1549 ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size / 2, cb_size / 2); 1550 ps_pu->b2_part_idx = 0; 1551 ps_pu = ps_codec->s_parse.ps_pu; 1552 ihevcd_parse_prediction_unit(ps_codec, x0 + (cb_size / 2), y0, cb_size / 2, cb_size / 2); 1553 1554 ps_pu->b2_part_idx = 1; 1555 ps_pu = ps_codec->s_parse.ps_pu; 1556 ihevcd_parse_prediction_unit(ps_codec, x0, y0 + (cb_size / 2), cb_size / 2, cb_size / 2); 1557 1558 ps_pu->b2_part_idx = 2; 1559 ps_pu = ps_codec->s_parse.ps_pu; 1560 ihevcd_parse_prediction_unit(ps_codec, x0 + (cb_size / 2), y0 + (cb_size / 2), cb_size / 2, cb_size / 2); 1561 1562 ps_pu->b2_part_idx = 3; 1563 } 1564 } 1565 1566 if(!pcm_flag) 1567 { 1568 WORD32 no_residual_syntax_flag = 0; 1569 pu_t *ps_pu; 1570 /* Since ps_pu is incremented for each PU parsed, decrement by 1 to 1571 * access last decoded PU 1572 */ 1573 ps_pu = ps_codec->s_parse.ps_pu - 1; 1574 if((PRED_MODE_INTRA != pred_mode) && 1575 (!((part_mode == PART_2Nx2N) && ps_pu->b1_merge_flag))) 1576 { 1577 1578 TRACE_CABAC_CTXT("rqt_root_cbf", ps_cabac->u4_range, IHEVC_CAB_NORES_IDX); 1579 no_residual_syntax_flag = ihevcd_cabac_decode_bin(ps_cabac, 1580 ps_bitstrm, 1581 IHEVC_CAB_NORES_IDX); 1582 1583 AEV_TRACE("rqt_root_cbf", no_residual_syntax_flag, 1584 ps_cabac->u4_range); 1585 /* TODO: HACK FOR COMPLIANCE WITH HM REFERENCE DECODER */ 1586 /*********************************************************/ 1587 /* currently the HM decoder expects qtroot cbf instead of */ 1588 /* no_residue_flag which has opposite meaning */ 1589 /* This will be fixed once the software / spec is fixed */ 1590 /*********************************************************/ 1591 no_residual_syntax_flag = 1 - no_residual_syntax_flag; 1592 } 1593 1594 if(!no_residual_syntax_flag) 1595 { 1596 1597 ps_codec->s_parse.s_cu.i4_max_trafo_depth = (pred_mode == PRED_MODE_INTRA) ? 1598 (ps_sps->i1_max_transform_hierarchy_depth_intra + intra_split_flag) : 1599 (ps_sps->i1_max_transform_hierarchy_depth_inter); 1600 ihevcd_parse_transform_tree(ps_codec, x0, y0, x0, y0, 1601 log2_cb_size, 0, 0, 1602 ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[0]); 1603 } 1604 else 1605 { 1606 WORD32 ctb_x_base; 1607 WORD32 ctb_y_base; 1608 1609 ctb_x_base = ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size; 1610 ctb_y_base = ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size; 1611 1612 ps_tu = ps_codec->s_parse.ps_tu; 1613 ps_tu->b1_cb_cbf = 0; 1614 ps_tu->b1_cr_cbf = 0; 1615 ps_tu->b1_y_cbf = 0; 1616 ps_tu->b4_pos_x = ((x0 - ctb_x_base) >> 2); 1617 ps_tu->b4_pos_y = ((y0 - ctb_y_base) >> 2); 1618 ps_tu->b1_transquant_bypass = 0; 1619 ps_tu->b3_size = (log2_cb_size - 2); 1620 ps_tu->b7_qp = ps_codec->s_parse.u4_qp; 1621 ps_tu->b3_chroma_intra_mode_idx = INTRA_PRED_CHROMA_IDX_NONE; 1622 ps_tu->b6_luma_intra_mode = ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[0]; 1623 1624 /* Set the first TU in CU flag */ 1625 { 1626 if((ps_codec->s_parse.s_cu.i4_pos_x << 3) == (ps_tu->b4_pos_x << 2) && 1627 (ps_codec->s_parse.s_cu.i4_pos_y << 3) == (ps_tu->b4_pos_y << 2)) 1628 { 1629 ps_tu->b1_first_tu_in_cu = 1; 1630 } 1631 else 1632 { 1633 ps_tu->b1_first_tu_in_cu = 0; 1634 } 1635 } 1636 ps_codec->s_parse.ps_tu++; 1637 ps_codec->s_parse.s_cu.i4_tu_cnt++; 1638 ps_codec->s_parse.i4_pic_tu_idx++; 1639 1640 } 1641 } 1642 1643 } 1644 1645 1646 1647 1648 return ret; 1649} 1650 1651 1652 1653 1654/** 1655 ******************************************************************************* 1656 * 1657 * @brief 1658 * Parses Coding Quad Tree 1659 * 1660 * @par Description: 1661 * Parses Coding Quad Tree as per Section:7.3.9.4 1662 * 1663 * @param[in] ps_codec 1664 * Pointer to codec context 1665 * 1666 * @returns Error from IHEVCD_ERROR_T 1667 * 1668 * @remarks 1669 * 1670 * 1671 ******************************************************************************* 1672 */ 1673IHEVCD_ERROR_T ihevcd_parse_coding_quadtree(codec_t *ps_codec, 1674 WORD32 x0, 1675 WORD32 y0, 1676 WORD32 log2_cb_size, 1677 WORD32 ct_depth) 1678{ 1679 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 1680 sps_t *ps_sps; 1681 pps_t *ps_pps; 1682 WORD32 split_cu_flag; 1683 WORD32 x1, y1; 1684 WORD32 cu_pos_x; 1685 WORD32 cu_pos_y; 1686 bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm; 1687 cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac; 1688 WORD32 cb_size = 1 << log2_cb_size; 1689 ps_sps = ps_codec->s_parse.ps_sps; 1690 ps_pps = ps_codec->s_parse.ps_pps; 1691 1692 /* Compute CU position with respect to current CTB in (8x8) units */ 1693 cu_pos_x = (x0 - (ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size)) >> 3; 1694 cu_pos_y = (y0 - (ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size)) >> 3; 1695 1696 ps_codec->s_parse.s_cu.i4_pos_x = cu_pos_x; 1697 ps_codec->s_parse.s_cu.i4_pos_y = cu_pos_y; 1698 1699 ps_codec->s_parse.s_cu.i4_log2_cb_size = log2_cb_size; 1700 1701 ps_codec->s_parse.i4_ct_depth = ct_depth; 1702 { 1703 UWORD32 *pu4_ct_depth_top = ps_codec->s_parse.pu4_ct_depth_top; 1704 UWORD32 u4_ct_depth_left = ps_codec->s_parse.u4_ct_depth_left; 1705 UWORD32 u4_ct_depth_top = 0; 1706 UWORD32 u4_mask; 1707 UWORD32 u4_top_mask, u4_left_mask; 1708 WORD32 ctxt_idx; 1709 UWORD32 u4_min_cu_x = x0 / 8; 1710 UWORD32 u4_min_cu_y = y0 / 8; 1711 1712 pu4_ct_depth_top += (u4_min_cu_x / 16); 1713 1714 1715 1716 1717 if(((x0 + (1 << log2_cb_size)) <= ps_sps->i2_pic_width_in_luma_samples) && 1718 ((y0 + (1 << log2_cb_size)) <= ps_sps->i2_pic_height_in_luma_samples) && 1719 (log2_cb_size > ps_sps->i1_log2_min_coding_block_size)) 1720 { 1721 1722 ctxt_idx = IHEVC_CAB_SPLIT_CU_FLAG; 1723 /* Split cu context increment is decided based on left and top Coding tree 1724 * depth which is stored at frame level 1725 */ 1726 /* Check if the CTB is in first row in the current slice or tile */ 1727 if((0 != cu_pos_y) || 1728 ((0 != ps_codec->s_parse.i4_ctb_slice_y) && 1729 (0 != ps_codec->s_parse.i4_ctb_tile_y))) 1730 { 1731 u4_ct_depth_top = *pu4_ct_depth_top; 1732 u4_ct_depth_top >>= ((u4_min_cu_x % 16) * 2); 1733 u4_ct_depth_top &= 3; 1734 1735 if((WORD32)u4_ct_depth_top > ct_depth) 1736 ctxt_idx++; 1737 } 1738 1739 /* Check if the CTB is in first column in the current slice or tile */ 1740 /*****************************************************************/ 1741 /* If cu_pos_x is non-zero then left is available */ 1742 /* If cu_pos_x is zero then ensure both the following are true */ 1743 /* Current CTB is not the first CTB in a tile row */ 1744 /* Current CTB is not the first CTB in a slice */ 1745 /*****************************************************************/ 1746 if((0 != cu_pos_x) || 1747 (((0 != ps_codec->s_parse.i4_ctb_slice_x) || (0 != ps_codec->s_parse.i4_ctb_slice_y)) && 1748 (0 != ps_codec->s_parse.i4_ctb_tile_x))) 1749 { 1750 u4_ct_depth_left >>= ((u4_min_cu_y % 16) * 2); 1751 u4_ct_depth_left &= 3; 1752 if((WORD32)u4_ct_depth_left > ct_depth) 1753 ctxt_idx++; 1754 } 1755 TRACE_CABAC_CTXT("split_cu_flag", ps_cabac->u4_range, ctxt_idx); 1756 split_cu_flag = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 1757 AEV_TRACE("split_cu_flag", split_cu_flag, ps_cabac->u4_range); 1758 } 1759 else 1760 { 1761 if(log2_cb_size > ps_sps->i1_log2_min_coding_block_size) 1762 split_cu_flag = 1; 1763 else 1764 split_cu_flag = 0; 1765 } 1766 1767 if(0 == split_cu_flag) 1768 { 1769 /* Update top ct_depth */ 1770 u4_ct_depth_top = *pu4_ct_depth_top; 1771 /* Since Max cb_size is 64, maximum of 8 bits will be set or reset */ 1772 /* Also since Coding block will be within 64x64 grid, only 8bits within a WORD32 1773 * need to be updated. These 8 bits will not cross 8 bit boundaries 1774 */ 1775 u4_mask = DUP_LSB_11(cb_size / 8); 1776 1777 u4_top_mask = u4_mask << ((u4_min_cu_x % 16) * 2); 1778 u4_ct_depth_top &= ~u4_top_mask; 1779 1780 if(ct_depth) 1781 { 1782 u4_top_mask = gau4_ct_depth_mask[ct_depth] & u4_mask; 1783 1784 u4_top_mask = u4_top_mask << ((u4_min_cu_x % 16) * 2); 1785 u4_ct_depth_top |= u4_top_mask; 1786 } 1787 1788 *pu4_ct_depth_top = u4_ct_depth_top; 1789 1790 /* Update left ct_depth */ 1791 u4_ct_depth_left = ps_codec->s_parse.u4_ct_depth_left; 1792 1793 u4_left_mask = u4_mask << ((u4_min_cu_y % 16) * 2); 1794 1795 u4_ct_depth_left &= ~u4_left_mask; 1796 if(ct_depth) 1797 { 1798 u4_left_mask = gau4_ct_depth_mask[ct_depth] & u4_mask; 1799 1800 u4_left_mask = u4_left_mask << ((u4_min_cu_y % 16) * 2); 1801 u4_ct_depth_left |= u4_left_mask; 1802 } 1803 1804 ps_codec->s_parse.u4_ct_depth_left = u4_ct_depth_left; 1805 } 1806 } 1807 if((ps_pps->i1_cu_qp_delta_enabled_flag) && 1808 (log2_cb_size >= ps_pps->i1_log2_min_cu_qp_delta_size)) 1809 { 1810 ps_codec->s_parse.i4_is_cu_qp_delta_coded = 0; 1811 ps_codec->s_parse.i4_cu_qp_delta = 0; 1812 } 1813 if(split_cu_flag) 1814 { 1815 x1 = x0 + ((1 << log2_cb_size) >> 1); 1816 y1 = y0 + ((1 << log2_cb_size) >> 1); 1817 1818 ihevcd_parse_coding_quadtree(ps_codec, x0, y0, log2_cb_size - 1, ct_depth + 1); 1819 1820 /* At frame boundaries coding quadtree nodes are sent only if they fall within the frame */ 1821 if(x1 < ps_sps->i2_pic_width_in_luma_samples) 1822 ihevcd_parse_coding_quadtree(ps_codec, x1, y0, log2_cb_size - 1, ct_depth + 1); 1823 1824 if(y1 < ps_sps->i2_pic_height_in_luma_samples) 1825 ihevcd_parse_coding_quadtree(ps_codec, x0, y1, log2_cb_size - 1, ct_depth + 1); 1826 1827 if((x1 < ps_sps->i2_pic_width_in_luma_samples) && 1828 (y1 < ps_sps->i2_pic_height_in_luma_samples)) 1829 ihevcd_parse_coding_quadtree(ps_codec, x1, y1, log2_cb_size - 1, ct_depth + 1); 1830 } 1831 else 1832 { 1833 /* Set current group QP if current CU is aligned with the group */ 1834 { 1835 WORD32 cu_pos_x = ps_codec->s_parse.s_cu.i4_pos_x << 3; 1836 WORD32 cu_pos_y = ps_codec->s_parse.s_cu.i4_pos_y << 3; 1837 1838 WORD32 qpg_x = (cu_pos_x - (cu_pos_x & ((1 << ps_pps->i1_log2_min_cu_qp_delta_size) - 1))); 1839 WORD32 qpg_y = (cu_pos_y - (cu_pos_y & ((1 << ps_pps->i1_log2_min_cu_qp_delta_size) - 1))); 1840 1841 if((cu_pos_x == qpg_x) && 1842 (cu_pos_y == qpg_y)) 1843 { 1844 ps_codec->s_parse.u4_qpg = ps_codec->s_parse.u4_qp; 1845 1846 ps_codec->s_parse.s_cu.i4_cu_qp_delta = 0; 1847 1848 } 1849 } 1850 1851 ihevcd_parse_coding_unit(ps_codec, x0, y0, log2_cb_size); 1852 1853 if(ps_pps->i1_cu_qp_delta_enabled_flag) 1854 { 1855 WORD32 qp_pred, qp_left, qp_top; 1856 WORD32 cu_pos_x; 1857 WORD32 cu_pos_y; 1858 WORD32 qpg_x; 1859 WORD32 qpg_y; 1860 WORD32 i, j; 1861 WORD32 qp; 1862 WORD32 cur_cu_offset; 1863 tu_t *ps_tu = ps_codec->s_parse.ps_tu; 1864 WORD32 cb_size = 1 << ps_codec->s_parse.s_cu.i4_log2_cb_size; 1865 1866 cu_pos_x = ps_codec->s_parse.s_cu.i4_pos_x << 3; 1867 cu_pos_y = ps_codec->s_parse.s_cu.i4_pos_y << 3; 1868 1869 qpg_x = (cu_pos_x - (cu_pos_x & ((1 << ps_pps->i1_log2_min_cu_qp_delta_size) - 1))) >> 3; 1870 qpg_y = (cu_pos_y - (cu_pos_y & ((1 << ps_pps->i1_log2_min_cu_qp_delta_size) - 1))) >> 3; 1871 1872 /*previous coded Qp*/ 1873 qp_left = ps_codec->s_parse.u4_qpg; 1874 qp_top = ps_codec->s_parse.u4_qpg; 1875 1876 if(qpg_x > 0) 1877 { 1878 qp_left = ps_codec->s_parse.ai1_8x8_cu_qp[qpg_x - 1 + (qpg_y * 8)]; 1879 } 1880 if(qpg_y > 0) 1881 { 1882 qp_top = ps_codec->s_parse.ai1_8x8_cu_qp[qpg_x + ((qpg_y - 1) * 8)]; 1883 } 1884 1885 qp_pred = (qp_left + qp_top + 1) >> 1; 1886 /* Since qp_pred + ps_codec->s_parse.s_cu.i4_cu_qp_delta can be negative, 1887 52 is added before taking modulo 52 */ 1888 qp = (qp_pred + ps_codec->s_parse.s_cu.i4_cu_qp_delta + 52) % 52; 1889 1890 cur_cu_offset = (cu_pos_x >> 3) + cu_pos_y; 1891 for(i = 0; i < (cb_size >> 3); i++) 1892 { 1893 for(j = 0; j < (cb_size >> 3); j++) 1894 { 1895 ps_codec->s_parse.ai1_8x8_cu_qp[cur_cu_offset + (i * 8) + j] = qp; 1896 } 1897 } 1898 1899 ps_codec->s_parse.u4_qp = qp; 1900 ps_codec->s_parse.s_cu.i4_qp = qp; 1901 1902 1903 /* When change in QP is signaled, update the QP in TUs that are already parsed in the CU */ 1904 { 1905 tu_t *ps_tu_tmp; 1906 ps_tu_tmp = ps_tu - ps_codec->s_parse.s_cu.i4_tu_cnt; 1907 ps_tu->b7_qp = ps_codec->s_parse.u4_qp; 1908 while(ps_tu_tmp != ps_tu) 1909 { 1910 ps_tu_tmp->b7_qp = ps_codec->s_parse.u4_qp; 1911 1912 ps_tu_tmp++; 1913 } 1914 } 1915 if(ps_codec->s_parse.s_cu.i4_cu_qp_delta) 1916 { 1917 WORD32 ctb_indx; 1918 ctb_indx = ps_codec->s_parse.i4_ctb_x + ps_sps->i2_pic_wd_in_ctb * ps_codec->s_parse.i4_ctb_y; 1919 ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp_const_in_ctb[ctb_indx >> 3] &= (~(1 << (ctb_indx & 7))); 1920 } 1921 1922 } 1923 1924 } 1925 1926 1927 1928 1929 return ret; 1930} 1931 1932 1933/** 1934 ******************************************************************************* 1935 * 1936 * @brief 1937 * Parses SAO (Sample adaptive offset syntax) 1938 * 1939 * @par Description: 1940 * Parses SAO (Sample adaptive offset syntax) as per Section:7.3.9.3 1941 * 1942 * @param[in] ps_codec 1943 * Pointer to codec context 1944 * 1945 * @returns Error from IHEVCD_ERROR_T 1946 * 1947 * @remarks 1948 * 1949 * 1950 ******************************************************************************* 1951 */ 1952IHEVCD_ERROR_T ihevcd_parse_sao(codec_t *ps_codec) 1953{ 1954 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 1955 sps_t *ps_sps; 1956 sao_t *ps_sao; 1957 WORD32 rx; 1958 WORD32 ry; 1959 WORD32 value; 1960 bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm; 1961 WORD32 sao_merge_left_flag; 1962 WORD32 sao_merge_up_flag; 1963 slice_header_t *ps_slice_hdr; 1964 cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac; 1965 WORD32 ctxt_idx; 1966 1967 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr_base; 1968 ps_slice_hdr += (ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1)); 1969 1970 ps_sps = (ps_codec->s_parse.ps_sps); 1971 rx = ps_codec->s_parse.i4_ctb_x; 1972 ry = ps_codec->s_parse.i4_ctb_y; 1973 1974 ps_sao = ps_codec->s_parse.ps_pic_sao + rx + ry * ps_sps->i2_pic_wd_in_ctb; 1975 1976 /* Default values */ 1977 ps_sao->b3_y_type_idx = 0; 1978 ps_sao->b3_cb_type_idx = 0; 1979 ps_sao->b3_cr_type_idx = 0; 1980 1981 UNUSED(value); 1982 ctxt_idx = IHEVC_CAB_SAO_MERGE; 1983 sao_merge_left_flag = 0; 1984 sao_merge_up_flag = 0; 1985 if(rx > 0) 1986 { 1987 /*TODO:Implemented only for slice. condition for tile is not tested*/ 1988 if(((0 != ps_codec->s_parse.i4_ctb_slice_x) || (0 != ps_codec->s_parse.i4_ctb_slice_y)) && 1989 (0 != ps_codec->s_parse.i4_ctb_tile_x)) 1990 { 1991 1992 TRACE_CABAC_CTXT("sao_merge_flag", ps_cabac->u4_range, ctxt_idx); 1993 sao_merge_left_flag = ihevcd_cabac_decode_bin(ps_cabac, 1994 ps_bitstrm, 1995 ctxt_idx); 1996 AEV_TRACE("sao_merge_flag", sao_merge_left_flag, ps_cabac->u4_range); 1997 } 1998 1999 } 2000 if(ry > 0 && !sao_merge_left_flag) 2001 { 2002 if((ps_codec->s_parse.i4_ctb_slice_y > 0) && (ps_codec->s_parse.i4_ctb_tile_y > 0)) 2003 { 2004 TRACE_CABAC_CTXT("sao_merge_flag", ps_cabac->u4_range, ctxt_idx); 2005 sao_merge_up_flag = ihevcd_cabac_decode_bin(ps_cabac, 2006 ps_bitstrm, 2007 ctxt_idx); 2008 AEV_TRACE("sao_merge_flag", sao_merge_up_flag, ps_cabac->u4_range); 2009 } 2010 } 2011 ctxt_idx = IHEVC_CAB_SAO_TYPE; 2012 2013 if(sao_merge_left_flag) 2014 { 2015 *ps_sao = *(ps_sao - 1); 2016 } 2017 else if(sao_merge_up_flag) 2018 { 2019 *ps_sao = *(ps_sao - ps_sps->i2_pic_wd_in_ctb); 2020 } 2021 else // if(!sao_merge_up_flag && !sao_merge_left_flag) 2022 { 2023 WORD32 c_idx; 2024 WORD32 sao_type_idx = 0; 2025 for(c_idx = 0; c_idx < 3; c_idx++) 2026 { 2027 if((ps_slice_hdr->i1_slice_sao_luma_flag && c_idx == 0) || (ps_slice_hdr->i1_slice_sao_chroma_flag && c_idx > 0)) 2028 { 2029 2030 2031 /* sao_type_idx will be same for c_idx == 1 and c_idx == 2 - hence not initialized to zero for c_idx == 2*/ 2032 2033 if(c_idx == 0) 2034 { 2035 sao_type_idx = 0; 2036 TRACE_CABAC_CTXT("sao_type_idx", ps_cabac->u4_range, ctxt_idx); 2037 sao_type_idx = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 2038 2039 if(sao_type_idx) 2040 { 2041 sao_type_idx += ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm); 2042 } 2043 AEV_TRACE("sao_type_idx", sao_type_idx, ps_cabac->u4_range); 2044 2045 ps_sao->b3_y_type_idx = sao_type_idx; 2046 } 2047 if(c_idx == 1) 2048 { 2049 sao_type_idx = 0; 2050 TRACE_CABAC_CTXT("sao_type_idx", ps_cabac->u4_range, ctxt_idx); 2051 sao_type_idx = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx); 2052 if(sao_type_idx) 2053 { 2054 sao_type_idx += ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm); 2055 } 2056 2057 AEV_TRACE("sao_type_idx", sao_type_idx, ps_cabac->u4_range); 2058 2059 ps_sao->b3_cb_type_idx = sao_type_idx; 2060 ps_sao->b3_cr_type_idx = sao_type_idx; 2061 } 2062 2063 if(sao_type_idx != 0) 2064 { 2065 WORD32 i; 2066 WORD32 sao_offset[4]; 2067 WORD32 sao_band_position = 0; 2068 WORD32 c_max = (1 << (MIN(BIT_DEPTH, 10) - 5)) - 1; 2069 for(i = 0; i < 4; i++) 2070 { 2071 sao_offset[i] = ihevcd_cabac_decode_bypass_bins_tunary(ps_cabac, ps_bitstrm, c_max); 2072 AEV_TRACE("sao_offset_abs", sao_offset[i], ps_cabac->u4_range); 2073 2074 if((2 == sao_type_idx) && (i > 1)) 2075 { 2076 sao_offset[i] = -sao_offset[i]; 2077 } 2078 } 2079 2080 if(sao_type_idx == 1) 2081 { 2082 for(i = 0; i < 4; i++) 2083 { 2084 if(sao_offset[i] != 0) 2085 { 2086 value = ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm); 2087 AEV_TRACE("sao_offset_sign", value, ps_cabac->u4_range); 2088 2089 if(value) 2090 { 2091 sao_offset[i] = -sao_offset[i]; 2092 } 2093 } 2094 } 2095 value = ihevcd_cabac_decode_bypass_bins(ps_cabac, ps_bitstrm, 5); 2096 AEV_TRACE("sao_band_position", value, ps_cabac->u4_range); 2097 2098 sao_band_position = value; 2099 } 2100 else 2101 { 2102 if(c_idx == 0) 2103 { 2104 value = ihevcd_cabac_decode_bypass_bins(ps_cabac, ps_bitstrm, 2); 2105 AEV_TRACE("sao_eo_class", value, ps_cabac->u4_range); 2106 2107 ps_sao->b3_y_type_idx += value; 2108 } 2109 2110 if(c_idx == 1) 2111 { 2112 value = ihevcd_cabac_decode_bypass_bins(ps_cabac, ps_bitstrm, 2); 2113 AEV_TRACE("sao_eo_class", value, ps_cabac->u4_range); 2114 2115 ps_sao->b3_cb_type_idx += value; 2116 ps_sao->b3_cr_type_idx += value; 2117 } 2118 } 2119 2120 if(0 == c_idx) 2121 { 2122 ps_sao->b4_y_offset_1 = sao_offset[0]; 2123 ps_sao->b4_y_offset_2 = sao_offset[1]; 2124 ps_sao->b4_y_offset_3 = sao_offset[2]; 2125 ps_sao->b4_y_offset_4 = sao_offset[3]; 2126 2127 ps_sao->b5_y_band_pos = sao_band_position; 2128 } 2129 else if(1 == c_idx) 2130 { 2131 ps_sao->b4_cb_offset_1 = sao_offset[0]; 2132 ps_sao->b4_cb_offset_2 = sao_offset[1]; 2133 ps_sao->b4_cb_offset_3 = sao_offset[2]; 2134 ps_sao->b4_cb_offset_4 = sao_offset[3]; 2135 2136 ps_sao->b5_cb_band_pos = sao_band_position; 2137 } 2138 else // 2 == c_idx 2139 { 2140 ps_sao->b4_cr_offset_1 = sao_offset[0]; 2141 ps_sao->b4_cr_offset_2 = sao_offset[1]; 2142 ps_sao->b4_cr_offset_3 = sao_offset[2]; 2143 ps_sao->b4_cr_offset_4 = sao_offset[3]; 2144 2145 ps_sao->b5_cr_band_pos = sao_band_position; 2146 } 2147 } 2148 } 2149 } 2150 } 2151 2152 return ret; 2153} 2154/** 2155 ******************************************************************************* 2156 * 2157 * @brief 2158 * Parses Slice data syntax 2159 * 2160 * @par Description: 2161 * Parses Slice data syntax as per Section:7.3.9.1 2162 * 2163 * @param[in] ps_codec 2164 * Pointer to codec context 2165 * 2166 * @returns Error from IHEVCD_ERROR_T 2167 * 2168 * @remarks 2169 * 2170 * 2171 ******************************************************************************* 2172 */ 2173IHEVCD_ERROR_T ihevcd_parse_slice_data(codec_t *ps_codec) 2174{ 2175 2176 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 2177 WORD32 end_of_slice_flag; 2178 sps_t *ps_sps; 2179 pps_t *ps_pps; 2180 slice_header_t *ps_slice_hdr; 2181 WORD32 end_of_pic; 2182 tile_t *ps_tile, *ps_tile_prev; 2183 WORD32 i; 2184 WORD32 ctb_addr; 2185 WORD32 tile_idx; 2186 WORD32 cabac_init_idc; 2187 WORD32 ctb_size; 2188 WORD32 num_ctb_in_row; 2189 WORD32 num_min4x4_in_ctb; 2190 WORD32 slice_qp; 2191 WORD32 slice_start_ctb_idx; 2192 WORD32 tile_start_ctb_idx; 2193 2194#ifdef GPU_BUILD 2195 WORD32 total_ctb_cnt = 0; 2196 proc_job_t s_job; 2197 gpu_ctxt_t *ps_gpu = &ps_codec->s_gpu_ctxt; 2198#endif 2199 2200 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr_base; 2201 ps_pps = ps_codec->s_parse.ps_pps_base; 2202 ps_sps = ps_codec->s_parse.ps_sps_base; 2203 2204 /* Get current slice header, pps and sps */ 2205 ps_slice_hdr += (ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1)); 2206 ps_pps += ps_slice_hdr->i1_pps_id; 2207 ps_sps += ps_pps->i1_sps_id; 2208 2209 if(0 != ps_codec->s_parse.i4_cur_slice_idx) 2210 { 2211 if(!ps_slice_hdr->i1_dependent_slice_flag) 2212 { 2213 ps_codec->s_parse.i4_cur_independent_slice_idx++; 2214 if(MAX_SLICE_HDR_CNT == ps_codec->s_parse.i4_cur_independent_slice_idx) 2215 ps_codec->s_parse.i4_cur_independent_slice_idx = 0; 2216 } 2217 } 2218 2219 2220 ctb_size = 1 << ps_sps->i1_log2_ctb_size; 2221 num_min4x4_in_ctb = (ctb_size / 4) * (ctb_size / 4); 2222 num_ctb_in_row = ps_sps->i2_pic_wd_in_ctb; 2223 2224 /* Update the parse context */ 2225 if(0 == ps_codec->i4_slice_error) 2226 { 2227 ps_codec->s_parse.i4_ctb_x = ps_slice_hdr->i2_ctb_x; 2228 ps_codec->s_parse.i4_ctb_y = ps_slice_hdr->i2_ctb_y; 2229 } 2230 ps_codec->s_parse.ps_pps = ps_pps; 2231 ps_codec->s_parse.ps_sps = ps_sps; 2232 ps_codec->s_parse.ps_slice_hdr = ps_slice_hdr; 2233 2234 /* Derive Tile positions for the current CTB */ 2235 /* Change this to lookup if required */ 2236 ihevcd_get_tile_pos(ps_pps, ps_sps, ps_codec->s_parse.i4_ctb_x, 2237 ps_codec->s_parse.i4_ctb_y, 2238 &ps_codec->s_parse.i4_ctb_tile_x, 2239 &ps_codec->s_parse.i4_ctb_tile_y, 2240 &tile_idx); 2241 ps_codec->s_parse.ps_tile = ps_pps->ps_tile + tile_idx; 2242 ps_codec->s_parse.i4_cur_tile_idx = tile_idx; 2243 ps_tile = ps_codec->s_parse.ps_tile; 2244 if(tile_idx) 2245 ps_tile_prev = ps_tile - 1; 2246 else 2247 ps_tile_prev = ps_tile; 2248 2249 /* If the present slice is dependent, then store the previous 2250 * independent slices' ctb x and y values for decoding process */ 2251 if(0 == ps_codec->i4_slice_error) 2252 { 2253 if(1 == ps_slice_hdr->i1_dependent_slice_flag) 2254 { 2255 /*If slice is present at the start of a new tile*/ 2256 if((0 == ps_codec->s_parse.i4_ctb_tile_x) && (0 == ps_codec->s_parse.i4_ctb_tile_y)) 2257 { 2258 ps_codec->s_parse.i4_ctb_slice_x = 0; 2259 ps_codec->s_parse.i4_ctb_slice_y = 0; 2260 } 2261 } 2262 2263 if(!ps_slice_hdr->i1_dependent_slice_flag) 2264 { 2265 ps_codec->s_parse.i4_ctb_slice_x = 0; 2266 ps_codec->s_parse.i4_ctb_slice_y = 0; 2267 } 2268 } 2269 2270 /* Frame level initializations */ 2271 if((0 == ps_codec->s_parse.i4_ctb_y) && 2272 (0 == ps_codec->s_parse.i4_ctb_x)) 2273 { 2274 ret = ihevcd_parse_pic_init(ps_codec); 2275 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); 2276 2277 ps_codec->s_parse.pu4_pic_tu_idx[0] = 0; 2278 ps_codec->s_parse.pu4_pic_pu_idx[0] = 0; 2279 ps_codec->s_parse.i4_cur_independent_slice_idx = 0; 2280 ps_codec->s_parse.i4_ctb_tile_x = 0; 2281 ps_codec->s_parse.i4_ctb_tile_y = 0; 2282 } 2283 2284 { 2285 /* Updating the poc list of current slice to ps_mv_buf */ 2286 mv_buf_t *ps_mv_buf = ps_codec->s_parse.ps_cur_mv_buf; 2287 2288 if(ps_slice_hdr->i1_num_ref_idx_l1_active != 0) 2289 { 2290 for(i = 0; i < ps_slice_hdr->i1_num_ref_idx_l1_active; i++) 2291 { 2292 ps_mv_buf->l1_collocated_poc[(ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1))][i] = ((pic_buf_t *)ps_slice_hdr->as_ref_pic_list1[i].pv_pic_buf)->i4_abs_poc; 2293 ps_mv_buf->u1_l1_collocated_poc_lt[(ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1))][i] = ((pic_buf_t *)ps_slice_hdr->as_ref_pic_list1[i].pv_pic_buf)->u1_used_as_ref; 2294 } 2295 } 2296 2297 if(ps_slice_hdr->i1_num_ref_idx_l0_active != 0) 2298 { 2299 for(i = 0; i < ps_slice_hdr->i1_num_ref_idx_l0_active; i++) 2300 { 2301 ps_mv_buf->l0_collocated_poc[(ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1))][i] = ((pic_buf_t *)ps_slice_hdr->as_ref_pic_list0[i].pv_pic_buf)->i4_abs_poc; 2302 ps_mv_buf->u1_l0_collocated_poc_lt[(ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1))][i] = ((pic_buf_t *)ps_slice_hdr->as_ref_pic_list0[i].pv_pic_buf)->u1_used_as_ref; 2303 } 2304 } 2305 } 2306 2307 /*Initialize the low delay flag at the beginning of every slice*/ 2308 if((0 == ps_codec->s_parse.i4_ctb_slice_x) || (0 == ps_codec->s_parse.i4_ctb_slice_y)) 2309 { 2310 /* Lowdelay flag */ 2311 WORD32 cur_poc, ref_list_poc, flag = 1; 2312 cur_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 2313 for(i = 0; i < ps_slice_hdr->i1_num_ref_idx_l0_active; i++) 2314 { 2315 ref_list_poc = ((mv_buf_t *)ps_slice_hdr->as_ref_pic_list0[i].pv_mv_buf)->i4_abs_poc; 2316 if(ref_list_poc > cur_poc) 2317 { 2318 flag = 0; 2319 break; 2320 } 2321 } 2322 if(flag && (ps_slice_hdr->i1_slice_type == BSLICE)) 2323 { 2324 for(i = 0; i < ps_slice_hdr->i1_num_ref_idx_l1_active; i++) 2325 { 2326 ref_list_poc = ((mv_buf_t *)ps_slice_hdr->as_ref_pic_list1[i].pv_mv_buf)->i4_abs_poc; 2327 if(ref_list_poc > cur_poc) 2328 { 2329 flag = 0; 2330 break; 2331 } 2332 } 2333 } 2334 ps_slice_hdr->i1_low_delay_flag = flag; 2335 } 2336 2337 /* initialize the cabac init idc based on slice type */ 2338 if(ps_slice_hdr->i1_slice_type == ISLICE) 2339 { 2340 cabac_init_idc = 0; 2341 } 2342 else if(ps_slice_hdr->i1_slice_type == PSLICE) 2343 { 2344 cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 2 : 1; 2345 } 2346 else 2347 { 2348 cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 1 : 2; 2349 } 2350 2351 slice_qp = ps_slice_hdr->i1_slice_qp_delta + ps_pps->i1_pic_init_qp; 2352 slice_qp = CLIP3(slice_qp, 0, 51); 2353 2354 /*Update QP value for every indepndent slice or for every dependent slice that begins at the start of a new tile*/ 2355 if((0 == ps_slice_hdr->i1_dependent_slice_flag) || 2356 ((1 == ps_slice_hdr->i1_dependent_slice_flag) && ((0 == ps_codec->s_parse.i4_ctb_tile_x) && (0 == ps_codec->s_parse.i4_ctb_tile_y)))) 2357 { 2358 ps_codec->s_parse.u4_qp = slice_qp; 2359 } 2360 2361 /*Cabac init at the beginning of a slice*/ 2362 //If the slice is a dependent slice, not present at the start of a tile 2363 if((1 == ps_slice_hdr->i1_dependent_slice_flag) && (!((ps_codec->s_parse.i4_ctb_tile_x == 0) && (ps_codec->s_parse.i4_ctb_tile_y == 0)))) 2364 { 2365 if((0 == ps_pps->i1_entropy_coding_sync_enabled_flag) || (ps_pps->i1_entropy_coding_sync_enabled_flag && (0 != ps_codec->s_parse.i4_ctb_x))) 2366 { 2367 ihevcd_cabac_reset(&ps_codec->s_parse.s_cabac, 2368 &ps_codec->s_parse.s_bitstrm); 2369 } 2370 } 2371 else if((0 == ps_pps->i1_entropy_coding_sync_enabled_flag) || (ps_pps->i1_entropy_coding_sync_enabled_flag && (0 != ps_codec->s_parse.i4_ctb_x))) 2372 { 2373 ihevcd_cabac_init(&ps_codec->s_parse.s_cabac, 2374 &ps_codec->s_parse.s_bitstrm, 2375 slice_qp, 2376 cabac_init_idc, 2377 &gau1_ihevc_cab_ctxts[cabac_init_idc][slice_qp][0]); 2378 } 2379 2380 2381 do 2382 { 2383 2384 { 2385 WORD32 cur_ctb_idx = ps_codec->s_parse.i4_ctb_x 2386 + ps_codec->s_parse.i4_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 2387 if(1 == ps_codec->i4_num_cores && 0 == cur_ctb_idx % RESET_TU_BUF_NCTB) 2388 { 2389 ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu; 2390 ps_codec->s_parse.i4_pic_tu_idx = 0; 2391 } 2392 } 2393 2394 end_of_pic = 0; 2395 /* Section:7.3.7 Coding tree unit syntax */ 2396 /* coding_tree_unit() inlined here */ 2397 /* If number of cores is greater than 1, then add job to the queue */ 2398 //TODO: Dual core implementation might need a different algo for better load balancing 2399 /* At the start of ctb row parsing in a tile, queue a job for processing the current tile row */ 2400 ps_codec->s_parse.i4_ctb_num_pcm_blks = 0; 2401 2402 2403 /*At the beginning of each tile-which is not the beginning of a slice, cabac context must be initialized. 2404 * Hence, check for the tile beginning here */ 2405 if(((0 == ps_codec->s_parse.i4_ctb_tile_x) && (0 == ps_codec->s_parse.i4_ctb_tile_y)) 2406 && (!((ps_tile->u1_pos_x == 0) && (ps_tile->u1_pos_y == 0))) 2407 && (!((0 == ps_codec->s_parse.i4_ctb_slice_x) && (0 == ps_codec->s_parse.i4_ctb_slice_y)))) 2408 { 2409 slice_qp = ps_slice_hdr->i1_slice_qp_delta + ps_pps->i1_pic_init_qp; 2410 slice_qp = CLIP3(slice_qp, 0, 51); 2411 ps_codec->s_parse.u4_qp = slice_qp; 2412 2413 ihevcd_get_tile_pos(ps_pps, ps_sps, ps_codec->s_parse.i4_ctb_x, 2414 ps_codec->s_parse.i4_ctb_y, 2415 &ps_codec->s_parse.i4_ctb_tile_x, 2416 &ps_codec->s_parse.i4_ctb_tile_y, 2417 &tile_idx); 2418 2419 ps_codec->s_parse.ps_tile = ps_pps->ps_tile + tile_idx; 2420 ps_codec->s_parse.i4_cur_tile_idx = tile_idx; 2421 ps_tile_prev = ps_tile - 1; 2422 2423 tile_start_ctb_idx = ps_tile->u1_pos_x 2424 + ps_tile->u1_pos_y * (ps_sps->i2_pic_wd_in_ctb); 2425 2426 slice_start_ctb_idx = ps_slice_hdr->i2_ctb_x 2427 + ps_slice_hdr->i2_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 2428 2429 /*For slices that span across multiple tiles*/ 2430 if(slice_start_ctb_idx < tile_start_ctb_idx) 2431 { /* 2 Cases 2432 * 1 - slice spans across frame-width- but does not start from 1st column 2433 * 2 - Slice spans across multiple tiles anywhere is a frame 2434 */ 2435 ps_codec->s_parse.i4_ctb_slice_y = ps_tile->u1_pos_y - ps_slice_hdr->i2_ctb_y; 2436 if(!(((ps_slice_hdr->i2_ctb_x + ps_tile_prev->u2_wd) % ps_sps->i2_pic_wd_in_ctb) == ps_tile->u1_pos_x)) //Case 2 2437 { 2438 if(ps_slice_hdr->i2_ctb_y <= ps_tile->u1_pos_y) 2439 { 2440 //Check if ctb x is before or after 2441 if(ps_slice_hdr->i2_ctb_x > ps_tile->u1_pos_x) 2442 { 2443 ps_codec->s_parse.i4_ctb_slice_y -= 1; 2444 } 2445 } 2446 } 2447 /*ps_codec->s_parse.i4_ctb_slice_y = ps_tile->u1_pos_y - ps_slice_hdr->i2_ctb_y; 2448 if (ps_slice_hdr->i2_ctb_y <= ps_tile->u1_pos_y) 2449 { 2450 //Check if ctb x is before or after 2451 if (ps_slice_hdr->i2_ctb_x > ps_tile->u1_pos_x ) 2452 { 2453 ps_codec->s_parse.i4_ctb_slice_y -= 1 ; 2454 } 2455 }*/ 2456 } 2457 2458 if(!ps_slice_hdr->i1_dependent_slice_flag) 2459 { 2460 ihevcd_cabac_init(&ps_codec->s_parse.s_cabac, 2461 &ps_codec->s_parse.s_bitstrm, 2462 slice_qp, 2463 cabac_init_idc, 2464 &gau1_ihevc_cab_ctxts[cabac_init_idc][slice_qp][0]); 2465 2466 } 2467 } 2468 /* If number of cores is greater than 1, then add job to the queue */ 2469 //TODO: Dual core implementation might need a different algo for better load balancing 2470 /* At the start of ctb row parsing in a tile, queue a job for processing the current tile row */ 2471 2472 if(0 == ps_codec->s_parse.i4_ctb_tile_x) 2473 { 2474 2475#ifndef GPU_BUILD 2476 if(1 < ps_codec->i4_num_cores) 2477 { 2478 proc_job_t s_job; 2479 IHEVCD_ERROR_T ret; 2480 s_job.i4_cmd = CMD_PROCESS; 2481 s_job.i2_ctb_cnt = (WORD16)ps_tile->u2_wd; 2482 s_job.i2_ctb_x = (WORD16)ps_codec->s_parse.i4_ctb_x; 2483 s_job.i2_ctb_y = (WORD16)ps_codec->s_parse.i4_ctb_y; 2484 s_job.i2_slice_idx = (WORD16)ps_codec->s_parse.i4_cur_slice_idx; 2485 s_job.i4_tu_coeff_data_ofst = (UWORD8 *)ps_codec->s_parse.pv_tu_coeff_data - 2486 (UWORD8 *)ps_codec->s_parse.pv_pic_tu_coeff_data; 2487 ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq, &s_job, sizeof(proc_job_t), 1); 2488 2489 if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS) 2490 return ret; 2491 } 2492 else 2493#endif 2494 { 2495#ifdef GPU_BUILD 2496 process_ctxt_t *ps_proc = &ps_codec->as_process[(ps_codec->i4_num_cores == 1) ? 1 : (ps_codec->i4_num_cores - 1)]; 2497#else 2498 process_ctxt_t *ps_proc = &ps_codec->as_process[0]; 2499#endif 2500 WORD32 tu_coeff_data_ofst = (UWORD8 *)ps_codec->s_parse.pv_tu_coeff_data - 2501 (UWORD8 *)ps_codec->s_parse.pv_pic_tu_coeff_data; 2502 2503 /* If the codec is running in single core mode, 2504 * initialize zeroth process context 2505 * TODO: Dual core mode might need a different implementation instead of jobq 2506 */ 2507 2508 ps_proc->i4_ctb_cnt = ps_tile->u2_wd; 2509 ps_proc->i4_ctb_x = ps_codec->s_parse.i4_ctb_x; 2510 ps_proc->i4_ctb_y = ps_codec->s_parse.i4_ctb_y; 2511 ps_proc->i4_cur_slice_idx = ps_codec->s_parse.i4_cur_slice_idx; 2512 2513#ifdef GPU_BUILD 2514 ps_proc->ps_slice_hdr = ps_slice_hdr; 2515 ps_gpu->ai4_tu_coeff_data_ofst[ps_codec->s_parse.i4_ctb_tile_y] = tu_coeff_data_ofst; 2516 2517 ps_gpu->ai4_cur_slice_idx[ps_codec->s_parse.i4_ctb_tile_y] = ps_codec->s_parse.i4_cur_slice_idx; 2518#endif 2519 ihevcd_init_proc_ctxt(ps_proc, tu_coeff_data_ofst); 2520 } 2521 } 2522 2523 2524 /* Restore cabac context model from top right CTB if entropy sync is enabled */ 2525 if(ps_pps->i1_entropy_coding_sync_enabled_flag) 2526 { 2527 /*TODO Handle single CTB and top-right belonging to a different slice */ 2528 if(0 == ps_codec->s_parse.i4_ctb_x) 2529 { 2530 //WORD32 size = sizeof(ps_codec->s_parse.s_cabac.au1_ctxt_models); 2531 WORD32 default_ctxt = 0; 2532 2533 if((0 == ps_codec->s_parse.i4_ctb_slice_y) && (!ps_slice_hdr->i1_dependent_slice_flag)) 2534 default_ctxt = 1; 2535 if(1 == ps_sps->i2_pic_wd_in_ctb) 2536 default_ctxt = 1; 2537 2538 ps_codec->s_parse.u4_qp = slice_qp; 2539 if(default_ctxt) 2540 { 2541 //memcpy(&ps_codec->s_parse.s_cabac.au1_ctxt_models, &gau1_ihevc_cab_ctxts[cabac_init_idc][slice_qp][0], size); 2542 ihevcd_cabac_init(&ps_codec->s_parse.s_cabac, 2543 &ps_codec->s_parse.s_bitstrm, 2544 slice_qp, 2545 cabac_init_idc, 2546 &gau1_ihevc_cab_ctxts[cabac_init_idc][slice_qp][0]); 2547 2548 } 2549 else 2550 { 2551 //memcpy(&ps_codec->s_parse.s_cabac.au1_ctxt_models, &ps_codec->s_parse.s_cabac.au1_ctxt_models_sync, size); 2552 ihevcd_cabac_init(&ps_codec->s_parse.s_cabac, 2553 &ps_codec->s_parse.s_bitstrm, 2554 slice_qp, 2555 cabac_init_idc, 2556 (const UWORD8 *)&ps_codec->s_parse.s_cabac.au1_ctxt_models_sync); 2557 2558 } 2559 } 2560 } 2561 2562 2563 2564 if(0 == ps_codec->i4_slice_error) 2565 { 2566 if(ps_slice_hdr->i1_slice_sao_luma_flag || ps_slice_hdr->i1_slice_sao_chroma_flag) 2567 ihevcd_parse_sao(ps_codec); 2568 } 2569 else 2570 { 2571 sao_t *ps_sao = ps_codec->s_parse.ps_pic_sao + 2572 ps_codec->s_parse.i4_ctb_x + 2573 ps_codec->s_parse.i4_ctb_y * ps_sps->i2_pic_wd_in_ctb; 2574 2575 /* Default values */ 2576 ps_sao->b3_y_type_idx = 0; 2577 ps_sao->b3_cb_type_idx = 0; 2578 ps_sao->b3_cr_type_idx = 0; 2579 } 2580 2581 //AEV_TRACE("CTB x", ps_codec->s_parse.i4_ctb_x, 0); 2582 //AEV_TRACE("CTB y", ps_codec->s_parse.i4_ctb_y, 0); 2583 2584 { 2585 WORD32 ctb_indx; 2586 ctb_indx = ps_codec->s_parse.i4_ctb_x + ps_sps->i2_pic_wd_in_ctb * ps_codec->s_parse.i4_ctb_y; 2587 ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp_const_in_ctb[ctb_indx >> 3] |= (1 << (ctb_indx & 7)); 2588 { 2589 UWORD16 *pu1_slice_idx = ps_codec->s_parse.pu1_slice_idx; 2590 pu1_slice_idx[ctb_indx] = ps_codec->s_parse.i4_cur_independent_slice_idx; 2591 } 2592 } 2593 2594 if(0 == ps_codec->i4_slice_error) 2595 { 2596 ihevcd_parse_coding_quadtree(ps_codec, 2597 (ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size), 2598 (ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size), 2599 ps_sps->i1_log2_ctb_size, 2600 0); 2601 } 2602 else 2603 { 2604 tu_t *ps_tu = ps_codec->s_parse.ps_tu; 2605 pu_t *ps_pu = ps_codec->s_parse.ps_pu; 2606 2607 ps_tu->b1_cb_cbf = 0; 2608 ps_tu->b1_cr_cbf = 0; 2609 ps_tu->b1_y_cbf = 0; 2610 ps_tu->b4_pos_x = 0; 2611 ps_tu->b4_pos_y = 0; 2612 ps_tu->b1_transquant_bypass = 0; 2613 ps_tu->b3_size = (ps_sps->i1_log2_ctb_size - 2); 2614 ps_tu->b7_qp = ps_codec->s_parse.u4_qp; 2615 ps_tu->b3_chroma_intra_mode_idx = INTRA_PRED_CHROMA_IDX_NONE; 2616 ps_tu->b6_luma_intra_mode = INTRA_PRED_NONE; 2617 ps_tu->b1_first_tu_in_cu = 1; 2618 2619 ps_codec->s_parse.ps_tu++; 2620 ps_codec->s_parse.s_cu.i4_tu_cnt++; 2621 ps_codec->s_parse.i4_pic_tu_idx++; 2622 2623 ps_codec->s_parse.s_cu.i4_pred_mode = PRED_MODE_SKIP; 2624 ps_codec->s_parse.s_cu.i4_part_mode = PART_2Nx2N; 2625 2626 ps_pu->b2_part_idx = 0; 2627 ps_pu->b4_pos_x = 0; 2628 ps_pu->b4_pos_y = 0; 2629 ps_pu->b4_wd = (ctb_size >> 2) - 1; 2630 ps_pu->b4_ht = (ctb_size >> 2) - 1; 2631 ps_pu->b1_intra_flag = 0; 2632 ps_pu->b3_part_mode = ps_codec->s_parse.s_cu.i4_part_mode; 2633 ps_pu->b1_merge_flag = 1; 2634 ps_pu->b3_merge_idx = 0; 2635 2636 ps_codec->s_parse.ps_pu++; 2637 ps_codec->s_parse.i4_pic_pu_idx++; 2638 2639 } 2640 2641 if(0 == ps_codec->i4_slice_error) 2642 end_of_slice_flag = ihevcd_cabac_decode_terminate(&ps_codec->s_parse.s_cabac, &ps_codec->s_parse.s_bitstrm); 2643 else 2644 end_of_slice_flag = 0; 2645 2646 AEV_TRACE("end_of_slice_flag", end_of_slice_flag, ps_codec->s_parse.s_cabac.u4_range); 2647 2648 2649 /* In case of tiles or entropy sync, terminate cabac and copy cabac context backed up at the end of top-right CTB */ 2650 if(ps_pps->i1_tiles_enabled_flag || ps_pps->i1_entropy_coding_sync_enabled_flag) 2651 { 2652 WORD32 end_of_tile = 0; 2653 WORD32 end_of_tile_row = 0; 2654 2655 /* Take a back up of cabac context models if entropy sync is enabled */ 2656 if(ps_pps->i1_entropy_coding_sync_enabled_flag || ps_pps->i1_tiles_enabled_flag) 2657 { 2658 if(1 == ps_codec->s_parse.i4_ctb_x) 2659 { 2660 WORD32 size = sizeof(ps_codec->s_parse.s_cabac.au1_ctxt_models); 2661 memcpy(&ps_codec->s_parse.s_cabac.au1_ctxt_models_sync, &ps_codec->s_parse.s_cabac.au1_ctxt_models, size); 2662 } 2663 } 2664 2665 /* Since tiles and entropy sync are not enabled simultaneously, the following will not result in any problems */ 2666 if((ps_codec->s_parse.i4_ctb_tile_x + 1) == (ps_tile->u2_wd)) 2667 { 2668 end_of_tile_row = 1; 2669 if((ps_codec->s_parse.i4_ctb_tile_y + 1) == ps_tile->u2_ht) 2670 end_of_tile = 1; 2671 } 2672 if((0 == end_of_slice_flag) && 2673 ((ps_pps->i1_tiles_enabled_flag && end_of_tile) || 2674 (ps_pps->i1_entropy_coding_sync_enabled_flag && end_of_tile_row))) 2675 { 2676 WORD32 end_of_sub_stream_one_bit; 2677 end_of_sub_stream_one_bit = ihevcd_cabac_decode_terminate(&ps_codec->s_parse.s_cabac, &ps_codec->s_parse.s_bitstrm); 2678 AEV_TRACE("end_of_sub_stream_one_bit", end_of_sub_stream_one_bit, ps_codec->s_parse.s_cabac.u4_range); 2679 2680 /* TODO: Remove the check for offset when HM is updated to include a byte unconditionally even for aligned location */ 2681 /* For Ittiam streams this check should not be there, for HM9.1 streams this should be there */ 2682 if(ps_codec->s_parse.s_bitstrm.u4_bit_ofst % 8) 2683 ihevcd_bits_flush_to_byte_boundary(&ps_codec->s_parse.s_bitstrm); 2684 2685 UNUSED(end_of_sub_stream_one_bit); 2686 } 2687 } 2688 { 2689 WORD32 ctb_indx; 2690 2691 ctb_addr = ps_codec->s_parse.i4_ctb_y * num_ctb_in_row + ps_codec->s_parse.i4_ctb_x; 2692 2693 ctb_indx = ++ctb_addr; 2694 2695 /* Store pu_idx for next CTB in frame level pu_idx array */ 2696 2697 //In case of multiple tiles, if end-of-tile row is reached 2698 if((ps_tile->u2_wd == (ps_codec->s_parse.i4_ctb_tile_x + 1)) && (ps_tile->u2_wd != ps_sps->i2_pic_wd_in_ctb)) 2699 { 2700 ctb_indx = (ps_sps->i2_pic_wd_in_ctb * (ps_codec->s_parse.i4_ctb_tile_y + 1 + ps_tile->u1_pos_y)) + ps_tile->u1_pos_x; //idx is the beginning of next row in current tile. 2701 if(ps_tile->u2_ht == (ps_codec->s_parse.i4_ctb_tile_y + 1)) 2702 { 2703 //If the current ctb is the last tile's last ctb 2704 if((ps_tile->u2_wd + ps_tile->u1_pos_x == ps_sps->i2_pic_wd_in_ctb) && ((ps_tile->u2_ht + ps_tile->u1_pos_y == ps_sps->i2_pic_ht_in_ctb))) 2705 { 2706 ctb_indx = ctb_addr; //Next continuous ctb address 2707 } 2708 else //Not last tile's end , but a tile end 2709 { 2710 tile_t *ps_next_tile = ps_codec->s_parse.ps_tile + 1; 2711 ctb_indx = ps_next_tile->u1_pos_x + (ps_next_tile->u1_pos_y * ps_sps->i2_pic_wd_in_ctb); //idx is the beginning of first row in next tile. 2712 } 2713 } 2714 } 2715 2716 ps_codec->s_parse.pu4_pic_pu_idx[ctb_indx] = ps_codec->s_parse.i4_pic_pu_idx; 2717 ps_codec->s_parse.i4_next_pu_ctb_cnt = ctb_indx; 2718 2719 ps_codec->s_parse.pu1_pu_map += num_min4x4_in_ctb; 2720 2721 /* Store tu_idx for next CTB in frame level tu_idx array */ 2722 if(1 == ps_codec->i4_num_cores) 2723 { 2724 ctb_indx = (0 == ctb_addr % RESET_TU_BUF_NCTB) ? 2725 RESET_TU_BUF_NCTB : ctb_addr % RESET_TU_BUF_NCTB; 2726 2727 //In case of multiple tiles, if end-of-tile row is reached 2728 if((ps_tile->u2_wd == (ps_codec->s_parse.i4_ctb_tile_x + 1)) && (ps_tile->u2_wd != ps_sps->i2_pic_wd_in_ctb)) 2729 { 2730 ctb_indx = (ps_sps->i2_pic_wd_in_ctb * (ps_codec->s_parse.i4_ctb_tile_y + 1 + ps_tile->u1_pos_y)) + ps_tile->u1_pos_x; //idx is the beginning of next row in current tile. 2731 if(ps_tile->u2_ht == (ps_codec->s_parse.i4_ctb_tile_y + 1)) 2732 { 2733 //If the current ctb is the last tile's last ctb 2734 if((ps_tile->u2_wd + ps_tile->u1_pos_x == ps_sps->i2_pic_wd_in_ctb) && ((ps_tile->u2_ht + ps_tile->u1_pos_y == ps_sps->i2_pic_ht_in_ctb))) 2735 { 2736 ctb_indx = (0 == ctb_addr % RESET_TU_BUF_NCTB) ? 2737 RESET_TU_BUF_NCTB : ctb_addr % RESET_TU_BUF_NCTB; 2738 } 2739 else //Not last tile's end , but a tile end 2740 { 2741 tile_t *ps_next_tile = ps_codec->s_parse.ps_tile + 1; 2742 ctb_indx = ps_next_tile->u1_pos_x + (ps_next_tile->u1_pos_y * ps_sps->i2_pic_wd_in_ctb); //idx is the beginning of first row in next tile. 2743 } 2744 } 2745 } 2746 ps_codec->s_parse.i4_next_tu_ctb_cnt = ctb_indx; 2747 ps_codec->s_parse.pu4_pic_tu_idx[ctb_indx] = ps_codec->s_parse.i4_pic_tu_idx; 2748 } 2749 else 2750 { 2751 ctb_indx = ctb_addr; 2752 if((ps_tile->u2_wd == (ps_codec->s_parse.i4_ctb_tile_x + 1)) && (ps_tile->u2_wd != ps_sps->i2_pic_wd_in_ctb)) 2753 { 2754 ctb_indx = (ps_sps->i2_pic_wd_in_ctb * (ps_codec->s_parse.i4_ctb_tile_y + 1 + ps_tile->u1_pos_y)) + ps_tile->u1_pos_x; //idx is the beginning of next row in current tile. 2755 if(ps_tile->u2_ht == (ps_codec->s_parse.i4_ctb_tile_y + 1)) 2756 { 2757 //If the current ctb is the last tile's last ctb 2758 if((ps_tile->u2_wd + ps_tile->u1_pos_x == ps_sps->i2_pic_wd_in_ctb) && ((ps_tile->u2_ht + ps_tile->u1_pos_y == ps_sps->i2_pic_ht_in_ctb))) 2759 { 2760 ctb_indx = ctb_addr; 2761 } 2762 else //Not last tile's end , but a tile end 2763 { 2764 tile_t *ps_next_tile = ps_codec->s_parse.ps_tile + 1; 2765 ctb_indx = ps_next_tile->u1_pos_x + (ps_next_tile->u1_pos_y * ps_sps->i2_pic_wd_in_ctb); //idx is the beginning of first row in next tile. 2766 } 2767 } 2768 } 2769 ps_codec->s_parse.i4_next_tu_ctb_cnt = ctb_indx; 2770 ps_codec->s_parse.pu4_pic_tu_idx[ctb_indx] = ps_codec->s_parse.i4_pic_tu_idx; 2771 } 2772 ps_codec->s_parse.pu1_tu_map += num_min4x4_in_ctb; 2773 } 2774 2775 2776 if(ps_codec->i4_num_cores <= MV_PRED_NUM_CORES_THRESHOLD) 2777 { 2778 /*************************************************/ 2779 /**************** MV pred **********************/ 2780 /*************************************************/ 2781 WORD8 u1_top_ctb_avail = 1; 2782 WORD8 u1_left_ctb_avail = 1; 2783 WORD8 u1_top_lt_ctb_avail = 1; 2784 WORD8 u1_top_rt_ctb_avail = 1; 2785 WORD16 i2_wd_in_ctb; 2786 2787 tile_start_ctb_idx = ps_tile->u1_pos_x 2788 + ps_tile->u1_pos_y * (ps_sps->i2_pic_wd_in_ctb); 2789 2790 slice_start_ctb_idx = ps_slice_hdr->i2_ctb_x 2791 + ps_slice_hdr->i2_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 2792 2793 if((slice_start_ctb_idx < tile_start_ctb_idx)) 2794 { 2795 //Slices span across multiple tiles. 2796 i2_wd_in_ctb = ps_sps->i2_pic_wd_in_ctb; 2797 } 2798 else 2799 { 2800 i2_wd_in_ctb = ps_tile->u2_wd; 2801 } 2802 /* slice and tile boundaries */ 2803 if((0 == ps_codec->s_parse.i4_ctb_y) || (0 == ps_codec->s_parse.i4_ctb_tile_y)) 2804 { 2805 u1_top_ctb_avail = 0; 2806 u1_top_lt_ctb_avail = 0; 2807 u1_top_rt_ctb_avail = 0; 2808 } 2809 2810 if((0 == ps_codec->s_parse.i4_ctb_x) || (0 == ps_codec->s_parse.i4_ctb_tile_x)) 2811 { 2812 u1_left_ctb_avail = 0; 2813 u1_top_lt_ctb_avail = 0; 2814 if((0 == ps_codec->s_parse.i4_ctb_slice_y) || (0 == ps_codec->s_parse.i4_ctb_tile_y)) 2815 { 2816 u1_top_ctb_avail = 0; 2817 if((i2_wd_in_ctb - 1) != ps_codec->s_parse.i4_ctb_slice_x) //TODO: For tile, not implemented 2818 { 2819 u1_top_rt_ctb_avail = 0; 2820 } 2821 } 2822 } 2823 /*For slices not beginning at start of a ctb row*/ 2824 else if(ps_codec->s_parse.i4_ctb_x > 0) 2825 { 2826 if((0 == ps_codec->s_parse.i4_ctb_slice_y) || (0 == ps_codec->s_parse.i4_ctb_tile_y)) 2827 { 2828 u1_top_ctb_avail = 0; 2829 u1_top_lt_ctb_avail = 0; 2830 if(0 == ps_codec->s_parse.i4_ctb_slice_x) 2831 { 2832 u1_left_ctb_avail = 0; 2833 } 2834 if((i2_wd_in_ctb - 1) != ps_codec->s_parse.i4_ctb_slice_x) 2835 { 2836 u1_top_rt_ctb_avail = 0; 2837 } 2838 } 2839 else if((1 == ps_codec->s_parse.i4_ctb_slice_y) && (0 == ps_codec->s_parse.i4_ctb_slice_x)) 2840 { 2841 u1_top_lt_ctb_avail = 0; 2842 } 2843 } 2844 2845 if(((ps_sps->i2_pic_wd_in_ctb - 1) == ps_codec->s_parse.i4_ctb_x) || ((ps_tile->u2_wd - 1) == ps_codec->s_parse.i4_ctb_tile_x)) 2846 { 2847 u1_top_rt_ctb_avail = 0; 2848 } 2849 2850 if(PSLICE == ps_slice_hdr->i1_slice_type 2851 || BSLICE == ps_slice_hdr->i1_slice_type) 2852 { 2853 mv_ctxt_t s_mv_ctxt; 2854 process_ctxt_t *ps_proc; 2855 UWORD32 *pu4_ctb_top_pu_idx; 2856 UWORD32 *pu4_ctb_left_pu_idx; 2857 UWORD32 *pu4_ctb_top_left_pu_idx; 2858 WORD32 i4_ctb_pu_cnt; 2859 WORD32 cur_ctb_idx; 2860 WORD32 next_ctb_idx; 2861 WORD32 cur_pu_idx; 2862 ps_proc = &ps_codec->as_process[(ps_codec->i4_num_cores == 1) ? 1 : (ps_codec->i4_num_cores - 1)]; 2863 cur_ctb_idx = ps_codec->s_parse.i4_ctb_x 2864 + ps_codec->s_parse.i4_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 2865 next_ctb_idx = ps_codec->s_parse.i4_next_pu_ctb_cnt; 2866 i4_ctb_pu_cnt = ps_codec->s_parse.pu4_pic_pu_idx[next_ctb_idx] 2867 - ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx]; 2868 2869 cur_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx]; 2870 2871 pu4_ctb_top_pu_idx = ps_proc->pu4_pic_pu_idx_top 2872 + (ps_codec->s_parse.i4_ctb_x * ctb_size / MIN_PU_SIZE); 2873 pu4_ctb_left_pu_idx = ps_proc->pu4_pic_pu_idx_left; 2874 pu4_ctb_top_left_pu_idx = &ps_proc->u4_ctb_top_left_pu_idx; 2875 2876 /* Initializing s_mv_ctxt */ 2877 { 2878 s_mv_ctxt.ps_pps = ps_pps; 2879 s_mv_ctxt.ps_sps = ps_sps; 2880 s_mv_ctxt.ps_slice_hdr = ps_slice_hdr; 2881 s_mv_ctxt.i4_ctb_x = ps_codec->s_parse.i4_ctb_x; 2882 s_mv_ctxt.i4_ctb_y = ps_codec->s_parse.i4_ctb_y; 2883 s_mv_ctxt.ps_pu = &ps_codec->s_parse.ps_pic_pu[cur_pu_idx]; 2884 s_mv_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu; 2885 s_mv_ctxt.ps_tile = ps_tile; 2886 s_mv_ctxt.pu4_pic_pu_idx_map = ps_proc->pu4_pic_pu_idx_map; 2887 s_mv_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx; 2888 s_mv_ctxt.pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map; 2889 s_mv_ctxt.i4_ctb_pu_cnt = i4_ctb_pu_cnt; 2890 s_mv_ctxt.i4_ctb_start_pu_idx = cur_pu_idx; 2891 s_mv_ctxt.u1_top_ctb_avail = u1_top_ctb_avail; 2892 s_mv_ctxt.u1_top_rt_ctb_avail = u1_top_rt_ctb_avail; 2893 s_mv_ctxt.u1_top_lt_ctb_avail = u1_top_lt_ctb_avail; 2894 s_mv_ctxt.u1_left_ctb_avail = u1_left_ctb_avail; 2895 } 2896 2897 ihevcd_get_mv_ctb(&s_mv_ctxt, pu4_ctb_top_pu_idx, 2898 pu4_ctb_left_pu_idx, pu4_ctb_top_left_pu_idx); 2899 2900 } 2901 else 2902 { 2903 WORD32 num_minpu_in_ctb = (ctb_size / MIN_PU_SIZE) * (ctb_size / MIN_PU_SIZE); 2904 UWORD8 *pu1_pic_pu_map_ctb = ps_codec->s_parse.pu1_pic_pu_map + 2905 (ps_codec->s_parse.i4_ctb_x + ps_codec->s_parse.i4_ctb_y * ps_sps->i2_pic_wd_in_ctb) * num_minpu_in_ctb; 2906 process_ctxt_t *ps_proc = &ps_codec->as_process[(ps_codec->i4_num_cores == 1) ? 1 : (ps_codec->i4_num_cores - 1)]; 2907 WORD32 row, col; 2908 WORD32 pu_cnt; 2909 WORD32 num_pu_per_ctb; 2910 WORD32 cur_ctb_idx; 2911 WORD32 next_ctb_idx; 2912 WORD32 ctb_start_pu_idx; 2913 UWORD32 *pu4_nbr_pu_idx = ps_proc->pu4_pic_pu_idx_map; 2914 WORD32 nbr_pu_idx_strd = MAX_CTB_SIZE / MIN_PU_SIZE + 2; 2915 pu_t *ps_pu; 2916 2917 for(row = 0; row < ctb_size / MIN_PU_SIZE; row++) 2918 { 2919 for(col = 0; col < ctb_size / MIN_PU_SIZE; col++) 2920 { 2921 pu1_pic_pu_map_ctb[row * ctb_size / MIN_PU_SIZE + col] = 0; 2922 } 2923 } 2924 2925 2926 /* Neighbor PU idx update inside CTB */ 2927 /* 1byte per 4x4. Indicates the PU idx that 4x4 block belongs to */ 2928 2929 cur_ctb_idx = ps_codec->s_parse.i4_ctb_x 2930 + ps_codec->s_parse.i4_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 2931 next_ctb_idx = ps_codec->s_parse.i4_next_pu_ctb_cnt; 2932 num_pu_per_ctb = ps_codec->s_parse.pu4_pic_pu_idx[next_ctb_idx] 2933 - ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx]; 2934 ctb_start_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx]; 2935 ps_pu = &ps_codec->s_parse.ps_pic_pu[ctb_start_pu_idx]; 2936 2937 for(pu_cnt = 0; pu_cnt < num_pu_per_ctb; pu_cnt++, ps_pu++) 2938 { 2939 UWORD32 cur_pu_idx; 2940 WORD32 pu_ht = (ps_pu->b4_ht + 1) << 2; 2941 WORD32 pu_wd = (ps_pu->b4_wd + 1) << 2; 2942 2943 cur_pu_idx = ctb_start_pu_idx + pu_cnt; 2944 2945 for(row = 0; row < pu_ht / MIN_PU_SIZE; row++) 2946 for(col = 0; col < pu_wd / MIN_PU_SIZE; col++) 2947 pu4_nbr_pu_idx[(1 + ps_pu->b4_pos_x + col) 2948 + (1 + ps_pu->b4_pos_y + row) 2949 * nbr_pu_idx_strd] = 2950 cur_pu_idx; 2951 } 2952 2953 /* Updating Top and Left pointers */ 2954 { 2955 WORD32 rows_remaining = ps_sps->i2_pic_height_in_luma_samples 2956 - (ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size); 2957 WORD32 ctb_size_left = MIN(ctb_size, rows_remaining); 2958 2959 /* Top Left */ 2960 /* saving top left before updating top ptr, as updating top ptr will overwrite the top left for the next ctb */ 2961 ps_proc->u4_ctb_top_left_pu_idx = ps_proc->pu4_pic_pu_idx_top[(ps_codec->s_parse.i4_ctb_x * ctb_size / MIN_PU_SIZE) + ctb_size / MIN_PU_SIZE - 1]; 2962 for(i = 0; i < ctb_size / MIN_PU_SIZE; i++) 2963 { 2964 /* Left */ 2965 /* Last column of au4_nbr_pu_idx */ 2966 ps_proc->pu4_pic_pu_idx_left[i] = pu4_nbr_pu_idx[(ctb_size / MIN_PU_SIZE) 2967 + (i + 1) * nbr_pu_idx_strd]; 2968 /* Top */ 2969 /* Last row of au4_nbr_pu_idx */ 2970 ps_proc->pu4_pic_pu_idx_top[(ps_codec->s_parse.i4_ctb_x * ctb_size / MIN_PU_SIZE) + i] = 2971 pu4_nbr_pu_idx[(ctb_size_left / MIN_PU_SIZE) * nbr_pu_idx_strd + i + 1]; 2972 2973 } 2974 } 2975 } 2976 2977 /*************************************************/ 2978 /****************** BS, QP *********************/ 2979 /*************************************************/ 2980 /* Check if deblock is disabled for the current slice or if it is disabled for the current picture 2981 * because of disable deblock api 2982 */ 2983 if(0 == ps_codec->i4_disable_deblk_pic) 2984 { 2985 if((0 == ps_slice_hdr->i1_slice_disable_deblocking_filter_flag) && 2986 (0 == ps_codec->i4_slice_error)) 2987 { 2988 WORD32 i4_ctb_tu_cnt; 2989 WORD32 cur_ctb_idx, next_ctb_idx; 2990 WORD32 cur_pu_idx; 2991 WORD32 cur_tu_idx; 2992 process_ctxt_t *ps_proc; 2993 2994 ps_proc = &ps_codec->as_process[(ps_codec->i4_num_cores == 1) ? 1 : (ps_codec->i4_num_cores - 1)]; 2995 cur_ctb_idx = ps_codec->s_parse.i4_ctb_x 2996 + ps_codec->s_parse.i4_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 2997 2998 cur_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx]; 2999 next_ctb_idx = ps_codec->s_parse.i4_next_tu_ctb_cnt; 3000 if(1 == ps_codec->i4_num_cores) 3001 { 3002 i4_ctb_tu_cnt = ps_codec->s_parse.pu4_pic_tu_idx[next_ctb_idx] - 3003 ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx % RESET_TU_BUF_NCTB]; 3004 3005 cur_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx % RESET_TU_BUF_NCTB]; 3006 } 3007 else 3008 { 3009 i4_ctb_tu_cnt = ps_codec->s_parse.pu4_pic_tu_idx[next_ctb_idx] - 3010 ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx]; 3011 3012 cur_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx]; 3013 } 3014 3015 ps_codec->s_parse.s_bs_ctxt.ps_pps = ps_codec->s_parse.ps_pps; 3016 ps_codec->s_parse.s_bs_ctxt.ps_sps = ps_codec->s_parse.ps_sps; 3017 ps_codec->s_parse.s_bs_ctxt.ps_codec = ps_codec; 3018 ps_codec->s_parse.s_bs_ctxt.i4_ctb_tu_cnt = i4_ctb_tu_cnt; 3019 ps_codec->s_parse.s_bs_ctxt.i4_ctb_x = ps_codec->s_parse.i4_ctb_x; 3020 ps_codec->s_parse.s_bs_ctxt.i4_ctb_y = ps_codec->s_parse.i4_ctb_y; 3021 ps_codec->s_parse.s_bs_ctxt.i4_ctb_tile_x = ps_codec->s_parse.i4_ctb_tile_x; 3022 ps_codec->s_parse.s_bs_ctxt.i4_ctb_tile_y = ps_codec->s_parse.i4_ctb_tile_y; 3023 ps_codec->s_parse.s_bs_ctxt.i4_ctb_slice_x = ps_codec->s_parse.i4_ctb_slice_x; 3024 ps_codec->s_parse.s_bs_ctxt.i4_ctb_slice_y = ps_codec->s_parse.i4_ctb_slice_y; 3025 ps_codec->s_parse.s_bs_ctxt.ps_tu = &ps_codec->s_parse.ps_pic_tu[cur_tu_idx]; 3026 ps_codec->s_parse.s_bs_ctxt.ps_pu = &ps_codec->s_parse.ps_pic_pu[cur_pu_idx]; 3027 ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx_map = ps_proc->pu4_pic_pu_idx_map; 3028 ps_codec->s_parse.s_bs_ctxt.i4_next_pu_ctb_cnt = ps_codec->s_parse.i4_next_pu_ctb_cnt; 3029 ps_codec->s_parse.s_bs_ctxt.i4_next_tu_ctb_cnt = ps_codec->s_parse.i4_next_tu_ctb_cnt; 3030 ps_codec->s_parse.s_bs_ctxt.pu1_slice_idx = ps_codec->s_parse.pu1_slice_idx; 3031 ps_codec->s_parse.s_bs_ctxt.ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 3032 ps_codec->s_parse.s_bs_ctxt.ps_tile = ps_codec->s_parse.ps_tile; 3033 3034 if(ISLICE == ps_slice_hdr->i1_slice_type) 3035 { 3036 ihevcd_ctb_boundary_strength_islice(&ps_codec->s_parse.s_bs_ctxt); 3037 } 3038 else 3039 { 3040 ihevcd_ctb_boundary_strength_pbslice(&ps_codec->s_parse.s_bs_ctxt); 3041 } 3042 } 3043 else 3044 { 3045 WORD32 vert_bs_strd = ps_sps->i2_pic_wd_in_ctb * (ctb_size * ctb_size / 8 / 16); 3046 WORD32 horz_bs_strd = (ps_sps->i2_pic_wd_in_ctb + 1) * (ctb_size * ctb_size / 8 / 16); 3047 UWORD32 *pu4_vert_bs = (UWORD32 *)((UWORD8 *)ps_codec->s_parse.s_bs_ctxt.pu4_pic_vert_bs + 3048 ps_codec->s_parse.i4_ctb_x * (ctb_size * ctb_size / 8 / 16) + 3049 ps_codec->s_parse.i4_ctb_y * vert_bs_strd); 3050 UWORD32 *pu4_horz_bs = (UWORD32 *)((UWORD8 *)ps_codec->s_parse.s_bs_ctxt.pu4_pic_horz_bs + 3051 ps_codec->s_parse.i4_ctb_x * (ctb_size * ctb_size / 8 / 16) + 3052 ps_codec->s_parse.i4_ctb_y * horz_bs_strd); 3053 3054 memset(pu4_vert_bs, 0, (ctb_size / 8 + 1) * (ctb_size / 4) / 8 * 2); 3055 memset(pu4_horz_bs, 0, (ctb_size / 8) * (ctb_size / 4) / 8 * 2); 3056 3057 } 3058 } 3059 3060 } 3061 3062 3063 /* Update the parse status map */ 3064 { 3065 sps_t *ps_sps = ps_codec->s_parse.ps_sps; 3066 UWORD8 *pu1_buf; 3067 WORD32 idx; 3068 idx = (ps_codec->s_parse.i4_ctb_x); 3069 idx += ((ps_codec->s_parse.i4_ctb_y) * ps_sps->i2_pic_wd_in_ctb); 3070 pu1_buf = (ps_codec->pu1_parse_map + idx); 3071 *pu1_buf = 1; 3072 } 3073 3074 /* Increment CTB x and y positions */ 3075 ps_codec->s_parse.i4_ctb_tile_x++; 3076 ps_codec->s_parse.i4_ctb_x++; 3077 ps_codec->s_parse.i4_ctb_slice_x++; 3078 3079 /*If tiles are enabled, handle the slice counters differently*/ 3080 if(ps_pps->i1_tiles_enabled_flag) 3081 { 3082 //Indicates multiple tiles in a slice case 3083 tile_start_ctb_idx = ps_tile->u1_pos_x 3084 + ps_tile->u1_pos_y * (ps_sps->i2_pic_wd_in_ctb); 3085 3086 slice_start_ctb_idx = ps_slice_hdr->i2_ctb_x 3087 + ps_slice_hdr->i2_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 3088 3089 if((slice_start_ctb_idx < tile_start_ctb_idx)) 3090 { 3091 if(ps_codec->s_parse.i4_ctb_slice_x == (ps_tile->u1_pos_x + ps_tile->u2_wd)) 3092 { 3093 /* Reached end of slice row within a tile /frame */ 3094 ps_codec->s_parse.i4_ctb_slice_y++; 3095 ps_codec->s_parse.i4_ctb_slice_x = ps_tile->u1_pos_x; //todo:Check 3096 } 3097 } 3098 //Indicates multiple slices in a tile case - hence, reset slice_x 3099 else if(ps_codec->s_parse.i4_ctb_slice_x == (ps_tile->u2_wd)) 3100 { 3101 ps_codec->s_parse.i4_ctb_slice_y++; 3102 ps_codec->s_parse.i4_ctb_slice_x = 0; 3103 } 3104 } 3105 else 3106 { 3107 if(ps_codec->s_parse.i4_ctb_slice_x == ps_tile->u2_wd) 3108 { 3109 /* Reached end of slice row within a tile /frame */ 3110 ps_codec->s_parse.i4_ctb_slice_y++; 3111 ps_codec->s_parse.i4_ctb_slice_x = 0; 3112 } 3113 } 3114 3115 3116 if(ps_codec->s_parse.i4_ctb_tile_x == (ps_tile->u2_wd)) 3117 { 3118 /* Reached end of tile row */ 3119 ps_codec->s_parse.i4_ctb_tile_x = 0; 3120 ps_codec->s_parse.i4_ctb_x = ps_tile->u1_pos_x; 3121 3122 ps_codec->s_parse.i4_ctb_tile_y++; 3123 ps_codec->s_parse.i4_ctb_y++; 3124 3125 if(ps_codec->s_parse.i4_ctb_tile_y == (ps_tile->u2_ht)) 3126 { 3127 /* Reached End of Tile */ 3128 ps_codec->s_parse.i4_ctb_tile_y = 0; 3129 ps_codec->s_parse.i4_ctb_tile_x = 0; 3130 ps_codec->s_parse.ps_tile++; 3131 3132 if((ps_tile->u2_ht + ps_tile->u1_pos_y == ps_sps->i2_pic_ht_in_ctb) && (ps_tile->u2_wd + ps_tile->u1_pos_x == ps_sps->i2_pic_wd_in_ctb)) 3133 { 3134 /* Reached end of frame */ 3135 end_of_pic = 1; 3136 ps_codec->s_parse.i4_ctb_x = 0; 3137 ps_codec->s_parse.i4_ctb_y = ps_sps->i2_pic_ht_in_ctb; 3138 } 3139 else 3140 { 3141 /* Initialize ctb_x and ctb_y to start of next tile */ 3142 ps_tile = ps_codec->s_parse.ps_tile; 3143 ps_codec->s_parse.i4_ctb_x = ps_tile->u1_pos_x; 3144 ps_codec->s_parse.i4_ctb_y = ps_tile->u1_pos_y; 3145 ps_codec->s_parse.i4_ctb_tile_y = 0; 3146 ps_codec->s_parse.i4_ctb_tile_x = 0; 3147 ps_codec->s_parse.i4_ctb_slice_x = ps_tile->u1_pos_x; 3148 ps_codec->s_parse.i4_ctb_slice_y = ps_tile->u1_pos_y; 3149 3150 } 3151 } 3152 3153 } 3154 3155 ps_codec->s_parse.i4_next_ctb_indx = ps_codec->s_parse.i4_ctb_x + 3156 ps_codec->s_parse.i4_ctb_y * ps_sps->i2_pic_wd_in_ctb; 3157 3158 /* If the current slice is in error, check if the next slice's address 3159 * is reached and mark the end_of_slice flag */ 3160 if(ps_codec->i4_slice_error) 3161 { 3162 slice_header_t *ps_slice_hdr_next = ps_slice_hdr + 1; 3163 WORD32 next_slice_addr = ps_slice_hdr_next->i2_ctb_x + 3164 ps_slice_hdr_next->i2_ctb_y * ps_sps->i2_pic_wd_in_ctb; 3165 3166 if(ps_codec->s_parse.i4_next_ctb_indx == next_slice_addr) 3167 end_of_slice_flag = 1; 3168 } 3169 3170#ifndef GPU_BUILD 3171 /* If the codec is running in single core mode 3172 * then call process function for current CTB 3173 */ 3174 if((1 == ps_codec->i4_num_cores) && (ps_codec->s_parse.i4_ctb_tile_x == 0)) 3175 { 3176 process_ctxt_t *ps_proc = &ps_codec->as_process[0]; 3177// ps_proc->i4_ctb_cnt = ihevcd_nctb_cnt(ps_codec, ps_sps); 3178 ps_proc->i4_ctb_cnt = ps_proc->ps_tile->u2_wd; 3179 ihevcd_process(ps_proc); 3180 } 3181#else 3182 /* Now call the function that will popluated mc data for the 3183 * current ctb. 3184 */ 3185 if(ps_codec->u4_gpu_enabled) // == ps_codec->i4_num_cores) 3186 { 3187 process_ctxt_t *ps_proc = &ps_codec->as_process[(ps_codec->i4_num_cores == 1) ? 1 : (ps_codec->i4_num_cores - 1)]; 3188 WORD32 nctb_mc = 1; 3189 WORD32 cur_ctb_idx; 3190 WORD32 cur_pu_idx; 3191 //ps_proc->i4_ctb_cnt = ihevcd_nctb_cnt(ps_codec, ps_sps); 3192 //ihevcd_process(ps_proc); 3193 cur_ctb_idx = ps_proc->i4_ctb_x + ps_proc->i4_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 3194 cur_pu_idx = ps_proc->pu4_pic_pu_idx[cur_ctb_idx]; 3195 ps_proc->ps_pu = &ps_proc->ps_pic_pu[cur_pu_idx]; 3196 ps_proc->ps_slice_hdr = ps_slice_hdr; 3197 3198 if(ISLICE != ps_slice_hdr->i1_slice_type) 3199 ihevcd_gpu_mc_populate_data_nctb(ps_proc, nctb_mc); 3200 3201 ps_proc->i4_ctb_x += nctb_mc; 3202 ps_proc->i4_ctb_cnt -= nctb_mc; 3203 ps_proc->i4_ctb_tile_x += nctb_mc; 3204 } 3205 3206 total_ctb_cnt++; 3207 ps_gpu->i4_curr_grain_ctb_cnt++; 3208 if(1) 3209 { 3210 3211 if(ps_gpu->i4_curr_grain_ctb_cnt == ps_gpu->ai4_ctbs_in_grain[ps_gpu->i4_curr_grain_idx]) 3212 { 3213 process_ctxt_t *ps_proc = &ps_codec->as_process[(ps_codec->i4_num_cores == 1) ? 1 : (ps_codec->i4_num_cores - 1)]; 3214 3215 if(ps_codec->u4_gpu_enabled) 3216 ihevcd_gpu_mc_execute(ps_proc); 3217 3218 3219#if 1 3220 if(1 < ps_codec->i4_num_cores) 3221 { 3222 IHEVCD_ERROR_T ret; 3223 WORD32 i, cnt = ps_gpu->ai4_grain_ht_in_ctb[ps_gpu->i4_curr_grain_idx]; 3224 WORD32 ctb_y_idx = 0; 3225 3226 for(i = 0; i < ps_gpu->i4_curr_grain_idx; i++) 3227 ctb_y_idx += ps_gpu->ai4_grain_ht_in_ctb[i]; 3228 3229 if(ps_gpu->i4_curr_grain_idx == 0) 3230 cnt--; 3231 else if(ps_gpu->i4_curr_grain_idx == (GRANULARITY - 1)) 3232 cnt++; 3233 3234 if(ps_gpu->i4_curr_grain_idx != 0) 3235 ctb_y_idx--; 3236 3237 for(i = 0; i < cnt; i++) 3238 { 3239 s_job.i4_cmd = CMD_PROCESS; 3240 s_job.i2_ctb_cnt = (WORD16)ps_sps->i2_pic_wd_in_ctb; 3241 s_job.i2_ctb_x = 0; //(WORD16)ps_codec->s_parse.i4_ctb_tile_x; 3242 s_job.i2_ctb_y = (WORD16)ctb_y_idx; 3243 s_job.i2_slice_idx = (WORD16)ps_codec->s_parse.i4_cur_slice_idx; 3244 s_job.i4_tu_coeff_data_ofst = ps_gpu->ai4_tu_coeff_data_ofst[ctb_y_idx]; 3245 s_job.i2_granularity_idx = ps_gpu->i4_curr_grain_idx; 3246 s_job.i2_slice_idx = (WORD16)ps_gpu->ai4_cur_slice_idx[ctb_y_idx]; 3247 3248 printf("Queued ctb y row %d\n", ctb_y_idx); 3249 3250 if((i == 0) && (ps_codec->u4_gpu_enabled)) 3251 s_job.i2_wait = 1; 3252 else 3253 s_job.i2_wait = 0; 3254 3255 ret = ihevcd_jobq_queue(ps_codec->s_parse.pv_proc_jobq, &s_job, sizeof(proc_job_t), 1); 3256 ASSERT(ret == IHEVC_SUCCESS); 3257 ctb_y_idx++; 3258 3259 } 3260 } 3261#endif 3262 ps_gpu->i4_curr_grain_ctb_cnt = 0; 3263 ps_gpu->i4_curr_grain_idx++; 3264 3265 } 3266 } 3267#endif 3268 3269 /* If the bytes for the current slice are exhausted 3270 * set end_of_slice flag to 1 3271 * This slice will be treated as incomplete */ 3272 if((UWORD8 *)ps_codec->s_parse.s_bitstrm.pu1_buf_max + BITSTRM_OFF_THRS < 3273 ((UWORD8 *)ps_codec->s_parse.s_bitstrm.pu4_buf + (ps_codec->s_parse.s_bitstrm.u4_bit_ofst / 8))) 3274 { 3275 // end_of_slice_flag = ps_codec->i4_slice_error ? 0 : 1; 3276 3277 if(0 == ps_codec->i4_slice_error) 3278 end_of_slice_flag = 1; 3279 } 3280 3281 3282 if(end_of_pic) 3283 break; 3284 } while(!end_of_slice_flag); 3285 3286 /* Increment the slice index for parsing next slice */ 3287 if(0 == end_of_pic) 3288 { 3289#ifdef GPU_BUILD 3290 // TODO GPU : The following logic needs different implementation. 3291#endif 3292 while(1) 3293 { 3294 3295 WORD32 parse_slice_idx; 3296#ifdef GPU_BUILD 3297 WORD32 min_proc_slice_idx; 3298 WORD32 proc_idx = (ps_codec->u4_parsing_view * 2) + (ps_codec->i4_num_cores - 1); 3299 /* Identify the min slice index currently in use by processing threads */ 3300 min_proc_slice_idx = ps_codec->as_process[proc_idx].i4_cur_slice_idx; 3301#endif 3302 parse_slice_idx = ps_codec->s_parse.i4_cur_slice_idx; 3303 parse_slice_idx++; 3304 3305#if 0 3306 for(i = 1; i < (ps_codec->i4_num_cores - 1); i++) 3307 { 3308 if(ps_codec->as_process[i].i4_cur_slice_idx 3309 < min_proc_slice_idx) 3310 min_proc_slice_idx = 3311 ps_codec->as_process[i].i4_cur_slice_idx; 3312 3313 3314 } 3315 3316 3317 /* If MAX slice header count is reached, then reset the parsing slice idx to zero */ 3318 if(parse_slice_idx == MAX_SLICE_HDR_CNT) 3319 { 3320 parse_slice_idx = 0; 3321 } 3322 3323 /* If parse_slice_idx and min_proc_slice_idx are different then break */ 3324 if(parse_slice_idx != min_proc_slice_idx) 3325 { 3326 ps_codec->s_parse.i4_cur_slice_idx = parse_slice_idx; 3327 break; 3328 } 3329 else 3330 { 3331 /* If Processing threads are still using the slice where parsing thread 3332 * has to write next slice data, wait for processing threads to consume that slice 3333 */ 3334 ithread_yield(); 3335 } 3336#else 3337 { 3338 /* If the next slice header is not initialized, update cur_slice_idx and break */ 3339 if((1 == ps_codec->i4_num_cores) || (0 != (parse_slice_idx & (MAX_SLICE_HDR_CNT - 1)))) 3340 { 3341 ps_codec->s_parse.i4_cur_slice_idx = parse_slice_idx; 3342 break; 3343 } 3344 3345 /* If the next slice header is initialised, wait for the parsed slices to be processed */ 3346 else 3347 { 3348#ifndef GPU_BUILD 3349 WORD32 ctb_indx = 0; 3350 3351 while(ctb_indx != ps_sps->i4_pic_size_in_ctb) 3352 { 3353 WORD32 parse_status = *(ps_codec->pu1_parse_map + ctb_indx); 3354 WORD32 proc_status = *(ps_codec->pu1_proc_map + ctb_indx) & 1; 3355 3356 if(parse_status == proc_status) 3357 ctb_indx++; 3358 } 3359 ps_codec->s_parse.i4_cur_slice_idx = parse_slice_idx; 3360 break; 3361#else 3362 printf("\nFix this code for multiCore multi-Slice\n"); 3363 exit(-1); 3364#endif 3365 } 3366 3367 } 3368#endif 3369 } 3370 3371 } 3372 else 3373 { 3374#ifdef GPU_BUILD 3375 if(1 == ps_codec->i4_num_cores) 3376 { 3377 3378 if(!ps_pps->i1_tiles_enabled_flag) 3379 { 3380 process_ctxt_t *ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1]; 3381 WORD32 i; 3382 WORD32 tu_coeff_data_ofst = 0; 3383 ps_proc->i4_ctb_cnt = total_ctb_cnt; 3384 ps_proc->i4_ctb_x = 0; //ps_codec->s_parse.i4_ctb_tile_x; 3385 ps_proc->i4_ctb_y = 0; //ps_codec->s_parse.i4_ctb_tile_y; 3386 ps_proc->i4_cur_slice_idx = ps_gpu->ai4_cur_slice_idx[0]; //ps_codec->s_parse.i4_cur_slice_idx; 3387 3388 for(i = 0; i < GRANULARITY; i++) 3389 { 3390 ps_proc->i4_ctb_cnt = ps_gpu->ai4_ctbs_in_grain[i]; 3391 total_ctb_cnt -= ps_gpu->ai4_ctbs_in_grain[i]; 3392 3393// if(i == 0) 3394// { 3395// ps_proc->i4_ctb_cnt -= ps_sps->i2_pic_wd_in_ctb; 3396// total_ctb_cnt += ps_sps->i2_pic_wd_in_ctb; 3397// } 3398// else if(i == (GRANULARITY - 1)) 3399// { 3400// ps_proc->i4_ctb_cnt += ps_sps->i2_pic_wd_in_ctb; 3401// //total_ctb_cnt -= ps_sps->i2_pic_wd_in_ctb; 3402// } 3403 3404 // TODO GPU : Buggy don't wait for I-slice. 3405 if(ps_codec->u4_gpu_enabled) 3406 { 3407 ihevcd_gpu_mc_wait(ps_proc, i); 3408 } 3409 3410 //printf("Calling ihevcd_init_proc_ctxt ps_proc->i4_ctb_cnt = %d\n", ps_proc->i4_ctb_cnt); 3411 3412 ihevcd_init_proc_ctxt(ps_proc, tu_coeff_data_ofst); 3413 //printf("ihevcd_process\n"); 3414 ihevcd_process(ps_proc); 3415 tu_coeff_data_ofst = (UWORD8 *)ps_proc->pv_tu_coeff_data - (UWORD8 *)ps_proc->pv_pic_tu_coeff_data; 3416 } 3417 3418 3419 } 3420 else 3421 { 3422 process_ctxt_t *ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1]; 3423 WORD32 i, j, k, l; 3424 WORD32 tu_coeff_data_ofst = 0; 3425 tile_t *ps_tile = ps_pps->ps_tile; 3426 3427 3428 // ps_proc->i4_cur_slice_idx = ps_gpu->ai4_cur_slice_idx[0];//ps_codec->s_parse.i4_cur_slice_idx; 3429 ps_proc->i4_cur_slice_idx = 0; 3430 3431 i = 0; 3432 printf("Processing tile\n"); 3433 for(j = 0; j < ps_pps->i1_num_tile_rows; j++) 3434 { 3435 if(ps_gpu->ai4_grain_pos_y[i] == ps_tile->u1_pos_y) 3436 { 3437 // TODO GPU : Buggy don't wait for I-slice. 3438 if(ps_codec->u4_gpu_enabled) 3439 { 3440 ihevcd_gpu_mc_wait(ps_proc, i); 3441 } 3442 i++; 3443 3444 } 3445 for(k = 0; k < ps_pps->i1_num_tile_columns; k++) 3446 { 3447 ps_proc->i4_ctb_x = ps_tile->u1_pos_x; 3448 ps_proc->i4_ctb_y = ps_tile->u1_pos_y; 3449 3450// ps_proc->i4_cur_slice_idx = *(ps_codec->s_parse.pu1_slice_idx + ps_proc->i4_ctb_x + ps_proc->i4_ctb_y * ps_sps->i2_pic_wd_in_ctb ); 3451 for(l = 0; l < ps_tile->u2_ht; l++) 3452 { 3453 ps_proc->i4_ctb_cnt = ps_tile->u2_wd; //* ps_tile->u2_ht; 3454 3455 ihevcd_init_proc_ctxt(ps_proc, tu_coeff_data_ofst); 3456 //printf("ihevcd_process\n"); 3457 ihevcd_process(ps_proc); 3458 tu_coeff_data_ofst = (UWORD8 *)ps_proc->pv_tu_coeff_data - (UWORD8 *)ps_proc->pv_pic_tu_coeff_data; 3459 } 3460 ps_tile++; 3461 } 3462 } 3463 3464 3465 3466 } 3467 } 3468#endif 3469#if FRAME_ILF_PAD 3470 if(FRAME_ILF_PAD && 1 == ps_codec->i4_num_cores) 3471 { 3472 if(ps_slice_hdr->i4_abs_pic_order_cnt == 0) 3473 { 3474 DUMP_PRE_ILF(ps_codec->as_process[0].pu1_cur_pic_luma, 3475 ps_codec->as_process[0].pu1_cur_pic_chroma, 3476 ps_sps->i2_pic_width_in_luma_samples, 3477 ps_sps->i2_pic_height_in_luma_samples, 3478 ps_codec->i4_strd); 3479 3480 DUMP_BS(ps_codec->as_process[0].s_bs_ctxt.pu4_pic_vert_bs, 3481 ps_codec->as_process[0].s_bs_ctxt.pu4_pic_horz_bs, 3482 ps_sps->i2_pic_wd_in_ctb * (ctb_size * ctb_size / 8 / 16) * ps_sps->i2_pic_ht_in_ctb, 3483 (ps_sps->i2_pic_wd_in_ctb + 1) * (ctb_size * ctb_size / 8 / 16) * ps_sps->i2_pic_ht_in_ctb); 3484 3485 DUMP_QP(ps_codec->as_process[0].s_bs_ctxt.pu1_pic_qp, 3486 (ps_sps->i2_pic_height_in_luma_samples * ps_sps->i2_pic_width_in_luma_samples) / (MIN_CU_SIZE * MIN_CU_SIZE)); 3487 3488 DUMP_QP_CONST_IN_CTB(ps_codec->as_process[0].s_bs_ctxt.pu1_pic_qp_const_in_ctb, 3489 (ps_sps->i2_pic_height_in_luma_samples * ps_sps->i2_pic_width_in_luma_samples) / (MIN_CTB_SIZE * MIN_CTB_SIZE) / 8); 3490 3491 DUMP_NO_LOOP_FILTER(ps_codec->as_process[0].pu1_pic_no_loop_filter_flag, 3492 (ps_sps->i2_pic_width_in_luma_samples / MIN_CU_SIZE) * (ps_sps->i2_pic_height_in_luma_samples / MIN_CU_SIZE) / 8); 3493 3494 DUMP_OFFSETS(ps_slice_hdr->i1_beta_offset_div2, 3495 ps_slice_hdr->i1_tc_offset_div2, 3496 ps_pps->i1_pic_cb_qp_offset, 3497 ps_pps->i1_pic_cr_qp_offset); 3498 } 3499 ps_codec->s_parse.s_deblk_ctxt.ps_pps = ps_codec->s_parse.ps_pps; 3500 ps_codec->s_parse.s_deblk_ctxt.ps_sps = ps_codec->s_parse.ps_sps; 3501 ps_codec->s_parse.s_deblk_ctxt.ps_codec = ps_codec; 3502 ps_codec->s_parse.s_deblk_ctxt.ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 3503 ps_codec->s_parse.s_deblk_ctxt.is_chroma_yuv420sp_vu = (ps_codec->e_ref_chroma_fmt == IV_YUV_420SP_VU); 3504 3505 ps_codec->s_parse.s_sao_ctxt.ps_pps = ps_codec->s_parse.ps_pps; 3506 ps_codec->s_parse.s_sao_ctxt.ps_sps = ps_codec->s_parse.ps_sps; 3507 ps_codec->s_parse.s_sao_ctxt.ps_codec = ps_codec; 3508 ps_codec->s_parse.s_sao_ctxt.ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 3509 3510 ihevcd_ilf_pad_frame(&ps_codec->s_parse.s_deblk_ctxt, &ps_codec->s_parse.s_sao_ctxt); 3511 3512 } 3513#endif 3514 ps_codec->s_parse.i4_end_of_frame = 1; 3515 } 3516 return ret; 3517} 3518 3519 3520 3521 3522 3523 3524 3525 3526