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 */ 88 const UWORD8 gau1_part_mode_amp[] = { PART_nLx2N, PART_nRx2N, PART_Nx2N, 0xFF, PART_2NxnU, PART_2NxnD, PART_2NxN, 0xFF }; 89 90 const 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 114 WORD32 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 */ 421 IHEVCD_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 524 IHEVCD_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 624 IHEVCD_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 802 IHEVCD_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 910 WORD32 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 } 946 IHEVCD_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 1151 IHEVCD_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 */ 1670 IHEVCD_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 */ 1949 IHEVCD_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 */ 2170 IHEVCD_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 if(MAX_SLICE_HDR_CNT == ps_codec->s_parse.i4_cur_independent_slice_idx) 2207 ps_codec->s_parse.i4_cur_independent_slice_idx = 0; 2208 } 2209 } 2210 2211 2212 ctb_size = 1 << ps_sps->i1_log2_ctb_size; 2213 num_min4x4_in_ctb = (ctb_size / 4) * (ctb_size / 4); 2214 num_ctb_in_row = ps_sps->i2_pic_wd_in_ctb; 2215 2216 /* Update the parse context */ 2217 if(0 == ps_codec->i4_slice_error) 2218 { 2219 ps_codec->s_parse.i4_ctb_x = ps_slice_hdr->i2_ctb_x; 2220 ps_codec->s_parse.i4_ctb_y = ps_slice_hdr->i2_ctb_y; 2221 } 2222 ps_codec->s_parse.ps_pps = ps_pps; 2223 ps_codec->s_parse.ps_sps = ps_sps; 2224 ps_codec->s_parse.ps_slice_hdr = ps_slice_hdr; 2225 2226 /* Derive Tile positions for the current CTB */ 2227 /* Change this to lookup if required */ 2228 ihevcd_get_tile_pos(ps_pps, ps_sps, ps_codec->s_parse.i4_ctb_x, 2229 ps_codec->s_parse.i4_ctb_y, 2230 &ps_codec->s_parse.i4_ctb_tile_x, 2231 &ps_codec->s_parse.i4_ctb_tile_y, 2232 &tile_idx); 2233 ps_codec->s_parse.ps_tile = ps_pps->ps_tile + tile_idx; 2234 ps_codec->s_parse.i4_cur_tile_idx = tile_idx; 2235 ps_tile = ps_codec->s_parse.ps_tile; 2236 if(tile_idx) 2237 ps_tile_prev = ps_tile - 1; 2238 else 2239 ps_tile_prev = ps_tile; 2240 2241 /* If the present slice is dependent, then store the previous 2242 * independent slices' ctb x and y values for decoding process */ 2243 if(0 == ps_codec->i4_slice_error) 2244 { 2245 if(1 == ps_slice_hdr->i1_dependent_slice_flag) 2246 { 2247 /*If slice is present at the start of a new tile*/ 2248 if((0 == ps_codec->s_parse.i4_ctb_tile_x) && (0 == ps_codec->s_parse.i4_ctb_tile_y)) 2249 { 2250 ps_codec->s_parse.i4_ctb_slice_x = 0; 2251 ps_codec->s_parse.i4_ctb_slice_y = 0; 2252 } 2253 } 2254 2255 if(!ps_slice_hdr->i1_dependent_slice_flag) 2256 { 2257 ps_codec->s_parse.i4_ctb_slice_x = 0; 2258 ps_codec->s_parse.i4_ctb_slice_y = 0; 2259 } 2260 } 2261 2262 /* Frame level initializations */ 2263 if((0 == ps_codec->s_parse.i4_ctb_y) && 2264 (0 == ps_codec->s_parse.i4_ctb_x)) 2265 { 2266 ret = ihevcd_parse_pic_init(ps_codec); 2267 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); 2268 2269 ps_codec->s_parse.pu4_pic_tu_idx[0] = 0; 2270 ps_codec->s_parse.pu4_pic_pu_idx[0] = 0; 2271 ps_codec->s_parse.i4_cur_independent_slice_idx = 0; 2272 ps_codec->s_parse.i4_ctb_tile_x = 0; 2273 ps_codec->s_parse.i4_ctb_tile_y = 0; 2274 } 2275 2276 { 2277 /* Updating the poc list of current slice to ps_mv_buf */ 2278 mv_buf_t *ps_mv_buf = ps_codec->s_parse.ps_cur_mv_buf; 2279 2280 if(ps_slice_hdr->i1_num_ref_idx_l1_active != 0) 2281 { 2282 for(i = 0; i < ps_slice_hdr->i1_num_ref_idx_l1_active; i++) 2283 { 2284 ps_mv_buf->l1_collocated_poc[(ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1))][i] = ((pic_buf_t *)ps_slice_hdr->as_ref_pic_list1[i].pv_pic_buf)->i4_abs_poc; 2285 ps_mv_buf->u1_l1_collocated_poc_lt[(ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1))][i] = ((pic_buf_t *)ps_slice_hdr->as_ref_pic_list1[i].pv_pic_buf)->u1_used_as_ref; 2286 } 2287 } 2288 2289 if(ps_slice_hdr->i1_num_ref_idx_l0_active != 0) 2290 { 2291 for(i = 0; i < ps_slice_hdr->i1_num_ref_idx_l0_active; i++) 2292 { 2293 ps_mv_buf->l0_collocated_poc[(ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1))][i] = ((pic_buf_t *)ps_slice_hdr->as_ref_pic_list0[i].pv_pic_buf)->i4_abs_poc; 2294 ps_mv_buf->u1_l0_collocated_poc_lt[(ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1))][i] = ((pic_buf_t *)ps_slice_hdr->as_ref_pic_list0[i].pv_pic_buf)->u1_used_as_ref; 2295 } 2296 } 2297 } 2298 2299 /*Initialize the low delay flag at the beginning of every slice*/ 2300 if((0 == ps_codec->s_parse.i4_ctb_slice_x) || (0 == ps_codec->s_parse.i4_ctb_slice_y)) 2301 { 2302 /* Lowdelay flag */ 2303 WORD32 cur_poc, ref_list_poc, flag = 1; 2304 cur_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 2305 for(i = 0; i < ps_slice_hdr->i1_num_ref_idx_l0_active; i++) 2306 { 2307 ref_list_poc = ((mv_buf_t *)ps_slice_hdr->as_ref_pic_list0[i].pv_mv_buf)->i4_abs_poc; 2308 if(ref_list_poc > cur_poc) 2309 { 2310 flag = 0; 2311 break; 2312 } 2313 } 2314 if(flag && (ps_slice_hdr->i1_slice_type == BSLICE)) 2315 { 2316 for(i = 0; i < ps_slice_hdr->i1_num_ref_idx_l1_active; i++) 2317 { 2318 ref_list_poc = ((mv_buf_t *)ps_slice_hdr->as_ref_pic_list1[i].pv_mv_buf)->i4_abs_poc; 2319 if(ref_list_poc > cur_poc) 2320 { 2321 flag = 0; 2322 break; 2323 } 2324 } 2325 } 2326 ps_slice_hdr->i1_low_delay_flag = flag; 2327 } 2328 2329 /* initialize the cabac init idc based on slice type */ 2330 if(ps_slice_hdr->i1_slice_type == ISLICE) 2331 { 2332 cabac_init_idc = 0; 2333 } 2334 else if(ps_slice_hdr->i1_slice_type == PSLICE) 2335 { 2336 cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 2 : 1; 2337 } 2338 else 2339 { 2340 cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 1 : 2; 2341 } 2342 2343 slice_qp = ps_slice_hdr->i1_slice_qp_delta + ps_pps->i1_pic_init_qp; 2344 slice_qp = CLIP3(slice_qp, 0, 51); 2345 2346 /*Update QP value for every indepndent slice or for every dependent slice that begins at the start of a new tile*/ 2347 if((0 == ps_slice_hdr->i1_dependent_slice_flag) || 2348 ((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)))) 2349 { 2350 ps_codec->s_parse.u4_qp = slice_qp; 2351 } 2352 2353 /*Cabac init at the beginning of a slice*/ 2354 //If the slice is a dependent slice, not present at the start of a tile 2355 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)))) 2356 { 2357 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))) 2358 { 2359 ihevcd_cabac_reset(&ps_codec->s_parse.s_cabac, 2360 &ps_codec->s_parse.s_bitstrm); 2361 } 2362 } 2363 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))) 2364 { 2365 ihevcd_cabac_init(&ps_codec->s_parse.s_cabac, 2366 &ps_codec->s_parse.s_bitstrm, 2367 slice_qp, 2368 cabac_init_idc, 2369 &gau1_ihevc_cab_ctxts[cabac_init_idc][slice_qp][0]); 2370 } 2371 2372 2373 do 2374 { 2375 2376 { 2377 WORD32 cur_ctb_idx = ps_codec->s_parse.i4_ctb_x 2378 + ps_codec->s_parse.i4_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 2379 if(1 == ps_codec->i4_num_cores && 0 == cur_ctb_idx % RESET_TU_BUF_NCTB) 2380 { 2381 ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu; 2382 ps_codec->s_parse.i4_pic_tu_idx = 0; 2383 } 2384 } 2385 2386 end_of_pic = 0; 2387 /* Section:7.3.7 Coding tree unit syntax */ 2388 /* coding_tree_unit() inlined here */ 2389 /* If number of cores is greater than 1, then add job to the queue */ 2390 //TODO: Dual core implementation might need a different algo for better load balancing 2391 /* At the start of ctb row parsing in a tile, queue a job for processing the current tile row */ 2392 ps_codec->s_parse.i4_ctb_num_pcm_blks = 0; 2393 2394 2395 /*At the beginning of each tile-which is not the beginning of a slice, cabac context must be initialized. 2396 * Hence, check for the tile beginning here */ 2397 if(((0 == ps_codec->s_parse.i4_ctb_tile_x) && (0 == ps_codec->s_parse.i4_ctb_tile_y)) 2398 && (!((ps_tile->u1_pos_x == 0) && (ps_tile->u1_pos_y == 0))) 2399 && (!((0 == ps_codec->s_parse.i4_ctb_slice_x) && (0 == ps_codec->s_parse.i4_ctb_slice_y)))) 2400 { 2401 slice_qp = ps_slice_hdr->i1_slice_qp_delta + ps_pps->i1_pic_init_qp; 2402 slice_qp = CLIP3(slice_qp, 0, 51); 2403 ps_codec->s_parse.u4_qp = slice_qp; 2404 2405 ihevcd_get_tile_pos(ps_pps, ps_sps, ps_codec->s_parse.i4_ctb_x, 2406 ps_codec->s_parse.i4_ctb_y, 2407 &ps_codec->s_parse.i4_ctb_tile_x, 2408 &ps_codec->s_parse.i4_ctb_tile_y, 2409 &tile_idx); 2410 2411 ps_codec->s_parse.ps_tile = ps_pps->ps_tile + tile_idx; 2412 ps_codec->s_parse.i4_cur_tile_idx = tile_idx; 2413 ps_tile_prev = ps_tile - 1; 2414 2415 tile_start_ctb_idx = ps_tile->u1_pos_x 2416 + ps_tile->u1_pos_y * (ps_sps->i2_pic_wd_in_ctb); 2417 2418 slice_start_ctb_idx = ps_slice_hdr->i2_ctb_x 2419 + ps_slice_hdr->i2_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 2420 2421 /*For slices that span across multiple tiles*/ 2422 if(slice_start_ctb_idx < tile_start_ctb_idx) 2423 { /* 2 Cases 2424 * 1 - slice spans across frame-width- but does not start from 1st column 2425 * 2 - Slice spans across multiple tiles anywhere is a frame 2426 */ 2427 ps_codec->s_parse.i4_ctb_slice_y = ps_tile->u1_pos_y - ps_slice_hdr->i2_ctb_y; 2428 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 2429 { 2430 if(ps_slice_hdr->i2_ctb_y <= ps_tile->u1_pos_y) 2431 { 2432 //Check if ctb x is before or after 2433 if(ps_slice_hdr->i2_ctb_x > ps_tile->u1_pos_x) 2434 { 2435 ps_codec->s_parse.i4_ctb_slice_y -= 1; 2436 } 2437 } 2438 } 2439 /*ps_codec->s_parse.i4_ctb_slice_y = ps_tile->u1_pos_y - ps_slice_hdr->i2_ctb_y; 2440 if (ps_slice_hdr->i2_ctb_y <= ps_tile->u1_pos_y) 2441 { 2442 //Check if ctb x is before or after 2443 if (ps_slice_hdr->i2_ctb_x > ps_tile->u1_pos_x ) 2444 { 2445 ps_codec->s_parse.i4_ctb_slice_y -= 1 ; 2446 } 2447 }*/ 2448 } 2449 2450 if(!ps_slice_hdr->i1_dependent_slice_flag) 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 2756 if(ps_codec->i4_num_cores <= MV_PRED_NUM_CORES_THRESHOLD) 2757 { 2758 /*************************************************/ 2759 /**************** MV pred **********************/ 2760 /*************************************************/ 2761 WORD8 u1_top_ctb_avail = 1; 2762 WORD8 u1_left_ctb_avail = 1; 2763 WORD8 u1_top_lt_ctb_avail = 1; 2764 WORD8 u1_top_rt_ctb_avail = 1; 2765 WORD16 i2_wd_in_ctb; 2766 2767 tile_start_ctb_idx = ps_tile->u1_pos_x 2768 + ps_tile->u1_pos_y * (ps_sps->i2_pic_wd_in_ctb); 2769 2770 slice_start_ctb_idx = ps_slice_hdr->i2_ctb_x 2771 + ps_slice_hdr->i2_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 2772 2773 if((slice_start_ctb_idx < tile_start_ctb_idx)) 2774 { 2775 //Slices span across multiple tiles. 2776 i2_wd_in_ctb = ps_sps->i2_pic_wd_in_ctb; 2777 } 2778 else 2779 { 2780 i2_wd_in_ctb = ps_tile->u2_wd; 2781 } 2782 /* slice and tile boundaries */ 2783 if((0 == ps_codec->s_parse.i4_ctb_y) || (0 == ps_codec->s_parse.i4_ctb_tile_y)) 2784 { 2785 u1_top_ctb_avail = 0; 2786 u1_top_lt_ctb_avail = 0; 2787 u1_top_rt_ctb_avail = 0; 2788 } 2789 2790 if((0 == ps_codec->s_parse.i4_ctb_x) || (0 == ps_codec->s_parse.i4_ctb_tile_x)) 2791 { 2792 u1_left_ctb_avail = 0; 2793 u1_top_lt_ctb_avail = 0; 2794 if((0 == ps_codec->s_parse.i4_ctb_slice_y) || (0 == ps_codec->s_parse.i4_ctb_tile_y)) 2795 { 2796 u1_top_ctb_avail = 0; 2797 if((i2_wd_in_ctb - 1) != ps_codec->s_parse.i4_ctb_slice_x) //TODO: For tile, not implemented 2798 { 2799 u1_top_rt_ctb_avail = 0; 2800 } 2801 } 2802 } 2803 /*For slices not beginning at start of a ctb row*/ 2804 else if(ps_codec->s_parse.i4_ctb_x > 0) 2805 { 2806 if((0 == ps_codec->s_parse.i4_ctb_slice_y) || (0 == ps_codec->s_parse.i4_ctb_tile_y)) 2807 { 2808 u1_top_ctb_avail = 0; 2809 u1_top_lt_ctb_avail = 0; 2810 if(0 == ps_codec->s_parse.i4_ctb_slice_x) 2811 { 2812 u1_left_ctb_avail = 0; 2813 } 2814 if((i2_wd_in_ctb - 1) != ps_codec->s_parse.i4_ctb_slice_x) 2815 { 2816 u1_top_rt_ctb_avail = 0; 2817 } 2818 } 2819 else if((1 == ps_codec->s_parse.i4_ctb_slice_y) && (0 == ps_codec->s_parse.i4_ctb_slice_x)) 2820 { 2821 u1_top_lt_ctb_avail = 0; 2822 } 2823 } 2824 2825 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)) 2826 { 2827 u1_top_rt_ctb_avail = 0; 2828 } 2829 2830 if(PSLICE == ps_slice_hdr->i1_slice_type 2831 || BSLICE == ps_slice_hdr->i1_slice_type) 2832 { 2833 mv_ctxt_t s_mv_ctxt; 2834 process_ctxt_t *ps_proc; 2835 UWORD32 *pu4_ctb_top_pu_idx; 2836 UWORD32 *pu4_ctb_left_pu_idx; 2837 UWORD32 *pu4_ctb_top_left_pu_idx; 2838 WORD32 i4_ctb_pu_cnt; 2839 WORD32 cur_ctb_idx; 2840 WORD32 next_ctb_idx; 2841 WORD32 cur_pu_idx; 2842 ps_proc = &ps_codec->as_process[(ps_codec->i4_num_cores == 1) ? 1 : (ps_codec->i4_num_cores - 1)]; 2843 cur_ctb_idx = ps_codec->s_parse.i4_ctb_x 2844 + ps_codec->s_parse.i4_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 2845 next_ctb_idx = ps_codec->s_parse.i4_next_pu_ctb_cnt; 2846 i4_ctb_pu_cnt = ps_codec->s_parse.pu4_pic_pu_idx[next_ctb_idx] 2847 - ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx]; 2848 2849 cur_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx]; 2850 2851 pu4_ctb_top_pu_idx = ps_proc->pu4_pic_pu_idx_top 2852 + (ps_codec->s_parse.i4_ctb_x * ctb_size / MIN_PU_SIZE); 2853 pu4_ctb_left_pu_idx = ps_proc->pu4_pic_pu_idx_left; 2854 pu4_ctb_top_left_pu_idx = &ps_proc->u4_ctb_top_left_pu_idx; 2855 2856 /* Initializing s_mv_ctxt */ 2857 { 2858 s_mv_ctxt.ps_pps = ps_pps; 2859 s_mv_ctxt.ps_sps = ps_sps; 2860 s_mv_ctxt.ps_slice_hdr = ps_slice_hdr; 2861 s_mv_ctxt.i4_ctb_x = ps_codec->s_parse.i4_ctb_x; 2862 s_mv_ctxt.i4_ctb_y = ps_codec->s_parse.i4_ctb_y; 2863 s_mv_ctxt.ps_pu = &ps_codec->s_parse.ps_pic_pu[cur_pu_idx]; 2864 s_mv_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu; 2865 s_mv_ctxt.ps_tile = ps_tile; 2866 s_mv_ctxt.pu4_pic_pu_idx_map = ps_proc->pu4_pic_pu_idx_map; 2867 s_mv_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx; 2868 s_mv_ctxt.pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map; 2869 s_mv_ctxt.i4_ctb_pu_cnt = i4_ctb_pu_cnt; 2870 s_mv_ctxt.i4_ctb_start_pu_idx = cur_pu_idx; 2871 s_mv_ctxt.u1_top_ctb_avail = u1_top_ctb_avail; 2872 s_mv_ctxt.u1_top_rt_ctb_avail = u1_top_rt_ctb_avail; 2873 s_mv_ctxt.u1_top_lt_ctb_avail = u1_top_lt_ctb_avail; 2874 s_mv_ctxt.u1_left_ctb_avail = u1_left_ctb_avail; 2875 } 2876 2877 ihevcd_get_mv_ctb(&s_mv_ctxt, pu4_ctb_top_pu_idx, 2878 pu4_ctb_left_pu_idx, pu4_ctb_top_left_pu_idx); 2879 2880 } 2881 else 2882 { 2883 WORD32 num_minpu_in_ctb = (ctb_size / MIN_PU_SIZE) * (ctb_size / MIN_PU_SIZE); 2884 UWORD8 *pu1_pic_pu_map_ctb = ps_codec->s_parse.pu1_pic_pu_map + 2885 (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; 2886 process_ctxt_t *ps_proc = &ps_codec->as_process[(ps_codec->i4_num_cores == 1) ? 1 : (ps_codec->i4_num_cores - 1)]; 2887 WORD32 row, col; 2888 WORD32 pu_cnt; 2889 WORD32 num_pu_per_ctb; 2890 WORD32 cur_ctb_idx; 2891 WORD32 next_ctb_idx; 2892 WORD32 ctb_start_pu_idx; 2893 UWORD32 *pu4_nbr_pu_idx = ps_proc->pu4_pic_pu_idx_map; 2894 WORD32 nbr_pu_idx_strd = MAX_CTB_SIZE / MIN_PU_SIZE + 2; 2895 pu_t *ps_pu; 2896 2897 for(row = 0; row < ctb_size / MIN_PU_SIZE; row++) 2898 { 2899 for(col = 0; col < ctb_size / MIN_PU_SIZE; col++) 2900 { 2901 pu1_pic_pu_map_ctb[row * ctb_size / MIN_PU_SIZE + col] = 0; 2902 } 2903 } 2904 2905 2906 /* Neighbor PU idx update inside CTB */ 2907 /* 1byte per 4x4. Indicates the PU idx that 4x4 block belongs to */ 2908 2909 cur_ctb_idx = ps_codec->s_parse.i4_ctb_x 2910 + ps_codec->s_parse.i4_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 2911 next_ctb_idx = ps_codec->s_parse.i4_next_pu_ctb_cnt; 2912 num_pu_per_ctb = ps_codec->s_parse.pu4_pic_pu_idx[next_ctb_idx] 2913 - ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx]; 2914 ctb_start_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx]; 2915 ps_pu = &ps_codec->s_parse.ps_pic_pu[ctb_start_pu_idx]; 2916 2917 for(pu_cnt = 0; pu_cnt < num_pu_per_ctb; pu_cnt++, ps_pu++) 2918 { 2919 UWORD32 cur_pu_idx; 2920 WORD32 pu_ht = (ps_pu->b4_ht + 1) << 2; 2921 WORD32 pu_wd = (ps_pu->b4_wd + 1) << 2; 2922 2923 cur_pu_idx = ctb_start_pu_idx + pu_cnt; 2924 2925 for(row = 0; row < pu_ht / MIN_PU_SIZE; row++) 2926 for(col = 0; col < pu_wd / MIN_PU_SIZE; col++) 2927 pu4_nbr_pu_idx[(1 + ps_pu->b4_pos_x + col) 2928 + (1 + ps_pu->b4_pos_y + row) 2929 * nbr_pu_idx_strd] = 2930 cur_pu_idx; 2931 } 2932 2933 /* Updating Top and Left pointers */ 2934 { 2935 WORD32 rows_remaining = ps_sps->i2_pic_height_in_luma_samples 2936 - (ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size); 2937 WORD32 ctb_size_left = MIN(ctb_size, rows_remaining); 2938 2939 /* Top Left */ 2940 /* saving top left before updating top ptr, as updating top ptr will overwrite the top left for the next ctb */ 2941 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]; 2942 for(i = 0; i < ctb_size / MIN_PU_SIZE; i++) 2943 { 2944 /* Left */ 2945 /* Last column of au4_nbr_pu_idx */ 2946 ps_proc->pu4_pic_pu_idx_left[i] = pu4_nbr_pu_idx[(ctb_size / MIN_PU_SIZE) 2947 + (i + 1) * nbr_pu_idx_strd]; 2948 /* Top */ 2949 /* Last row of au4_nbr_pu_idx */ 2950 ps_proc->pu4_pic_pu_idx_top[(ps_codec->s_parse.i4_ctb_x * ctb_size / MIN_PU_SIZE) + i] = 2951 pu4_nbr_pu_idx[(ctb_size_left / MIN_PU_SIZE) * nbr_pu_idx_strd + i + 1]; 2952 2953 } 2954 } 2955 } 2956 2957 /*************************************************/ 2958 /****************** BS, QP *********************/ 2959 /*************************************************/ 2960 /* Check if deblock is disabled for the current slice or if it is disabled for the current picture 2961 * because of disable deblock api 2962 */ 2963 if(0 == ps_codec->i4_disable_deblk_pic) 2964 { 2965 if((0 == ps_slice_hdr->i1_slice_disable_deblocking_filter_flag) && 2966 (0 == ps_codec->i4_slice_error)) 2967 { 2968 WORD32 i4_ctb_tu_cnt; 2969 WORD32 cur_ctb_idx, next_ctb_idx; 2970 WORD32 cur_pu_idx; 2971 WORD32 cur_tu_idx; 2972 process_ctxt_t *ps_proc; 2973 2974 ps_proc = &ps_codec->as_process[(ps_codec->i4_num_cores == 1) ? 1 : (ps_codec->i4_num_cores - 1)]; 2975 cur_ctb_idx = ps_codec->s_parse.i4_ctb_x 2976 + ps_codec->s_parse.i4_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 2977 2978 cur_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx]; 2979 next_ctb_idx = ps_codec->s_parse.i4_next_tu_ctb_cnt; 2980 if(1 == ps_codec->i4_num_cores) 2981 { 2982 i4_ctb_tu_cnt = ps_codec->s_parse.pu4_pic_tu_idx[next_ctb_idx] - 2983 ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx % RESET_TU_BUF_NCTB]; 2984 2985 cur_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx % RESET_TU_BUF_NCTB]; 2986 } 2987 else 2988 { 2989 i4_ctb_tu_cnt = ps_codec->s_parse.pu4_pic_tu_idx[next_ctb_idx] - 2990 ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx]; 2991 2992 cur_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx]; 2993 } 2994 2995 ps_codec->s_parse.s_bs_ctxt.ps_pps = ps_codec->s_parse.ps_pps; 2996 ps_codec->s_parse.s_bs_ctxt.ps_sps = ps_codec->s_parse.ps_sps; 2997 ps_codec->s_parse.s_bs_ctxt.ps_codec = ps_codec; 2998 ps_codec->s_parse.s_bs_ctxt.i4_ctb_tu_cnt = i4_ctb_tu_cnt; 2999 ps_codec->s_parse.s_bs_ctxt.i4_ctb_x = ps_codec->s_parse.i4_ctb_x; 3000 ps_codec->s_parse.s_bs_ctxt.i4_ctb_y = ps_codec->s_parse.i4_ctb_y; 3001 ps_codec->s_parse.s_bs_ctxt.i4_ctb_tile_x = ps_codec->s_parse.i4_ctb_tile_x; 3002 ps_codec->s_parse.s_bs_ctxt.i4_ctb_tile_y = ps_codec->s_parse.i4_ctb_tile_y; 3003 ps_codec->s_parse.s_bs_ctxt.i4_ctb_slice_x = ps_codec->s_parse.i4_ctb_slice_x; 3004 ps_codec->s_parse.s_bs_ctxt.i4_ctb_slice_y = ps_codec->s_parse.i4_ctb_slice_y; 3005 ps_codec->s_parse.s_bs_ctxt.ps_tu = &ps_codec->s_parse.ps_pic_tu[cur_tu_idx]; 3006 ps_codec->s_parse.s_bs_ctxt.ps_pu = &ps_codec->s_parse.ps_pic_pu[cur_pu_idx]; 3007 ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx_map = ps_proc->pu4_pic_pu_idx_map; 3008 ps_codec->s_parse.s_bs_ctxt.i4_next_pu_ctb_cnt = ps_codec->s_parse.i4_next_pu_ctb_cnt; 3009 ps_codec->s_parse.s_bs_ctxt.i4_next_tu_ctb_cnt = ps_codec->s_parse.i4_next_tu_ctb_cnt; 3010 ps_codec->s_parse.s_bs_ctxt.pu1_slice_idx = ps_codec->s_parse.pu1_slice_idx; 3011 ps_codec->s_parse.s_bs_ctxt.ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 3012 ps_codec->s_parse.s_bs_ctxt.ps_tile = ps_codec->s_parse.ps_tile; 3013 3014 if(ISLICE == ps_slice_hdr->i1_slice_type) 3015 { 3016 ihevcd_ctb_boundary_strength_islice(&ps_codec->s_parse.s_bs_ctxt); 3017 } 3018 else 3019 { 3020 ihevcd_ctb_boundary_strength_pbslice(&ps_codec->s_parse.s_bs_ctxt); 3021 } 3022 } 3023 else 3024 { 3025 WORD32 bs_strd = (ps_sps->i2_pic_wd_in_ctb + 1) * (ctb_size * ctb_size / 8 / 16); 3026 3027 UWORD32 *pu4_vert_bs = (UWORD32 *)((UWORD8 *)ps_codec->s_parse.s_bs_ctxt.pu4_pic_vert_bs + 3028 ps_codec->s_parse.i4_ctb_x * (ctb_size * ctb_size / 8 / 16) + 3029 ps_codec->s_parse.i4_ctb_y * bs_strd); 3030 UWORD32 *pu4_horz_bs = (UWORD32 *)((UWORD8 *)ps_codec->s_parse.s_bs_ctxt.pu4_pic_horz_bs + 3031 ps_codec->s_parse.i4_ctb_x * (ctb_size * ctb_size / 8 / 16) + 3032 ps_codec->s_parse.i4_ctb_y * bs_strd); 3033 3034 memset(pu4_vert_bs, 0, (ctb_size / 8 + 1) * (ctb_size / 4) / 8 * 2); 3035 memset(pu4_horz_bs, 0, (ctb_size / 8) * (ctb_size / 4) / 8 * 2); 3036 3037 } 3038 } 3039 3040 } 3041 3042 3043 /* Update the parse status map */ 3044 { 3045 sps_t *ps_sps = ps_codec->s_parse.ps_sps; 3046 UWORD8 *pu1_buf; 3047 WORD32 idx; 3048 idx = (ps_codec->s_parse.i4_ctb_x); 3049 idx += ((ps_codec->s_parse.i4_ctb_y) * ps_sps->i2_pic_wd_in_ctb); 3050 pu1_buf = (ps_codec->pu1_parse_map + idx); 3051 *pu1_buf = 1; 3052 } 3053 3054 /* Increment CTB x and y positions */ 3055 ps_codec->s_parse.i4_ctb_tile_x++; 3056 ps_codec->s_parse.i4_ctb_x++; 3057 ps_codec->s_parse.i4_ctb_slice_x++; 3058 3059 /*If tiles are enabled, handle the slice counters differently*/ 3060 if(ps_pps->i1_tiles_enabled_flag) 3061 { 3062 //Indicates multiple tiles in a slice case 3063 tile_start_ctb_idx = ps_tile->u1_pos_x 3064 + ps_tile->u1_pos_y * (ps_sps->i2_pic_wd_in_ctb); 3065 3066 slice_start_ctb_idx = ps_slice_hdr->i2_ctb_x 3067 + ps_slice_hdr->i2_ctb_y * (ps_sps->i2_pic_wd_in_ctb); 3068 3069 if((slice_start_ctb_idx < tile_start_ctb_idx)) 3070 { 3071 if(ps_codec->s_parse.i4_ctb_slice_x == (ps_tile->u1_pos_x + ps_tile->u2_wd)) 3072 { 3073 /* Reached end of slice row within a tile /frame */ 3074 ps_codec->s_parse.i4_ctb_slice_y++; 3075 ps_codec->s_parse.i4_ctb_slice_x = ps_tile->u1_pos_x; //todo:Check 3076 } 3077 } 3078 //Indicates multiple slices in a tile case - hence, reset slice_x 3079 else if(ps_codec->s_parse.i4_ctb_slice_x == (ps_tile->u2_wd)) 3080 { 3081 ps_codec->s_parse.i4_ctb_slice_y++; 3082 ps_codec->s_parse.i4_ctb_slice_x = 0; 3083 } 3084 } 3085 else 3086 { 3087 if(ps_codec->s_parse.i4_ctb_slice_x == ps_tile->u2_wd) 3088 { 3089 /* Reached end of slice row within a tile /frame */ 3090 ps_codec->s_parse.i4_ctb_slice_y++; 3091 ps_codec->s_parse.i4_ctb_slice_x = 0; 3092 } 3093 } 3094 3095 3096 if(ps_codec->s_parse.i4_ctb_tile_x == (ps_tile->u2_wd)) 3097 { 3098 /* Reached end of tile row */ 3099 ps_codec->s_parse.i4_ctb_tile_x = 0; 3100 ps_codec->s_parse.i4_ctb_x = ps_tile->u1_pos_x; 3101 3102 ps_codec->s_parse.i4_ctb_tile_y++; 3103 ps_codec->s_parse.i4_ctb_y++; 3104 3105 if(ps_codec->s_parse.i4_ctb_tile_y == (ps_tile->u2_ht)) 3106 { 3107 /* Reached End of Tile */ 3108 ps_codec->s_parse.i4_ctb_tile_y = 0; 3109 ps_codec->s_parse.i4_ctb_tile_x = 0; 3110 ps_codec->s_parse.ps_tile++; 3111 3112 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)) 3113 { 3114 /* Reached end of frame */ 3115 end_of_pic = 1; 3116 ps_codec->s_parse.i4_ctb_x = 0; 3117 ps_codec->s_parse.i4_ctb_y = ps_sps->i2_pic_ht_in_ctb; 3118 } 3119 else 3120 { 3121 /* Initialize ctb_x and ctb_y to start of next tile */ 3122 ps_tile = ps_codec->s_parse.ps_tile; 3123 ps_codec->s_parse.i4_ctb_x = ps_tile->u1_pos_x; 3124 ps_codec->s_parse.i4_ctb_y = ps_tile->u1_pos_y; 3125 ps_codec->s_parse.i4_ctb_tile_y = 0; 3126 ps_codec->s_parse.i4_ctb_tile_x = 0; 3127 ps_codec->s_parse.i4_ctb_slice_x = ps_tile->u1_pos_x; 3128 ps_codec->s_parse.i4_ctb_slice_y = ps_tile->u1_pos_y; 3129 3130 } 3131 } 3132 3133 } 3134 3135 ps_codec->s_parse.i4_next_ctb_indx = ps_codec->s_parse.i4_ctb_x + 3136 ps_codec->s_parse.i4_ctb_y * ps_sps->i2_pic_wd_in_ctb; 3137 3138 /* If the current slice is in error, check if the next slice's address 3139 * is reached and mark the end_of_slice flag */ 3140 if(ps_codec->i4_slice_error) 3141 { 3142 slice_header_t *ps_slice_hdr_next = ps_slice_hdr + 1; 3143 WORD32 next_slice_addr = ps_slice_hdr_next->i2_ctb_x + 3144 ps_slice_hdr_next->i2_ctb_y * ps_sps->i2_pic_wd_in_ctb; 3145 3146 if(ps_codec->s_parse.i4_next_ctb_indx == next_slice_addr) 3147 end_of_slice_flag = 1; 3148 } 3149 3150 /* If the codec is running in single core mode 3151 * then call process function for current CTB 3152 */ 3153 if((1 == ps_codec->i4_num_cores) && (ps_codec->s_parse.i4_ctb_tile_x == 0)) 3154 { 3155 process_ctxt_t *ps_proc = &ps_codec->as_process[0]; 3156 // ps_proc->i4_ctb_cnt = ihevcd_nctb_cnt(ps_codec, ps_sps); 3157 ps_proc->i4_ctb_cnt = ps_proc->ps_tile->u2_wd; 3158 ihevcd_process(ps_proc); 3159 } 3160 3161 /* If the bytes for the current slice are exhausted 3162 * set end_of_slice flag to 1 3163 * This slice will be treated as incomplete */ 3164 if((UWORD8 *)ps_codec->s_parse.s_bitstrm.pu1_buf_max + BITSTRM_OFF_THRS < 3165 ((UWORD8 *)ps_codec->s_parse.s_bitstrm.pu4_buf + (ps_codec->s_parse.s_bitstrm.u4_bit_ofst / 8))) 3166 { 3167 // end_of_slice_flag = ps_codec->i4_slice_error ? 0 : 1; 3168 3169 if(0 == ps_codec->i4_slice_error) 3170 end_of_slice_flag = 1; 3171 } 3172 3173 3174 if(end_of_pic) 3175 break; 3176 } while(!end_of_slice_flag); 3177 3178 /* Increment the slice index for parsing next slice */ 3179 if(0 == end_of_pic) 3180 { 3181 while(1) 3182 { 3183 3184 WORD32 parse_slice_idx; 3185 parse_slice_idx = ps_codec->s_parse.i4_cur_slice_idx; 3186 parse_slice_idx++; 3187 3188 { 3189 /* If the next slice header is not initialized, update cur_slice_idx and break */ 3190 if((1 == ps_codec->i4_num_cores) || (0 != (parse_slice_idx & (MAX_SLICE_HDR_CNT - 1)))) 3191 { 3192 ps_codec->s_parse.i4_cur_slice_idx = parse_slice_idx; 3193 break; 3194 } 3195 3196 /* If the next slice header is initialised, wait for the parsed slices to be processed */ 3197 else 3198 { 3199 WORD32 ctb_indx = 0; 3200 3201 while(ctb_indx != ps_sps->i4_pic_size_in_ctb) 3202 { 3203 WORD32 parse_status = *(ps_codec->pu1_parse_map + ctb_indx); 3204 volatile WORD32 proc_status = *(ps_codec->pu1_proc_map + ctb_indx) & 1; 3205 3206 if(parse_status == proc_status) 3207 ctb_indx++; 3208 } 3209 ps_codec->s_parse.i4_cur_slice_idx = parse_slice_idx; 3210 break; 3211 } 3212 3213 } 3214 } 3215 3216 } 3217 else 3218 { 3219 #if FRAME_ILF_PAD 3220 if(FRAME_ILF_PAD && 1 == ps_codec->i4_num_cores) 3221 { 3222 if(ps_slice_hdr->i4_abs_pic_order_cnt == 0) 3223 { 3224 DUMP_PRE_ILF(ps_codec->as_process[0].pu1_cur_pic_luma, 3225 ps_codec->as_process[0].pu1_cur_pic_chroma, 3226 ps_sps->i2_pic_width_in_luma_samples, 3227 ps_sps->i2_pic_height_in_luma_samples, 3228 ps_codec->i4_strd); 3229 3230 DUMP_BS(ps_codec->as_process[0].s_bs_ctxt.pu4_pic_vert_bs, 3231 ps_codec->as_process[0].s_bs_ctxt.pu4_pic_horz_bs, 3232 ps_sps->i2_pic_wd_in_ctb * (ctb_size * ctb_size / 8 / 16) * ps_sps->i2_pic_ht_in_ctb, 3233 (ps_sps->i2_pic_wd_in_ctb + 1) * (ctb_size * ctb_size / 8 / 16) * ps_sps->i2_pic_ht_in_ctb); 3234 3235 DUMP_QP(ps_codec->as_process[0].s_bs_ctxt.pu1_pic_qp, 3236 (ps_sps->i2_pic_height_in_luma_samples * ps_sps->i2_pic_width_in_luma_samples) / (MIN_CU_SIZE * MIN_CU_SIZE)); 3237 3238 DUMP_QP_CONST_IN_CTB(ps_codec->as_process[0].s_bs_ctxt.pu1_pic_qp_const_in_ctb, 3239 (ps_sps->i2_pic_height_in_luma_samples * ps_sps->i2_pic_width_in_luma_samples) / (MIN_CTB_SIZE * MIN_CTB_SIZE) / 8); 3240 3241 DUMP_NO_LOOP_FILTER(ps_codec->as_process[0].pu1_pic_no_loop_filter_flag, 3242 (ps_sps->i2_pic_width_in_luma_samples / MIN_CU_SIZE) * (ps_sps->i2_pic_height_in_luma_samples / MIN_CU_SIZE) / 8); 3243 3244 DUMP_OFFSETS(ps_slice_hdr->i1_beta_offset_div2, 3245 ps_slice_hdr->i1_tc_offset_div2, 3246 ps_pps->i1_pic_cb_qp_offset, 3247 ps_pps->i1_pic_cr_qp_offset); 3248 } 3249 ps_codec->s_parse.s_deblk_ctxt.ps_pps = ps_codec->s_parse.ps_pps; 3250 ps_codec->s_parse.s_deblk_ctxt.ps_sps = ps_codec->s_parse.ps_sps; 3251 ps_codec->s_parse.s_deblk_ctxt.ps_codec = ps_codec; 3252 ps_codec->s_parse.s_deblk_ctxt.ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 3253 ps_codec->s_parse.s_deblk_ctxt.is_chroma_yuv420sp_vu = (ps_codec->e_ref_chroma_fmt == IV_YUV_420SP_VU); 3254 3255 ps_codec->s_parse.s_sao_ctxt.ps_pps = ps_codec->s_parse.ps_pps; 3256 ps_codec->s_parse.s_sao_ctxt.ps_sps = ps_codec->s_parse.ps_sps; 3257 ps_codec->s_parse.s_sao_ctxt.ps_codec = ps_codec; 3258 ps_codec->s_parse.s_sao_ctxt.ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 3259 3260 ihevcd_ilf_pad_frame(&ps_codec->s_parse.s_deblk_ctxt, &ps_codec->s_parse.s_sao_ctxt); 3261 3262 } 3263 #endif 3264 ps_codec->s_parse.i4_end_of_frame = 1; 3265 } 3266 return ret; 3267 } 3268 3269 3270 3271 3272 3273 3274 3275 3276