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