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