1 /*****************************************************************************
2  * This file is part of Kvazaar HEVC encoder.
3  *
4  * Copyright (c) 2021, Tampere University, ITU/ISO/IEC, project contributors
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted provided that the following conditions are met:
9  *
10  * * Redistributions of source code must retain the above copyright notice, this
11  *   list of conditions and the following disclaimer.
12  *
13  * * Redistributions in binary form must reproduce the above copyright notice, this
14  *   list of conditions and the following disclaimer in the documentation and/or
15  *   other materials provided with the distribution.
16  *
17  * * Neither the name of the Tampere University or ITU/ISO/IEC nor the names of its
18  *   contributors may be used to endorse or promote products derived from
19  *   this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
25  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND ON
28  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  * INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
31  ****************************************************************************/
32 
33 #include "encode_coding_tree.h"
34 
35 #include "cabac.h"
36 #include "context.h"
37 #include "cu.h"
38 #include "encoder.h"
39 #include "extras/crypto.h"
40 #include "global.h"
41 #include "imagelist.h"
42 #include "inter.h"
43 #include "intra.h"
44 #include "kvazaar.h"
45 #include "kvz_math.h"
46 #include "strategyselector.h"
47 #include "tables.h"
48 #include "videoframe.h"
49 
50 /**
51  * \brief Encode (X,Y) position of the last significant coefficient
52  *
53  * \param lastpos_x   X component of last coefficient
54  * \param lastpos_y   Y component of last coefficient
55  * \param width       Block width
56  * \param height      Block height
57  * \param type        plane type / luminance or chrominance
58  * \param scan        scan type (diag, hor, ver)
59  *
60  * This method encodes the X and Y component within a block of the last
61  * significant coefficient.
62  */
kvz_encode_last_significant_xy(cabac_data_t * const cabac,uint8_t lastpos_x,uint8_t lastpos_y,uint8_t width,uint8_t height,uint8_t type,uint8_t scan)63 void kvz_encode_last_significant_xy(cabac_data_t * const cabac,
64                                     uint8_t lastpos_x, uint8_t lastpos_y,
65                                     uint8_t width, uint8_t height,
66                                     uint8_t type, uint8_t scan)
67 {
68   const int index = kvz_math_floor_log2(width) - 2;
69   uint8_t ctx_offset = type ? 0 : (index * 3 + (index + 1) / 4);
70   uint8_t shift = type ? index : (index + 3) / 4;
71 
72   cabac_ctx_t *base_ctx_x = (type ? cabac->ctx.cu_ctx_last_x_chroma : cabac->ctx.cu_ctx_last_x_luma);
73   cabac_ctx_t *base_ctx_y = (type ? cabac->ctx.cu_ctx_last_y_chroma : cabac->ctx.cu_ctx_last_y_luma);
74 
75   if (scan == SCAN_VER) {
76     SWAP(lastpos_x, lastpos_y, uint8_t);
77   }
78 
79   const int group_idx_x = g_group_idx[lastpos_x];
80   const int group_idx_y = g_group_idx[lastpos_y];
81 
82   // x prefix
83   for (int last_x = 0; last_x < group_idx_x; last_x++) {
84     cabac->cur_ctx = &base_ctx_x[ctx_offset + (last_x >> shift)];
85     CABAC_BIN(cabac, 1, "last_sig_coeff_x_prefix");
86   }
87   if (group_idx_x < g_group_idx[width - 1]) {
88     cabac->cur_ctx = &base_ctx_x[ctx_offset + (group_idx_x >> shift)];
89     CABAC_BIN(cabac, 0, "last_sig_coeff_x_prefix");
90   }
91 
92   // y prefix
93   for (int last_y = 0; last_y < group_idx_y; last_y++) {
94     cabac->cur_ctx = &base_ctx_y[ctx_offset + (last_y >> shift)];
95     CABAC_BIN(cabac, 1, "last_sig_coeff_y_prefix");
96   }
97   if (group_idx_y < g_group_idx[height - 1]) {
98     cabac->cur_ctx = &base_ctx_y[ctx_offset + (group_idx_y >> shift)];
99     CABAC_BIN(cabac, 0, "last_sig_coeff_y_prefix");
100   }
101 
102   // last_sig_coeff_x_suffix
103   if (group_idx_x > 3) {
104     const int suffix = lastpos_x - g_min_in_group[group_idx_x];
105     const int bits = (group_idx_x - 2) / 2;
106     CABAC_BINS_EP(cabac, suffix, bits, "last_sig_coeff_x_suffix");
107   }
108 
109   // last_sig_coeff_y_suffix
110   if (group_idx_y > 3) {
111     const int suffix = lastpos_y - g_min_in_group[group_idx_y];
112     const int bits = (group_idx_y - 2) / 2;
113     CABAC_BINS_EP(cabac, suffix, bits, "last_sig_coeff_y_suffix");
114   }
115 }
116 
encode_transform_unit(encoder_state_t * const state,int x,int y,int depth)117 static void encode_transform_unit(encoder_state_t * const state,
118                                   int x, int y, int depth)
119 {
120   assert(depth >= 1 && depth <= MAX_PU_DEPTH);
121 
122   const videoframe_t * const frame = state->tile->frame;
123   const uint8_t width = LCU_WIDTH >> depth;
124   const uint8_t width_c = (depth == MAX_PU_DEPTH ? width : width / 2);
125 
126   const cu_info_t *cur_pu = kvz_cu_array_at_const(frame->cu_array, x, y);
127 
128   int8_t scan_idx = kvz_get_scan_order(cur_pu->type, cur_pu->intra.mode, depth);
129 
130   int cbf_y = cbf_is_set(cur_pu->cbf, depth, COLOR_Y);
131 
132   if (cbf_y) {
133     int x_local = x % LCU_WIDTH;
134     int y_local = y % LCU_WIDTH;
135     const coeff_t *coeff_y = &state->coeff->y[xy_to_zorder(LCU_WIDTH, x_local, y_local)];
136 
137     // CoeffNxN
138     // Residual Coding
139     kvz_encode_coeff_nxn(state,
140                          &state->cabac,
141                          coeff_y,
142                          width,
143                          0,
144                          scan_idx,
145                          cur_pu->tr_skip);
146   }
147 
148   if (depth == MAX_DEPTH + 1) {
149     // For size 4x4 luma transform the corresponding chroma transforms are
150     // also of size 4x4 covering 8x8 luma pixels. The residual is coded in
151     // the last transform unit.
152     if (x % 8 == 0 || y % 8 == 0) {
153       // Not the last luma transform block so there is nothing more to do.
154       return;
155     } else {
156       // Time to to code the chroma transform blocks. Move to the top-left
157       // corner of the block.
158       x -= 4;
159       y -= 4;
160       cur_pu = kvz_cu_array_at_const(frame->cu_array, x, y);
161     }
162   }
163 
164   bool chroma_cbf_set = cbf_is_set(cur_pu->cbf, depth, COLOR_U) ||
165                         cbf_is_set(cur_pu->cbf, depth, COLOR_V);
166   if (chroma_cbf_set) {
167     int x_local = (x >> 1) % LCU_WIDTH_C;
168     int y_local = (y >> 1) % LCU_WIDTH_C;
169     scan_idx = kvz_get_scan_order(cur_pu->type, cur_pu->intra.mode_chroma, depth);
170 
171     const coeff_t *coeff_u = &state->coeff->u[xy_to_zorder(LCU_WIDTH_C, x_local, y_local)];
172     const coeff_t *coeff_v = &state->coeff->v[xy_to_zorder(LCU_WIDTH_C, x_local, y_local)];
173 
174     if (cbf_is_set(cur_pu->cbf, depth, COLOR_U)) {
175       kvz_encode_coeff_nxn(state, &state->cabac, coeff_u, width_c, 2, scan_idx, 0);
176     }
177 
178     if (cbf_is_set(cur_pu->cbf, depth, COLOR_V)) {
179       kvz_encode_coeff_nxn(state, &state->cabac, coeff_v, width_c, 2, scan_idx, 0);
180     }
181   }
182 }
183 
184 /**
185  * \param encoder
186  * \param x_pu            Prediction units' x coordinate.
187  * \param y_pu            Prediction units' y coordinate.
188  * \param depth           Depth from LCU.
189  * \param tr_depth        Depth from last CU.
190  * \param parent_coeff_u  What was signaled at previous level for cbf_cb.
191  * \param parent_coeff_v  What was signlaed at previous level for cbf_cr.
192  */
encode_transform_coeff(encoder_state_t * const state,int32_t x,int32_t y,int8_t depth,int8_t tr_depth,uint8_t parent_coeff_u,uint8_t parent_coeff_v)193 static void encode_transform_coeff(encoder_state_t * const state,
194                                    int32_t x,
195                                    int32_t y,
196                                    int8_t depth,
197                                    int8_t tr_depth,
198                                    uint8_t parent_coeff_u,
199                                    uint8_t parent_coeff_v)
200 {
201   cabac_data_t * const cabac = &state->cabac;
202   const encoder_control_t *const ctrl = state->encoder_control;
203   const videoframe_t * const frame = state->tile->frame;
204 
205   const cu_info_t *cur_pu = kvz_cu_array_at_const(frame->cu_array, x, y);
206   // Round coordinates down to a multiple of 8 to get the location of the
207   // containing CU.
208   const int x_cu = 8 * (x / 8);
209   const int y_cu = 8 * (y / 8);
210   const cu_info_t *cur_cu = kvz_cu_array_at_const(frame->cu_array, x_cu, y_cu);
211 
212   // NxN signifies implicit transform split at the first transform level.
213   // There is a similar implicit split for inter, but it is only used when
214   // transform hierarchy is not in use.
215   int intra_split_flag = (cur_cu->type == CU_INTRA && cur_cu->part_size == SIZE_NxN);
216 
217   // The implicit split by intra NxN is not counted towards max_tr_depth.
218   int max_tr_depth;
219   if (cur_cu->type == CU_INTRA) {
220     max_tr_depth = ctrl->cfg.tr_depth_intra + intra_split_flag;
221   } else {
222     max_tr_depth = ctrl->tr_depth_inter;
223   }
224 
225   int8_t split = (cur_cu->tr_depth > depth);
226 
227   const int cb_flag_y = cbf_is_set(cur_pu->cbf, depth, COLOR_Y);
228   const int cb_flag_u = cbf_is_set(cur_cu->cbf, depth, COLOR_U);
229   const int cb_flag_v = cbf_is_set(cur_cu->cbf, depth, COLOR_V);
230 
231   // The split_transform_flag is not signaled when:
232   // - transform size is greater than 32 (depth == 0)
233   // - transform size is 4 (depth == MAX_PU_DEPTH)
234   // - transform depth is max
235   // - cu is intra NxN and it's the first split
236   if (depth > 0 &&
237       depth < MAX_PU_DEPTH &&
238       tr_depth < max_tr_depth &&
239       !(intra_split_flag && tr_depth == 0))
240   {
241     cabac->cur_ctx = &(cabac->ctx.trans_subdiv_model[5 - ((kvz_g_convert_to_bit[LCU_WIDTH] + 2) - depth)]);
242     CABAC_BIN(cabac, split, "split_transform_flag");
243   }
244 
245   // Chroma cb flags are not signaled when one of the following:
246   // - transform size is 4 (2x2 chroma transform doesn't exist)
247   // - they have already been signaled to 0 previously
248   // When they are not present they are inferred to be 0, except for size 4
249   // when the flags from previous level are used.
250   if (depth < MAX_PU_DEPTH && state->encoder_control->chroma_format != KVZ_CSP_400) {
251     cabac->cur_ctx = &(cabac->ctx.qt_cbf_model_chroma[tr_depth]);
252     if (tr_depth == 0 || parent_coeff_u) {
253       CABAC_BIN(cabac, cb_flag_u, "cbf_cb");
254     }
255     if (tr_depth == 0 || parent_coeff_v) {
256       CABAC_BIN(cabac, cb_flag_v, "cbf_cr");
257     }
258   }
259 
260   if (split) {
261     uint8_t offset = LCU_WIDTH >> (depth + 1);
262     int x2 = x + offset;
263     int y2 = y + offset;
264     encode_transform_coeff(state, x,  y,  depth + 1, tr_depth + 1, cb_flag_u, cb_flag_v);
265     encode_transform_coeff(state, x2, y,  depth + 1, tr_depth + 1, cb_flag_u, cb_flag_v);
266     encode_transform_coeff(state, x,  y2, depth + 1, tr_depth + 1, cb_flag_u, cb_flag_v);
267     encode_transform_coeff(state, x2, y2, depth + 1, tr_depth + 1, cb_flag_u, cb_flag_v);
268     return;
269   }
270 
271   // Luma coded block flag is signaled when one of the following:
272   // - prediction mode is intra
273   // - transform depth > 0
274   // - we have chroma coefficients at this level
275   // When it is not present, it is inferred to be 1.
276   if (cur_cu->type == CU_INTRA || tr_depth > 0 || cb_flag_u || cb_flag_v) {
277       cabac->cur_ctx = &(cabac->ctx.qt_cbf_model_luma[!tr_depth]);
278       CABAC_BIN(cabac, cb_flag_y, "cbf_luma");
279   }
280 
281   if (cb_flag_y | cb_flag_u | cb_flag_v) {
282     if (state->must_code_qp_delta) {
283       const int qp_pred      = kvz_get_cu_ref_qp(state, x_cu, y_cu, state->last_qp);
284       const int qp_delta     = cur_cu->qp - qp_pred;
285       // Possible deltaQP range depends on bit depth as stated in HEVC specification.
286       assert(qp_delta >= KVZ_QP_DELTA_MIN && qp_delta <= KVZ_QP_DELTA_MAX && "QP delta not in valid range.");
287 
288       const int qp_delta_abs = ABS(qp_delta);
289       cabac_data_t* cabac    = &state->cabac;
290 
291       // cu_qp_delta_abs prefix
292       cabac->cur_ctx = &cabac->ctx.cu_qp_delta_abs[0];
293       kvz_cabac_write_unary_max_symbol(cabac, cabac->ctx.cu_qp_delta_abs, MIN(qp_delta_abs, 5), 1, 5);
294 
295       if (qp_delta_abs >= 5) {
296         // cu_qp_delta_abs suffix
297         kvz_cabac_write_ep_ex_golomb(state, cabac, qp_delta_abs - 5, 0);
298       }
299 
300       if (qp_delta != 0) {
301         CABAC_BIN_EP(cabac, (qp_delta >= 0 ? 0 : 1), "qp_delta_sign_flag");
302       }
303 
304       state->must_code_qp_delta = false;
305     }
306 
307     encode_transform_unit(state, x, y, depth);
308   }
309 }
310 
encode_inter_prediction_unit(encoder_state_t * const state,cabac_data_t * const cabac,const cu_info_t * const cur_cu,int x,int y,int width,int height,int depth)311 static void encode_inter_prediction_unit(encoder_state_t * const state,
312                                          cabac_data_t * const cabac,
313                                          const cu_info_t * const cur_cu,
314                                          int x, int y, int width, int height,
315                                          int depth)
316 {
317   // Mergeflag
318   int16_t num_cand = 0;
319   cabac->cur_ctx = &(cabac->ctx.cu_merge_flag_ext_model);
320   CABAC_BIN(cabac, cur_cu->merged, "MergeFlag");
321   num_cand = state->encoder_control->cfg.max_merge;
322   if (cur_cu->merged) { //merge
323     if (num_cand > 1) {
324       int32_t ui;
325       for (ui = 0; ui < num_cand - 1; ui++) {
326         int32_t symbol = (ui != cur_cu->merge_idx);
327         if (ui == 0) {
328           cabac->cur_ctx = &(cabac->ctx.cu_merge_idx_ext_model);
329           CABAC_BIN(cabac, symbol, "MergeIndex");
330         } else {
331           CABAC_BIN_EP(cabac,symbol,"MergeIndex");
332         }
333         if (symbol == 0) break;
334       }
335     }
336   } else {
337     if (state->frame->slicetype == KVZ_SLICE_B) {
338       // Code Inter Dir
339       uint8_t inter_dir = cur_cu->inter.mv_dir-1;
340 
341       if (cur_cu->part_size == SIZE_2Nx2N || (LCU_WIDTH >> depth) != 8) {
342         cabac->cur_ctx = &(cabac->ctx.inter_dir[depth]);
343         CABAC_BIN(cabac, (inter_dir == 2), "inter_pred_idc");
344       }
345       if (inter_dir < 2) {
346         cabac->cur_ctx = &(cabac->ctx.inter_dir[4]);
347         CABAC_BIN(cabac, inter_dir, "inter_pred_idc");
348       }
349     }
350 
351     for (uint32_t ref_list_idx = 0; ref_list_idx < 2; ref_list_idx++) {
352       if (!(cur_cu->inter.mv_dir & (1 << ref_list_idx))) {
353         continue;
354       }
355 
356       // size of the current reference index list (L0/L1)
357       uint8_t ref_LX_size = state->frame->ref_LX_size[ref_list_idx];
358 
359       if (ref_LX_size > 1) {
360         // parseRefFrmIdx
361         int32_t ref_frame = cur_cu->inter.mv_ref[ref_list_idx];
362 
363         cabac->cur_ctx = &(cabac->ctx.cu_ref_pic_model[0]);
364         CABAC_BIN(cabac, (ref_frame != 0), "ref_idx_lX");
365 
366         if (ref_frame > 0) {
367           ref_frame--;
368 
369           int32_t ref_num = ref_LX_size - 2;
370 
371           for (int32_t i = 0; i < ref_num; ++i) {
372             const uint32_t symbol = (i == ref_frame) ? 0 : 1;
373 
374             if (i == 0) {
375               cabac->cur_ctx = &cabac->ctx.cu_ref_pic_model[1];
376               CABAC_BIN(cabac, symbol, "ref_idx_lX");
377             } else {
378               CABAC_BIN_EP(cabac, symbol, "ref_idx_lX");
379             }
380             if (symbol == 0) break;
381           }
382         }
383       }
384 
385       if (state->frame->ref_list != REF_PIC_LIST_1 || cur_cu->inter.mv_dir != 3) {
386 
387         int16_t mv_cand[2][2];
388         kvz_inter_get_mv_cand_cua(
389             state,
390             x, y, width, height,
391             mv_cand, cur_cu, ref_list_idx);
392 
393         uint8_t cu_mv_cand = CU_GET_MV_CAND(cur_cu, ref_list_idx);
394         const int32_t mvd_hor = cur_cu->inter.mv[ref_list_idx][0] - mv_cand[cu_mv_cand][0];
395         const int32_t mvd_ver = cur_cu->inter.mv[ref_list_idx][1] - mv_cand[cu_mv_cand][1];
396 
397         kvz_encode_mvd(state, cabac, mvd_hor, mvd_ver);
398       }
399 
400       // Signal which candidate MV to use
401       kvz_cabac_write_unary_max_symbol(cabac,
402                                        cabac->ctx.mvp_idx_model,
403                                        CU_GET_MV_CAND(cur_cu, ref_list_idx),
404                                        1,
405                                        AMVP_MAX_NUM_CANDS - 1);
406 
407     } // for ref_list
408   } // if !merge
409 }
410 
411 
intra_mode_encryption(encoder_state_t * const state,uint8_t intra_pred_mode)412 static INLINE uint8_t intra_mode_encryption(encoder_state_t * const state,
413                                             uint8_t intra_pred_mode)
414 {
415   const uint8_t sets[3][17] =
416   {
417     {  0,  1,  2,  3,  4,  5, 15, 16, 17, 18, 19, 20, 21, 31, 32, 33, 34},  /* 17 */
418     { 22, 23, 24, 25, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1},  /* 9  */
419     {  6,  7,  8,  9, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1}   /* 9  */
420   };
421 
422   const uint8_t nb_elems[3] = {17, 8, 8};
423 
424   if (intra_pred_mode == 26 || intra_pred_mode == 10) {
425     // correct chroma intra prediction mode
426     return intra_pred_mode;
427 
428   } else {
429     uint8_t keybits, scan_dir, elem_idx=0;
430 
431     keybits = kvz_crypto_get_key(state->crypto_hdl, 5);
432 
433     scan_dir = SCAN_DIAG;
434     if (intra_pred_mode > 5  && intra_pred_mode < 15) {
435       scan_dir = SCAN_VER;
436     }
437     if (intra_pred_mode > 21 && intra_pred_mode < 31) {
438       scan_dir = SCAN_HOR;
439     }
440 
441     for (int i = 0; i < nb_elems[scan_dir]; i++) {
442       if (intra_pred_mode == sets[scan_dir][i]) {
443         elem_idx = i;
444         break;
445       }
446     }
447 
448     keybits = keybits % nb_elems[scan_dir];
449     keybits = (elem_idx + keybits) % nb_elems[scan_dir];
450 
451     return sets[scan_dir][keybits];
452   }
453 }
454 
455 
encode_intra_coding_unit(encoder_state_t * const state,cabac_data_t * const cabac,const cu_info_t * const cur_cu,int x,int y,int depth)456 static void encode_intra_coding_unit(encoder_state_t * const state,
457                                      cabac_data_t * const cabac,
458                                      const cu_info_t * const cur_cu,
459                                      int x, int y, int depth)
460 {
461   const videoframe_t * const frame = state->tile->frame;
462   uint8_t intra_pred_mode_actual[4];
463   uint8_t *intra_pred_mode = intra_pred_mode_actual;
464 
465 #if KVZ_SEL_ENCRYPTION
466   const bool do_crypto =
467     !state->cabac.only_count &&
468     state->encoder_control->cfg.crypto_features & KVZ_CRYPTO_INTRA_MODE;
469 #else
470   const bool do_crypto = false;
471 #endif
472 
473   uint8_t intra_pred_mode_encry[4] = {-1, -1, -1, -1};
474   if (do_crypto) {
475     intra_pred_mode = intra_pred_mode_encry;
476   }
477 
478   uint8_t intra_pred_mode_chroma = cur_cu->intra.mode_chroma;
479   int8_t intra_preds[4][3] = {{-1, -1, -1},{-1, -1, -1},{-1, -1, -1},{-1, -1, -1}};
480   int8_t mpm_preds[4] = {-1, -1, -1, -1};
481   uint32_t flag[4];
482 
483   #if ENABLE_PCM == 1
484   // Code must start after variable initialization
485   kvz_cabac_encode_bin_trm(cabac, 0); // IPCMFlag == 0
486   #endif
487 
488   // PREDINFO CODING
489   // If intra prediction mode is found from the predictors,
490   // it can be signaled with two EP's. Otherwise we can send
491   // 5 EP bins with the full predmode
492   const int num_pred_units = kvz_part_mode_num_parts[cur_cu->part_size];
493   const int cu_width = LCU_WIDTH >> depth;
494 
495   for (int j = 0; j < num_pred_units; ++j) {
496     const int pu_x = PU_GET_X(cur_cu->part_size, cu_width, x, j);
497     const int pu_y = PU_GET_Y(cur_cu->part_size, cu_width, y, j);
498     const cu_info_t *cur_pu = kvz_cu_array_at_const(frame->cu_array, pu_x, pu_y);
499 
500     const cu_info_t *left_pu = NULL;
501     const cu_info_t *above_pu = NULL;
502 
503     if (pu_x > 0) {
504       assert(pu_x >> 2 > 0);
505       left_pu = kvz_cu_array_at_const(frame->cu_array, pu_x - 1, pu_y);
506     }
507     // Don't take the above PU across the LCU boundary.
508     if (pu_y % LCU_WIDTH > 0 && pu_y > 0) {
509       assert(pu_y >> 2 > 0);
510       above_pu = kvz_cu_array_at_const(frame->cu_array, pu_x, pu_y - 1);
511     }
512 
513     if (do_crypto) {
514 #if KVZ_SEL_ENCRYPTION
515       // Need to wrap in preprocessor directives because this function is
516       // only defined when KVZ_SEL_ENCRYPTION is defined.
517       kvz_intra_get_dir_luma_predictor_encry(pu_x, pu_y,
518                                              intra_preds[j],
519                                              cur_pu,
520                                              left_pu, above_pu);
521 #endif
522     } else {
523       kvz_intra_get_dir_luma_predictor(pu_x, pu_y,
524                                        intra_preds[j],
525                                        cur_pu,
526                                        left_pu, above_pu);
527     }
528 
529     intra_pred_mode_actual[j] = cur_pu->intra.mode;
530     if (do_crypto) {
531       intra_pred_mode_encry[j] = intra_mode_encryption(state, cur_pu->intra.mode);
532     }
533 
534     for (int i = 0; i < 3; i++) {
535       if (intra_preds[j][i] == intra_pred_mode[j]) {
536         mpm_preds[j] = (int8_t)i;
537         break;
538       }
539     }
540     flag[j] = (mpm_preds[j] == -1) ? 0 : 1;
541 
542 #if KVZ_SEL_ENCRYPTION
543     // Need to wrap in preprocessor directives because
544     // cu_info_t.intra.mode_encry is only defined when KVZ_SEL_ENCRYPTION
545     // is defined.
546     if (do_crypto) {
547       // Set the modified intra_pred_mode of the current pu here to make it
548       // available from its neighbours for mpm decision.
549 
550       // FIXME: there might be a more efficient way to propagate mode_encry
551       // for future use from left and above PUs
552       const int pu_width = PU_GET_W(cur_cu->part_size, cu_width, j);
553       for (int y = pu_y; y < pu_y + pu_width; y += 4 ) {
554         for (int x = pu_x; x < pu_x + pu_width; x += 4) {
555           cu_info_t *cu = kvz_cu_array_at(frame->cu_array, x, y);
556           cu->intra.mode_encry = intra_pred_mode_encry[j];
557         }
558       }
559     }
560 #endif
561   }
562 
563   cabac->cur_ctx = &(cabac->ctx.intra_mode_model);
564   for (int j = 0; j < num_pred_units; ++j) {
565     CABAC_BIN(cabac, flag[j], "prev_intra_luma_pred_flag");
566   }
567 
568   for (int j = 0; j < num_pred_units; ++j) {
569     // Signal index of the prediction mode in the prediction list.
570     if (flag[j]) {
571       CABAC_BIN_EP(cabac, (mpm_preds[j] == 0 ? 0 : 1), "mpm_idx");
572       if (mpm_preds[j] != 0) {
573         CABAC_BIN_EP(cabac, (mpm_preds[j] == 1 ? 0 : 1), "mpm_idx");
574       }
575     } else {
576       // Signal the actual prediction mode.
577       int32_t tmp_pred = intra_pred_mode[j];
578 
579       // Sort prediction list from lowest to highest.
580       if (intra_preds[j][0] > intra_preds[j][1]) SWAP(intra_preds[j][0], intra_preds[j][1], int8_t);
581       if (intra_preds[j][0] > intra_preds[j][2]) SWAP(intra_preds[j][0], intra_preds[j][2], int8_t);
582       if (intra_preds[j][1] > intra_preds[j][2]) SWAP(intra_preds[j][1], intra_preds[j][2], int8_t);
583 
584       // Reduce the index of the signaled prediction mode according to the
585       // prediction list, as it has been already signaled that it's not one
586       // of the prediction modes.
587       for (int i = 2; i >= 0; i--) {
588         tmp_pred = (tmp_pred > intra_preds[j][i] ? tmp_pred - 1 : tmp_pred);
589       }
590 
591       CABAC_BINS_EP(cabac, tmp_pred, 5, "rem_intra_luma_pred_mode");
592     }
593   }
594 
595   // Code chroma prediction mode.
596   if (state->encoder_control->chroma_format != KVZ_CSP_400) {
597     unsigned pred_mode = 5;
598     unsigned chroma_pred_modes[4] = {0, 26, 10, 1};
599 
600     if (intra_pred_mode_chroma == intra_pred_mode_actual[0]) {
601       pred_mode = 4;
602     } else if (intra_pred_mode_chroma == 34) {
603       // Angular 34 mode is possible only if intra pred mode is one of the
604       // possible chroma pred modes, in which case it is signaled with that
605       // duplicate mode.
606       for (int i = 0; i < 4; ++i) {
607         if (intra_pred_mode_actual[0] == chroma_pred_modes[i]) pred_mode = i;
608       }
609     } else {
610       for (int i = 0; i < 4; ++i) {
611         if (intra_pred_mode_chroma == chroma_pred_modes[i]) pred_mode = i;
612       }
613     }
614 
615     // pred_mode == 5 mean intra_pred_mode_chroma is something that can't
616     // be coded.
617     assert(pred_mode != 5);
618 
619     /**
620      * Table 9-35 - Binarization for intra_chroma_pred_mode
621      *   intra_chroma_pred_mode  bin_string
622      *                        4           0
623      *                        0         100
624      *                        1         101
625      *                        2         110
626      *                        3         111
627      * Table 9-37 - Assignment of ctxInc to syntax elements with context coded bins
628      *   intra_chroma_pred_mode[][] = 0, bypass, bypass
629      */
630     cabac->cur_ctx = &(cabac->ctx.chroma_pred_model[0]);
631     if (pred_mode == 4) {
632       CABAC_BIN(cabac, 0, "intra_chroma_pred_mode");
633     } else {
634       CABAC_BIN(cabac, 1, "intra_chroma_pred_mode");
635       CABAC_BINS_EP(cabac, pred_mode, 2, "intra_chroma_pred_mode");
636     }
637   }
638 
639   encode_transform_coeff(state, x, y, depth, 0, 0, 0);
640 }
641 
encode_part_mode(encoder_state_t * const state,cabac_data_t * const cabac,const cu_info_t * const cur_cu,int depth)642 static void encode_part_mode(encoder_state_t * const state,
643                              cabac_data_t * const cabac,
644                              const cu_info_t * const cur_cu,
645                              int depth)
646 {
647   // Binarization from Table 9-34 of the HEVC spec:
648   //
649   //                |   log2CbSize >     |    log2CbSize ==
650   //                |   MinCbLog2SizeY   |    MinCbLog2SizeY
651   // -------+-------+----------+---------+-----------+----------
652   //  pred  | part  | AMP      | AMP     |           |
653   //  mode  | mode  | disabled | enabled | size == 8 | size > 8
654   // -------+-------+----------+---------+-----------+----------
655   //  intra | 2Nx2N |        -         - |         1          1
656   //        |   NxN |        -         - |         0          0
657   // -------+-------+--------------------+----------------------
658   //  inter | 2Nx2N |        1         1 |         1          1
659   //        |  2NxN |       01       011 |        01         01
660   //        |  Nx2N |       00       001 |        00        001
661   //        |   NxN |        -         - |         -        000
662   //        | 2NxnU |        -      0100 |         -          -
663   //        | 2NxnD |        -      0101 |         -          -
664   //        | nLx2N |        -      0000 |         -          -
665   //        | nRx2N |        -      0001 |         -          -
666   // -------+-------+--------------------+----------------------
667   //
668   //
669   // Context indices from Table 9-37 of the HEVC spec:
670   //
671   //                                      binIdx
672   //                               |  0  1  2       3
673   // ------------------------------+------------------
674   //  log2CbSize == MinCbLog2SizeY |  0  1  2  bypass
675   //  log2CbSize >  MinCbLog2SizeY |  0  1  3  bypass
676   // ------------------------------+------------------
677 
678   if (cur_cu->type == CU_INTRA) {
679     if (depth == MAX_DEPTH) {
680       cabac->cur_ctx = &(cabac->ctx.part_size_model[0]);
681       if (cur_cu->part_size == SIZE_2Nx2N) {
682         CABAC_BIN(cabac, 1, "part_mode 2Nx2N");
683       } else {
684         CABAC_BIN(cabac, 0, "part_mode NxN");
685       }
686     }
687   } else {
688 
689     cabac->cur_ctx = &(cabac->ctx.part_size_model[0]);
690     if (cur_cu->part_size == SIZE_2Nx2N) {
691       CABAC_BIN(cabac, 1, "part_mode 2Nx2N");
692       return;
693     }
694     CABAC_BIN(cabac, 0, "part_mode split");
695 
696     cabac->cur_ctx = &(cabac->ctx.part_size_model[1]);
697     if (cur_cu->part_size == SIZE_2NxN ||
698         cur_cu->part_size == SIZE_2NxnU ||
699         cur_cu->part_size == SIZE_2NxnD) {
700       CABAC_BIN(cabac, 1, "part_mode vertical");
701     } else {
702       CABAC_BIN(cabac, 0, "part_mode horizontal");
703     }
704 
705     if (state->encoder_control->cfg.amp_enable && depth < MAX_DEPTH) {
706       cabac->cur_ctx = &(cabac->ctx.part_size_model[3]);
707 
708       if (cur_cu->part_size == SIZE_2NxN ||
709           cur_cu->part_size == SIZE_Nx2N) {
710         CABAC_BIN(cabac, 1, "part_mode SMP");
711         return;
712       }
713       CABAC_BIN(cabac, 0, "part_mode AMP");
714 
715       if (cur_cu->part_size == SIZE_2NxnU ||
716           cur_cu->part_size == SIZE_nLx2N) {
717         CABAC_BINS_EP(cabac, 0, 1, "part_mode AMP");
718       } else {
719         CABAC_BINS_EP(cabac, 1, 1, "part_mode AMP");
720       }
721     }
722   }
723 }
724 
kvz_encode_coding_tree(encoder_state_t * const state,uint16_t x,uint16_t y,uint8_t depth)725 void kvz_encode_coding_tree(encoder_state_t * const state,
726                             uint16_t x,
727                             uint16_t y,
728                             uint8_t depth)
729 {
730   cabac_data_t * const cabac = &state->cabac;
731   const encoder_control_t * const ctrl = state->encoder_control;
732   const videoframe_t * const frame = state->tile->frame;
733   const cu_info_t *cur_cu   = kvz_cu_array_at_const(frame->cu_array, x, y);
734 
735   const int cu_width = LCU_WIDTH >> depth;
736   const int half_cu  = cu_width >> 1;
737 
738   const cu_info_t *left_cu  = NULL;
739   if (x > 0) {
740     left_cu = kvz_cu_array_at_const(frame->cu_array, x - 1, y);
741   }
742   const cu_info_t *above_cu = NULL;
743   if (y > 0) {
744     above_cu = kvz_cu_array_at_const(frame->cu_array, x, y - 1);
745   }
746 
747   uint8_t split_flag = GET_SPLITDATA(cur_cu, depth);
748   uint8_t split_model = 0;
749 
750   // Absolute coordinates
751   uint16_t abs_x = x + state->tile->offset_x;
752   uint16_t abs_y = y + state->tile->offset_y;
753 
754   // Check for slice border
755   bool border_x = ctrl->in.width  < abs_x + cu_width;
756   bool border_y = ctrl->in.height < abs_y + cu_width;
757   bool border_split_x = ctrl->in.width  >= abs_x + (LCU_WIDTH >> MAX_DEPTH) + half_cu;
758   bool border_split_y = ctrl->in.height >= abs_y + (LCU_WIDTH >> MAX_DEPTH) + half_cu;
759   bool border = border_x || border_y; /*!< are we in any border CU */
760 
761   if (depth <= ctrl->max_qp_delta_depth) {
762     state->must_code_qp_delta = true;
763   }
764 
765   // When not in MAX_DEPTH, insert split flag and split the blocks if needed
766   if (depth != MAX_DEPTH) {
767     // Implisit split flag when on border
768     if (!border) {
769       // Get left and top block split_flags and if they are present and true, increase model number
770       if (left_cu && GET_SPLITDATA(left_cu, depth) == 1) {
771         split_model++;
772       }
773 
774       if (above_cu && GET_SPLITDATA(above_cu, depth) == 1) {
775         split_model++;
776       }
777 
778       cabac->cur_ctx = &(cabac->ctx.split_flag_model[split_model]);
779       CABAC_BIN(cabac, split_flag, "SplitFlag");
780     }
781 
782     if (split_flag || border) {
783       // Split blocks and remember to change x and y block positions
784       kvz_encode_coding_tree(state, x, y, depth + 1);
785 
786       if (!border_x || border_split_x) {
787         kvz_encode_coding_tree(state, x + half_cu, y, depth + 1);
788       }
789       if (!border_y || border_split_y) {
790         kvz_encode_coding_tree(state, x, y + half_cu, depth + 1);
791       }
792       if (!border || (border_split_x && border_split_y)) {
793         kvz_encode_coding_tree(state, x + half_cu, y + half_cu, depth + 1);
794       }
795       return;
796     }
797   }
798 
799   if (ctrl->cfg.lossless) {
800     cabac->cur_ctx = &cabac->ctx.cu_transquant_bypass;
801     CABAC_BIN(cabac, 1, "cu_transquant_bypass_flag");
802   }
803 
804   // Encode skip flag
805   if (state->frame->slicetype != KVZ_SLICE_I) {
806     // uiCtxSkip = aboveskipped + leftskipped;
807     int8_t ctx_skip = 0;
808 
809     if (left_cu && left_cu->skipped) {
810       ctx_skip++;
811     }
812     if (above_cu && above_cu->skipped) {
813       ctx_skip++;
814     }
815 
816     cabac->cur_ctx = &(cabac->ctx.cu_skip_flag_model[ctx_skip]);
817     CABAC_BIN(cabac, cur_cu->skipped, "SkipFlag");
818 
819     if (cur_cu->skipped) {
820       int16_t num_cand = state->encoder_control->cfg.max_merge;
821       if (num_cand > 1) {
822         for (int ui = 0; ui < num_cand - 1; ui++) {
823           int32_t symbol = (ui != cur_cu->merge_idx);
824           if (ui == 0) {
825             cabac->cur_ctx = &(cabac->ctx.cu_merge_idx_ext_model);
826             CABAC_BIN(cabac, symbol, "MergeIndex");
827           } else {
828             CABAC_BIN_EP(cabac,symbol,"MergeIndex");
829           }
830           if (symbol == 0) {
831             break;
832           }
833         }
834       }
835       goto end;
836     }
837   }
838 
839   // Prediction mode
840   if (state->frame->slicetype != KVZ_SLICE_I) {
841     cabac->cur_ctx = &(cabac->ctx.cu_pred_mode_model);
842     CABAC_BIN(cabac, (cur_cu->type == CU_INTRA), "PredMode");
843   }
844 
845   // part_mode
846   encode_part_mode(state, cabac, cur_cu, depth);
847 
848   if (cur_cu->type == CU_INTER) {
849     const int num_pu = kvz_part_mode_num_parts[cur_cu->part_size];
850 
851     for (int i = 0; i < num_pu; ++i) {
852       const int pu_x = PU_GET_X(cur_cu->part_size, cu_width, x, i);
853       const int pu_y = PU_GET_Y(cur_cu->part_size, cu_width, y, i);
854       const int pu_w = PU_GET_W(cur_cu->part_size, cu_width, i);
855       const int pu_h = PU_GET_H(cur_cu->part_size, cu_width, i);
856       const cu_info_t *cur_pu = kvz_cu_array_at_const(frame->cu_array, pu_x, pu_y);
857 
858       encode_inter_prediction_unit(state, cabac, cur_pu, pu_x, pu_y, pu_w, pu_h, depth);
859     }
860 
861     {
862       int cbf = cbf_is_set_any(cur_cu->cbf, depth);
863       // Only need to signal coded block flag if not skipped or merged
864       // skip = no coded residual, merge = coded residual
865       if (cur_cu->part_size != SIZE_2Nx2N || !cur_cu->merged) {
866         cabac->cur_ctx = &(cabac->ctx.cu_qt_root_cbf_model);
867         CABAC_BIN(cabac, cbf, "rqt_root_cbf");
868       }
869       // Code (possible) coeffs to bitstream
870 
871       if (cbf) {
872         encode_transform_coeff(state, x, y, depth, 0, 0, 0);
873       }
874     }
875   } else if (cur_cu->type == CU_INTRA) {
876     encode_intra_coding_unit(state, cabac, cur_cu, x, y, depth);
877   }
878 
879 #if ENABLE_PCM
880   // Code IPCM block
881   else if (cur_cu->type == CU_PCM) {
882     kvz_cabac_encode_bin_trm(cabac, 1); // IPCMFlag == 1
883     kvz_cabac_finish(cabac);
884     kvz_bitstream_add_rbsp_trailing_bits(cabac.stream);
885 
886     // PCM sample
887     pixel *base_y = &cur_pic->y_data[x     + y * encoder->in.width];
888     pixel *base_u = &cur_pic->u_data[x / 2 + y / 2 * encoder->in.width / 2];
889     pixel *base_v = &cur_pic->v_data[x / 2 + y / 2 * encoder->in.width / 2];
890 
891     // Luma
892     for (unsigned y_px = 0; y_px < LCU_WIDTH >> depth; y_px++) {
893       for (unsigned  x_px = 0; x_px < LCU_WIDTH >> depth; x_px++) {
894         kvz_bitstream_put(cabac.stream, base_y[x_px + y_px * encoder->in.width], 8);
895       }
896     }
897 
898     // Chroma
899     if (encoder->in.video_format != FORMAT_400) {
900       for (unsigned y_px = 0; y_px < LCU_WIDTH >> (depth + 1); y_px++) {
901         for (unsigned x_px = 0; x_px < LCU_WIDTH >> (depth + 1); x_px++) {
902           kvz_bitstream_put(cabac.stream, base_u[x_px + y_px * (encoder->in.width >> 1)], 8);
903         }
904       }
905       for (unsigned y_px = 0; y_px < LCU_WIDTH >> (depth + 1); y_px++) {
906         for (unsigned x_px = 0; x_px < LCU_WIDTH >> (depth + 1); x_px++) {
907           kvz_bitstream_put(cabac.stream, base_v[x_px + y_px * (encoder->in.width >> 1)], 8);
908         }
909       }
910     }
911     kvz_cabac_start(cabac);
912   }
913 #endif
914 
915   else {
916     // CU type not set. Should not happen.
917     assert(0);
918     exit(1);
919   }
920 
921 end:
922 
923   if (is_last_cu_in_qg(state, x, y, depth)) {
924     state->last_qp = cur_cu->qp;
925   }
926 }
927 
928 
kvz_encode_mvd(encoder_state_t * const state,cabac_data_t * cabac,int32_t mvd_hor,int32_t mvd_ver)929 void kvz_encode_mvd(encoder_state_t * const state,
930                     cabac_data_t *cabac,
931                     int32_t mvd_hor,
932                     int32_t mvd_ver)
933 {
934   const int8_t hor_abs_gr0 = mvd_hor != 0;
935   const int8_t ver_abs_gr0 = mvd_ver != 0;
936   const uint32_t mvd_hor_abs = abs(mvd_hor);
937   const uint32_t mvd_ver_abs = abs(mvd_ver);
938 
939   cabac->cur_ctx = &cabac->ctx.cu_mvd_model[0];
940   CABAC_BIN(cabac, (mvd_hor != 0), "abs_mvd_greater0_flag_hor");
941   CABAC_BIN(cabac, (mvd_ver != 0), "abs_mvd_greater0_flag_ver");
942 
943   cabac->cur_ctx = &cabac->ctx.cu_mvd_model[1];
944   if (hor_abs_gr0) {
945     CABAC_BIN(cabac, (mvd_hor_abs>1), "abs_mvd_greater1_flag_hor");
946   }
947   if (ver_abs_gr0) {
948     CABAC_BIN(cabac, (mvd_ver_abs>1), "abs_mvd_greater1_flag_ver");
949   }
950 
951   if (hor_abs_gr0) {
952     if (mvd_hor_abs > 1) {
953       kvz_cabac_write_ep_ex_golomb(state, cabac, mvd_hor_abs - 2, 1);
954     }
955     uint32_t mvd_hor_sign = (mvd_hor > 0) ? 0 : 1;
956     if (!state->cabac.only_count &&
957         state->encoder_control->cfg.crypto_features & KVZ_CRYPTO_MV_SIGNS)
958     {
959       mvd_hor_sign = mvd_hor_sign ^ kvz_crypto_get_key(state->crypto_hdl, 1);
960     }
961     CABAC_BIN_EP(cabac, mvd_hor_sign, "mvd_sign_flag_hor");
962   }
963   if (ver_abs_gr0) {
964     if (mvd_ver_abs > 1) {
965       kvz_cabac_write_ep_ex_golomb(state, cabac, mvd_ver_abs - 2, 1);
966     }
967     uint32_t mvd_ver_sign = mvd_ver > 0 ? 0 : 1;
968     if (!state->cabac.only_count &&
969         state->encoder_control->cfg.crypto_features & KVZ_CRYPTO_MV_SIGNS)
970     {
971       mvd_ver_sign = mvd_ver_sign^kvz_crypto_get_key(state->crypto_hdl, 1);
972     }
973     CABAC_BIN_EP(cabac, mvd_ver_sign, "mvd_sign_flag_ver");
974   }
975 }
976