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