1 /******************************************************************************
2 *
3 * Copyright (C) 2018 The Android Open Source Project
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 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 /**
21 ******************************************************************************
22 * @file ihevce_cabac_cu_pu.c
23 *
24 * @brief
25 * This file contains function definitions for cabac entropy coding of CU
26 * and PU structures in HEVC syntax
27 *
28 * @author
29 * ittiam
30 *
31 * @List of Functions
32 * ihevce_cabac_encode_intra_pu()
33 * ihevce_cabac_encode_skip_flag()
34 * ihevce_cabac_encode_part_mode()
35 * ihevce_cabac_encode_merge_idx()
36 * ihevce_cabac_encode_inter_pred_idc()
37 * ihevce_cabac_encode_refidx()
38 * ihevce_cabac_encode_mvd()
39 * ihevce_cabac_encode_inter_pu()
40 * ihevce_cabac_encode_coding_unit()
41 * ihevce_cabac_encode_sao()
42 * ihevce_encode_coding_quadtree()
43 * ihevce_encode_slice_data()
44 *
45 ******************************************************************************
46 */
47
48 /*****************************************************************************/
49 /* File Includes */
50 /*****************************************************************************/
51 /* System include files */
52 #include <stdio.h>
53 #include <string.h>
54 #include <stdlib.h>
55 #include <assert.h>
56 #include <stdarg.h>
57 #include <math.h>
58
59 /* User include files */
60 #include "ihevc_typedefs.h"
61 #include "itt_video_api.h"
62 #include "ihevce_api.h"
63
64 #include "rc_cntrl_param.h"
65 #include "rc_frame_info_collector.h"
66 #include "rc_look_ahead_params.h"
67
68 #include "ihevc_defs.h"
69 #include "ihevc_structs.h"
70 #include "ihevc_platform_macros.h"
71 #include "ihevc_deblk.h"
72 #include "ihevc_itrans_recon.h"
73 #include "ihevc_chroma_itrans_recon.h"
74 #include "ihevc_chroma_intra_pred.h"
75 #include "ihevc_intra_pred.h"
76 #include "ihevc_inter_pred.h"
77 #include "ihevc_mem_fns.h"
78 #include "ihevc_padding.h"
79 #include "ihevc_weighted_pred.h"
80 #include "ihevc_sao.h"
81 #include "ihevc_resi_trans.h"
82 #include "ihevc_quant_iquant_ssd.h"
83 #include "ihevc_cabac_tables.h"
84
85 #include "ihevce_defs.h"
86 #include "ihevce_lap_enc_structs.h"
87 #include "ihevce_multi_thrd_structs.h"
88 #include "ihevce_me_common_defs.h"
89 #include "ihevce_had_satd.h"
90 #include "ihevce_error_codes.h"
91 #include "ihevce_bitstream.h"
92 #include "ihevce_cabac.h"
93 #include "ihevce_rdoq_macros.h"
94 #include "ihevce_function_selector.h"
95 #include "ihevce_enc_structs.h"
96 #include "ihevce_entropy_structs.h"
97 #include "ihevce_cmn_utils_instr_set_router.h"
98 #include "ihevce_enc_loop_structs.h"
99 #include "ihevce_trace.h"
100
101 #define TEST_CABAC_BITESTIMATE 0
102
103 // clang-format off
104 /**
105 ******************************************************************************
106 * @brief LUT for binarization of inter partmode bins for cu size > mincu size
107 * as per Table9-34 of spec
108 *
109 * @input : amp_enable flag and part_mode
110 *
111 * @output : packed bins and count of bins as per following bit packed format
112 * Bins : (bits3-bit0) first bin starts from bit3
113 * Bins Count: (bits7-bit4)
114 * 0xFF in the following table is invalid entry
115 *
116 * @remarks See Table 9-34 of HEVC spec for Binarization of part_mode
117 *******************************************************************************
118 */
119 #define INVALID 0xFF
120 const UWORD8 gu1_hevce_inter_part_mode_bins[2][8] = {
121
122 /* cusize > minCUsize, no amp */
123 { 0x18, 0x24, 0x20, INVALID, INVALID, INVALID, INVALID, INVALID, },
124
125 /* cusize > minCUsize, amp enable, minCUsize > 8 (irrelevant) */
126 { 0x18, 0x36, 0x32, INVALID, 0x44, 0x45, 0x40, 0x41, },
127
128 };
129
130 /**
131 ******************************************************************************
132 * @brief LUT for binarization of inter partmode bins for cu size = mincu size
133 * as per Table9-34 of spec
134 *
135 * @input : mincusize==8 flag and part_mode
136 *
137 * @output : packed bins and count of bins as per following bit packed format
138 * Bins : (bits3-bit0) first bin starts from bit3
139 * Bins Count: (bits7-bit4)
140 * 0xFF in the following table is invalid entry
141 *
142 * @remarks See Table 9-34 of HEVC spec for Binarization of part_mode
143 *******************************************************************************
144 */
145 const UWORD8 gu1_hevce_inter_part_mode_bins_mincu[2][4] = {
146
147 /* cusize == minCUsize, minCUsize > 8 */
148 { 0x18, 0x24, 0x32, 0x30, },
149
150 /* cusize == minCUsize, minCUsize = 8 */
151 { 0x18, 0x24, 0x20, INVALID },
152
153 };
154 // clang-format on
155
156 /*****************************************************************************/
157 /* Function Definitions */
158 /*****************************************************************************/
159 /**
160 ******************************************************************************
161 *
162 * @brief Entropy encoding of luma and chroma intra pred modes
163 *
164 * @par Description
165 * Encodes prev_intra_ped_mode, mpm_idx and rem_intra_pred_mode for each
166 * luma partition and chrom intra pred of cu as per section:7.3.9.1
167 *
168 * Binzarization, context model as per Table 9-32 for luma
169 * Binzarization, context model as per Table 9-35, section 9.3.2.8 for chroma
170 *
171 * @param[inout] ps_entropy_ctxt
172 * pointer to entropy context (handle)
173 *
174 * @param[in] part_mode
175 * indicates whether the mode is 2Nx2N or NxN luma parition
176 *
177 * @param[in] ps_enc_cu
178 * pointer to the intra cu whose luma and chroma pred modes are encoded
179 *
180 * @return success or failure error code
181 *
182 ******************************************************************************
183 */
ihevce_cabac_encode_intra_pu(entropy_context_t * ps_entropy_ctxt,WORD32 part_mode,cu_enc_loop_out_t * ps_enc_cu)184 WORD32 ihevce_cabac_encode_intra_pu(
185 entropy_context_t *ps_entropy_ctxt, WORD32 part_mode, cu_enc_loop_out_t *ps_enc_cu)
186 {
187 WORD32 error = IHEVCE_SUCCESS;
188 cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
189 intra_prev_rem_flags_t *ps_prev_mpm_rem_flags = &ps_enc_cu->as_prev_rem[0];
190 WORD32 i, num_parts;
191
192 /* intra can only be 2Nx2N partition or a NxN partition */
193 num_parts = (PART_NxN == part_mode) ? 4 : 1;
194
195 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
196 {
197 WORD32 cu_size = ps_enc_cu->b4_cu_size << 3;
198
199 /*PIC_INFO : INTRA CU in frame*/
200 ps_entropy_ctxt->ps_pic_level_info->i8_total_intra_cu++;
201 ps_entropy_ctxt->ps_pic_level_info->i8_total_pu += num_parts;
202 ps_entropy_ctxt->ps_pic_level_info->i8_total_intra_pu += num_parts;
203 /*PIC_INFO : Total CU in frame based on cu size */
204
205 if(PART_2Nx2N == part_mode)
206 {
207 // clang-format off
208 if(cu_size == 64)
209 ps_entropy_ctxt->ps_pic_level_info->i8_total_2nx2n_intra_pu[3]++;
210 else
211 ps_entropy_ctxt->ps_pic_level_info->i8_total_2nx2n_intra_pu[cu_size >> 4]++;
212 // clang-format on
213 }
214 else if(PART_NxN == part_mode)
215 {
216 ps_entropy_ctxt->ps_pic_level_info->i8_total_nxn_intra_pu++;
217 }
218 }
219 /* encode prev intra pred mode flags : context model based */
220 for(i = 0; i < num_parts; i++)
221 {
222 WORD32 prev_intra_pred_flag = ps_prev_mpm_rem_flags[i].b1_prev_intra_luma_pred_flag;
223 error |=
224 ihevce_cabac_encode_bin(ps_cabac, prev_intra_pred_flag, IHEVC_CAB_INTRA_LUMA_PRED_FLAG);
225 AEV_TRACE("prev_intra_pred_luma_flag", prev_intra_pred_flag, ps_cabac->u4_range);
226 }
227
228 /* encode mpm_idx or rem_intra_pred_mode bypass bins */
229 for(i = 0; i < num_parts; i++)
230 {
231 if(ps_prev_mpm_rem_flags[i].b1_prev_intra_luma_pred_flag)
232 {
233 WORD32 mpm_idx = ps_prev_mpm_rem_flags[i].b2_mpm_idx;
234
235 /* tunary bins for cmax = 2 */
236 WORD32 num_bins = mpm_idx ? 2 : 1;
237 UWORD32 bins = mpm_idx ? ((1 << 1) | (mpm_idx - 1)) : 0;
238
239 ASSERT(mpm_idx < 3);
240
241 error |= ihevce_cabac_encode_bypass_bins(ps_cabac, bins, num_bins);
242 AEV_TRACE("mpm_idx", mpm_idx, ps_cabac->u4_range);
243 }
244 else
245 {
246 WORD32 rem_intra_pred_mode = ps_prev_mpm_rem_flags[i].b5_rem_intra_pred_mode;
247 error |= ihevce_cabac_encode_bypass_bins(ps_cabac, rem_intra_pred_mode, 5);
248 AEV_TRACE("rem_intra_luma_pred_mode", rem_intra_pred_mode, ps_cabac->u4_range);
249 }
250 }
251
252 /************************************************************************/
253 /* encode the chroma intra prediction mode as per Table 9-35 */
254 /* First bin is context model based prefix : 0 if chroma_mode==4 else 1 */
255 /* If chroma pred mode is not 4, suffix bins are coded as bypass bins */
256 /************************************************************************/
257 {
258 WORD32 chroma_pred_mode = ps_enc_cu->b3_chroma_intra_pred_mode;
259 WORD32 prefix_bin = (chroma_pred_mode == 4) ? 0 : 1;
260
261 /* encode prefix bin */
262 error |= ihevce_cabac_encode_bin(ps_cabac, prefix_bin, IHEVC_CAB_CHROMA_PRED_MODE);
263
264 /* encode suffix bins */
265 if(prefix_bin)
266 {
267 error |= ihevce_cabac_encode_bypass_bins(ps_cabac, chroma_pred_mode, 2);
268 }
269 AEV_TRACE("intra_chroma_pred_mode", chroma_pred_mode, ps_cabac->u4_range);
270 }
271
272 return (error);
273 }
274
275 /**
276 ******************************************************************************
277 *
278 * @brief Entropy encoding of skip flag (Coding Unit syntax)
279 *
280 * @par Description
281 * context increment for skip flag is derived based on left and top skip flag
282 * as per section 9.3.3.1.1, Table 9-38
283 *
284 * @param[inout] ps_entropy_ctxt
285 * pointer to entropy context (handle)
286 *
287 * @param[in] ps_enc_cu
288 * pointer to inter cu whose skip flag is to be coded
289 *
290 * @param[in] top_avail
291 * top availabilty flag for current cu (boolean)
292 *
293 * @param[in] left_avail
294 * left availabilty flag for current cu (boolean)
295 *
296 * @return success or failure error code
297 *
298 ******************************************************************************
299 */
ihevce_cabac_encode_skip_flag(entropy_context_t * ps_entropy_ctxt,cu_enc_loop_out_t * ps_enc_cu,WORD32 top_avail,WORD32 left_avail)300 WORD32 ihevce_cabac_encode_skip_flag(
301 entropy_context_t *ps_entropy_ctxt,
302 cu_enc_loop_out_t *ps_enc_cu,
303 WORD32 top_avail,
304 WORD32 left_avail)
305
306 {
307 WORD32 error = IHEVCE_SUCCESS;
308 WORD32 skip_flag = ps_enc_cu->b1_skip_flag;
309 cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
310
311 /* CU top left co-ordinates w.r.t ctb */
312 WORD32 cu_x0 = ps_enc_cu->b3_cu_pos_x << 3;
313 WORD32 cu_y0 = ps_enc_cu->b3_cu_pos_y << 3;
314
315 /* CU size in pels */
316 WORD32 cu_size = ps_enc_cu->b4_cu_size << 3;
317
318 /* CU x co-ordinate w.r.t frame start */
319 WORD32 ctb_x0_frm = (ps_entropy_ctxt->i4_ctb_x << ps_entropy_ctxt->i1_log2_ctb_size);
320
321 WORD32 cu_x0_frm = cu_x0 + ctb_x0_frm;
322
323 /* bit postion from where top skip flag is extracted; 1bit per 8 pel */
324 WORD32 x_pos = ((cu_x0_frm >> 3) & 0x7);
325
326 /* bit postion from where left skip flag is extracted; 1bit per 8 pel */
327 WORD32 y_pos = ((cu_y0 >> 3) & 0x7);
328
329 /* top and left skip flags computed based on nbr availability */
330 UWORD8 *pu1_top_skip_flags = ps_entropy_ctxt->pu1_skip_cu_top + (cu_x0_frm >> 6);
331 UWORD32 u4_skip_left_flags = ps_entropy_ctxt->u4_skip_cu_left;
332
333 /* context incerements based on top and left neigbours */
334 UWORD32 ctxt_inc = 0;
335
336 if(top_avail)
337 {
338 WORD32 val;
339 EXTRACT_BIT(val, pu1_top_skip_flags[0], x_pos);
340 ctxt_inc += val;
341 }
342
343 if(left_avail)
344 {
345 WORD32 val;
346 EXTRACT_BIT(val, u4_skip_left_flags, y_pos);
347 ctxt_inc += val;
348 }
349
350 if(CABAC_MODE_COMPUTE_BITS == ps_cabac->e_cabac_op_mode)
351 {
352 //ASSERT(ctxt_inc == ps_entropy_ctxt->i4_num_nbr_skip_cus);
353 ctxt_inc = ps_entropy_ctxt->i4_num_nbr_skip_cus;
354 ASSERT(ctxt_inc < 3);
355 ASSERT((WORD32)ctxt_inc <= (top_avail + left_avail));
356 }
357
358 /* encode the skip flag */
359 error |= ihevce_cabac_encode_bin(ps_cabac, skip_flag, (IHEVC_CAB_SKIP_FLAG + ctxt_inc));
360
361 AEV_TRACE("cu_skip_flag", skip_flag, ps_cabac->u4_range);
362
363 if(CABAC_MODE_ENCODE_BITS == ps_cabac->e_cabac_op_mode)
364 {
365 /* update top and left skip flags only in encode mode */
366 if(skip_flag)
367 {
368 SET_BITS(pu1_top_skip_flags[0], x_pos, (cu_size >> 3));
369 SET_BITS(u4_skip_left_flags, y_pos, (cu_size >> 3));
370 }
371 else
372 {
373 CLEAR_BITS(pu1_top_skip_flags[0], x_pos, (cu_size >> 3));
374 CLEAR_BITS(u4_skip_left_flags, y_pos, (cu_size >> 3));
375 }
376
377 ps_entropy_ctxt->u4_skip_cu_left = u4_skip_left_flags;
378 }
379
380 return (error);
381 }
382
383 /**
384 ******************************************************************************
385 *
386 * @brief Entropy encoding of partition mode (Coding Unit syntax)
387 *
388 * @par Description
389 * Binarization process and context modelling of partition mode is done as per
390 * section 9.3.2.6 (Table 9-34) and se
391 *
392 * @param[inout] ps_cabac
393 * pointer to cabac encoding context (handle)
394 *
395 * @param[in] intra
396 * boolean indicating if current cu is intra cu
397 *
398 * @param[in] is_mincu
399 * boolean indicating if current cu size is equal to mincu
400 *
401 * @param[in] amp_enabled
402 * flag to indicate if AMP(Assymetric motion partition) is enabled at sps level
403 *
404 * @param[in] cu_eq_8
405 * boolean indicating if current cu size is equal to 8
406 *
407 * @param[in] part_mode
408 * partition mode of current CU
409 *
410 * @return success or failure error code
411 *
412 ******************************************************************************
413 */
ihevce_cabac_encode_part_mode(cab_ctxt_t * ps_cabac,WORD32 intra,WORD32 is_mincu,WORD32 amp_enabled,WORD32 cu_eq_8,WORD32 part_mode)414 WORD32 ihevce_cabac_encode_part_mode(
415 cab_ctxt_t *ps_cabac,
416 WORD32 intra,
417 WORD32 is_mincu,
418 WORD32 amp_enabled,
419 WORD32 cu_eq_8,
420 WORD32 part_mode)
421 {
422 /* Binarization depends on intra/inter, is_mincu, amp flag, cbsize == 8 */
423 WORD32 bins;
424 WORD32 bin_count, i;
425 WORD32 error = IHEVCE_SUCCESS;
426
427 (void)is_mincu;
428 (void)amp_enabled;
429 (void)cu_eq_8;
430 if(intra)
431 {
432 /* sanity checks for intra part mode */
433 ASSERT(is_mincu);
434 ASSERT((part_mode == SIZE_NxN) || (part_mode == SIZE_2Nx2N));
435
436 bins = (part_mode == SIZE_2Nx2N) ? 1 : 0;
437 error |= ihevce_cabac_encode_bin(ps_cabac, bins, IHEVC_CAB_PART_MODE);
438 }
439 else
440 {
441 /* sanity checks for inter part mode....Too many but good to have */
442 ASSERT((amp_enabled == 0) || (amp_enabled == 1));
443 ASSERT((is_mincu == 0) || (is_mincu == 1));
444 ASSERT((cu_eq_8 == 0) || (cu_eq_8 == 1));
445 ASSERT((part_mode <= SIZE_nRx2N) && (part_mode >= SIZE_2Nx2N));
446 if(!amp_enabled)
447 ASSERT(part_mode <= SIZE_NxN);
448 if(!is_mincu)
449 ASSERT(part_mode != SIZE_NxN);
450 if(is_mincu)
451 ASSERT(part_mode <= SIZE_NxN);
452 if(cu_eq_8)
453 ASSERT(part_mode < SIZE_NxN);
454 if(cu_eq_8)
455 ASSERT(is_mincu);
456
457 /* look up table for bins and number of bins for inter pred mode */
458 if(!is_mincu)
459 {
460 bins = gu1_hevce_inter_part_mode_bins[amp_enabled][part_mode];
461 }
462 else
463 {
464 bins = gu1_hevce_inter_part_mode_bins_mincu[cu_eq_8][part_mode];
465 }
466
467 bin_count = (bins >> 4) & 0xF;
468
469 /* Encode the context model based bins, max of 3 */
470 for(i = 0; i < MIN(bin_count, 3); i++)
471 {
472 //TODO: HM-8.0-dev uses 0 context increment for bin2 (i===2) when amp is enabled
473 WORD32 ctxt_inc = IHEVC_CAB_PART_MODE + i;
474 WORD32 bin = (bins >> (3 - i)) & 0x1;
475 error |= ihevce_cabac_encode_bin(ps_cabac, bin, ctxt_inc);
476 }
477
478 /* Encode the last bin as bypass bin for amp partitions */
479 if(bin_count == 4)
480 {
481 error |= ihevce_cabac_encode_bypass_bin(ps_cabac, (bins & 0x1));
482 }
483 }
484 AEV_TRACE("part_mode", part_mode, ps_cabac->u4_range);
485 return (error);
486 }
487
488 /**
489 ******************************************************************************
490 *
491 * @brief Entropy encoding of merge_idx of inter prediction unit as per sec
492 * as per sec 9.3.2 Table9-32. (tunary binarization)
493 *
494 * @par Description
495 * trunacted unary binarization is done based on max merge candidates
496 * First bin is context modelled bin and the rest are coded as bypass
497 *
498 * @param[inout] ps_cabac
499 * pointer to cabac encoding context (handle)
500 *
501 * @param[in] merge_idx
502 * merge idx of the pu to be encoded;
503 *
504 * @param[in] max_merge_cand
505 * maximum merge candidates signalled in the slice header*
506 *
507 * @return success or failure error code
508 *
509 ******************************************************************************
510 */
ihevce_cabac_encode_merge_idx(cab_ctxt_t * ps_cabac,WORD32 merge_idx,WORD32 max_merge_cand)511 WORD32 ihevce_cabac_encode_merge_idx(cab_ctxt_t *ps_cabac, WORD32 merge_idx, WORD32 max_merge_cand)
512 {
513 WORD32 ret = IHEVCE_SUCCESS;
514 WORD32 ctxt_inc = IHEVC_CAB_MERGE_IDX_EXT;
515
516 /* sanity checks */
517 ASSERT((merge_idx >= 0) && (merge_idx < max_merge_cand));
518
519 /* encode the merge idx only if required */
520 if(max_merge_cand > 1)
521 {
522 /* encode the context modelled first bin */
523 ret |= ihevce_cabac_encode_bin(ps_cabac, (merge_idx > 0), ctxt_inc);
524
525 /* encode the remaining bins as bypass tunary */
526 if((max_merge_cand > 2) && (merge_idx > 0))
527 {
528 ret |=
529 ihevce_cabac_encode_tunary_bypass(ps_cabac, (merge_idx - 1), (max_merge_cand - 2));
530 }
531
532 AEV_TRACE("merge_idx", merge_idx, ps_cabac->u4_range);
533 }
534
535 return (ret);
536 }
537
538 /**
539 ******************************************************************************
540 *
541 * @brief Entropy encoding of inter_pred_idc for prediction unit of B slice as
542 * per sec 9.3.2.9 Table9-36
543 *
544 * @par Description
545 * Max of two context modelled bins coded for pu size > 8x4 or 4x8
546 * one context modelled bin coded for pu size = 8x4 or 4x8; bipred not allowed
547 * for 8x4 or 4x8.
548 *
549 * @param[inout] ps_cabac
550 * pointer to cabac encoding context (handle)
551 *
552 * @param[in] inter_pred_idc
553 * inter pred mode to be encoded; shall be PRED_L0 or PRED_L1 or PRED_BI
554 *
555 * @param[in] cu_depth
556 * depth of the cu to which current pu belongs (required for context increment)
557 *
558 * @param[in] pu_w_plus_pu_h
559 * required to check if pu_w_plus_pu_h is 12 (8x4PU or 4x8PU)
560 *
561 * @return success or failure error code
562 *
563 ******************************************************************************
564 */
ihevce_cabac_encode_inter_pred_idc(cab_ctxt_t * ps_cabac,WORD32 inter_pred_idc,WORD32 cu_depth,WORD32 pu_w_plus_pu_h)565 WORD32 ihevce_cabac_encode_inter_pred_idc(
566 cab_ctxt_t *ps_cabac, WORD32 inter_pred_idc, WORD32 cu_depth, WORD32 pu_w_plus_pu_h)
567 {
568 WORD32 ret = IHEVCE_SUCCESS;
569 WORD32 ctxt_inc;
570
571 ASSERT(inter_pred_idc <= PRED_BI);
572
573 /* check if PU is 8x4/4x8 */
574 if(pu_w_plus_pu_h == 12)
575 {
576 /* case of 8x4 or 4x8 where bi_pred is not allowed */
577 ASSERT((inter_pred_idc == PRED_L0) || (inter_pred_idc == PRED_L1));
578
579 ctxt_inc = IHEVC_CAB_INTER_PRED_IDC + 4;
580 ret |= ihevce_cabac_encode_bin(ps_cabac, inter_pred_idc, ctxt_inc);
581 }
582 else
583 {
584 /* larger PUs can be encoded as bi_pred/l0/l1 inter_pred_idc */
585 WORD32 is_bipred = (inter_pred_idc == PRED_BI);
586
587 ctxt_inc = IHEVC_CAB_INTER_PRED_IDC + cu_depth;
588 ret |= ihevce_cabac_encode_bin(ps_cabac, is_bipred, ctxt_inc);
589
590 if(!is_bipred)
591 {
592 ctxt_inc = IHEVC_CAB_INTER_PRED_IDC + 4;
593 ret |= ihevce_cabac_encode_bin(ps_cabac, inter_pred_idc, ctxt_inc);
594 }
595 }
596
597 AEV_TRACE("inter_pred_idc", inter_pred_idc, ps_cabac->u4_range);
598
599 return (ret);
600 }
601
602 /**
603 ******************************************************************************
604 *
605 * @brief Entropy encoding of refidx for prediction unit; Binarization done as
606 * tunary code as per sec 9.3.2 Table9-32
607 *
608 * @par Description
609 * First two bins are context modelled while the rest are coded as bypass
610 *
611 * @param[inout] ps_cabac
612 * pointer to cabac encoding context (handle)
613 *
614 * @param[in] ref_idx
615 * ref idx of partition unit
616 *
617 * @param[in] active_refs
618 * max number of active references signalled in slice header
619 *
620 * @return success or failure error code
621 *
622 ******************************************************************************
623 */
ihevce_cabac_encode_refidx(cab_ctxt_t * ps_cabac,WORD32 ref_idx,WORD32 active_refs)624 WORD32 ihevce_cabac_encode_refidx(cab_ctxt_t *ps_cabac, WORD32 ref_idx, WORD32 active_refs)
625 {
626 /************************************************************/
627 /* encode ref_idx as tunary binarization Table 9-32 */
628 /* First 2 bin use context model and rest coded as bypass */
629 /************************************************************/
630 WORD32 ret = IHEVCE_SUCCESS;
631 WORD32 ctxt_inc = IHEVC_CAB_INTER_REF_IDX;
632
633 /* sanity checks */
634 ASSERT((ref_idx >= 0) && (ref_idx < active_refs));
635
636 /* encode the ref idx only if required */
637 if(active_refs > 1)
638 {
639 /* encode the context modelled first bin */
640 ret |= ihevce_cabac_encode_bin(ps_cabac, (ref_idx > 0), ctxt_inc);
641
642 if((active_refs > 2) && (ref_idx > 0))
643 {
644 /* encode the context modelled second bin */
645 ctxt_inc++;
646 ret |= ihevce_cabac_encode_bin(ps_cabac, (ref_idx > 1), ctxt_inc);
647 }
648
649 if((active_refs > 3) && (ref_idx > 1))
650 {
651 /* encode remaining bypass bins */
652 ret |= ihevce_cabac_encode_tunary_bypass(ps_cabac, (ref_idx - 2), (active_refs - 3));
653 }
654
655 AEV_TRACE("ref_idx", ref_idx, ps_cabac->u4_range);
656 }
657
658 return (ret);
659 }
660
661 /**
662 ******************************************************************************
663 *
664 * @brief Entropy encoding of mvd for inter pu as per section 7.3.10.2
665 *
666 * @par Description
667 * syntax coded as per section 7.3.10.2 for mvdx and mvdy
668 * context modeling of abs_mvd_greater0 abs_mvd_greater1 done as per Table 9-32
669 * binazrization of abs_mvd_minus2 is done as done as EG1 code section 9.3.2.4
670 *
671 * @param[inout] ps_cabac
672 * pointer to cabac encoding context (handle)
673 *
674 * @param[in] ps_mvd
675 * pointer to mvd struct containing mvdx and mvdy
676 *
677 * @return success or failure error code
678 *
679 ******************************************************************************
680 */
ihevce_cabac_encode_mvd(cab_ctxt_t * ps_cabac,mv_t * ps_mvd)681 WORD32 ihevce_cabac_encode_mvd(cab_ctxt_t *ps_cabac, mv_t *ps_mvd)
682 {
683 WORD32 ret = IHEVCE_SUCCESS;
684 WORD32 mvd_x = ps_mvd->i2_mvx;
685 WORD32 mvd_y = ps_mvd->i2_mvy;
686
687 WORD32 abs_mvd_x = ABS(mvd_x);
688 WORD32 abs_mvd_y = ABS(mvd_y);
689
690 WORD32 abs_mvd_x_gt0 = abs_mvd_x > 0;
691 WORD32 abs_mvd_y_gt0 = abs_mvd_y > 0;
692
693 WORD32 abs_mvd_x_gt1 = abs_mvd_x > 1;
694 WORD32 abs_mvd_y_gt1 = abs_mvd_y > 1;
695
696 WORD32 ctxt_inc = IHEVC_CAB_MVD_GRT0;
697
698 /* encode absmvd_x > 0 */
699 ret |= ihevce_cabac_encode_bin(ps_cabac, abs_mvd_x_gt0, ctxt_inc);
700 AEV_TRACE("abs_mvd_greater0_flag[0]", abs_mvd_x_gt0, ps_cabac->u4_range);
701
702 /* encode absmvd_y > 0 */
703 ret |= ihevce_cabac_encode_bin(ps_cabac, abs_mvd_y_gt0, ctxt_inc);
704 AEV_TRACE("abs_mvd_greater0_flag[1]", abs_mvd_y_gt0, ps_cabac->u4_range);
705
706 ctxt_inc = IHEVC_CAB_MVD_GRT1;
707
708 /* encode abs_mvd_x > 1 iff (abs_mvd_x > 0) */
709 if(abs_mvd_x_gt0)
710 {
711 ret |= ihevce_cabac_encode_bin(ps_cabac, abs_mvd_x_gt1, ctxt_inc);
712 AEV_TRACE("abs_mvd_greater1_flag[0]", abs_mvd_x_gt1, ps_cabac->u4_range);
713 }
714
715 /* encode abs_mvd_y > 1 iff (abs_mvd_y > 0) */
716 if(abs_mvd_y_gt0)
717 {
718 ret |= ihevce_cabac_encode_bin(ps_cabac, abs_mvd_y_gt1, ctxt_inc);
719 AEV_TRACE("abs_mvd_greater1_flag[1]", abs_mvd_y_gt1, ps_cabac->u4_range);
720 }
721
722 /* encode abs_mvd_x - 2 iff (abs_mvd_x > 1) */
723 if(abs_mvd_x_gt1)
724 {
725 ret |= ihevce_cabac_encode_egk(ps_cabac, (abs_mvd_x - 2), 1);
726 AEV_TRACE("abs_mvd_minus2[0]", (abs_mvd_x - 2), ps_cabac->u4_range);
727 }
728
729 /* encode mvd_x sign iff (abs_mvd_x > 0) */
730 if(abs_mvd_x_gt0)
731 {
732 ret |= ihevce_cabac_encode_bypass_bin(ps_cabac, (mvd_x < 0));
733 AEV_TRACE("mvd_sign_flag[0]", (mvd_x < 0), ps_cabac->u4_range);
734 }
735
736 /* encode abs_mvd_y - 2 iff (abs_mvd_y > 1) */
737 if(abs_mvd_y_gt1)
738 {
739 ret |= ihevce_cabac_encode_egk(ps_cabac, (abs_mvd_y - 2), 1);
740 AEV_TRACE("abs_mvd_minus2[1]", (abs_mvd_y - 2), ps_cabac->u4_range);
741 }
742
743 /* encode mvd_y sign iff (abs_mvd_y > 0) */
744 if(abs_mvd_y_gt0)
745 {
746 ret |= ihevce_cabac_encode_bypass_bin(ps_cabac, (mvd_y < 0));
747 AEV_TRACE("mvd_sign_flag[1]", (mvd_y < 0), ps_cabac->u4_range);
748 }
749
750 return ret;
751 }
752
753 /**
754 ******************************************************************************
755 *
756 * @brief Entropy encoding of all syntax elements of inter PUs in a CU
757 *
758 * @par Description
759 * syntax coded as per section 7.3.10.1 for inter prediction unit
760 *
761 * @param[inout] ps_entropy_ctxt
762 * pointer to entropy context (handle)
763 *
764 * @param[in] ps_enc_cu
765 * pointer to current cu whose inter prediction units are to be encoded
766 *
767 * @param[in] cu_depth
768 * depth of the the current cu in coding tree
769 *
770 * @return success or failure error code
771 *
772 ******************************************************************************
773 */
ihevce_cabac_encode_inter_pu(entropy_context_t * ps_entropy_ctxt,cu_enc_loop_out_t * ps_enc_cu,WORD32 cu_depth)774 WORD32 ihevce_cabac_encode_inter_pu(
775 entropy_context_t *ps_entropy_ctxt, cu_enc_loop_out_t *ps_enc_cu, WORD32 cu_depth)
776 {
777 WORD32 ret = IHEVCE_SUCCESS;
778
779 slice_header_t *ps_slice_hdr = ps_entropy_ctxt->ps_slice_hdr;
780 cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
781 pu_t *ps_pu = ps_enc_cu->ps_pu;
782
783 WORD32 merge_idx = ps_pu->b3_merge_idx;
784 WORD32 max_merge_cand = ps_slice_hdr->i1_max_num_merge_cand;
785 WORD32 ctxt_inc;
786
787 if(ps_enc_cu->b1_skip_flag)
788 {
789 WORD32 cu_size = ps_enc_cu->b4_cu_size << 3;
790 /*PIC_INFO : SKIP CU in frame*/
791 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
792 {
793 ps_entropy_ctxt->ps_pic_level_info->i8_total_skip_cu++;
794 ps_entropy_ctxt->ps_pic_level_info->i8_total_pu++;
795 if(cu_size == 64)
796 ps_entropy_ctxt->ps_pic_level_info->i8_total_2nx2n_inter_pu[3]++;
797 else
798 ps_entropy_ctxt->ps_pic_level_info->i8_total_2nx2n_inter_pu[cu_size >> 4]++;
799 }
800 /* encode the merge idx for skip cu and return */
801 ret |= ihevce_cabac_encode_merge_idx(ps_cabac, merge_idx, max_merge_cand);
802 }
803 else
804 {
805 /* MODE_INTER */
806 WORD32 part_mode = ps_enc_cu->b3_part_mode;
807 WORD32 num_parts, i;
808
809 num_parts = (part_mode == SIZE_2Nx2N) ? 1 : ((part_mode == SIZE_NxN) ? 4 : 2);
810
811 /*PIC_INFO : INTER CU in frame*/
812 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
813 {
814 WORD32 cu_size = ps_enc_cu->b4_cu_size << 3;
815 ps_entropy_ctxt->ps_pic_level_info->i8_total_inter_cu++;
816 ps_entropy_ctxt->ps_pic_level_info->i8_total_pu += num_parts;
817
818 // clang-format off
819 if(PART_2Nx2N == part_mode)
820 {
821 if(cu_size == 64)
822 ps_entropy_ctxt->ps_pic_level_info->i8_total_2nx2n_inter_pu[3]++;
823 else
824 ps_entropy_ctxt->ps_pic_level_info->i8_total_2nx2n_inter_pu[cu_size >> 4]++;
825 }
826 else if((PART_2NxN == part_mode) || (PART_Nx2N == part_mode))
827 {
828 if(cu_size == 64)
829 ps_entropy_ctxt->ps_pic_level_info->i8_total_smp_inter_pu[3]++;
830 else
831 ps_entropy_ctxt->ps_pic_level_info->i8_total_smp_inter_pu[cu_size >> 4]++;
832 }
833 else if((PART_2NxnU == part_mode) || (PART_2NxnD == part_mode) ||
834 (PART_nLx2N == part_mode) || (PART_nRx2N == part_mode))
835 {
836 ps_entropy_ctxt->ps_pic_level_info->i8_total_amp_inter_pu[cu_size >> 5]++;
837 }
838 else
839 {
840 ps_entropy_ctxt->ps_pic_level_info->i8_total_nxn_inter_pu[cu_size >> 5]++;
841 }
842 // clang-format on
843 }
844
845 /* encode each pu partition */
846 for(i = 0; i < num_parts; i++)
847 {
848 /* encode the merge flag context modelled bin */
849 WORD32 merge_flag;
850 UWORD32 u4_bits_estimated_merge_flag = 0;
851 ps_pu = ps_enc_cu->ps_pu + i;
852
853 /* encode the merge flag context modelled bin */
854 merge_flag = ps_pu->b1_merge_flag;
855 u4_bits_estimated_merge_flag = ps_cabac->u4_bits_estimated_q12;
856 ctxt_inc = IHEVC_CAB_MERGE_FLAG_EXT;
857 ret |= ihevce_cabac_encode_bin(ps_cabac, merge_flag, ctxt_inc);
858
859 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
860 {
861 // clang-format off
862 /*PIC INFO : Populate merge flag */
863 ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_merge_flag =
864 (ps_cabac->u4_bits_estimated_q12 -
865 u4_bits_estimated_merge_flag);
866 // clang-format on
867 }
868 AEV_TRACE("merge_flag", merge_flag, ps_cabac->u4_range);
869
870 if(merge_flag)
871 {
872 merge_idx = ps_pu->b3_merge_idx;
873 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
874 ps_entropy_ctxt->ps_pic_level_info->i8_total_merge_pu++;
875 /* encode the merge idx for the pu */
876 ret |= ihevce_cabac_encode_merge_idx(ps_cabac, merge_idx, max_merge_cand);
877 }
878 else
879 {
880 /* encode the inter_pred_idc, ref_idx and mvd */
881 WORD32 inter_pred_idc = ps_pu->b2_pred_mode;
882 WORD32 ref_l0_active = ps_slice_hdr->i1_num_ref_idx_l0_active;
883 WORD32 ref_l1_active = ps_slice_hdr->i1_num_ref_idx_l1_active;
884
885 /*PIC_INFO : L0 L1 BI ro r1.. in frame*/
886 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
887 {
888 ps_entropy_ctxt->ps_pic_level_info->i8_total_non_skipped_inter_pu++;
889 // clang-format off
890 if(inter_pred_idc == PRED_L0)
891 {
892 ps_entropy_ctxt->ps_pic_level_info->i8_total_L0_mode++;
893 ps_entropy_ctxt->ps_pic_level_info->i8_total_L0_ref_idx[ps_pu->mv.i1_l0_ref_idx]++;
894 }
895 else if(inter_pred_idc == PRED_L1)
896 {
897 ps_entropy_ctxt->ps_pic_level_info->i8_total_L1_mode++;
898 ps_entropy_ctxt->ps_pic_level_info->i8_total_L1_ref_idx[ps_pu->mv.i1_l1_ref_idx]++;
899 }
900 else if(inter_pred_idc == PRED_BI)
901 {
902 ps_entropy_ctxt->ps_pic_level_info->i8_total_BI_mode++;
903 if(inter_pred_idc != PRED_L1)
904 ps_entropy_ctxt->ps_pic_level_info->i8_total_L0_ref_idx[ps_pu->mv.i1_l0_ref_idx]++;
905 if(inter_pred_idc != PRED_L0)
906 ps_entropy_ctxt->ps_pic_level_info->i8_total_L1_ref_idx[ps_pu->mv.i1_l1_ref_idx]++;
907 }
908 // clang-format on
909 }
910 if(ps_slice_hdr->i1_slice_type == BSLICE)
911 {
912 /* Encode inter_pred_idc as per sec 9.3.2.9 Table9-36 */
913 WORD32 pu_w_plus_pu_h;
914 WORD32 inter_pred_idc = ps_pu->b2_pred_mode;
915
916 /* required to check if w+h==12 case */
917 pu_w_plus_pu_h = ((ps_pu->b4_wd + 1) << 2) + ((ps_pu->b4_ht + 1) << 2);
918
919 ret |= ihevce_cabac_encode_inter_pred_idc(
920 ps_cabac, inter_pred_idc, cu_depth, pu_w_plus_pu_h);
921 }
922 else
923 {
924 ASSERT(inter_pred_idc == 0);
925 }
926
927 /* Decode ref idx and mvd for L0 (PRED_L0 or PRED_BI) */
928 if(inter_pred_idc != PRED_L1)
929 {
930 UWORD32 u4_bits_estimated_prev_mvd_ref_id;
931 /* encode L0 ref_idx */
932 WORD32 ref_idx_l0 = ps_pu->mv.i1_l0_ref_idx;
933
934 /*PIC INFO : Populate Ref Indx L0 Bits*/
935 u4_bits_estimated_prev_mvd_ref_id = ps_cabac->u4_bits_estimated_q12;
936 ret |= ihevce_cabac_encode_refidx(ps_cabac, ref_idx_l0, ref_l0_active);
937
938 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
939 {
940 // clang-format off
941 ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_ref_id +=
942 (ps_cabac->u4_bits_estimated_q12 -
943 u4_bits_estimated_prev_mvd_ref_id);
944 // clang-format on
945 }
946 /* Encode the mvd for L0 */
947 /*PIC INFO : Populate MVD Bits*/
948 u4_bits_estimated_prev_mvd_ref_id = ps_cabac->u4_bits_estimated_q12;
949
950 ret |= ihevce_cabac_encode_mvd(ps_cabac, &ps_pu->mv.s_l0_mv);
951
952 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
953 { // clang-format off
954 ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_mvd +=
955 (ps_cabac->u4_bits_estimated_q12 -
956 u4_bits_estimated_prev_mvd_ref_id);
957 // clang-format on
958 }
959
960 /* Encode the mvp_l0_flag */
961 ctxt_inc = IHEVC_CAB_MVP_L0L1;
962 ret |= ihevce_cabac_encode_bin(ps_cabac, ps_pu->b1_l0_mvp_idx, ctxt_inc);
963
964 AEV_TRACE("mvp_l0/l1_flag", ps_pu->b1_l0_mvp_idx, ps_cabac->u4_range);
965 }
966
967 /* Encode ref idx and MVD for L1 (PRED_L1 or PRED_BI) */
968 if(inter_pred_idc != PRED_L0)
969 {
970 /* encode L1 ref_idx */
971 WORD32 ref_idx_l1 = ps_pu->mv.i1_l1_ref_idx;
972
973 UWORD32 u4_bits_estimated_prev_mvd_ref_id;
974 /*PIC INFO : Populate Ref Indx L1 Bits*/
975 u4_bits_estimated_prev_mvd_ref_id = ps_cabac->u4_bits_estimated_q12;
976
977 ret |= ihevce_cabac_encode_refidx(ps_cabac, ref_idx_l1, ref_l1_active);
978
979 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
980 { // clang-format off
981 ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_ref_id +=
982 (ps_cabac->u4_bits_estimated_q12 -
983 u4_bits_estimated_prev_mvd_ref_id);
984 } // clang-format on
985
986 /* Check for zero mvd in case of bi_pred */
987 if(ps_slice_hdr->i1_mvd_l1_zero_flag && inter_pred_idc == PRED_BI)
988 {
989 ASSERT(ps_pu->mv.s_l1_mv.i2_mvx == 0);
990 ASSERT(ps_pu->mv.s_l1_mv.i2_mvy == 0);
991 }
992 else
993 {
994 /* Encode the mvd for L1 */
995 /*PIC INFO : Populate MVD Bits*/
996 u4_bits_estimated_prev_mvd_ref_id = ps_cabac->u4_bits_estimated_q12;
997
998 /* Encode the mvd for L1 */
999 ret |= ihevce_cabac_encode_mvd(ps_cabac, &ps_pu->mv.s_l1_mv);
1000
1001 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1002 {
1003 ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_mvd +=
1004 (ps_cabac->u4_bits_estimated_q12 -
1005 u4_bits_estimated_prev_mvd_ref_id);
1006 }
1007 }
1008
1009 /* Encode the mvp_l1_flag */
1010 ctxt_inc = IHEVC_CAB_MVP_L0L1;
1011 ret |= ihevce_cabac_encode_bin(ps_cabac, ps_pu->b1_l1_mvp_idx, ctxt_inc);
1012
1013 AEV_TRACE("mvp_l0/l1_flag", ps_pu->b1_l1_mvp_idx, ps_cabac->u4_range);
1014 }
1015 }
1016 }
1017 }
1018
1019 return ret;
1020 }
1021
1022 /**
1023 ******************************************************************************
1024 *
1025 * @brief Entropy encoding of coding unit (Coding Unit syntax)
1026 *
1027 * @par Description
1028 * Entropy encode of coding unit (Coding Unit syntax) as per section:7.3.9.1
1029 * General Coding unit syntax
1030 *
1031 * @param[inout] ps_entropy_ctxt
1032 * pointer to entropy context (handle)
1033 *
1034 * @param[in] ps_enc_cu
1035 * pointer to current cu whose entropy encode is done
1036 *
1037 * @param[in] cu_depth
1038 * depth of the the current cu in coding tree
1039 *
1040 * @param[in] top_avail
1041 * top availabilty flag for current cu (boolean)
1042 *
1043 * @param[in] left_avail
1044 * left availabilty flag for current cu (boolean)
1045 *
1046 * @return success or failure error code
1047 *
1048 ******************************************************************************
1049 */
ihevce_cabac_encode_coding_unit(entropy_context_t * ps_entropy_ctxt,cu_enc_loop_out_t * ps_enc_cu,WORD32 cu_depth,WORD32 top_avail,WORD32 left_avail)1050 WORD32 ihevce_cabac_encode_coding_unit(
1051 entropy_context_t *ps_entropy_ctxt,
1052 cu_enc_loop_out_t *ps_enc_cu,
1053 WORD32 cu_depth,
1054 WORD32 top_avail,
1055 WORD32 left_avail)
1056 {
1057 WORD32 ret = IHEVCE_SUCCESS;
1058 sps_t *ps_sps = ps_entropy_ctxt->ps_sps;
1059 pps_t *ps_pps = ps_entropy_ctxt->ps_pps;
1060 slice_header_t *ps_slice_hdr = ps_entropy_ctxt->ps_slice_hdr;
1061
1062 WORD32 skip_flag = 0;
1063 WORD32 no_res_flag = 0;
1064
1065 /* CU top left co-ordinates w.r.t ctb */
1066 WORD32 cu_x0 = ps_enc_cu->b3_cu_pos_x << 3;
1067 WORD32 cu_y0 = ps_enc_cu->b3_cu_pos_y << 3;
1068
1069 /* CU size in pels */
1070 WORD32 cu_size = ps_enc_cu->b4_cu_size << 3;
1071 WORD32 log2_cb_size;
1072
1073 cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
1074
1075 UWORD32 u4_header_bits_temp = ps_cabac->u4_bits_estimated_q12;
1076
1077 (void)cu_depth;
1078 (void)top_avail;
1079 (void)left_avail;
1080 /* Sanity checks */
1081 ASSERT((cu_x0 + cu_size) <= (1 << ps_entropy_ctxt->i1_log2_ctb_size));
1082 ASSERT((cu_y0 + cu_size) <= (1 << ps_entropy_ctxt->i1_log2_ctb_size));
1083
1084 /* code tq bypass flag */
1085 ASSERT(ps_pps->i1_transquant_bypass_enable_flag == 0);
1086
1087 /* log2_cb_size based on cu size */
1088 GETRANGE(log2_cb_size, cu_size);
1089 log2_cb_size -= 1;
1090
1091 if(ps_pps->i1_transquant_bypass_enable_flag)
1092 {
1093 ihevce_cabac_encode_bin(
1094 ps_cabac, ps_enc_cu->b1_tq_bypass_flag, IHEVC_CAB_CU_TQ_BYPASS_FLAG);
1095
1096 AEV_TRACE("cu_transquant_bypass_flag", ps_enc_cu->b1_tq_bypass_flag, ps_cabac->u4_range);
1097 }
1098 /* code the skip flag for inter slices */
1099 if(ps_slice_hdr->i1_slice_type != ISLICE)
1100 {
1101 skip_flag = ps_enc_cu->b1_skip_flag;
1102
1103 ret |= ihevce_cabac_encode_skip_flag(ps_entropy_ctxt, ps_enc_cu, top_avail, left_avail);
1104 }
1105 /*PIC_INFO : Total CU in frame based on cu size */
1106 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1107 {
1108 // clang-format off
1109 if(cu_size == 64)
1110 ps_entropy_ctxt->ps_pic_level_info->i8_total_cu_based_on_size[3]++;
1111 else
1112 ps_entropy_ctxt->ps_pic_level_info->i8_total_cu_based_on_size[cu_size >> 4]++;
1113 // clang-format on
1114 }
1115 if(skip_flag)
1116 {
1117 /* encode merge idx for the skip cu */
1118 ret |= ihevce_cabac_encode_inter_pu(ps_entropy_ctxt, ps_enc_cu, cu_depth);
1119
1120 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1121 {
1122 /*PIC INFO: Populated non-coded TUs in CU*/
1123 ps_entropy_ctxt->ps_pic_level_info->i8_total_non_coded_tu +=
1124 ps_enc_cu->u2_num_tus_in_cu;
1125 // clang-format off
1126 if(cu_size == 64)
1127 ps_entropy_ctxt->ps_pic_level_info->i8_total_tu_based_on_size[3] +=
1128 ps_enc_cu->u2_num_tus_in_cu;
1129 else if(cu_size == 32)
1130 ps_entropy_ctxt->ps_pic_level_info->i8_total_tu_based_on_size[3] +=
1131 ps_enc_cu->u2_num_tus_in_cu;
1132 else
1133 ps_entropy_ctxt->ps_pic_level_info->i8_total_tu_based_on_size[cu_size >> 3] +=
1134 ps_enc_cu->u2_num_tus_in_cu;
1135 // clang-format on
1136
1137 /*PIC INFO: Populate cu header bits*/
1138 ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_cu_hdr_bits +=
1139 (ps_cabac->u4_bits_estimated_q12 - u4_header_bits_temp);
1140 }
1141 }
1142 else
1143 {
1144 WORD32 pred_mode = PRED_MODE_INTRA;
1145 WORD32 part_mode = ps_enc_cu->b3_part_mode;
1146 WORD32 pcm_flag = ps_enc_cu->b1_pcm_flag;
1147 WORD32 is_mincu;
1148 WORD32 is_intra;
1149
1150 is_mincu = (cu_size == (1 << ps_sps->i1_log2_min_coding_block_size));
1151 /* encode pred mode flag for inter slice */
1152 if(ps_slice_hdr->i1_slice_type != ISLICE)
1153 {
1154 pred_mode = ps_enc_cu->b1_pred_mode_flag;
1155
1156 ret |= ihevce_cabac_encode_bin(ps_cabac, pred_mode, IHEVC_CAB_PRED_MODE);
1157
1158 AEV_TRACE("pred_mode_flag", pred_mode, ps_cabac->u4_range);
1159 }
1160 is_intra = (PRED_MODE_INTRA == pred_mode);
1161
1162 /* encode partition mode for inter pred or smallest intra pred cu */
1163 if((!is_intra) || is_mincu)
1164 {
1165 WORD32 amp_enabled = ps_sps->i1_amp_enabled_flag;
1166 WORD32 cusize_8 = (cu_size == 8);
1167
1168 ret |= ihevce_cabac_encode_part_mode(
1169 ps_cabac, is_intra, is_mincu, amp_enabled, cusize_8, part_mode);
1170 }
1171 else
1172 {
1173 ASSERT(part_mode == SIZE_2Nx2N);
1174 }
1175
1176 /* encode intra / inter pu modes of the current CU */
1177 if(is_intra)
1178 {
1179 /* NOTE: I_PCM not supported in encoder */
1180 ASSERT(0 == pcm_flag);
1181 ASSERT(0 == ps_sps->i1_pcm_enabled_flag);
1182
1183 ret |= ihevce_cabac_encode_intra_pu(ps_entropy_ctxt, part_mode, ps_enc_cu);
1184 }
1185 else
1186 {
1187 ret |= ihevce_cabac_encode_inter_pu(ps_entropy_ctxt, ps_enc_cu, cu_depth);
1188 }
1189 /* encode no residue syntax flag and transform tree conditionally */
1190 if(!pcm_flag)
1191 {
1192 pu_t *ps_pu = &ps_enc_cu->ps_pu[0];
1193 WORD32 merge_cu;
1194 /* Encode residue syntax flag for inter cus not merged as 2Nx2N */
1195 if(!is_intra)
1196 merge_cu = (part_mode == PART_2Nx2N) && ps_pu->b1_merge_flag;
1197
1198 if(!is_intra && !merge_cu)
1199 {
1200 no_res_flag = ps_enc_cu->b1_no_residual_syntax_flag;
1201
1202 #if 1 /* HACK FOR COMPLIANCE WITH HM REFERENCE DECODER */
1203 /*********************************************************/
1204 /* currently the HM decoder expects qtroot cbf instead of */
1205 /* no_residue_flag which has opposite meaning */
1206 /* This will be fixed once the software / spec is fixed */
1207 /*********************************************************/
1208 ret |= ihevce_cabac_encode_bin(ps_cabac, !no_res_flag, IHEVC_CAB_NORES_IDX);
1209
1210 AEV_TRACE("no_residual_syntax_flag (HACKY)", !no_res_flag, ps_cabac->u4_range);
1211 #else
1212 ret |= ihevce_cabac_encode_bin(ps_cabac, no_res_flag, IHEVC_CAB_NORES_IDX);
1213
1214 AEV_TRACE("no_residual_syntax_flag", no_res_flag, ps_cabac->u4_range);
1215 #endif
1216 }
1217 /*initialize header bits*/
1218 ps_cabac->u4_header_bits_estimated_q12 = ps_cabac->u4_bits_estimated_q12;
1219
1220 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1221 { // clang-format off
1222 /*PIC INFO: Populate cu header bits*/
1223 ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_cu_hdr_bits +=
1224 (ps_cabac->u4_bits_estimated_q12 - u4_header_bits_temp);
1225 } // clang-format on
1226
1227 ps_cabac->u4_true_tu_split_flag_q12 = 0;
1228 /* encode transform tree if no_residue_flag is 0 */
1229 if(!no_res_flag)
1230 {
1231 ps_entropy_ctxt->i4_tu_idx = 0;
1232
1233 ret |= ihevce_encode_transform_tree(
1234 ps_entropy_ctxt, cu_x0, cu_y0, log2_cb_size, 0, 0, ps_enc_cu);
1235 }
1236 else
1237 {
1238 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1239 {
1240 /*PIC INFO: Populated non-coded TUs in CU*/
1241 ps_entropy_ctxt->ps_pic_level_info->i8_total_non_coded_tu +=
1242 ps_enc_cu->u2_num_tus_in_cu;
1243 // clang-format off
1244 if(cu_size == 64)
1245 ps_entropy_ctxt->ps_pic_level_info->i8_total_tu_based_on_size[3] +=
1246 ps_enc_cu->u2_num_tus_in_cu;
1247 else if(cu_size == 32)
1248 ps_entropy_ctxt->ps_pic_level_info->i8_total_tu_based_on_size[3] +=
1249 ps_enc_cu->u2_num_tus_in_cu;
1250 else
1251 ps_entropy_ctxt->ps_pic_level_info->i8_total_tu_based_on_size[cu_size >> 3] +=
1252 ps_enc_cu->u2_num_tus_in_cu;
1253 // clang-format on
1254 }
1255 }
1256 ps_cabac->u4_cbf_bits_q12 = ps_cabac->u4_bits_estimated_q12 -
1257 ps_cabac->u4_header_bits_estimated_q12 -
1258 ps_cabac->u4_true_tu_split_flag_q12;
1259 }
1260 }
1261
1262 /*duplicate the qp values for 8x8 CU array to maintain neighbour qp*/
1263 if(CABAC_MODE_ENCODE_BITS == ps_entropy_ctxt->s_cabac_ctxt.e_cabac_op_mode)
1264 {
1265 WORD32 i, j;
1266 WORD32 cur_cu_offset, cur_qp, qp_left, qp_top;
1267 WORD32 is_last_blk_in_qg;
1268 /* CU x co-ordinate w.r.t frame start */
1269 WORD32 ctb_x0_frm = (ps_entropy_ctxt->i4_ctb_x << ps_entropy_ctxt->i1_log2_ctb_size);
1270
1271 WORD32 cu_x0_frm = cu_x0 + ctb_x0_frm;
1272
1273 /* CU y co-ordinate w.r.t frame start */
1274 WORD32 ctb_y0_frm = (ps_entropy_ctxt->i4_ctb_y << ps_entropy_ctxt->i1_log2_ctb_size);
1275
1276 WORD32 cu_y0_frm = cu_y0 + ctb_y0_frm;
1277
1278 WORD32 pic_width = ps_sps->i2_pic_width_in_luma_samples;
1279 WORD32 pic_height = ps_sps->i2_pic_height_in_luma_samples;
1280
1281 /* Added code for handling the QP neighbour population depending
1282 on the diff_cu_qp_delta_depth: Lokesh */
1283 /* is_last_blk_in_qg variables is to find if the coding block is the last CU in the Quantization group
1284 3 - i1_diff_cu_qp_delta_depth is done as the cu_pos_x and cu_pos_y are in terms of 8x8 positions in the CTB: Lokesh*/
1285 WORD32 log2_min_cu_qp_delta_size =
1286 ps_entropy_ctxt->i1_log2_ctb_size - ps_entropy_ctxt->ps_pps->i1_diff_cu_qp_delta_depth;
1287 UWORD32 min_cu_qp_delta_size = 1 << log2_min_cu_qp_delta_size;
1288
1289 WORD32 block_addr_align = 15 << (log2_min_cu_qp_delta_size - 3);
1290
1291 ps_entropy_ctxt->i4_qg_pos_x = ps_enc_cu->b3_cu_pos_x & block_addr_align;
1292 ps_entropy_ctxt->i4_qg_pos_y = ps_enc_cu->b3_cu_pos_y & block_addr_align;
1293
1294 /* Condition for detecting last cu in a qp group. */
1295 /* Case 1: Current cu position + size exceed or meets the next qp group start location */
1296 /* Case 2: Current cu position + size hits the incomplete ctb boundary in atleast one */
1297 /* direction and the qp grp limit in other direction */
1298
1299 /* case 1 */
1300 is_last_blk_in_qg =
1301 ((cu_x0 + cu_size) >=
1302 ((ps_entropy_ctxt->i4_qg_pos_x << 3) + (WORD32)min_cu_qp_delta_size) &&
1303 (cu_y0 + cu_size) >=
1304 ((ps_entropy_ctxt->i4_qg_pos_y << 3) + (WORD32)min_cu_qp_delta_size));
1305
1306 /* case 2 : x direction incomplete ctb */
1307 if((cu_x0_frm + cu_size) >= pic_width)
1308 {
1309 is_last_blk_in_qg |=
1310 ((cu_y0 + cu_size) >=
1311 ((ps_entropy_ctxt->i4_qg_pos_y << 3) + (WORD32)min_cu_qp_delta_size));
1312 }
1313
1314 /* case 2 : y direction incomplete ctb */
1315 if((cu_y0_frm + cu_size) >= pic_height)
1316 {
1317 is_last_blk_in_qg |=
1318 ((cu_x0 + cu_size) >=
1319 ((ps_entropy_ctxt->i4_qg_pos_x << 3) + (WORD32)min_cu_qp_delta_size));
1320 }
1321
1322 cur_cu_offset = ps_enc_cu->b3_cu_pos_x + (ps_enc_cu->b3_cu_pos_y * 8);
1323
1324 if((ps_entropy_ctxt->i4_is_cu_cbf_zero || no_res_flag || skip_flag) &&
1325 ((ps_entropy_ctxt->i1_encode_qp_delta)))
1326 {
1327 { // clang-format off
1328 /*it should remember average of qp_top and qp_left*/
1329 if(ps_entropy_ctxt->i4_qg_pos_x > 0)
1330 {
1331 qp_left =
1332 ps_entropy_ctxt->ai4_8x8_cu_qp[(ps_entropy_ctxt->i4_qg_pos_x - 1) +
1333 (ps_entropy_ctxt->i4_qg_pos_y * 8)];
1334 }
1335 if(ps_entropy_ctxt->i4_qg_pos_y > 0)
1336 {
1337 qp_top =
1338 ps_entropy_ctxt->ai4_8x8_cu_qp[ps_entropy_ctxt->i4_qg_pos_x +
1339 (ps_entropy_ctxt->i4_qg_pos_y - 1) *
1340 8];
1341 } // clang-format on
1342 if(ps_entropy_ctxt->i4_qg_pos_x == 0)
1343 {
1344 /*previous coded Qp*/
1345 qp_left = ps_entropy_ctxt->i1_cur_qp;
1346 }
1347 if(ps_entropy_ctxt->i4_qg_pos_y == 0)
1348 {
1349 /*previous coded Qp*/
1350 qp_top = ps_entropy_ctxt->i1_cur_qp;
1351 }
1352 cur_qp = (qp_top + qp_left + 1) >> 1;
1353 /*In case of skip or zero cbf CU the previous qp used has to be updated*/
1354 if(is_last_blk_in_qg)
1355 ps_entropy_ctxt->i1_cur_qp = cur_qp;
1356 }
1357 }
1358 else
1359 {
1360 cur_qp = (WORD32)ps_enc_cu->ps_enc_tu->s_tu.b7_qp;
1361 }
1362
1363 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1364 {
1365 WORD32 temp = 0;
1366 /*PIC_INFO: Accumalate average qp, min qp and max qp*/
1367 ps_entropy_ctxt->ps_pic_level_info->i8_total_qp += cur_qp;
1368 if(cu_size == 64)
1369 temp = 6;
1370 else if(cu_size == 32)
1371 temp = 4;
1372 else if(cu_size == 16)
1373 temp = 2;
1374 else if(cu_size == 8)
1375 temp = 0;
1376
1377 ps_entropy_ctxt->ps_pic_level_info->i8_total_qp_min_cu += (cur_qp * (1 << temp));
1378 if(cur_qp < ps_entropy_ctxt->ps_pic_level_info->i4_min_qp)
1379 ps_entropy_ctxt->ps_pic_level_info->i4_min_qp = cur_qp;
1380 if(cur_qp > ps_entropy_ctxt->ps_pic_level_info->i4_max_qp)
1381 ps_entropy_ctxt->ps_pic_level_info->i4_max_qp = cur_qp;
1382 }
1383
1384 for(i = 0; i < (WORD32)ps_enc_cu->b4_cu_size; i++)
1385 {
1386 for(j = 0; j < (WORD32)ps_enc_cu->b4_cu_size; j++)
1387 {
1388 ps_entropy_ctxt->ai4_8x8_cu_qp[cur_cu_offset + (i * 8) + j] = cur_qp;
1389 }
1390 }
1391 ps_entropy_ctxt->i4_is_cu_cbf_zero = 1;
1392 }
1393
1394 return ret;
1395 }
1396
1397 /**
1398 ******************************************************************************
1399 *
1400 * @brief Entropy encoding of SAO related syntax elements as per sec 7.3.8.3
1401 *
1402 * @par Description
1403 * Encoding of sao related syntax elements at ctb level.
1404 *
1405 * @param[inout] ps_entropy_ctxt
1406 * pointer to entropy context (handle)
1407 *
1408 * @param[in] ps_ctb_enc_loop_out
1409 * pointer to ctb level output structure from enc loop
1410 *
1411 * @return success or failure error code
1412 *
1413 ******************************************************************************
1414 */
ihevce_cabac_encode_sao(entropy_context_t * ps_entropy_ctxt,ctb_enc_loop_out_t * ps_ctb_enc_loop_out)1415 WORD32 ihevce_cabac_encode_sao(
1416 entropy_context_t *ps_entropy_ctxt, ctb_enc_loop_out_t *ps_ctb_enc_loop_out)
1417 {
1418 WORD32 error = IHEVCE_SUCCESS;
1419 sao_enc_t *ps_sao;
1420 nbr_avail_flags_t *ps_ctb_nbr_avail_flags;
1421 slice_header_t *ps_slice_hdr = ps_entropy_ctxt->ps_slice_hdr;
1422 cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
1423
1424 UWORD8 u1_left_avail, u1_top_avail;
1425
1426 ps_ctb_nbr_avail_flags = &ps_ctb_enc_loop_out->s_ctb_nbr_avail_flags;
1427
1428 ps_sao = &ps_ctb_enc_loop_out->s_sao;
1429
1430 ASSERT(ps_sao->b1_sao_merge_left_flag < 2);
1431
1432 u1_left_avail = ps_ctb_nbr_avail_flags->u1_left_avail;
1433 u1_top_avail = ps_ctb_nbr_avail_flags->u1_top_avail;
1434
1435 if(u1_left_avail == 1)
1436 {
1437 /*Encode the sao_merge_left_flag as FL as per table 9-32*/
1438 error |=
1439 ihevce_cabac_encode_bin(ps_cabac, ps_sao->b1_sao_merge_left_flag, IHEVC_CAB_SAO_MERGE);
1440
1441 AEV_TRACE("sao_merge_flag", ps_sao->b1_sao_merge_left_flag, ps_cabac->u4_range);
1442 }
1443
1444 if((u1_top_avail == 1) && (!ps_sao->b1_sao_merge_left_flag))
1445 {
1446 /*Encode the sao_merge_up_flag as FL as per table 9-32*/
1447 error |=
1448 ihevce_cabac_encode_bin(ps_cabac, ps_sao->b1_sao_merge_up_flag, IHEVC_CAB_SAO_MERGE);
1449
1450 AEV_TRACE("sao_merge_flag", ps_sao->b1_sao_merge_up_flag, ps_cabac->u4_range);
1451 }
1452
1453 if((!ps_sao->b1_sao_merge_left_flag) && (!ps_sao->b1_sao_merge_up_flag))
1454 {
1455 WORD32 c_idx;
1456 WORD32 sao_type_idx = ps_sao->b3_y_type_idx;
1457
1458 /*Run a loop for y,cb and cr to encode the type idx for luma and chroma*/
1459 for(c_idx = 0; c_idx < 3; c_idx++)
1460 {
1461 if((ps_slice_hdr->i1_slice_sao_luma_flag && c_idx == 0) ||
1462 (ps_slice_hdr->i1_slice_sao_chroma_flag && c_idx > 0))
1463 {
1464 WORD32 ctxt_bin;
1465
1466 /**************************************************************************/
1467 /* encode the sao_type_idx as per Table 9-33 */
1468 /* First bin is context model based prefix : 1 if sao_type_idx > 0 else 0 */
1469 /* Second bin is coded as bypass bin if sao_type_ide > 0 */
1470 /**************************************************************************/
1471
1472 if(c_idx < 2)
1473 {
1474 WORD32 sao_type_idx_temp;
1475
1476 ASSERT(ps_sao->b3_cb_type_idx == ps_sao->b3_cr_type_idx);
1477
1478 sao_type_idx = c_idx ? ps_sao->b3_cb_type_idx : ps_sao->b3_y_type_idx;
1479
1480 ctxt_bin = sao_type_idx ? 1 : 0;
1481
1482 if(sao_type_idx > 1)
1483 {
1484 sao_type_idx_temp = 2;
1485 }
1486 else
1487 {
1488 sao_type_idx_temp = sao_type_idx;
1489 }
1490
1491 ASSERT(sao_type_idx_temp < 3);
1492
1493 /*Encode the first bin as context bin as per table 9-37*/
1494 error |= ihevce_cabac_encode_bin(ps_cabac, ctxt_bin, IHEVC_CAB_SAO_TYPE);
1495
1496 if(sao_type_idx_temp)
1497 {
1498 /*Binarisation for sao_type_idx is TR(truncated rice) process as per
1499 * table 9-32 with cMax=2 and cRiceParam=0
1500 */
1501
1502 /* Encode the second bin as bypass bin as per below table*/
1503 /*
1504 |Symbol | Prefix |Prefix length |Prefix bins|
1505 | 0 | 0 | 1 | 0 |
1506 | 1 | 1 | 2 | 10 |
1507 | 2 | 2 | 2 | 11 |
1508
1509 Since cRiceParam=0, there is no suffix code
1510 */
1511
1512 error |= ihevce_cabac_encode_bypass_bin(ps_cabac, sao_type_idx_temp - 1);
1513 }
1514 AEV_TRACE("sao_type_idx", sao_type_idx_temp, ps_cabac->u4_range);
1515 }
1516
1517 if(sao_type_idx != 0)
1518 {
1519 WORD32 i;
1520 UWORD8 u1_bit_depth = ps_entropy_ctxt->ps_sps->i1_bit_depth_luma_minus8 + 8;
1521 WORD8 *sao_offset;
1522 WORD32 sao_band_position;
1523 WORD32 c_max = (1 << (MIN(u1_bit_depth, 10) - 5)) -
1524 1; //( 1 << (MIN(BIT_DEPTH, 10) - 5)) - 1;
1525
1526 if(c_idx == 0)
1527 {
1528 //sao_offset[0] = ps_sao->b4_y_offset_1;
1529 //sao_offset[1] = ps_sao->b4_y_offset_2;
1530 //sao_offset[2] = ps_sao->b4_y_offset_3;
1531 //sao_offset[3] = ps_sao->b4_y_offset_4;
1532 sao_offset = &ps_sao->u1_y_offset[1];
1533 sao_band_position = ps_sao->b5_y_band_pos;
1534 }
1535 else if(c_idx == 1)
1536 {
1537 //sao_offset[0] = ps_sao->b4_cb_offset_1;
1538 //sao_offset[1] = ps_sao->b4_cb_offset_2;
1539 //sao_offset[2] = ps_sao->b4_cb_offset_3;
1540 //sao_offset[3] = ps_sao->b4_cb_offset_4;
1541 sao_offset = &ps_sao->u1_cb_offset[1];
1542 sao_band_position = ps_sao->b5_cb_band_pos;
1543 }
1544 else
1545 {
1546 //sao_offset[0] = ps_sao->b4_cr_offset_1;
1547 //sao_offset[1] = ps_sao->b4_cr_offset_2;
1548 //sao_offset[2] = ps_sao->b4_cr_offset_3;
1549 //sao_offset[3] = ps_sao->b4_cr_offset_4;
1550 sao_offset = &ps_sao->u1_cr_offset[1];
1551 sao_band_position = ps_sao->b5_cr_band_pos;
1552 }
1553
1554 for(i = 0; i < 4; i++)
1555 {
1556 /*Encode the sao offset value as tunary bypass*/
1557 error |=
1558 ihevce_cabac_encode_tunary_bypass(ps_cabac, abs(sao_offset[i]), c_max);
1559
1560 AEV_TRACE("sao_offset_abs", abs(sao_offset[i]), ps_cabac->u4_range);
1561 }
1562
1563 /*Band offset case*/
1564 if(sao_type_idx == 1)
1565 {
1566 for(i = 0; i < 4; i++)
1567 {
1568 if(sao_offset[i] != 0)
1569 {
1570 /*Encode the sao offset sign as FL as per table 9-32*/
1571 error |= ihevce_cabac_encode_bypass_bin(
1572 ps_cabac,
1573 (abs(sao_offset[i]) + sao_offset[i] == 0)); //,
1574 //IHEVC_CAB_SAO_MERGE
1575 //);
1576
1577 AEV_TRACE(
1578 "sao_offset_sign",
1579 (abs(sao_offset[i]) + sao_offset[i] == 0),
1580 ps_cabac->u4_range);
1581 }
1582 }
1583
1584 /*Encode the sao band position as FL as per table 9-32*/
1585 error |= ihevce_cabac_encode_bypass_bins(ps_cabac, sao_band_position, 5);
1586 AEV_TRACE("sao_band_position", sao_band_position, ps_cabac->u4_range);
1587 }
1588 else
1589 {
1590 /*Encode the sao edge offset class for luma and chroma as FL as per table 9-32*/
1591 if(c_idx == 0)
1592 {
1593 error |= ihevce_cabac_encode_bypass_bins(
1594 ps_cabac, (ps_sao->b3_y_type_idx - 2), 2);
1595 AEV_TRACE(
1596 "sao_eo_class", (ps_sao->b3_y_type_idx - 2), ps_cabac->u4_range);
1597 }
1598
1599 if(c_idx == 1)
1600 {
1601 ASSERT(ps_sao->b3_cb_type_idx == ps_sao->b3_cr_type_idx);
1602 error |= ihevce_cabac_encode_bypass_bins(
1603 ps_cabac, (ps_sao->b3_cb_type_idx - 2), 2);
1604 AEV_TRACE(
1605 "sao_eo_class", (ps_sao->b3_cb_type_idx - 2), ps_cabac->u4_range);
1606 }
1607 }
1608 }
1609 }
1610 }
1611 }
1612
1613 return (error);
1614 }
1615
1616 /**
1617 ******************************************************************************
1618 *
1619 * @brief Encodes a coding quad tree (QuadTree syntax) as per section 7.3.8
1620 *
1621 * @par Description
1622 * Entropy encode of coding quad tree based on cu split flags of ctb as per
1623 * section:7.3.8
1624 *
1625 * @param[inout] ps_entropy_ctxt
1626 * pointer to entropy context (handle)
1627 *
1628 * @param[in] x0_frm
1629 * x co-ordinate of current cu node of coding tree
1630 *
1631 * @param[in] y0_frm
1632 * y co-ordinate of current cu node of coding tree
1633 *
1634 * @param[in] log2_cb_size
1635 * current cu node block size
1636 *
1637 * @param[in] ct_depth
1638 * depth of current cu node w.r.t ctb
1639 *
1640 * @param[in] ps_ctb
1641 * pointer to current ctb structure
1642 *
1643 * @return success or failure error code
1644 *
1645 ******************************************************************************
1646 */
ihevce_encode_coding_quadtree(entropy_context_t * ps_entropy_ctxt,WORD32 x0_frm,WORD32 y0_frm,WORD32 log2_cb_size,WORD32 ct_depth,ctb_enc_loop_out_t * ps_ctb,ihevce_tile_params_t * ps_tile_params)1647 WORD32 ihevce_encode_coding_quadtree(
1648 entropy_context_t *ps_entropy_ctxt,
1649 WORD32 x0_frm,
1650 WORD32 y0_frm,
1651 WORD32 log2_cb_size,
1652 WORD32 ct_depth,
1653 ctb_enc_loop_out_t *ps_ctb,
1654 ihevce_tile_params_t *ps_tile_params)
1655 {
1656 WORD32 ret = IHEVCE_SUCCESS;
1657 sps_t *ps_sps = ps_entropy_ctxt->ps_sps;
1658 pps_t *ps_pps = ps_entropy_ctxt->ps_pps;
1659 WORD32 split_cu_flag;
1660 WORD32 cu_idx = ps_entropy_ctxt->i4_cu_idx;
1661 cu_enc_loop_out_t *ps_enc_cu = ps_ctb->ps_enc_cu + cu_idx;
1662
1663 /* CU size in pels */
1664 WORD32 cu_size = ps_enc_cu->b4_cu_size << 3;
1665
1666 WORD32 pic_width = ps_tile_params->i4_curr_tile_width;
1667 WORD32 pic_height = ps_tile_params->i4_curr_tile_height;
1668
1669 WORD32 log2_min_cb_size = ps_sps->i1_log2_min_coding_block_size;
1670 WORD32 ctb_size = (1 << (log2_cb_size + ct_depth));
1671 cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
1672
1673 /* top row cu depth stored for frm_width (1byte per mincusize=8) */
1674 UWORD8 *pu1_cu_depth_top = ps_entropy_ctxt->pu1_cu_depth_top;
1675
1676 /* left cu depth stored for one ctb column (1byte per mincusize=8) */
1677 UWORD8 *pu1_cu_depth_left = &ps_entropy_ctxt->au1_cu_depth_left[0];
1678
1679 /* calculation of top and left nbr availability */
1680 WORD32 top_avail;
1681 WORD32 left_avail;
1682
1683 /* top and left cu within ctb or outside ctb boundary */
1684 left_avail = (x0_frm & (ctb_size - 1)) ? 1 : ps_ctb->s_ctb_nbr_avail_flags.u1_left_avail;
1685 top_avail = (y0_frm & (ctb_size - 1)) ? 1 : ps_ctb->s_ctb_nbr_avail_flags.u1_top_avail;
1686
1687 /* Sanity checks */
1688 ASSERT(ct_depth <= 3);
1689 ASSERT((cu_idx >= 0) && (cu_idx < ps_ctb->u1_num_cus_in_ctb));
1690 ASSERT(cu_size >= (1 << log2_min_cb_size));
1691 ASSERT(((ps_enc_cu->b3_cu_pos_x << 3) + cu_size) <= (UWORD32)ctb_size);
1692 ASSERT(((ps_enc_cu->b3_cu_pos_y << 3) + cu_size) <= (UWORD32)ctb_size);
1693
1694 /* Encode cu split flags based on following conditions; See section 7.3.8*/
1695 if(((x0_frm + (1 << log2_cb_size)) <= pic_width) &&
1696 ((y0_frm + (1 << log2_cb_size)) <= pic_height) && (log2_cb_size > log2_min_cb_size) &&
1697 (ps_entropy_ctxt->i1_ctb_num_pcm_blks == 0))
1698 {
1699 /* encode the split cu flag */
1700 WORD32 ctxt_inc = IHEVC_CAB_SPLIT_CU_FLAG;
1701 UWORD32 u4_bits_estimated_prev;
1702 /* Context increment for skip flag as per Table 9-38 */
1703 if(top_avail)
1704 {
1705 ctxt_inc += (pu1_cu_depth_top[x0_frm >> 3] > ct_depth);
1706 }
1707
1708 if(left_avail)
1709 {
1710 ctxt_inc += (pu1_cu_depth_left[(y0_frm >> 3) & 0x7] > ct_depth);
1711 }
1712
1713 /* split if actual cu size is smaller than target cu size */
1714 split_cu_flag = cu_size < (1 << log2_cb_size);
1715 u4_bits_estimated_prev = ps_cabac->u4_bits_estimated_q12;
1716 ret |= ihevce_cabac_encode_bin(ps_cabac, split_cu_flag, ctxt_inc);
1717
1718 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1719 { // clang-format off
1720 /*PIC INFO : populate cu split flag*/
1721 ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_split_cu_flag +=
1722 (ps_cabac->u4_bits_estimated_q12 - u4_bits_estimated_prev);
1723 } // clang-format on
1724
1725 AEV_TRACE("split_cu_flag", split_cu_flag, ps_cabac->u4_range);
1726 if(split_cu_flag == 0)
1727 {
1728 AEV_TRACE("split_cu_flag : X0", (x0_frm >> 6) << 6, ps_cabac->u4_range);
1729 AEV_TRACE("split_cu_flag : Y0", (y0_frm >> 6) << 6, ps_cabac->u4_range);
1730 }
1731 }
1732 else
1733 {
1734 /*********************************************************************/
1735 /* split cu is implicitly derived as 1 in frame/slice boundary case */
1736 /* else split cu is implicitly derived as 0 if mincu size is reached */
1737 /*********************************************************************/
1738 if(log2_cb_size > ps_sps->i1_log2_min_coding_block_size)
1739 split_cu_flag = 1;
1740 else
1741 split_cu_flag = 0;
1742 }
1743
1744 /************************************************************************/
1745 /* Reset qp delata coded flag appropriately so as to signal qp rightly */
1746 /* during transform coding */
1747 /************************************************************************/
1748 if((ps_pps->i1_cu_qp_delta_enabled_flag) && (ct_depth <= (ps_pps->i1_diff_cu_qp_delta_depth)))
1749
1750 {
1751 ps_entropy_ctxt->i1_encode_qp_delta = 1;
1752 }
1753 /*else
1754 {
1755 ps_entropy_ctxt->i1_encode_qp_delta = 0;
1756 }*/
1757
1758 if(split_cu_flag)
1759 {
1760 /* recurse quad tree till a leaf node is reached */
1761 WORD32 x1_frm = x0_frm + ((1 << log2_cb_size) >> 1);
1762 WORD32 y1_frm = y0_frm + ((1 << log2_cb_size) >> 1);
1763
1764 /* node0 of quad tree */
1765 ret |= ihevce_encode_coding_quadtree(
1766 ps_entropy_ctxt, x0_frm, y0_frm, log2_cb_size - 1, ct_depth + 1, ps_ctb, ps_tile_params);
1767
1768 if(x1_frm < pic_width)
1769 { /* node1 of quad tree */
1770 ret |= ihevce_encode_coding_quadtree(
1771 ps_entropy_ctxt,
1772 x1_frm,
1773 y0_frm,
1774 log2_cb_size - 1,
1775 ct_depth + 1,
1776 ps_ctb,
1777 ps_tile_params);
1778 }
1779
1780 if(y1_frm < pic_height)
1781 {
1782 /* node2 of quad tree */
1783 ret |= ihevce_encode_coding_quadtree(
1784 ps_entropy_ctxt,
1785 x0_frm,
1786 y1_frm,
1787 log2_cb_size - 1,
1788 ct_depth + 1,
1789 ps_ctb,
1790 ps_tile_params);
1791 }
1792
1793 if((x1_frm < pic_width) && (y1_frm < pic_height))
1794 {
1795 /* node3 of quad tree */
1796 ret |= ihevce_encode_coding_quadtree(
1797 ps_entropy_ctxt,
1798 x1_frm,
1799 y1_frm,
1800 log2_cb_size - 1,
1801 ct_depth + 1,
1802 ps_ctb,
1803 ps_tile_params);
1804 }
1805 }
1806 else
1807 {
1808 /* leaf node is reached! Encode the CU */
1809 WORD32 i;
1810
1811 /* sanity checks */
1812 ASSERT(ps_entropy_ctxt->i1_ctb_num_pcm_blks == 0);
1813
1814 if(ps_entropy_ctxt->i1_ctb_num_pcm_blks == 0)
1815 {
1816 UWORD32 u4_bits_eztimated = ps_entropy_ctxt->s_cabac_ctxt.u4_bits_estimated_q12;
1817 /* Encode a non-PCM CU */
1818 /*PCM INFO: populate total TUs*/
1819 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1820 {
1821 ps_entropy_ctxt->ps_pic_level_info->i8_total_tu += ps_enc_cu->u2_num_tus_in_cu;
1822 }
1823
1824 ret |= ihevce_cabac_encode_coding_unit(
1825 ps_entropy_ctxt, ps_enc_cu, ct_depth, top_avail, left_avail);
1826
1827 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1828 {
1829 // clang-format off
1830 if(PRED_MODE_INTRA == ps_enc_cu->b1_pred_mode_flag)
1831 {
1832 ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_intra +=
1833 (ps_entropy_ctxt->s_cabac_ctxt.u4_bits_estimated_q12 -
1834 u4_bits_eztimated);
1835 }
1836 else
1837 {
1838 ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_inter +=
1839 (ps_entropy_ctxt->s_cabac_ctxt.u4_bits_estimated_q12 -
1840 u4_bits_eztimated);
1841 }
1842 // clang-format on
1843 }
1844 }
1845 else
1846 { //TODO: //PCM not supported in this encoder
1847 }
1848
1849 /* update cu_idx, left and top arrays for cudepth after encoding cu */
1850 ps_entropy_ctxt->i4_cu_idx++;
1851 for(i = 0; i < (cu_size >> 3); i++)
1852 {
1853 pu1_cu_depth_top[(x0_frm >> 3) + i] = ct_depth;
1854 pu1_cu_depth_left[((y0_frm >> 3) & 0x7) + i] = ct_depth;
1855 }
1856 }
1857
1858 return ret;
1859 }
1860
1861 /**
1862 ******************************************************************************
1863 *
1864 * @brief Encodes slice data (General Slice syntax) as per section 7.3.6.1
1865 *
1866 * @par Description
1867 * Entropy encode of all ctbs in a slice as per section 7.3.6.1
1868 *
1869 * @param[inout] ps_entropy_ctxt
1870 * pointer to entropy context (handle)
1871 *
1872 * @return success or failure error code
1873 *
1874 ******************************************************************************
1875 */
ihevce_encode_slice_data(entropy_context_t * ps_entropy_ctxt,ihevce_tile_params_t * ps_tile_params,WORD32 * pi4_end_of_slice_flag)1876 WORD32 ihevce_encode_slice_data(
1877 entropy_context_t *ps_entropy_ctxt,
1878 ihevce_tile_params_t *ps_tile_params,
1879 WORD32 *pi4_end_of_slice_flag)
1880 {
1881 WORD32 ret = IHEVCE_SUCCESS;
1882 WORD32 end_of_slice_seg_flag = 0;
1883 sps_t *ps_sps = ps_entropy_ctxt->ps_sps;
1884 pps_t *ps_pps = ps_entropy_ctxt->ps_pps;
1885 slice_header_t *ps_slice_hdr = ps_entropy_ctxt->ps_slice_hdr;
1886
1887 cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
1888
1889 /* State of previous CTB before it's terminate bin is encoded */
1890 cab_ctxt_t s_cabac_prev_ctb;
1891
1892 /* State after current CTB's encoding is complete but before
1893 the termintate bin encoding */
1894 cab_ctxt_t s_cabac_after_ctb;
1895
1896 /* Storing the last 4 bytes before adding terminate bin
1897 as these 4 bytes might get corrupted while encoding terminate bin */
1898 UWORD32 u4_prev_ctb_temp, u4_cur_ctb_temp;
1899 WORD8 i1_last_cu_qp = 0;
1900 bitstrm_t *ps_bit_strm = &ps_entropy_ctxt->s_bit_strm;
1901
1902 WORD32 log2_ctb_size, ctb_size;
1903 //WORD32 pic_width = ps_sps->i2_pic_width_in_luma_samples;
1904 //WORD32 pic_height = ps_sps->i2_pic_height_in_luma_samples;
1905 WORD32 pic_width = ps_tile_params->i4_curr_tile_width;
1906 WORD32 pic_height = ps_tile_params->i4_curr_tile_height;
1907 WORD32 num_ctb_in_row;
1908
1909 WORD32 i4_curr_ctb_x, i4_curr_ctb_y;
1910 UWORD32 u4_slice_seg_hdr_size = (UWORD32)ps_entropy_ctxt->i4_slice_seg_len;
1911 UWORD32 u4_slice_start_offset = ps_bit_strm->u4_strm_buf_offset - u4_slice_seg_hdr_size;
1912
1913 WORD32 ctb_slice_address = ps_slice_hdr->i2_slice_address;
1914 WORD32 slice_qp = ps_slice_hdr->i1_slice_qp_delta + ps_pps->i1_pic_init_qp;
1915 WORD32 cabac_init_idc;
1916 WORD32 x0_frm, y0_frm;
1917 ctb_enc_loop_out_t *ps_first_ctb; // Points to first CTB of ctb-row
1918 ctb_enc_loop_out_t *ps_ctb;
1919 WORD32 ctb_ctr = 0; //count ctb encoded in a ctb-row
1920
1921 ihevce_sys_api_t *ps_sys_api = (ihevce_sys_api_t *)ps_entropy_ctxt->pv_sys_api;
1922
1923 /* Structure to backup pic info in case we need to revert back to pervious
1924 CTB when i4_slice_segment_mode is 2 */
1925 s_pic_level_acc_info_t s_pic_level_info_backup; // info before
1926
1927 /* Initialize the CTB size from sps parameters */
1928 log2_ctb_size =
1929 ps_sps->i1_log2_min_coding_block_size + ps_sps->i1_log2_diff_max_min_coding_block_size;
1930
1931 ctb_size = (1 << log2_ctb_size);
1932
1933 /* sanity checks */
1934 ASSERT((log2_ctb_size >= 3) && (log2_ctb_size <= 6));
1935
1936 ps_entropy_ctxt->i1_log2_ctb_size = (WORD8)log2_ctb_size;
1937
1938 /* Initiallise before starting slice. For single slice case both
1939 x and y will be set to zero */
1940 ps_entropy_ctxt->i4_ctb_x = ps_entropy_ctxt->i4_next_slice_seg_x;
1941 ps_entropy_ctxt->i4_ctb_y = ps_entropy_ctxt->i4_next_slice_seg_y;
1942 num_ctb_in_row = (ps_sps->i2_pic_width_in_luma_samples + ctb_size - 1) >> log2_ctb_size;
1943
1944 /* initialize the cabac init idc based on slice type */
1945 if(ps_slice_hdr->i1_slice_type == ISLICE)
1946 {
1947 cabac_init_idc = 0;
1948 }
1949 else if(ps_slice_hdr->i1_slice_type == PSLICE)
1950 {
1951 cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 2 : 1;
1952 }
1953 else
1954 {
1955 cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 1 : 2;
1956 }
1957 ps_cabac->i1_entropy_coding_sync_enabled_flag = ps_pps->i1_entropy_coding_sync_enabled_flag;
1958
1959 /* Dependent slices should be ON only when slice segment mode is enabled */
1960 if(ps_slice_hdr->i1_dependent_slice_flag == 1)
1961 {
1962 ASSERT(
1963 (ps_entropy_ctxt->i4_slice_segment_mode == 1) ||
1964 (ps_entropy_ctxt->i4_slice_segment_mode == 2));
1965 }
1966
1967 /* initialize the cabac engine. For dependent slice segments
1968 cabac context models will not be reset */
1969 if(ps_slice_hdr->i1_dependent_slice_flag == 1)
1970 {
1971 ret = ihevce_cabac_reset(ps_cabac, ps_bit_strm, CABAC_MODE_ENCODE_BITS);
1972 }
1973 else
1974 {
1975 ret = ihevce_cabac_init(
1976 ps_cabac,
1977 ps_bit_strm,
1978 CLIP3(slice_qp, 0, IHEVC_MAX_QP),
1979 cabac_init_idc,
1980 CABAC_MODE_ENCODE_BITS);
1981
1982 /* initialize qp to slice start qp */
1983 ps_entropy_ctxt->i1_cur_qp = slice_qp;
1984 }
1985
1986 /* initialize slice x and y offset in pels w.r.t top left conrner */
1987 x0_frm = ps_entropy_ctxt->i4_ctb_x << log2_ctb_size;
1988 y0_frm = ps_entropy_ctxt->i4_ctb_y << log2_ctb_size;
1989
1990 /* Pointing ctb structure to the correct CTB in frame based on
1991 slice address */
1992 ps_first_ctb = ps_entropy_ctxt->ps_frm_ctb + ctb_slice_address;
1993 ps_ctb = ps_first_ctb - 1;
1994
1995 //ps_entropy_ctxt->i4_ctb_slice_x = 0;
1996 //ps_entropy_ctxt->i4_ctb_slice_y = 0;
1997
1998 /* Setting to NULL to detect if first CTB of slice itself
1999 exceeds the i4_slice_segment_max_length. Will be used only if
2000 i4_slice_segment_mode is non-zero */
2001 s_cabac_prev_ctb.pu1_strm_buffer = NULL;
2002
2003 do
2004 {
2005 UWORD8 au1_cu_depth_top[8] = { 0 }, au1_cu_depth_left[8] = { 0 };
2006 UWORD8 u1_skip_cu_top = 0;
2007 UWORD32 u4_skip_cu_left = 0;
2008
2009 /* By default assume that slice-segment is going to end after
2010 current CTB */
2011 end_of_slice_seg_flag = 1;
2012
2013 i4_curr_ctb_x = ps_entropy_ctxt->i4_ctb_x;
2014 i4_curr_ctb_y = ps_entropy_ctxt->i4_ctb_y;
2015
2016 if(1 == ps_tile_params->i4_tiles_enabled_flag)
2017 {
2018 ps_ctb = ps_first_ctb + ctb_ctr;
2019 }
2020 else
2021 {
2022 ps_ctb++;
2023 }
2024
2025 /* Store some parameters. Will be used if current CTB's encoding
2026 has to be reverted in the event of overflow beyond i4_slice_segment_max_length */
2027 if(2 == ps_entropy_ctxt->i4_slice_segment_mode)
2028 {
2029 /* Store CU depths flag */
2030 memcpy(au1_cu_depth_top, &ps_entropy_ctxt->pu1_cu_depth_top[i4_curr_ctb_x * 8], 8);
2031 memcpy(au1_cu_depth_left, ps_entropy_ctxt->au1_cu_depth_left, 8);
2032
2033 /* Store CU skip flags */
2034 u1_skip_cu_top = *(ps_entropy_ctxt->pu1_skip_cu_top + i4_curr_ctb_x);
2035 u4_skip_cu_left = ps_entropy_ctxt->u4_skip_cu_left;
2036
2037 /* Backup current state of pic info */
2038 s_pic_level_info_backup = *(ps_entropy_ctxt->ps_pic_level_info);
2039 }
2040
2041 /* Section:7.3.7 Coding tree unit syntax */
2042 /* coding_tree_unit() inlined here */
2043 ps_entropy_ctxt->i1_ctb_num_pcm_blks = 0;
2044
2045 /* Simple Neigbour avail calculation */
2046 ps_ctb->s_ctb_nbr_avail_flags.u1_left_avail = (x0_frm > 0);
2047 ps_ctb->s_ctb_nbr_avail_flags.u1_top_avail = (y0_frm > 0);
2048
2049 ps_entropy_ctxt->i4_cu_idx = 0;
2050
2051 /* Encode SAO syntax as per section 7.3.8.3 */
2052 if(ps_sps->i1_sample_adaptive_offset_enabled_flag)
2053 {
2054 if((ps_slice_hdr->i1_slice_sao_luma_flag) || (ps_slice_hdr->i1_slice_sao_chroma_flag))
2055 {
2056 /*PIC INFO: SAO encode biys*/
2057 UWORD32 u4_bits_estimated_prev =
2058 ps_entropy_ctxt->s_cabac_ctxt.u4_bits_estimated_q12;
2059
2060 ret |= ihevce_cabac_encode_sao(ps_entropy_ctxt, ps_ctb);
2061
2062 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
2063 {
2064 ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_sao +=
2065 (ps_entropy_ctxt->s_cabac_ctxt.u4_bits_estimated_q12 -
2066 u4_bits_estimated_prev);
2067 }
2068 }
2069 }
2070
2071 ps_entropy_ctxt->s_cabac_ctxt.u4_bits_estimated_q12 = 0;
2072
2073 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
2074 {
2075 /*PIC_INFO: Update total no.of CUS*/
2076 ps_entropy_ctxt->ps_pic_level_info->i8_total_cu += ps_ctb->u1_num_cus_in_ctb;
2077 }
2078 /* call recursive coding tree structure to encode all cus in ctb */
2079 ret |= ihevce_encode_coding_quadtree(
2080 ps_entropy_ctxt, x0_frm, y0_frm, log2_ctb_size, 0, ps_ctb, ps_tile_params);
2081
2082 /* post ctb encode increments */
2083 ctb_ctr++;
2084 x0_frm += ctb_size;
2085 ps_entropy_ctxt->i4_ctb_x++;
2086 //ps_entropy_ctxt->i4_ctb_slice_x++;
2087
2088 if(ps_pps->i1_entropy_coding_sync_enabled_flag && ps_entropy_ctxt->i4_ctb_x == 2)
2089 {
2090 /*backup cabac context at end of second CTB(top right neighbour for start of bottom row)*/
2091 ihevce_cabac_ctxt_backup(ps_cabac);
2092 }
2093
2094 /* end of row check using x0_frm offset */
2095 if(x0_frm >= pic_width)
2096 {
2097 ctb_ctr = 0;
2098 ps_first_ctb += num_ctb_in_row;
2099 x0_frm = 0;
2100 y0_frm += ctb_size;
2101
2102 ps_entropy_ctxt->i4_ctb_x = 0;
2103 ps_entropy_ctxt->i4_ctb_y++;
2104 //ps_entropy_ctxt->i4_ctb_slice_y++;
2105 }
2106
2107 /* Detect end of slice. Which would mean end-of-slice-segment too */
2108 *pi4_end_of_slice_flag = (y0_frm >= pic_height);
2109
2110 if(0 == ps_entropy_ctxt->i4_slice_segment_mode)
2111 {
2112 /* If slice ends then so does slice segment */
2113 end_of_slice_seg_flag = *pi4_end_of_slice_flag;
2114
2115 /* encode terminate bin */
2116 ret |= ihevce_cabac_encode_terminate(ps_cabac, end_of_slice_seg_flag, 0);
2117 }
2118 else if(1 == ps_entropy_ctxt->i4_slice_segment_mode)
2119 {
2120 ps_entropy_ctxt->i4_slice_seg_len++;
2121 if((ps_entropy_ctxt->i4_slice_seg_len) >= ps_entropy_ctxt->i4_slice_segment_max_length)
2122 {
2123 /* Store the address of CTB from where next slice segment will start */
2124 ps_entropy_ctxt->i4_next_slice_seg_x = ps_entropy_ctxt->i4_ctb_x;
2125 ps_entropy_ctxt->i4_next_slice_seg_y = ps_entropy_ctxt->i4_ctb_y;
2126 }
2127 else
2128 {
2129 /* If slice ends then so does slice segment */
2130 end_of_slice_seg_flag = *pi4_end_of_slice_flag;
2131 }
2132
2133 /* encode terminate bin */
2134 ret |= ihevce_cabac_encode_terminate(ps_cabac, end_of_slice_seg_flag, 0);
2135 }
2136 else if(2 == ps_entropy_ctxt->i4_slice_segment_mode)
2137 {
2138 //WORD32 i4_slice_seg_len_prev = i4_slice_seg_len;
2139
2140 /* Store some parameters. Will be used to revert back to this state if
2141 i4_slice_segment_max_length is not exceeded after encoding end-of-slice */
2142 s_cabac_after_ctb = *ps_cabac;
2143 u4_cur_ctb_temp =
2144 *((UWORD32 *)(ps_cabac->pu1_strm_buffer + ps_cabac->u4_strm_buf_offset - 4));
2145
2146 /* encode terminate bin. For dependent slices, always simulate
2147 end-of-slice to check if i4_slice_segment_max_length is surpassed */
2148 ret |= ihevce_cabac_encode_terminate(ps_cabac, 1, 0);
2149
2150 //i4_slice_seg_len_prev = i4_slice_seg_len;
2151 ps_entropy_ctxt->i4_slice_seg_len =
2152 (WORD32)(ps_cabac->u4_strm_buf_offset - u4_slice_start_offset);
2153
2154 //ps_entropy_ctxt->i4_slice_seg_len = i4_slice_seg_len; //No need to update it.
2155
2156 if(ps_entropy_ctxt->i4_slice_seg_len > ps_entropy_ctxt->i4_slice_segment_max_length)
2157 {
2158 if(s_cabac_prev_ctb.pu1_strm_buffer == NULL)
2159 {
2160 /* Bytes in a single CTB has exceeded the i4_slice_segment_max_length
2161 set by the user. Close the slice-segment and print a warning */
2162
2163 /* Store the address of CTB from where next slice segment will start */
2164 ps_entropy_ctxt->i4_next_slice_seg_x = ps_entropy_ctxt->i4_ctb_x;
2165 ps_entropy_ctxt->i4_next_slice_seg_y = ps_entropy_ctxt->i4_ctb_y;
2166
2167 ps_sys_api->ihevce_printf(
2168 ps_sys_api->pv_cb_handle,
2169 "IHEVCE_WARNING: CTB(%2d, %2d) encoded using %d bytes; "
2170 "this exceeds max slice segment size %d as requested "
2171 "by the user\n",
2172 i4_curr_ctb_x,
2173 i4_curr_ctb_y,
2174 ps_entropy_ctxt->i4_slice_seg_len,
2175 ps_entropy_ctxt->i4_slice_segment_max_length);
2176 }
2177 else /* Revert back to previous CTB's state and close current slice */
2178 {
2179 *ps_cabac = s_cabac_prev_ctb;
2180 *((UWORD32 *)(ps_cabac->pu1_strm_buffer + ps_cabac->u4_strm_buf_offset - 4)) =
2181 u4_prev_ctb_temp;
2182
2183 memcpy(
2184 &ps_entropy_ctxt->pu1_cu_depth_top[i4_curr_ctb_x * 8], au1_cu_depth_top, 8);
2185 memcpy(ps_entropy_ctxt->au1_cu_depth_left, au1_cu_depth_left, 8);
2186
2187 *(ps_entropy_ctxt->pu1_skip_cu_top + i4_curr_ctb_x) = u1_skip_cu_top;
2188 ps_entropy_ctxt->u4_skip_cu_left = u4_skip_cu_left;
2189
2190 ps_entropy_ctxt->i1_cur_qp = i1_last_cu_qp;
2191
2192 /* Restore pic info */
2193 *(ps_entropy_ctxt->ps_pic_level_info) = s_pic_level_info_backup;
2194
2195 /* encode terminate bin with end-of-slice */
2196 ret |= ihevce_cabac_encode_terminate(ps_cabac, 1, 0);
2197
2198 /* Store the address of CTB from where next slice segment will start */
2199 ps_entropy_ctxt->i4_next_slice_seg_x = i4_curr_ctb_x;
2200 ps_entropy_ctxt->i4_next_slice_seg_y = i4_curr_ctb_y;
2201
2202 /* As we are reverted back to the previous CTB, force end of slice to zero */
2203 *pi4_end_of_slice_flag = 0;
2204 }
2205 }
2206 else if(0 == *pi4_end_of_slice_flag)
2207 {
2208 /* As this is not the end of slice, therefore revert back
2209 the end-of-slice encoding and then add terminate bit */
2210
2211 /* Signal that this is not slice segment end */
2212 end_of_slice_seg_flag = 0;
2213
2214 *ps_cabac = s_cabac_after_ctb;
2215 *((UWORD32 *)(ps_cabac->pu1_strm_buffer + ps_cabac->u4_strm_buf_offset - 4)) =
2216 u4_cur_ctb_temp;
2217
2218 /* encode terminate bin */
2219 ret |= ihevce_cabac_encode_terminate(ps_cabac, 0, 0);
2220 }
2221
2222 /* Update variables storing previous CTB's state in order to be
2223 able to revert to previous CTB's state */
2224 s_cabac_prev_ctb = s_cabac_after_ctb;
2225 u4_prev_ctb_temp = u4_cur_ctb_temp;
2226
2227 i1_last_cu_qp = ps_entropy_ctxt->i1_cur_qp;
2228 }
2229 else //No other slice segment mode supported
2230 {
2231 ASSERT(0);
2232 }
2233
2234 AEV_TRACE("end_of_slice_flag", end_of_slice_seg_flag, ps_cabac->u4_range);
2235
2236 if((0 == ps_entropy_ctxt->i4_ctb_x) && (!end_of_slice_seg_flag) &&
2237 (ps_pps->i1_entropy_coding_sync_enabled_flag))
2238 {
2239 /* initialize qp to slice start qp */
2240 ps_entropy_ctxt->i1_cur_qp = slice_qp;
2241
2242 /* flush and align to byte bounary for entropy sync every row */
2243 ret |= ihevce_cabac_encode_terminate(ps_cabac, 1, 1);
2244
2245 /*This will be entered only during row end, tap bits generated in that row to cal entry point offset*/
2246 /*add error check to make sure row count doesnt exceed the size of array allocated*/
2247 ASSERT(ps_entropy_ctxt->i4_ctb_y < MAX_NUM_CTB_ROWS_FRM);
2248 ps_slice_hdr->pu4_entry_point_offset[ps_entropy_ctxt->i4_ctb_y] =
2249 ps_cabac->u4_strm_buf_offset;
2250
2251 /*init the cabac context with top right neighbour*/
2252 ret |= ihevce_cabac_ctxt_row_init(ps_cabac);
2253 }
2254
2255 } while(!end_of_slice_seg_flag);
2256
2257 if(end_of_slice_seg_flag && ps_pps->i1_entropy_coding_sync_enabled_flag)
2258 {
2259 ps_slice_hdr->pu4_entry_point_offset[ps_entropy_ctxt->i4_ctb_y] =
2260 ps_cabac->u4_strm_buf_offset;
2261 }
2262
2263 return ret;
2264 }
2265