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