LCOV - code coverage report
Current view: top level - Codec - EbEntropyCoding.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2621 3241 80.9 %
Date: 2019-11-25 17:38:06 Functions: 179 203 88.2 %

          Line data    Source code
       1             : /*
       2             : * Copyright(c) 2019 Intel Corporation
       3             : * SPDX - License - Identifier: BSD - 2 - Clause - Patent
       4             : */
       5             : 
       6             : /*
       7             : * Copyright (c) 2016, Alliance for Open Media. All rights reserved
       8             : *
       9             : * This source code is subject to the terms of the BSD 2 Clause License and
      10             : * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
      11             : * was not distributed with this source code in the LICENSE file, you can
      12             : * obtain it at www.aomedia.org/license/software. If the Alliance for Open
      13             : * Media Patent License 1.0 was not distributed with this source code in the
      14             : * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
      15             : */
      16             : 
      17             : #include <stdlib.h>
      18             : #include <string.h>
      19             : 
      20             : #include "EbEntropyCoding.h"
      21             : #include "EbEntropyCodingUtil.h"
      22             : #include "EbUtility.h"
      23             : #include "EbCodingUnit.h"
      24             : #include "EbSvtAv1ErrorCodes.h"
      25             : #include "EbTransforms.h"
      26             : #include "EbEntropyCodingProcess.h"
      27             : #include "EbSegmentation.h"
      28             : #include "EbCommonUtils.h"
      29             : #include "EbAdaptiveMotionVectorPrediction.h"
      30             : 
      31             : #include "aom_dsp_rtcd.h"
      32             : 
      33             : #define S32 32*32
      34             : #define S16 16*16
      35             : #define S8  8*8
      36             : #define S4  4*4
      37             : 
      38             : #if PAL_SUP
      39             : int svt_av1_allow_palette(int allow_palette,
      40             :     BlockSize sb_type);
      41             : #endif
      42             : int32_t eb_av1_loop_restoration_corners_in_sb(Av1Common *cm, int32_t plane,
      43             :     int32_t mi_row, int32_t mi_col, BlockSize bsize,
      44             :     int32_t *rcol0, int32_t *rcol1, int32_t *rrow0,
      45             :     int32_t *rrow1, int32_t *tile_tl_idx);
      46             : 
      47   723249000 : static INLINE int has_second_ref(const MbModeInfo *mbmi) {
      48   723249000 :     return mbmi->block_mi.ref_frame[1] > INTRA_FRAME;
      49             : }
      50             : 
      51   117165000 : static INLINE int has_uni_comp_refs(const MbModeInfo *mbmi) {
      52   234373000 :     return has_second_ref(mbmi) && (!((mbmi->block_mi.ref_frame[0] >= BWDREF_FRAME) ^
      53   117208000 :         (mbmi->block_mi.ref_frame[1] >= BWDREF_FRAME)));
      54             : }
      55             : int32_t is_inter_block(const BlockModeInfo *mbmi);
      56             : #if(CHAR_BIT!=8)
      57             : #undef CHAR_BIT
      58             : #define CHAR_BIT      8         /* number of bits in a char */
      59             : #endif
      60             : #if ADD_DELTA_QP_SUPPORT
      61             : #define OD_CLZ0 (1)
      62             : #define OD_CLZ(x) (-get_msb(x))
      63             : #define OD_ILOG_NZ(x) (OD_CLZ0 - OD_CLZ(x))
      64             : #endif
      65             : 
      66             : int32_t eb_av1_loop_restoration_corners_in_sb(Av1Common *cm, int32_t plane,
      67             :     int32_t mi_row, int32_t mi_col, BlockSize bsize,
      68             :     int32_t *rcol0, int32_t *rcol1, int32_t *rrow0,
      69             :     int32_t *rrow1, int32_t *tile_tl_idx);
      70             : 
      71             : /*****************************
      72             : * Enums
      73             : *****************************/
      74             : 
      75             : enum COEFF_SCAN_TYPE
      76             : {
      77             :     SCAN_ZIGZAG = 0,      // zigzag scan
      78             :     SCAN_HOR,             // first scan is horizontal
      79             :     SCAN_VER,             // first scan is vertical
      80             :     SCAN_DIAG             // up-right diagonal scan
      81             : };
      82             : 
      83             : extern void av1_set_ref_frame(MvReferenceFrame *rf,
      84             :     int8_t ref_frame_type);
      85             : int get_relative_dist_enc(SeqHeader *seq_header, int ref_hint, int order_hint);
      86    40421200 : int get_comp_index_context_enc(
      87             :     PictureParentControlSet   *pcs_ptr,
      88             :     int cur_frame_index,
      89             :     int bck_frame_index,
      90             :     int fwd_frame_index,
      91             :     const MacroBlockD *xd) {
      92             : 
      93    40421200 :     int fwd = abs(get_relative_dist_enc(&pcs_ptr->sequence_control_set_ptr->seq_header,
      94             :         fwd_frame_index, cur_frame_index));
      95    40393100 :     int bck = abs(get_relative_dist_enc(&pcs_ptr->sequence_control_set_ptr->seq_header,
      96             :         cur_frame_index, bck_frame_index));
      97    40425200 :     const MbModeInfo *const above_mi = xd->above_mbmi;
      98    40425200 :     const MbModeInfo *const left_mi = xd->left_mbmi;
      99    40425200 :     int above_ctx = 0, left_ctx = 0;
     100    40425200 :     const int offset = (fwd == bck);
     101    40425200 :     if (above_mi != NULL) {
     102    38077600 :         if (has_second_ref(above_mi))
     103    32858100 :             above_ctx = above_mi->block_mi.compound_idx;
     104     5223170 :         else if (above_mi->block_mi.ref_frame[0] == ALTREF_FRAME)
     105           0 :             above_ctx = 1;
     106             :     }
     107    40428900 :     if (left_mi != NULL) {
     108    38483500 :         if (has_second_ref(left_mi))
     109    33271400 :             left_ctx = left_mi->block_mi.compound_idx;
     110     5206270 :         else if (left_mi->block_mi.ref_frame[0] == ALTREF_FRAME)
     111         128 :             left_ctx = 1;
     112             :     }
     113    40423100 :     return above_ctx + left_ctx + 3 * offset;
     114             : }
     115             : 
     116             : 
     117    71602200 : int get_comp_group_idx_context_enc(const MacroBlockD *xd) {
     118    71602200 :     const MbModeInfo *const above_mi = xd->above_mbmi;
     119    71602200 :     const MbModeInfo *const left_mi = xd->left_mbmi;
     120    71602200 :     int above_ctx = 0, left_ctx = 0;
     121    71602200 :     if (above_mi) {
     122    67594200 :         if (has_second_ref(above_mi))
     123    58155600 :             above_ctx = above_mi->comp_group_idx;
     124     9438760 :         else if (above_mi->block_mi.ref_frame[0] == ALTREF_FRAME)
     125           0 :             above_ctx = 3;
     126             :     }
     127    71602400 :     if (left_mi) {
     128    68228700 :         if (has_second_ref(left_mi))
     129    58821200 :             left_ctx = left_mi->comp_group_idx;
     130     9394860 :         else if (left_mi->block_mi.ref_frame[0] == ALTREF_FRAME)
     131         254 :             left_ctx = 3;
     132             :     }
     133    71589700 :     return AOMMIN(5, above_ctx + left_ctx);
     134             : }
     135   373589000 : int is_masked_compound_type(COMPOUND_TYPE type) {
     136   373589000 :     return (type == COMPOUND_WEDGE || type == COMPOUND_DIFFWTD);
     137             : }
     138             : 
     139             : /************************************************
     140             : * CABAC Encoder Constructor
     141             : ************************************************/
     142           0 : void CabacCtor(
     143             :     CabacEncodeContext *cabacEncContextPtr)
     144             : {
     145           0 :     EB_MEMSET(cabacEncContextPtr, 0, sizeof(CabacEncodeContext));
     146             : 
     147           0 :     return;
     148             : }
     149             : 
     150           4 : static INLINE int32_t does_level_match(int32_t width, int32_t height, double fps,
     151             :     int32_t lvl_width, int32_t lvl_height,
     152             :     double lvl_fps, int32_t lvl_dim_mult) {
     153           4 :     const int64_t lvl_luma_pels = lvl_width * lvl_height;
     154           4 :     const double lvl_display_sample_rate = lvl_luma_pels * lvl_fps;
     155           4 :     const int64_t luma_pels = width * height;
     156           4 :     const double display_sample_rate = luma_pels * fps;
     157           2 :     return luma_pels <= lvl_luma_pels &&
     158           2 :         display_sample_rate <= lvl_display_sample_rate &&
     159           8 :         width <= lvl_width * lvl_dim_mult &&
     160           2 :         height <= lvl_height * lvl_dim_mult;
     161             : }
     162             : 
     163           2 : static void SetBitstreamLevelTier(SequenceControlSet *scs_ptr) {
     164             :     // TODO(any): This is a placeholder function that only addresses dimensions
     165             :     // and max display sample rates.
     166             :     // Need to add checks for max bit rate, max decoded luma sample rate, header
     167             :     // rate, etc. that are not covered by this function.
     168             : 
     169           2 :     BitstreamLevel bl = { 9, 3 };
     170           2 :     if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16), 512,
     171             :         288, 30.0, 4)) {
     172           0 :         bl.major = 2;
     173           0 :         bl.minor = 0;
     174             :     }
     175           2 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     176             :         704, 396, 30.0, 4)) {
     177           2 :         bl.major = 2;
     178           2 :         bl.minor = 1;
     179             :     }
     180           0 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     181             :         1088, 612, 30.0, 4)) {
     182           0 :         bl.major = 3;
     183           0 :         bl.minor = 0;
     184             :     }
     185           0 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     186             :         1376, 774, 30.0, 4)) {
     187           0 :         bl.major = 3;
     188           0 :         bl.minor = 1;
     189             :     }
     190           0 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     191             :         2048, 1152, 30.0, 3)) {
     192           0 :         bl.major = 4;
     193           0 :         bl.minor = 0;
     194             :     }
     195           0 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     196             :         2048, 1152, 60.0, 3)) {
     197           0 :         bl.major = 4;
     198           0 :         bl.minor = 1;
     199             :     }
     200           0 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     201             :         4096, 2176, 30.0, 2)) {
     202           0 :         bl.major = 5;
     203           0 :         bl.minor = 0;
     204             :     }
     205           0 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     206             :         4096, 2176, 60.0, 2)) {
     207           0 :         bl.major = 5;
     208           0 :         bl.minor = 1;
     209             :     }
     210           0 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     211             :         4096, 2176, 120.0, 2)) {
     212           0 :         bl.major = 5;
     213           0 :         bl.minor = 2;
     214             :     }
     215           0 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     216             :         8192, 4352, 30.0, 2)) {
     217           0 :         bl.major = 6;
     218           0 :         bl.minor = 0;
     219             :     }
     220           0 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     221             :         8192, 4352, 60.0, 2)) {
     222           0 :         bl.major = 6;
     223           0 :         bl.minor = 1;
     224             :     }
     225           0 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     226             :         8192, 4352, 120.0, 2)) {
     227           0 :         bl.major = 6;
     228           0 :         bl.minor = 2;
     229             :     }
     230           0 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     231             :         16384, 8704, 30.0, 2)) {
     232           0 :         bl.major = 7;
     233           0 :         bl.minor = 0;
     234             :     }
     235           0 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     236             :         16384, 8704, 60.0, 2)) {
     237           0 :         bl.major = 7;
     238           0 :         bl.minor = 1;
     239             :     }
     240           0 :     else if (does_level_match(scs_ptr->seq_header.max_frame_width, scs_ptr->seq_header.max_frame_height, (scs_ptr->frame_rate >> 16),
     241             :         16384, 8704, 120.0, 2)) {
     242           0 :         bl.major = 7;
     243           0 :         bl.minor = 2;
     244             :     }
     245          66 :     for (int32_t i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
     246          64 :         scs_ptr->level[i] = bl;
     247          64 :         scs_ptr->seq_header.operating_point[i].seq_tier = 0;  // setting main tier by default
     248             :     }
     249           2 : }
     250             : 
     251             : const uint8_t KEobOffsetBits[12] = { 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
     252             : 
     253         407 : static void WriteGolomb(AomWriter *w, int32_t level) {
     254         407 :     int32_t x = level + 1;
     255         407 :     int32_t i = x;
     256         407 :     int32_t length = 0;
     257             : 
     258        1518 :     while (i) {
     259        1111 :         i >>= 1;
     260        1111 :         ++length;
     261             :     }
     262         407 :     assert(length > 0);
     263             : 
     264        1111 :     for (i = 0; i < length - 1; ++i) aom_write_bit(w, 0);
     265             : 
     266        1518 :     for (i = length - 1; i >= 0; --i) aom_write_bit(w, (x >> i) & 0x01);
     267         407 : }
     268             : 
     269             : static const uint8_t EobToPosSmall[33] = {
     270             :     0, 1, 2,                                        // 0-2
     271             :     3, 3,                                           // 3-4
     272             :     4, 4, 4, 4,                                     // 5-8
     273             :     5, 5, 5, 5, 5, 5, 5, 5,                         // 9-16
     274             :     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6  // 17-32
     275             : };
     276             : 
     277             : static const uint8_t EobToPosLarge[17] = {
     278             :     6,                               // place holder
     279             :     7,                               // 33-64
     280             :     8, 8,                           // 65-128
     281             :     9, 9, 9, 9,                   // 129-256
     282             :     10, 10, 10, 10, 10, 10, 10, 10,  // 257-512
     283             :     11                               // 513-
     284             : };
     285             : const int16_t KEobGroupStart[12] = { 0,  1,  2,  3,   5,   9,
     286             :                                         17, 33, 65, 129, 257, 513 };
     287             : 
     288       18926 : static INLINE int16_t GetEobPosToken(const int16_t eob, int16_t *const extra) {
     289             :     int16_t t;
     290             : 
     291       18926 :     if (eob < 33)
     292       14991 :         t = EobToPosSmall[eob];
     293             :     else {
     294        3935 :         const int16_t e = MIN((eob - 1) >> 5, 16);
     295        3935 :         t = EobToPosLarge[e];
     296             :     }
     297             : 
     298       18926 :     *extra = eob - KEobGroupStart[t];
     299             : 
     300       18926 :     return t;
     301             : }
     302             : 
     303       38018 : static INLINE uint8_t *SetLevels(uint8_t *const levelsBuf, const int32_t width) {
     304       38018 :     return levelsBuf + TX_PAD_TOP * (width + TX_PAD_HOR);
     305             : }
     306             : 
     307       18926 : static INLINE void av1TxbInitLevels(
     308             :     int32_t         *coeffBufferPtr,
     309             :     const uint32_t    coeff_stride,
     310             :     const int16_t    width,
     311             :     const int16_t    height,
     312             :     uint8_t *const    levels) {
     313       18926 :     const int16_t stride = width + TX_PAD_HOR;
     314       18926 :     uint8_t *ls = levels;
     315             : 
     316       18926 :     memset(levels - TX_PAD_TOP * stride, 0,
     317             :         sizeof(*levels) * TX_PAD_TOP * stride);
     318       18926 :     memset(levels + stride * height, 0,
     319       18926 :         sizeof(*levels) * (TX_PAD_BOTTOM * stride + TX_PAD_END));
     320             : 
     321      187194 :     for (int16_t i = 0; i < height; i++) {
     322     2296700 :         for (int16_t j = 0; j < width; j++)
     323     2128430 :             *ls++ = (uint8_t)CLIP3(0, INT8_MAX, abs(coeffBufferPtr[i * coeff_stride + j]));
     324      841340 :         for (int16_t j = 0; j < TX_PAD_HOR; j++)
     325      673072 :             *ls++ = 0;
     326             :     }
     327       18926 : }
     328             : 
     329             : /************************************************************************************************/
     330             : // blockd.h
     331             : 
     332       17405 : static INLINE int16_t GetBrCtx(
     333             :     const uint8_t *const levels,
     334             :     const int16_t c,  // raster order
     335             :     const int16_t bwl,
     336             :     const TxType tx_type
     337             : ) {
     338       17405 :     const int16_t row = c >> bwl;
     339       17405 :     const int16_t col = c - (row << bwl);
     340       17405 :     const int16_t stride = (1 << bwl) + TX_PAD_HOR;
     341       17405 :     const TxClass tx_class = tx_type_to_class[tx_type];
     342       17405 :     const int16_t pos = row * stride + col;
     343       17405 :     int16_t mag = levels[pos + 1];
     344       17405 :     mag += levels[pos + stride];
     345       17405 :     switch (tx_class) {
     346       16421 :     case TX_CLASS_2D:
     347       16421 :         mag += levels[pos + stride + 1];
     348       16421 :         mag = MIN((mag + 1) >> 1, 6);
     349       16421 :         if (c == 0) return mag;
     350       13277 :         if ((row < 2) && (col < 2)) return mag + 7;
     351       10071 :         break;
     352             : 
     353         723 :     case TX_CLASS_HORIZ:
     354         723 :         mag += levels[pos + 2];
     355         723 :         mag = AOMMIN((mag + 1) >> 1, 6);
     356         723 :         if (c == 0) return mag;
     357         640 :         if (col == 0) return mag + 7;
     358         253 :         break;
     359         261 :     case TX_CLASS_VERT:
     360         261 :         mag += levels[pos + (stride << 1)];
     361         261 :         mag = AOMMIN((mag + 1) >> 1, 6);
     362         261 :         if (c == 0) return mag;
     363         140 :         if (row == 0) return mag + 7;
     364          52 :         break;
     365             : 
     366           0 :     default: break;
     367             :     }
     368             : 
     369       10376 :     return mag + 14;
     370             : }
     371             : 
     372    93903400 : void get_txb_ctx(
     373             :     SequenceControlSet *sequence_control_set_ptr,
     374             :     const int32_t        plane,
     375             :     NeighborArrayUnit   *dc_sign_level_coeff_neighbor_array,
     376             :     uint32_t             cu_origin_x,
     377             :     uint32_t             cu_origin_y,
     378             :     const BlockSize      plane_bsize,
     379             :     const TxSize         tx_size,
     380             :     int16_t *const       txb_skip_ctx,
     381             :     int16_t *const       dc_sign_ctx) {
     382    93903400 :     uint32_t dcSignLevelCoeffLeftNeighborIndex = get_neighbor_array_unit_left_index(
     383             :         dc_sign_level_coeff_neighbor_array,
     384             :         cu_origin_y);
     385    93885600 :     uint32_t dcSignLevelCoeffTopNeighborIndex = get_neighbor_array_unit_top_index(
     386             :         dc_sign_level_coeff_neighbor_array,
     387             :         cu_origin_x);
     388             : 
     389             : #define MAX_TX_SIZE_UNIT 16
     390             :     static const int8_t signs[3] = { 0, -1, 1 };
     391             :     int32_t txb_w_unit;
     392             :     int32_t txb_h_unit;
     393    93984100 :     if (plane) {
     394    34500000 :         txb_w_unit = MIN(tx_size_wide_unit[tx_size], (int32_t)(sequence_control_set_ptr->seq_header.max_frame_width / 2 - cu_origin_x) >> 2);
     395    34500000 :         txb_h_unit = MIN(tx_size_high_unit[tx_size], (int32_t)(sequence_control_set_ptr->seq_header.max_frame_height / 2 - cu_origin_y) >> 2);
     396             :     }
     397             :     else {
     398    59484100 :         txb_w_unit = MIN(tx_size_wide_unit[tx_size], (int32_t)(sequence_control_set_ptr->seq_header.max_frame_width - cu_origin_x) >> 2);
     399    59484100 :         txb_h_unit = MIN(tx_size_high_unit[tx_size], (int32_t)(sequence_control_set_ptr->seq_header.max_frame_height - cu_origin_y) >> 2);
     400             :     }
     401    93984100 :     int16_t dc_sign = 0;
     402    93984100 :     uint16_t k = 0;
     403             : 
     404             :     uint8_t sign;
     405             : 
     406    93984100 :     if (dc_sign_level_coeff_neighbor_array->top_array[dcSignLevelCoeffTopNeighborIndex] != INVALID_NEIGHBOR_DATA){
     407             :         do {
     408   245559000 :             sign = ((uint8_t)dc_sign_level_coeff_neighbor_array->top_array[k + dcSignLevelCoeffTopNeighborIndex] >> COEFF_CONTEXT_BITS);
     409   245559000 :             assert(sign <= 2);
     410   245559000 :             dc_sign += signs[sign];
     411   245559000 :         } while (++k < txb_w_unit);
     412             :     }
     413             : 
     414    93984100 :     if (dc_sign_level_coeff_neighbor_array->left_array[dcSignLevelCoeffLeftNeighborIndex] != INVALID_NEIGHBOR_DATA){
     415    89258700 :         k = 0;
     416             :         do {
     417   249292000 :             sign = ((uint8_t)dc_sign_level_coeff_neighbor_array->left_array[k + dcSignLevelCoeffLeftNeighborIndex] >> COEFF_CONTEXT_BITS);
     418   249292000 :             assert(sign <= 2);
     419   249292000 :             dc_sign += signs[sign];
     420   249292000 :         } while (++k < txb_h_unit);
     421             :     }
     422             : 
     423    93984100 :     if (dc_sign > 0)
     424    12475600 :         *dc_sign_ctx = 2;
     425    81508500 :     else if (dc_sign < 0)
     426    13110100 :         *dc_sign_ctx = 1;
     427             :     else
     428    68398400 :         *dc_sign_ctx = 0;
     429             : 
     430    93984100 :     if (plane == 0) {
     431    59481700 :         if (plane_bsize == txsize_to_bsize[tx_size])
     432    54708400 :             *txb_skip_ctx = 0;
     433             :         else {
     434             :             static const uint8_t skip_contexts[5][5] = { { 1, 2, 2, 2, 3 },
     435             :             { 1, 4, 4, 4, 5 },
     436             :             { 1, 4, 4, 4, 5 },
     437             :             { 1, 4, 4, 4, 5 },
     438             :             { 1, 4, 4, 4, 6 } };
     439     4773310 :             int32_t top = 0;
     440     4773310 :             int32_t left = 0;
     441             : 
     442     4773310 :             k = 0;
     443     4773310 :             if (dc_sign_level_coeff_neighbor_array->top_array[dcSignLevelCoeffTopNeighborIndex] != INVALID_NEIGHBOR_DATA) {
     444             :                 do {
     445     8139070 :                     top |= (int32_t)(dc_sign_level_coeff_neighbor_array->top_array[k + dcSignLevelCoeffTopNeighborIndex]);
     446     8139070 :                 } while (++k < txb_w_unit);
     447             :             }
     448     4773310 :             top &= COEFF_CONTEXT_MASK;
     449             : 
     450     4773310 :             if (dc_sign_level_coeff_neighbor_array->left_array[dcSignLevelCoeffLeftNeighborIndex] != INVALID_NEIGHBOR_DATA) {
     451     4638060 :                 k = 0;
     452             :                 do {
     453     8128110 :                     left |= (int32_t)(dc_sign_level_coeff_neighbor_array->left_array[k + dcSignLevelCoeffLeftNeighborIndex]);
     454     8128110 :                 } while (++k < txb_h_unit);
     455             :             }
     456     4773310 :             left &= COEFF_CONTEXT_MASK;
     457             :             //do {
     458             :             //    top |= a[k];
     459             :             //} while (++k < txb_w_unit);
     460             :             //top &= COEFF_CONTEXT_MASK;
     461             : 
     462             :             //k = 0;
     463             :             //do {
     464             :             //    left |= l[k];
     465             :             //} while (++k < txb_h_unit);
     466             :             //left &= COEFF_CONTEXT_MASK;
     467     4773310 :             const int32_t max = AOMMIN(top | left, 4);
     468     4773310 :             const int32_t min = AOMMIN(AOMMIN(top, left), 4);
     469             : 
     470     4773310 :             *txb_skip_ctx = skip_contexts[min][max];
     471             :         }
     472             :     }
     473             :     else {
     474             :         //const int32_t ctx_base = get_entropy_context(tx_size, a, l);
     475    34502400 :         int16_t ctx_base_left = 0;
     476    34502400 :         int16_t ctx_base_top = 0;
     477             : 
     478    34502400 :         if (dc_sign_level_coeff_neighbor_array->top_array[dcSignLevelCoeffTopNeighborIndex] != INVALID_NEIGHBOR_DATA) {
     479    32483500 :             k = 0;
     480             :             do {
     481    57151000 :                 ctx_base_top += (dc_sign_level_coeff_neighbor_array->top_array[k + dcSignLevelCoeffTopNeighborIndex] != 0);
     482    57151000 :             } while (++k < txb_w_unit);
     483             :         }
     484    34502400 :         if (dc_sign_level_coeff_neighbor_array->left_array[dcSignLevelCoeffLeftNeighborIndex] != INVALID_NEIGHBOR_DATA) {
     485    32612300 :             k = 0;
     486             :             do {
     487    57563500 :                 ctx_base_left += (dc_sign_level_coeff_neighbor_array->left_array[k + dcSignLevelCoeffLeftNeighborIndex] != 0);
     488    57563500 :             } while (++k < txb_h_unit);
     489             :         }
     490    34502400 :         const int32_t ctx_base = ((ctx_base_left != 0) + (ctx_base_top != 0));
     491    69004800 :         const int32_t ctx_offset = (num_pels_log2_lookup[plane_bsize] >
     492    34502400 :             num_pels_log2_lookup[txsize_to_bsize[tx_size]])
     493             :             ? 10
     494    34502400 :             : 7;
     495    34502400 :         *txb_skip_ctx = (int16_t)(ctx_base + ctx_offset);
     496             :     }
     497             : #undef MAX_TX_SIZE_UNIT
     498    93984100 : }
     499             : 
     500       13910 : void Av1WriteTxType(
     501             :     PictureParentControlSet   *pcs_ptr,
     502             :     FRAME_CONTEXT               *frameContext,
     503             :     AomWriter                  *ec_writer,
     504             :     CodingUnit                *cu_ptr,
     505             :     uint32_t                      intraDir,
     506             :     TxType                     txType,
     507             :     TxSize                      txSize) {
     508             : 
     509       13910 :     FrameHeader *frm_hdr = &pcs_ptr->frm_hdr;
     510       13910 :     const int32_t isInter = cu_ptr->av1xd->use_intrabc || (cu_ptr->prediction_mode_flag == INTER_MODE);
     511             : 
     512       13910 :     if (get_ext_tx_types(txSize, isInter, frm_hdr->reduced_tx_set) > 1 &&
     513       13497 :         (frm_hdr->quantization_params.base_q_idx > 0)) {
     514       13497 :         const TxSize squareTxSize = txsize_sqr_map[txSize];
     515       13497 :         assert(squareTxSize <= EXT_TX_SIZES);
     516             : 
     517             :         const TxSetType txSetType =
     518       13497 :             get_ext_tx_set_type(txSize, isInter, frm_hdr->reduced_tx_set);
     519       13497 :         const int32_t eset = get_ext_tx_set(txSize, isInter, frm_hdr->reduced_tx_set);
     520             :         // eset == 0 should correspond to a set with only DCT_DCT and there
     521             :         // is no need to send the tx_type
     522       13497 :         assert(eset > 0);
     523       13497 :         assert(av1_ext_tx_used[txSetType][txType]);
     524       13497 :         if (isInter) {
     525        7077 :             aom_write_symbol(ec_writer, av1_ext_tx_ind[txSetType][txType],
     526        7077 :                 frameContext->inter_ext_tx_cdf[eset][squareTxSize],
     527             :                 av1_num_ext_tx_set[txSetType]);
     528             :         }
     529             :         else {
     530             : #if FILTER_INTRA_FLAG
     531             :         PredictionMode intra_dir;
     532        6420 :           if (cu_ptr->filter_intra_mode != FILTER_INTRA_MODES)
     533        1932 :             intra_dir =
     534        1932 :                 fimode_to_intradir[cu_ptr->filter_intra_mode];
     535             :         else
     536        4488 :             intra_dir = intraDir;
     537             : #endif
     538        6420 :             aom_write_symbol(
     539             :                 ec_writer, av1_ext_tx_ind[txSetType][txType],
     540             : #if FILTER_INTRA_FLAG
     541        6420 :                 frameContext->intra_ext_tx_cdf[eset][squareTxSize][intra_dir],
     542             : #else
     543             :                 frameContext->intra_ext_tx_cdf[eset][squareTxSize][intraDir],
     544             : #endif
     545             :                 av1_num_ext_tx_set[txSetType]);
     546             :         }
     547             :     }
     548       13910 : }
     549             : 
     550       18926 : static INLINE void set_dc_sign(int32_t *cul_level, int32_t dc_val) {
     551       18926 :     if (dc_val < 0)
     552        6591 :         *cul_level |= 1 << COEFF_CONTEXT_BITS;
     553       12335 :     else if (dc_val > 0)
     554        6932 :         *cul_level += 2 << COEFF_CONTEXT_BITS;
     555       18926 : }
     556             : 
     557       38018 : int32_t  Av1WriteCoeffsTxb1D(
     558             :     PictureParentControlSet   *parent_pcs_ptr,
     559             :     FRAME_CONTEXT               *frameContext,
     560             :     AomWriter                  *ec_writer,
     561             :     CodingUnit                *cu_ptr,
     562             :     TxSize                     txSize,
     563             :     uint32_t                       pu_index,
     564             :     uint32_t                       tu_index,
     565             :     uint32_t                       intraLumaDir,
     566             :     int32_t                     *coeffBufferPtr,
     567             :     const uint16_t                coeff_stride,
     568             :     COMPONENT_TYPE              component_type,
     569             :     int16_t                      txb_skip_ctx,
     570             :     int16_t                      dcSignCtx,
     571             :     int16_t                      eob)
     572             : {
     573             :     (void)pu_index;
     574             :     (void)coeff_stride;
     575       38018 :     const TxSize txs_ctx = (TxSize)((txsize_sqr_map[txSize] + txsize_sqr_up_map[txSize] + 1) >> 1);
     576       38018 :     TxType txType = cu_ptr->transform_unit_array[tu_index].transform_type[component_type];
     577       38018 :     const ScanOrder *const scan_order = &av1_scan_orders[txSize][txType];
     578       38018 :     const int16_t *const scan = scan_order->scan;
     579             :     int32_t c;
     580       38018 :     const int16_t bwl = (const uint16_t)get_txb_bwl(txSize);
     581       38018 :     const uint16_t width = (const uint16_t)get_txb_wide(txSize);
     582       38018 :     const uint16_t height = (const uint16_t)get_txb_high(txSize);
     583             : 
     584             :     uint8_t levelsBuf[TX_PAD_2D];
     585       38018 :     uint8_t *const levels = SetLevels(levelsBuf, width);
     586             :     DECLARE_ALIGNED(16, int8_t, coeffContexts[MAX_TX_SQUARE]);
     587             : 
     588       38018 :     assert(txs_ctx < TX_SIZES);
     589             : 
     590       38018 :     aom_write_symbol(ec_writer, eob == 0,
     591       38018 :         frameContext->txb_skip_cdf[txs_ctx][txb_skip_ctx], 2);
     592             : 
     593       38018 :     if (component_type == 0 && eob == 0) {
     594             :         // INTER. Chroma follows Luma in transform type
     595        1579 :         if (cu_ptr->prediction_mode_flag == INTER_MODE) {
     596         494 :             txType = cu_ptr->transform_unit_array[tu_index].transform_type[PLANE_TYPE_Y] = DCT_DCT;
     597             : #if ENHANCE_ATB
     598         494 :             cu_ptr->transform_unit_array[tu_index].transform_type[PLANE_TYPE_UV] = DCT_DCT;
     599             : #else
     600             :             cu_ptr->transform_unit_array[0].transform_type[PLANE_TYPE_UV] = DCT_DCT;
     601             : #endif
     602             :         }
     603             :         else { // INTRA
     604        1085 :             txType = cu_ptr->transform_unit_array[tu_index].transform_type[PLANE_TYPE_Y] = DCT_DCT;
     605             :         }
     606        1579 :         assert(txType == DCT_DCT);
     607             :     }
     608       38018 :     if (eob == 0) return 0;
     609             : 
     610       18925 :     av1TxbInitLevels(
     611             :         coeffBufferPtr,
     612             :         width,
     613             :         width,
     614             :         height,
     615             :         levels);
     616             : 
     617       18926 :     if (component_type == COMPONENT_LUMA) {
     618       13910 :         Av1WriteTxType(
     619             :             parent_pcs_ptr,
     620             :             frameContext,
     621             :             ec_writer,
     622             :             cu_ptr,
     623             :             intraLumaDir,
     624             :             txType,
     625             :             txSize);
     626             :     }
     627             : 
     628             :     int16_t eobExtra;
     629       18926 :     const int16_t eobPt = GetEobPosToken(eob, &eobExtra);
     630       18926 :     const int16_t eobMultiSize = txsize_log2_minus4[txSize];
     631       18926 :     const int16_t eobMultiCtx = (tx_type_to_class[txType] == TX_CLASS_2D) ? 0 : 1;
     632       18926 :     switch (eobMultiSize) {
     633        4923 :     case 0:
     634        4923 :         aom_write_symbol(ec_writer, eobPt - 1,
     635        4923 :             frameContext->eob_flag_cdf16[component_type][eobMultiCtx], 5);
     636        4923 :         break;
     637        1668 :     case 1:
     638        1668 :         aom_write_symbol(ec_writer, eobPt - 1,
     639        1668 :             frameContext->eob_flag_cdf32[component_type][eobMultiCtx], 6);
     640        1668 :         break;
     641        8398 :     case 2:
     642        8398 :         aom_write_symbol(ec_writer, eobPt - 1,
     643        8398 :             frameContext->eob_flag_cdf64[component_type][eobMultiCtx], 7);
     644        8398 :         break;
     645         677 :     case 3:
     646         677 :         aom_write_symbol(ec_writer, eobPt - 1,
     647         677 :             frameContext->eob_flag_cdf128[component_type][eobMultiCtx], 8);
     648         677 :         break;
     649        2496 :     case 4:
     650        2496 :         aom_write_symbol(ec_writer, eobPt - 1,
     651        2496 :             frameContext->eob_flag_cdf256[component_type][eobMultiCtx], 9);
     652        2496 :         break;
     653          96 :     case 5:
     654          96 :         aom_write_symbol(ec_writer, eobPt - 1,
     655          96 :             frameContext->eob_flag_cdf512[component_type][eobMultiCtx], 10);
     656          96 :         break;
     657         668 :     default:
     658         668 :         aom_write_symbol(ec_writer, eobPt - 1,
     659         668 :             frameContext->eob_flag_cdf1024[component_type][eobMultiCtx], 11);
     660         668 :         break;
     661             :     }
     662             : 
     663       18926 :     uint8_t eobOffsetBits = KEobOffsetBits[eobPt];
     664       18926 :     if (eobOffsetBits > 0) {
     665       12746 :         int32_t eobShift = eobOffsetBits - 1;
     666       12746 :         int32_t bit = (eobExtra & (1 << eobShift)) ? 1 : 0;
     667       12746 :         aom_write_symbol(ec_writer, bit, frameContext->eob_extra_cdf[txs_ctx][component_type][eobPt], 2);
     668       46090 :         for (int32_t i = 1; i < eobOffsetBits; i++) {
     669       33344 :             eobShift = eobOffsetBits - 1 - i;
     670       33344 :             bit = (eobExtra & (1 << eobShift)) ? 1 : 0;
     671       33344 :             aom_write_bit(ec_writer, bit);
     672             :         }
     673             :     }
     674             : 
     675       18926 :     eb_av1_get_nz_map_contexts(levels, scan, eob, txSize, tx_type_to_class[txType], coeffContexts);
     676             : 
     677      465347 :     for (c = eob - 1; c >= 0; --c) {
     678      446421 :         const int16_t pos = scan[c];
     679      446421 :         const int32_t v = coeffBufferPtr[pos];
     680      446421 :         const int16_t coeffCtx = coeffContexts[pos];
     681      446421 :         int32_t level = ABS(v);
     682             : 
     683      446421 :         if (c == eob - 1) {
     684       18926 :             aom_write_symbol(
     685       18926 :                 ec_writer, AOMMIN(level, 3) - 1,
     686       18926 :                 frameContext->coeff_base_eob_cdf[txs_ctx][component_type][coeffCtx], 3);
     687             :         }
     688             :         else {
     689      427495 :             aom_write_symbol(ec_writer, AOMMIN(level, 3),
     690      427495 :                 frameContext->coeff_base_cdf[txs_ctx][component_type][coeffCtx],
     691             :                 4);
     692             :         }
     693      446421 :         if (level > NUM_BASE_LEVELS) {
     694             :             // level is above 1.
     695       17405 :             int32_t base_range = level - 1 - NUM_BASE_LEVELS;
     696       17405 :             int16_t brCtx = GetBrCtx(levels, pos, bwl, txType);
     697             : 
     698       23885 :             for (int32_t idx = 0; idx < COEFF_BASE_RANGE; idx += BR_CDF_SIZE - 1) {
     699       23478 :                 const int32_t k = AOMMIN(base_range - idx, BR_CDF_SIZE - 1);
     700       23478 :                 aom_write_symbol(
     701             :                     ec_writer, k,
     702       23478 :                     frameContext->coeff_br_cdf[AOMMIN(txs_ctx, TX_32X32)][component_type][brCtx],
     703             :                     BR_CDF_SIZE);
     704       23478 :                 if (k < BR_CDF_SIZE - 1) break;
     705             :             }
     706             :         }
     707             :     }
     708             :     // Loop to code all signs in the transform block,
     709             :     // starting with the sign of DC (if applicable)
     710             : 
     711       18926 :     int32_t cul_level = 0;
     712      465347 :     for (c = 0; c < eob; ++c) {
     713      446421 :         const int16_t pos = scan[c];
     714      446421 :         const int32_t v = coeffBufferPtr[pos];
     715      446421 :         int32_t level = ABS(v);
     716      446421 :         cul_level += level;
     717             : 
     718      446421 :         const int32_t sign = (v < 0) ? 1 : 0;
     719      446421 :         if (level) {
     720      142160 :             if (c == 0) {
     721       13523 :                 aom_write_symbol(
     722       13523 :                     ec_writer, sign, frameContext->dc_sign_cdf[component_type][dcSignCtx], 2);
     723             :             }
     724             :             else
     725      128637 :                 aom_write_bit(ec_writer, sign);
     726      142160 :             if (level > COEFF_BASE_RANGE + NUM_BASE_LEVELS) {
     727         407 :                 WriteGolomb(ec_writer,
     728             :                     level - COEFF_BASE_RANGE - 1 - NUM_BASE_LEVELS);
     729             :             }
     730             :         }
     731             :     }
     732             : 
     733       18926 :     cul_level = AOMMIN(COEFF_CONTEXT_MASK, cul_level);
     734             :     // DC value
     735       18926 :     set_dc_sign(&cul_level, coeffBufferPtr[0]);
     736       18926 :     return cul_level;
     737             : }
     738             : 
     739        1307 : static EbErrorType av1_encode_tx_coef_y(
     740             :     PictureControlSet     *pcs_ptr,
     741             :     EntropyCodingContext  *context_ptr,
     742             :     FRAME_CONTEXT         *frameContext,
     743             :     AomWriter             *ec_writer,
     744             :     CodingUnit            *cu_ptr,
     745             :     uint32_t               cu_origin_x,
     746             :     uint32_t               cu_origin_y,
     747             :     uint32_t               intraLumaDir,
     748             :     BlockSize              plane_bsize,
     749             :     EbPictureBufferDesc   *coeff_ptr,
     750             :     NeighborArrayUnit     *luma_dc_sign_level_coeff_neighbor_array)
     751             : {
     752        1307 :     EbErrorType return_error = EB_ErrorNone;
     753             : 
     754        1307 :     const BlockGeom *blk_geom = get_blk_geom_mds(cu_ptr->mds_idx);
     755        1307 :     int32_t cul_level_y = 0;
     756             : 
     757        1307 :     uint8_t  tx_depth = cu_ptr->tx_depth;
     758        1307 :     uint16_t txb_count = blk_geom->txb_count[cu_ptr->tx_depth];
     759        1307 :     uint8_t  txb_itr = 0;
     760             : 
     761             :     uint8_t tx_index;
     762        5805 :     for (tx_index = 0; tx_index < txb_count; tx_index++) {
     763        4498 :         txb_itr = tx_index;
     764             : 
     765        4498 :         const TxSize tx_size = blk_geom->txsize[tx_depth][txb_itr];
     766             : 
     767             :         int32_t *coeff_buffer;
     768             : 
     769        4498 :         const uint32_t coeff1dOffset = context_ptr->coded_area_sb;
     770             : 
     771        4498 :         coeff_buffer = (int32_t*)coeff_ptr->buffer_y + coeff1dOffset;
     772             : 
     773             :         {
     774        4498 :             int16_t txb_skip_ctx = 0;
     775        4498 :             int16_t dcSignCtx = 0;
     776             : 
     777        4498 :             get_txb_ctx(
     778        4498 :                 pcs_ptr->parent_pcs_ptr->sequence_control_set_ptr,
     779             :                 COMPONENT_LUMA,
     780             :                 luma_dc_sign_level_coeff_neighbor_array,
     781        4498 :                 cu_origin_x + blk_geom->tx_org_x[tx_depth][txb_itr] - blk_geom->origin_x,
     782        4498 :                 cu_origin_y + blk_geom->tx_org_y[tx_depth][txb_itr] - blk_geom->origin_y,
     783             :                 plane_bsize,
     784             :                 tx_size,
     785             :                 &txb_skip_ctx,
     786             :                 &dcSignCtx);
     787             : 
     788             :             cul_level_y =
     789        4498 :                 Av1WriteCoeffsTxb1D(
     790        4498 :                     pcs_ptr->parent_pcs_ptr,
     791             :                     frameContext,
     792             :                     ec_writer,
     793             :                     cu_ptr,
     794             :                     tx_size,
     795             :                     0,
     796             :                     txb_itr,
     797             :                     intraLumaDir,
     798             :                     coeff_buffer,
     799        4498 :                     coeff_ptr->stride_y,
     800             :                     COMPONENT_LUMA,
     801             :                     txb_skip_ctx,
     802             :                     dcSignCtx,
     803        4498 :                     cu_ptr->transform_unit_array[txb_itr].nz_coef_count[0]);
     804             :         }
     805             : 
     806             :         // Update the luma Dc Sign Level Coeff Neighbor Array
     807             :         {
     808        4498 :             uint8_t dc_sign_level_coeff = (uint8_t)cul_level_y;
     809             : 
     810        4498 :             neighbor_array_unit_mode_write(
     811             :                 luma_dc_sign_level_coeff_neighbor_array,
     812             :                 (uint8_t*)&dc_sign_level_coeff,
     813        4498 :                 cu_origin_x + blk_geom->tx_org_x[tx_depth][txb_itr] - blk_geom->origin_x,
     814        4498 :                 cu_origin_y + blk_geom->tx_org_y[tx_depth][txb_itr] - blk_geom->origin_y,
     815        4498 :                 blk_geom->tx_width[tx_depth][txb_itr],
     816        4498 :                 blk_geom->tx_height[tx_depth][txb_itr],
     817             :                 NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
     818             :         }
     819             : 
     820        4498 :         context_ptr->coded_area_sb += blk_geom->tx_width[tx_depth][txb_itr] * blk_geom->tx_height[tx_depth][txb_itr];
     821             :     }
     822             : 
     823        1307 :     return return_error;
     824             : }
     825        1307 : static EbErrorType av1_encode_tx_coef_uv(
     826             :     PictureControlSet     *pcs_ptr,
     827             :     EntropyCodingContext  *context_ptr,
     828             :     FRAME_CONTEXT         *frameContext,
     829             :     AomWriter             *ec_writer,
     830             :     CodingUnit            *cu_ptr,
     831             :     uint32_t               cu_origin_x,
     832             :     uint32_t               cu_origin_y,
     833             :     uint32_t               intraLumaDir,
     834             :     EbPictureBufferDesc   *coeff_ptr,
     835             :     NeighborArrayUnit     *cr_dc_sign_level_coeff_neighbor_array,
     836             :     NeighborArrayUnit     *cb_dc_sign_level_coeff_neighbor_array)
     837             : {
     838        1307 :     EbErrorType return_error = EB_ErrorNone;
     839             : 
     840        1307 :     const BlockGeom *blk_geom = get_blk_geom_mds(cu_ptr->mds_idx);
     841             : 
     842        1307 :     if (!blk_geom->has_uv) return return_error;
     843             : 
     844        1176 :     int32_t cul_level_cb = 0, cul_level_cr = 0;
     845             : 
     846        1176 :     uint8_t tx_depth   = cu_ptr->tx_depth;
     847        1176 :     uint16_t txb_count = 1;
     848        1176 :     uint8_t txb_itr    = 0;
     849             : 
     850             :     uint8_t tx_index;
     851             : 
     852        2352 :     for (tx_index = 0; tx_index < txb_count; tx_index++) {
     853        1176 :         txb_itr = tx_index;
     854             : 
     855        1176 :         const TxSize chroma_tx_size = blk_geom->txsize_uv[tx_depth][txb_itr];
     856             : 
     857             :         int32_t *coeff_buffer;
     858             : 
     859        1176 :         const uint32_t coeff1dOffset = context_ptr->coded_area_sb;
     860             : 
     861        1176 :         coeff_buffer = (int32_t*)coeff_ptr->buffer_y + coeff1dOffset;
     862             : 
     863        1176 :         if (blk_geom->has_uv) {
     864             :             // cb
     865        1176 :             coeff_buffer = (int32_t*)coeff_ptr->buffer_cb + context_ptr->coded_area_sb_uv;
     866             :             {
     867        1176 :                 int16_t txb_skip_ctx = 0;
     868        1176 :                 int16_t dcSignCtx = 0;
     869             : 
     870        1176 :                 get_txb_ctx(
     871        1176 :                     pcs_ptr->parent_pcs_ptr->sequence_control_set_ptr,
     872             :                     COMPONENT_CHROMA,
     873             :                     cb_dc_sign_level_coeff_neighbor_array,
     874        1176 :                     ROUND_UV(cu_origin_x + blk_geom->tx_org_x[tx_depth][txb_itr] - blk_geom->origin_x) >> 1,
     875        1176 :                     ROUND_UV(cu_origin_y + blk_geom->tx_org_y[tx_depth][txb_itr] - blk_geom->origin_y) >> 1,
     876        1176 :                     blk_geom->bsize_uv,
     877             :                     chroma_tx_size,
     878             :                     &txb_skip_ctx,
     879             :                     &dcSignCtx);
     880             : 
     881             :                 cul_level_cb =
     882        1176 :                     Av1WriteCoeffsTxb1D(
     883        1176 :                         pcs_ptr->parent_pcs_ptr,
     884             :                         frameContext,
     885             :                         ec_writer,
     886             :                         cu_ptr,
     887             :                         chroma_tx_size,
     888             :                         0,
     889             :                         txb_itr,
     890             :                         intraLumaDir,
     891             :                         coeff_buffer,
     892        1176 :                         coeff_ptr->stride_cb,
     893             :                         COMPONENT_CHROMA,
     894             :                         txb_skip_ctx,
     895             :                         dcSignCtx,
     896        1176 :                         cu_ptr->transform_unit_array[txb_itr].nz_coef_count[1]);
     897             :             }
     898             : 
     899             :             // cr
     900        1176 :             coeff_buffer = (int32_t*)coeff_ptr->buffer_cr + context_ptr->coded_area_sb_uv;
     901             :             {
     902        1176 :                 int16_t txb_skip_ctx = 0;
     903        1176 :                 int16_t dcSignCtx = 0;
     904             : 
     905        1176 :                 get_txb_ctx(
     906        1176 :                     pcs_ptr->parent_pcs_ptr->sequence_control_set_ptr,
     907             :                     COMPONENT_CHROMA,
     908             :                     cr_dc_sign_level_coeff_neighbor_array,
     909        1176 :                     ROUND_UV(cu_origin_x + blk_geom->tx_org_x[tx_depth][txb_itr] - blk_geom->origin_x) >> 1,
     910        1176 :                     ROUND_UV(cu_origin_y + blk_geom->tx_org_y[tx_depth][txb_itr] - blk_geom->origin_y) >> 1,
     911        1176 :                     blk_geom->bsize_uv,
     912             :                     chroma_tx_size,
     913             :                     &txb_skip_ctx,
     914             :                     &dcSignCtx);
     915             : 
     916             :                 cul_level_cr =
     917        1176 :                     Av1WriteCoeffsTxb1D(
     918        1176 :                         pcs_ptr->parent_pcs_ptr,
     919             :                         frameContext,
     920             :                         ec_writer,
     921             :                         cu_ptr,
     922             :                         chroma_tx_size,
     923             :                         0,
     924             :                         txb_itr,
     925             :                         intraLumaDir,
     926             :                         coeff_buffer,
     927        1176 :                         coeff_ptr->stride_cr,
     928             :                         COMPONENT_CHROMA,
     929             :                         txb_skip_ctx,
     930             :                         dcSignCtx,
     931        1176 :                         cu_ptr->transform_unit_array[txb_itr].nz_coef_count[2]);
     932             :             }
     933             :         }
     934             : 
     935             :         // Update the cb Dc Sign Level Coeff Neighbor Array
     936             : 
     937        1176 :         if (blk_geom->has_uv)
     938             :         {
     939        1176 :             uint8_t dc_sign_level_coeff = (uint8_t)cul_level_cb;
     940        1176 :             neighbor_array_unit_mode_write(
     941             :                 cb_dc_sign_level_coeff_neighbor_array,
     942             :                 (uint8_t*)&dc_sign_level_coeff,
     943        1176 :                 ROUND_UV(cu_origin_x + blk_geom->tx_org_x[tx_depth][txb_itr] - blk_geom->origin_x) >> 1,
     944        1176 :                 ROUND_UV(cu_origin_y + blk_geom->tx_org_y[tx_depth][txb_itr] - blk_geom->origin_y) >> 1,
     945        1176 :                 blk_geom->tx_width_uv[tx_depth][txb_itr],
     946        1176 :                 blk_geom->tx_height_uv[tx_depth][txb_itr],
     947             :                 NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
     948             :         }
     949             : 
     950        1176 :         if (blk_geom->has_uv)
     951             :             // Update the cr DC Sign Level Coeff Neighbor Array
     952             :         {
     953        1176 :             uint8_t dc_sign_level_coeff = (uint8_t)cul_level_cr;
     954        1176 :             neighbor_array_unit_mode_write(
     955             :                 cr_dc_sign_level_coeff_neighbor_array,
     956             :                 (uint8_t*)&dc_sign_level_coeff,
     957        1176 :                 ROUND_UV(cu_origin_x + blk_geom->tx_org_x[tx_depth][txb_itr] - blk_geom->origin_x) >> 1,
     958        1176 :                 ROUND_UV(cu_origin_y + blk_geom->tx_org_y[tx_depth][txb_itr] - blk_geom->origin_y) >> 1,
     959        1176 :                 blk_geom->tx_width_uv[tx_depth][txb_itr],
     960        1176 :                 blk_geom->tx_height_uv[tx_depth][txb_itr],
     961             :                 NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
     962             :         }
     963             : 
     964        1176 :         context_ptr->coded_area_sb_uv += blk_geom->tx_width_uv[tx_depth][txb_itr] * blk_geom->tx_height_uv[tx_depth][txb_itr];
     965             :     }
     966             : 
     967        1176 :     return return_error;
     968             : }
     969             : /************************************
     970             : ******* Av1EncodeTuCoeff
     971             : **************************************/
     972       12298 : static EbErrorType Av1EncodeCoeff1D(
     973             :     PictureControlSet    *pcs_ptr,
     974             :     EntropyCodingContext *context_ptr,
     975             :     FRAME_CONTEXT        *frameContext,
     976             :     AomWriter            *ec_writer,
     977             :     CodingUnit           *cu_ptr,
     978             :     uint32_t              cu_origin_x,
     979             :     uint32_t              cu_origin_y,
     980             :     uint32_t              intraLumaDir,
     981             :     BlockSize             plane_bsize,
     982             :     EbPictureBufferDesc  *coeff_ptr,
     983             :     NeighborArrayUnit     *luma_dc_sign_level_coeff_neighbor_array,
     984             :     NeighborArrayUnit     *cr_dc_sign_level_coeff_neighbor_array,
     985             :     NeighborArrayUnit     *cb_dc_sign_level_coeff_neighbor_array)
     986             : {
     987       12298 :     EbErrorType return_error = EB_ErrorNone;
     988             : #if ENHANCE_ATB
     989       12298 :     if (cu_ptr->tx_depth) {
     990             : #else
     991             :     if (cu_ptr->prediction_mode_flag == INTRA_MODE && cu_ptr->tx_depth) {
     992             : #endif
     993        1307 :         av1_encode_tx_coef_y(
     994             :             pcs_ptr,
     995             :             context_ptr,
     996             :             frameContext,
     997             :             ec_writer,
     998             :             cu_ptr,
     999             :             cu_origin_x,
    1000             :             cu_origin_y,
    1001             :             intraLumaDir,
    1002             :             plane_bsize,
    1003             :             coeff_ptr,
    1004             :             luma_dc_sign_level_coeff_neighbor_array);
    1005             : 
    1006        1307 :         av1_encode_tx_coef_uv(
    1007             :             pcs_ptr,
    1008             :             context_ptr,
    1009             :             frameContext,
    1010             :             ec_writer,
    1011             :             cu_ptr,
    1012             :             cu_origin_x,
    1013             :             cu_origin_y,
    1014             :             intraLumaDir,
    1015             :             coeff_ptr,
    1016             :             cr_dc_sign_level_coeff_neighbor_array,
    1017             :             cb_dc_sign_level_coeff_neighbor_array);
    1018             :     } else {
    1019             :         // Transform partitioning free patch (except the 128x128 case)
    1020       10991 :         const BlockGeom *blk_geom = get_blk_geom_mds(cu_ptr->mds_idx);
    1021       10991 :         int32_t cul_level_y, cul_level_cb = 0, cul_level_cr = 0;
    1022             : 
    1023       10991 :         uint16_t txb_count = blk_geom->txb_count[cu_ptr->tx_depth];
    1024       10991 :         uint8_t txb_itr = 0;
    1025             : 
    1026       21982 :         for (txb_itr = 0; txb_itr < txb_count; txb_itr++) {
    1027       10991 :             const TxSize tx_size = blk_geom->txsize[cu_ptr->tx_depth][txb_itr];
    1028       10991 :             const TxSize chroma_tx_size = blk_geom->txsize_uv[cu_ptr->tx_depth][txb_itr];
    1029             :             int32_t *coeff_buffer;
    1030             : 
    1031       10991 :             const uint32_t coeff1dOffset = context_ptr->coded_area_sb;
    1032             : 
    1033       10991 :             coeff_buffer = (int32_t*)coeff_ptr->buffer_y + coeff1dOffset;
    1034             : 
    1035             :             {
    1036       10991 :                 int16_t txb_skip_ctx = 0;
    1037       10991 :                 int16_t dcSignCtx = 0;
    1038             : 
    1039       10991 :                 get_txb_ctx(
    1040       10991 :                     pcs_ptr->parent_pcs_ptr->sequence_control_set_ptr,
    1041             :                     COMPONENT_LUMA,
    1042             :                     luma_dc_sign_level_coeff_neighbor_array,
    1043       10991 :                     cu_origin_x + blk_geom->tx_org_x[cu_ptr->tx_depth][txb_itr] - blk_geom->origin_x,
    1044       10991 :                     cu_origin_y + blk_geom->tx_org_y[cu_ptr->tx_depth][txb_itr] - blk_geom->origin_y,
    1045             :                     plane_bsize,
    1046             :                     tx_size,
    1047             :                     &txb_skip_ctx,
    1048             :                     &dcSignCtx);
    1049             : 
    1050             :                 cul_level_y =
    1051       10991 :                     Av1WriteCoeffsTxb1D(
    1052       10991 :                         pcs_ptr->parent_pcs_ptr,
    1053             :                         frameContext,
    1054             :                         ec_writer,
    1055             :                         cu_ptr,
    1056             :                         tx_size,
    1057             :                         0,
    1058             :                         txb_itr,
    1059             :                         intraLumaDir,
    1060             :                         coeff_buffer,
    1061       10991 :                         coeff_ptr->stride_y,
    1062             :                         COMPONENT_LUMA,
    1063             :                         txb_skip_ctx,
    1064             :                         dcSignCtx,
    1065       10991 :                         cu_ptr->transform_unit_array[txb_itr].nz_coef_count[0]);
    1066             :             }
    1067             : 
    1068       10991 :             if (blk_geom->has_uv) {
    1069             :                 // cb
    1070       10089 :                 coeff_buffer = (int32_t*)coeff_ptr->buffer_cb + context_ptr->coded_area_sb_uv;
    1071             :                 {
    1072       10089 :                     int16_t txb_skip_ctx = 0;
    1073       10089 :                     int16_t dcSignCtx = 0;
    1074             : 
    1075       10089 :                     get_txb_ctx(
    1076       10089 :                         pcs_ptr->parent_pcs_ptr->sequence_control_set_ptr,
    1077             :                         COMPONENT_CHROMA,
    1078             :                         cb_dc_sign_level_coeff_neighbor_array,
    1079       10089 :                         ROUND_UV(cu_origin_x + blk_geom->tx_org_x[cu_ptr->tx_depth][txb_itr] - blk_geom->origin_x) >> 1,
    1080       10089 :                         ROUND_UV(cu_origin_y + blk_geom->tx_org_y[cu_ptr->tx_depth][txb_itr] - blk_geom->origin_y) >> 1,
    1081       10089 :                         blk_geom->bsize_uv,
    1082             :                         chroma_tx_size,
    1083             :                         &txb_skip_ctx,
    1084             :                         &dcSignCtx);
    1085             : 
    1086             :                     cul_level_cb =
    1087       10089 :                         Av1WriteCoeffsTxb1D(
    1088       10089 :                             pcs_ptr->parent_pcs_ptr,
    1089             :                             frameContext,
    1090             :                             ec_writer,
    1091             :                             cu_ptr,
    1092             :                             chroma_tx_size,
    1093             :                             0,
    1094             :                             txb_itr,
    1095             :                             intraLumaDir,
    1096             :                             coeff_buffer,
    1097       10089 :                             coeff_ptr->stride_cb,
    1098             :                             COMPONENT_CHROMA,
    1099             :                             txb_skip_ctx,
    1100             :                             dcSignCtx,
    1101       10089 :                             cu_ptr->transform_unit_array[txb_itr].nz_coef_count[1]);
    1102             :                 }
    1103             : 
    1104             :                 // cr
    1105       10089 :                 coeff_buffer = (int32_t*)coeff_ptr->buffer_cr + context_ptr->coded_area_sb_uv;
    1106             :                 {
    1107       10089 :                     int16_t txb_skip_ctx = 0;
    1108       10089 :                     int16_t dcSignCtx = 0;
    1109             : 
    1110       10089 :                     get_txb_ctx(
    1111       10089 :                         pcs_ptr->parent_pcs_ptr->sequence_control_set_ptr,
    1112             :                         COMPONENT_CHROMA,
    1113             :                         cr_dc_sign_level_coeff_neighbor_array,
    1114       10089 :                         ROUND_UV(cu_origin_x + blk_geom->tx_org_x[cu_ptr->tx_depth][txb_itr] - blk_geom->origin_x) >> 1,
    1115       10089 :                         ROUND_UV(cu_origin_y + blk_geom->tx_org_y[cu_ptr->tx_depth][txb_itr] - blk_geom->origin_y) >> 1,
    1116       10089 :                         blk_geom->bsize_uv,
    1117             :                         chroma_tx_size,
    1118             :                         &txb_skip_ctx,
    1119             :                         &dcSignCtx);
    1120             : 
    1121             :                     cul_level_cr =
    1122       10089 :                         Av1WriteCoeffsTxb1D(
    1123       10089 :                             pcs_ptr->parent_pcs_ptr,
    1124             :                             frameContext,
    1125             :                             ec_writer,
    1126             :                             cu_ptr,
    1127             :                             chroma_tx_size,
    1128             :                             0,
    1129             :                             txb_itr,
    1130             :                             intraLumaDir,
    1131             :                             coeff_buffer,
    1132       10089 :                             coeff_ptr->stride_cr,
    1133             :                             COMPONENT_CHROMA,
    1134             :                             txb_skip_ctx,
    1135             :                             dcSignCtx,
    1136       10089 :                             cu_ptr->transform_unit_array[txb_itr].nz_coef_count[2]);
    1137             :                 }
    1138             :             }
    1139             : 
    1140             :             // Update the luma Dc Sign Level Coeff Neighbor Array
    1141             :             {
    1142       10991 :                 uint8_t dc_sign_level_coeff = (uint8_t)cul_level_y;
    1143             :                 //if (!txb_ptr->lumaCbf)
    1144             :                 //    dc_sign_level_coeff = 0;
    1145       10991 :                 neighbor_array_unit_mode_write(
    1146             :                     luma_dc_sign_level_coeff_neighbor_array,
    1147             :                     (uint8_t*)&dc_sign_level_coeff,
    1148       10991 :                     cu_origin_x + blk_geom->tx_org_x[cu_ptr->tx_depth][txb_itr] - blk_geom->origin_x,
    1149       10991 :                     cu_origin_y + blk_geom->tx_org_y[cu_ptr->tx_depth][txb_itr] - blk_geom->origin_y,
    1150       10991 :                     blk_geom->tx_width[cu_ptr->tx_depth][txb_itr],
    1151       10991 :                     blk_geom->tx_height[cu_ptr->tx_depth][txb_itr],
    1152             :                     NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    1153             :             }
    1154             : 
    1155             :             // Update the cb Dc Sign Level Coeff Neighbor Array
    1156             : 
    1157       10991 :             if (blk_geom->has_uv)
    1158             :             {
    1159       10089 :                 uint8_t dc_sign_level_coeff = (uint8_t)cul_level_cb;
    1160       10089 :                 neighbor_array_unit_mode_write(
    1161             :                     cb_dc_sign_level_coeff_neighbor_array,
    1162             :                     (uint8_t*)&dc_sign_level_coeff,
    1163       10089 :                     ROUND_UV(cu_origin_x + blk_geom->tx_org_x[cu_ptr->tx_depth][txb_itr] - blk_geom->origin_x) >> 1,
    1164       10089 :                     ROUND_UV(cu_origin_y + blk_geom->tx_org_y[cu_ptr->tx_depth][txb_itr] - blk_geom->origin_y) >> 1,
    1165       10089 :                     blk_geom->tx_width_uv[cu_ptr->tx_depth][txb_itr],
    1166       10089 :                     blk_geom->tx_height_uv[cu_ptr->tx_depth][txb_itr],
    1167             :                     NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    1168             :             }
    1169             : 
    1170       10991 :             if (blk_geom->has_uv)
    1171             :                 // Update the cr DC Sign Level Coeff Neighbor Array
    1172             :             {
    1173       10089 :                 uint8_t dc_sign_level_coeff = (uint8_t)cul_level_cr;
    1174       10089 :                 neighbor_array_unit_mode_write(
    1175             :                     cr_dc_sign_level_coeff_neighbor_array,
    1176             :                     (uint8_t*)&dc_sign_level_coeff,
    1177       10089 :                     ROUND_UV(cu_origin_x + blk_geom->tx_org_x[cu_ptr->tx_depth][txb_itr] - blk_geom->origin_x) >> 1,
    1178       10089 :                     ROUND_UV(cu_origin_y + blk_geom->tx_org_y[cu_ptr->tx_depth][txb_itr] - blk_geom->origin_y) >> 1,
    1179       10089 :                     blk_geom->tx_width_uv[cu_ptr->tx_depth][txb_itr],
    1180       10089 :                     blk_geom->tx_height_uv[cu_ptr->tx_depth][txb_itr],
    1181             :                     NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    1182             :             }
    1183             : 
    1184       10991 :             context_ptr->coded_area_sb += blk_geom->tx_width[cu_ptr->tx_depth][txb_itr] * blk_geom->tx_height[cu_ptr->tx_depth][txb_itr];
    1185             : 
    1186       10991 :             if (blk_geom->has_uv)
    1187       10089 :                 context_ptr->coded_area_sb_uv += blk_geom->tx_width_uv[cu_ptr->tx_depth][txb_itr] * blk_geom->tx_height_uv[cu_ptr->tx_depth][txb_itr];
    1188             :         }
    1189             :     }
    1190       12298 :     return return_error;
    1191             : }
    1192             : 
    1193             : /*********************************************************************
    1194             : * EncodePartitionAv1
    1195             : *   Encodes the partition
    1196             : *********************************************************************/
    1197             : // Return the number of elements in the partition CDF when
    1198             : // partitioning the (square) block with luma block size of bsize.
    1199       34771 : static INLINE int32_t partition_cdf_length(BlockSize bsize) {
    1200       34771 :     if (bsize <= BLOCK_8X8)
    1201       12320 :         return PARTITION_TYPES;
    1202       22451 :     else if (bsize == BLOCK_128X128)
    1203           0 :         return EXT_PARTITION_TYPES - 2;
    1204             :     else
    1205       22451 :         return EXT_PARTITION_TYPES;
    1206             : }
    1207       39013 : static void EncodePartitionAv1(
    1208             :     SequenceControlSet    *sequence_control_set_ptr,
    1209             :     FRAME_CONTEXT           *frameContext,
    1210             :     AomWriter              *ec_writer,
    1211             :     BlockSize              bsize,
    1212             :     PartitionType          p,
    1213             :     uint32_t                  cu_origin_x,
    1214             :     uint32_t                  cu_origin_y,
    1215             :     NeighborArrayUnit    *partition_context_neighbor_array)
    1216             : {
    1217       39013 :     const int32_t is_partition_point = bsize >= BLOCK_8X8;
    1218             : 
    1219       39013 :     if (!is_partition_point) return;
    1220             : 
    1221       39013 :     const int32_t hbs = (mi_size_wide[bsize] << 2) >> 1;
    1222       39013 :     const int32_t hasRows = (cu_origin_y + hbs) < sequence_control_set_ptr->seq_header.max_frame_height;
    1223       39013 :     const int32_t hasCols = (cu_origin_x + hbs) < sequence_control_set_ptr->seq_header.max_frame_width;
    1224             : 
    1225       39013 :     uint32_t partitionContextLeftNeighborIndex = get_neighbor_array_unit_left_index(
    1226             :         partition_context_neighbor_array,
    1227             :         cu_origin_y);
    1228       39014 :     uint32_t partitionContextTopNeighborIndex = get_neighbor_array_unit_top_index(
    1229             :         partition_context_neighbor_array,
    1230             :         cu_origin_x);
    1231             : 
    1232       39015 :     uint32_t contextIndex = 0;
    1233             : 
    1234       39015 :     const PartitionContextType above_ctx = (((PartitionContext*)partition_context_neighbor_array->top_array)[partitionContextTopNeighborIndex].above == (int8_t)INVALID_NEIGHBOR_DATA) ?
    1235       36237 :         0 : ((PartitionContext*)partition_context_neighbor_array->top_array)[partitionContextTopNeighborIndex].above;
    1236       39015 :     const PartitionContextType left_ctx = (((PartitionContext*)partition_context_neighbor_array->left_array)[partitionContextLeftNeighborIndex].left == (int8_t)INVALID_NEIGHBOR_DATA) ?
    1237       36177 :         0 : ((PartitionContext*)partition_context_neighbor_array->left_array)[partitionContextLeftNeighborIndex].left;
    1238             : 
    1239       39015 :     const int32_t bsl = mi_size_wide_log2[bsize] - mi_size_wide_log2[BLOCK_8X8];
    1240       39015 :     int32_t above = (above_ctx >> bsl) & 1, left = (left_ctx >> bsl) & 1;
    1241             : 
    1242       39015 :     assert(mi_size_wide_log2[bsize] == mi_size_high_log2[bsize]);
    1243       39015 :     assert(bsl >= 0);
    1244       39015 :     assert(p < CDF_SIZE(EXT_PARTITION_TYPES));
    1245             : 
    1246       39015 :     contextIndex = (left * 2 + above) + bsl * PARTITION_PLOFFSET;
    1247             : 
    1248       39015 :     if (!hasRows && !hasCols) {
    1249           0 :         assert(p == PARTITION_SPLIT);
    1250           0 :         return;
    1251             :     }
    1252             : 
    1253       39015 :     if (hasRows && hasCols) {
    1254       34771 :         aom_write_symbol(
    1255             :             ec_writer,
    1256             :             p,
    1257       34771 :             frameContext->partition_cdf[contextIndex],
    1258             :             partition_cdf_length(bsize));
    1259             :     }
    1260        8492 :     else if (!hasRows && hasCols) {
    1261             :         AomCdfProb cdf[CDF_SIZE(2)];
    1262        4248 :         partition_gather_vert_alike(cdf, frameContext->partition_cdf[contextIndex], bsize);
    1263        4248 :         aom_write_symbol(
    1264             :             ec_writer,
    1265             :             p == PARTITION_SPLIT,
    1266             :             cdf,
    1267             :             2);
    1268             :     }
    1269             :     else {
    1270             :         AomCdfProb cdf[CDF_SIZE(2)];
    1271           0 :         partition_gather_horz_alike(cdf, frameContext->partition_cdf[contextIndex], bsize);
    1272           0 :         aom_write_symbol(
    1273             :             ec_writer,
    1274             :             p == PARTITION_SPLIT,
    1275             :             cdf,
    1276             :             2);
    1277             :     }
    1278             : 
    1279       39018 :     return;
    1280             : }
    1281             : 
    1282             : /*********************************************************************
    1283             : * EncodeSkipCoeffAv1
    1284             : *   Encodes the skip coefficient flag
    1285             : *********************************************************************/
    1286       25869 : static void EncodeSkipCoeffAv1(
    1287             :     FRAME_CONTEXT           *frameContext,
    1288             :     AomWriter              *ec_writer,
    1289             :     EbBool                 skipCoeffFlag,
    1290             :     uint32_t                  cu_origin_x,
    1291             :     uint32_t                  cu_origin_y,
    1292             :     NeighborArrayUnit    *skip_coeff_neighbor_array)
    1293             : {
    1294             :     //TODO: need to code in syntax for segmentation map + skip
    1295       25869 :     uint32_t skipCoeffLeftNeighborIndex = get_neighbor_array_unit_left_index(
    1296             :         skip_coeff_neighbor_array,
    1297             :         cu_origin_y);
    1298       25868 :     uint32_t skipCoeffTopNeighborIndex = get_neighbor_array_unit_top_index(
    1299             :         skip_coeff_neighbor_array,
    1300             :         cu_origin_x);
    1301             : 
    1302       25869 :     uint32_t contextIndex = 0;
    1303             : 
    1304       25869 :     contextIndex =
    1305       49946 :         (skip_coeff_neighbor_array->left_array[skipCoeffLeftNeighborIndex] == (uint8_t)INVALID_NEIGHBOR_DATA) ? 0 :
    1306       24077 :         (skip_coeff_neighbor_array->left_array[skipCoeffLeftNeighborIndex]) ? 1 : 0;
    1307             : 
    1308       25869 :     contextIndex +=
    1309       49901 :         (skip_coeff_neighbor_array->top_array[skipCoeffTopNeighborIndex] == (uint8_t)INVALID_NEIGHBOR_DATA) ? 0 :
    1310       24032 :         (skip_coeff_neighbor_array->top_array[skipCoeffTopNeighborIndex]) ? 1 : 0;
    1311             : 
    1312       25869 :     aom_write_symbol(
    1313             :         ec_writer,
    1314             :         skipCoeffFlag ? 1 : 0,
    1315       25869 :         frameContext->skip_cdfs[contextIndex],
    1316             :         2);
    1317             : 
    1318       25868 :     return;
    1319             : }
    1320             : #if FILTER_INTRA_FLAG
    1321     5077580 :  int av1_filter_intra_allowed_bsize(
    1322             :     uint8_t enable_filter_intra,
    1323             :     BlockSize bs)
    1324             : {
    1325     5077580 :  if (!enable_filter_intra) return 0;
    1326     5000240 :   return block_size_wide[bs] <= 32 && block_size_high[bs] <= 32;
    1327             : }
    1328   241350000 : int av1_filter_intra_allowed(
    1329             :  uint8_t   enable_filter_intra,
    1330             :  BlockSize bsize,
    1331             : #if PAL_SUP
    1332             :  uint8_t palette_size,
    1333             : #endif
    1334             :  uint32_t  mode)
    1335             :  {
    1336     4950810 :   return  mode == DC_PRED &&
    1337             : #if PAL_SUP
    1338   246301000 :       palette_size == 0 &&
    1339             : #else
    1340             :        //  mbmi->palette_mode_info.palette_size[0] == 0 &&
    1341             : #endif
    1342     4950900 :          av1_filter_intra_allowed_bsize(enable_filter_intra,bsize);
    1343             : }
    1344             : #endif
    1345             : /*********************************************************************
    1346             : * EncodeIntraLumaModeAv1
    1347             : *   Encodes the Intra Luma Mode
    1348             : *********************************************************************/
    1349        4876 : static void EncodeIntraLumaModeAv1(
    1350             :     FRAME_CONTEXT           *frameContext,
    1351             :     AomWriter              *ec_writer,
    1352             :     CodingUnit            *cu_ptr,
    1353             :     uint32_t                  cu_origin_x,
    1354             :     uint32_t                  cu_origin_y,
    1355             :     BlockSize               bsize,
    1356             :     uint32_t                  luma_mode,
    1357             :     NeighborArrayUnit    *mode_type_neighbor_array,
    1358             :     NeighborArrayUnit    *intra_luma_mode_neighbor_array)
    1359             : {
    1360        4876 :     uint32_t modeTypeLeftNeighborIndex = get_neighbor_array_unit_left_index(
    1361             :         mode_type_neighbor_array,
    1362             :         cu_origin_y);
    1363        4876 :     uint32_t modeTypeTopNeighborIndex = get_neighbor_array_unit_top_index(
    1364             :         mode_type_neighbor_array,
    1365             :         cu_origin_x);
    1366        4876 :     uint32_t intraLumaModeLeftNeighborIndex = get_neighbor_array_unit_left_index(
    1367             :         intra_luma_mode_neighbor_array,
    1368             :         cu_origin_y);
    1369        4876 :     uint32_t intraLumaModeTopNeighborIndex = get_neighbor_array_unit_top_index(
    1370             :         intra_luma_mode_neighbor_array,
    1371             :         cu_origin_x);
    1372             : 
    1373        4876 :     uint32_t topContext = 0, leftContext = 0;
    1374             : 
    1375         136 :     uint32_t left_neighbor_mode = (uint32_t)(
    1376        4876 :         (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] != INTRA_MODE) ? (uint32_t)DC_PRED :
    1377        4740 :         intra_luma_mode_neighbor_array->left_array[intraLumaModeLeftNeighborIndex]);
    1378             : 
    1379         175 :     uint32_t top_neighbor_mode = (uint32_t)(
    1380        4876 :         (mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] != INTRA_MODE) ? (uint32_t)DC_PRED :
    1381        4701 :         intra_luma_mode_neighbor_array->top_array[intraLumaModeTopNeighborIndex]);
    1382             : 
    1383        4876 :     topContext = intra_mode_context[top_neighbor_mode];
    1384        4876 :     leftContext = intra_mode_context[left_neighbor_mode];
    1385             : 
    1386        4876 :     aom_write_symbol(
    1387             :         ec_writer,
    1388             :         luma_mode,
    1389        4876 :         frameContext->kf_y_cdf[topContext][leftContext],
    1390             :         INTRA_MODES);
    1391             : 
    1392        4876 :     if (cu_ptr->pred_mode != INTRA_MODE_4x4)
    1393        4876 :         if (bsize >= BLOCK_8X8 && cu_ptr->prediction_unit_array[0].is_directional_mode_flag) {
    1394        1111 :             aom_write_symbol(ec_writer,
    1395        1111 :                 cu_ptr->prediction_unit_array[0].angle_delta[PLANE_TYPE_Y] + MAX_ANGLE_DELTA,
    1396        1111 :                 frameContext->angle_delta_cdf[luma_mode - V_PRED],
    1397             :                 2 * MAX_ANGLE_DELTA + 1);
    1398             :         }
    1399             : 
    1400        4876 :     return;
    1401             : }
    1402             : /*********************************************************************
    1403             : * EncodeIntraLumaModeNonKeyAv1
    1404             : *   Encodes the Intra Luma Mode for non Key frames
    1405             : *********************************************************************/
    1406        1542 : static void EncodeIntraLumaModeNonKeyAv1(
    1407             :     FRAME_CONTEXT           *frameContext,
    1408             :     AomWriter              *ec_writer,
    1409             :     CodingUnit            *cu_ptr,
    1410             :     BlockSize                bsize,
    1411             :     uint32_t                  luma_mode)
    1412             : {
    1413        1542 :     aom_write_symbol(
    1414             :         ec_writer,
    1415             :         luma_mode,
    1416        1542 :         frameContext->y_mode_cdf[size_group_lookup[bsize]],
    1417             :         INTRA_MODES);
    1418             : 
    1419        1542 :     if (cu_ptr->pred_mode != INTRA_MODE_4x4)
    1420        1542 :         if (bsize >= BLOCK_8X8 && cu_ptr->prediction_unit_array[0].is_directional_mode_flag) {
    1421         105 :             aom_write_symbol(ec_writer,
    1422         105 :                 cu_ptr->prediction_unit_array[0].angle_delta[PLANE_TYPE_Y] + MAX_ANGLE_DELTA,
    1423         105 :                 frameContext->angle_delta_cdf[luma_mode - V_PRED],
    1424             :                 2 * MAX_ANGLE_DELTA + 1);
    1425             :         }
    1426             : 
    1427        1542 :     return;
    1428             : }
    1429             : 
    1430        2058 : static void write_cfl_alphas(FRAME_CONTEXT *const ec_ctx, int32_t idx,
    1431             :     int32_t joint_sign, AomWriter *w) {
    1432        2058 :     aom_write_symbol(w, joint_sign, ec_ctx->cfl_sign_cdf, CFL_JOINT_SIGNS);
    1433             :     // Magnitudes are only signaled for nonzero codes.
    1434        2058 :     if (CFL_SIGN_U(joint_sign) != CFL_SIGN_ZERO) {
    1435        1981 :         AomCdfProb *cdf_u = ec_ctx->cfl_alpha_cdf[CFL_CONTEXT_U(joint_sign)];
    1436        1981 :         aom_write_symbol(w, CFL_IDX_U(idx), cdf_u, CFL_ALPHABET_SIZE);
    1437             :     }
    1438        2058 :     if (CFL_SIGN_V(joint_sign) != CFL_SIGN_ZERO) {
    1439        1836 :         AomCdfProb *cdf_v = ec_ctx->cfl_alpha_cdf[CFL_CONTEXT_V(joint_sign)];
    1440        1836 :         aom_write_symbol(w, CFL_IDX_V(idx), cdf_v, CFL_ALPHABET_SIZE);
    1441             :     }
    1442        2058 : }
    1443             : 
    1444             : /*********************************************************************
    1445             : * EncodeIntraChromaModeAv1
    1446             : *   Encodes the Intra Chroma Mode
    1447             : *********************************************************************/
    1448        5347 : static void EncodeIntraChromaModeAv1(
    1449             :     FRAME_CONTEXT           *frameContext,
    1450             :     AomWriter              *ec_writer,
    1451             :     CodingUnit            *cu_ptr,
    1452             :     BlockSize     bsize,
    1453             :     uint32_t                  luma_mode,
    1454             :     uint32_t                  chroma_mode,
    1455             :     uint8_t                   cflAllowed)
    1456             : {
    1457        5347 :     aom_write_symbol(
    1458             :         ec_writer,
    1459             :         chroma_mode,
    1460        5347 :         frameContext->uv_mode_cdf[cflAllowed][luma_mode],
    1461             :         UV_INTRA_MODES - !cflAllowed);
    1462             : 
    1463        5347 :     if (chroma_mode == UV_CFL_PRED)
    1464        2058 :         write_cfl_alphas(frameContext, cu_ptr->prediction_unit_array->cfl_alpha_idx, cu_ptr->prediction_unit_array->cfl_alpha_signs, ec_writer);
    1465             : 
    1466        5347 :     if (cu_ptr->pred_mode != INTRA_MODE_4x4)
    1467        5347 :         if (bsize >= BLOCK_8X8 && cu_ptr->prediction_unit_array[0].is_directional_chroma_mode_flag) {
    1468         408 :             aom_write_symbol(ec_writer,
    1469         408 :                 cu_ptr->prediction_unit_array[0].angle_delta[PLANE_TYPE_UV] + MAX_ANGLE_DELTA,
    1470         408 :                 frameContext->angle_delta_cdf[chroma_mode - V_PRED],
    1471             :                 2 * MAX_ANGLE_DELTA + 1);
    1472             :         }
    1473             : 
    1474        5347 :     return;
    1475             : }
    1476             : 
    1477             : /*********************************************************************
    1478             : * EncodeSkipModeAv1
    1479             : *   Encodes the skip Mode flag
    1480             : *********************************************************************/
    1481       20150 : static void EncodeSkipModeAv1(
    1482             :     FRAME_CONTEXT           *frameContext,
    1483             :     AomWriter              *ec_writer,
    1484             :     EbBool                 skipModeFlag,
    1485             :     uint32_t                  cu_origin_x,
    1486             :     uint32_t                  cu_origin_y,
    1487             :     NeighborArrayUnit    *skip_flag_neighbor_array)
    1488             : {
    1489             : 
    1490             :     //TODO: not coded in syntax for skip mode/ref-frame/global-mv in segmentation map
    1491       20150 :     uint32_t skipFlagLeftNeighborIndex = get_neighbor_array_unit_left_index(
    1492             :         skip_flag_neighbor_array,
    1493             :         cu_origin_y);
    1494       20149 :     uint32_t skipFlagTopNeighborIndex = get_neighbor_array_unit_top_index(
    1495             :         skip_flag_neighbor_array,
    1496             :         cu_origin_x);
    1497             : 
    1498       20150 :     uint32_t contextIndex = 0;
    1499             : 
    1500       20150 :     contextIndex =
    1501       38835 :         (skip_flag_neighbor_array->left_array[skipFlagLeftNeighborIndex] == (uint8_t)INVALID_NEIGHBOR_DATA) ? 0 :
    1502       18685 :         (skip_flag_neighbor_array->left_array[skipFlagLeftNeighborIndex]) ? 1 : 0;
    1503             : 
    1504       20150 :     contextIndex +=
    1505       38629 :         (skip_flag_neighbor_array->top_array[skipFlagTopNeighborIndex] == (uint8_t)INVALID_NEIGHBOR_DATA) ? 0 :
    1506       18479 :         (skip_flag_neighbor_array->top_array[skipFlagTopNeighborIndex]) ? 1 : 0;
    1507             : 
    1508       20150 :     aom_write_symbol(
    1509             :         ec_writer,
    1510             :         skipModeFlag ? 1 : 0,
    1511       20150 :         frameContext->skip_mode_cdfs[contextIndex],
    1512             :         2);
    1513             : 
    1514       20151 :     return;
    1515             : }
    1516             : /*********************************************************************
    1517             : * EncodePredModeAv1
    1518             : *   Encodes the Prediction Mode
    1519             : *********************************************************************/
    1520       20992 : static void EncodePredModeAv1(
    1521             :     FRAME_CONTEXT           *frameContext,
    1522             :     AomWriter              *ec_writer,
    1523             :     EbBool                 predModeFlag,
    1524             :     uint32_t                  cu_origin_x,
    1525             :     uint32_t                  cu_origin_y,
    1526             :     NeighborArrayUnit    *mode_type_neighbor_array)
    1527             : {
    1528       20992 :     uint32_t modeTypeLeftNeighborIndex = get_neighbor_array_unit_left_index(
    1529             :         mode_type_neighbor_array,
    1530             :         cu_origin_y);
    1531       20992 :     uint32_t modeTypeTopNeighborIndex = get_neighbor_array_unit_top_index(
    1532             :         mode_type_neighbor_array,
    1533             :         cu_origin_x);
    1534             : 
    1535       20993 :     uint32_t contextIndex = 0;
    1536             : 
    1537       20993 :     if (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] != (uint8_t)INVALID_MODE && mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] != (uint8_t)INVALID_MODE) {
    1538       34713 :         contextIndex = (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] == (uint8_t)INTRA_MODE && mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] == (uint8_t)INTRA_MODE) ? 3 :
    1539       16925 :             (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] == (uint8_t)INTRA_MODE || mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] == (uint8_t)INTRA_MODE) ? 1 : 0;
    1540             :     }
    1541        3205 :     else  if (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] != (uint8_t)INVALID_MODE)
    1542        1549 :         contextIndex = (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] == (uint8_t)INTRA_MODE) ? 2 : 0;
    1543        1656 :     else if (mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] != (uint8_t)INVALID_MODE)
    1544        1544 :         contextIndex = (mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] == (uint8_t)INTRA_MODE) ? 2 : 0;
    1545             :     else
    1546         112 :         contextIndex = 0;
    1547       20993 :     aom_write_symbol(
    1548             :         ec_writer,
    1549             :         predModeFlag == INTER_MODE ? 1 : 0,
    1550       20993 :         frameContext->intra_inter_cdf[contextIndex],
    1551             :         2);
    1552             : 
    1553       20993 :     return;
    1554             : }
    1555             : 
    1556             : //****************************************************************************************************//
    1557             : 
    1558             : /*********************************************************************
    1559             : * motion_mode_allowed
    1560             : *   checks the motion modes that are allowed for the current block
    1561             : *********************************************************************/
    1562             : 
    1563    31933900 : static INLINE int is_inter_mode(PredictionMode mode)
    1564             : {
    1565    31933900 :     return mode >= SINGLE_INTER_MODE_START && mode < SINGLE_INTER_MODE_END;
    1566             : }
    1567             : 
    1568             : #if OBMC_FLAG
    1569    12523200 : MotionMode obmc_motion_mode_allowed(
    1570             :     const PictureControlSet         *picture_control_set_ptr,
    1571             :     const CodingUnit                *cu_ptr,
    1572             :     const BlockSize                 bsize,
    1573             :     MvReferenceFrame                rf0,
    1574             :     MvReferenceFrame                rf1,
    1575             :     PredictionMode                  mode)
    1576             : {
    1577             : 
    1578    12523200 :     if(!picture_control_set_ptr->parent_pcs_ptr->pic_obmc_mode)
    1579      507181 :         return SIMPLE_TRANSLATION;
    1580             : 
    1581    12016000 :     FrameHeader *frm_hdr = &picture_control_set_ptr->parent_pcs_ptr->frm_hdr;
    1582             : 
    1583    12016000 :     if (!frm_hdr->is_motion_mode_switchable)
    1584           0 :         return SIMPLE_TRANSLATION;
    1585             : 
    1586    12016000 :     if (frm_hdr->force_integer_mv == 0) {
    1587    12016600 :         const TransformationType gm_type =
    1588    12016600 :             picture_control_set_ptr->parent_pcs_ptr->global_motion[rf0].wmtype;
    1589    12016600 :         if (is_global_mv_block(mode, bsize, gm_type))
    1590           0 :             return SIMPLE_TRANSLATION;
    1591             :     }
    1592             : 
    1593    19553000 :     if (is_motion_variation_allowed_bsize(bsize) &&
    1594    15070800 :         is_inter_mode(mode) &&
    1595     7536830 :         rf1 != INTRA_FRAME &&
    1596             :         !(rf1 > INTRA_FRAME)) // is_motion_variation_allowed_compound
    1597             :     {
    1598     7536850 :         if (!has_overlappable_candidates(cu_ptr)) // check_num_overlappable_neighbors
    1599       27556 :             return SIMPLE_TRANSLATION;
    1600             : 
    1601     7509300 :         return OBMC_CAUSAL;
    1602             :     }
    1603             :     else
    1604     4482280 :         return SIMPLE_TRANSLATION;
    1605             : }
    1606             : #endif
    1607             : 
    1608    33957000 : MotionMode motion_mode_allowed(
    1609             :     const PictureControlSet       *picture_control_set_ptr,
    1610             :     const CodingUnit              *cu_ptr,
    1611             :     const BlockSize                 bsize,
    1612             :     MvReferenceFrame                rf0,
    1613             :     MvReferenceFrame                rf1,
    1614             :     PredictionMode                  mode)
    1615             : {
    1616    33957000 :     FrameHeader *frm_hdr = &picture_control_set_ptr->parent_pcs_ptr->frm_hdr;
    1617    33957000 :     if(!frm_hdr->is_motion_mode_switchable)
    1618     3616600 :         return SIMPLE_TRANSLATION;
    1619             : 
    1620    30340400 :     if (frm_hdr->force_integer_mv == 0) {
    1621    30349800 :         const TransformationType gm_type =
    1622    30349800 :             picture_control_set_ptr->parent_pcs_ptr->global_motion[rf0].wmtype;
    1623    30349800 :         if (is_global_mv_block(mode, bsize, gm_type))
    1624      997389 :             return SIMPLE_TRANSLATION;
    1625             :     }
    1626             : 
    1627    53758300 :     if (is_motion_variation_allowed_bsize(bsize) &&
    1628    48816100 :         is_inter_mode(mode) &&
    1629    24411900 :         rf1 != INTRA_FRAME &&
    1630             :         !(rf1 > INTRA_FRAME) ) // is_motion_variation_allowed_compound
    1631             :     {
    1632    24412000 :         if (!has_overlappable_candidates(cu_ptr)) // check_num_overlappable_neighbors
    1633       92758 :             return SIMPLE_TRANSLATION;
    1634             : 
    1635    24319700 :         if (cu_ptr->prediction_unit_array[0].num_proj_ref >= 1 &&
    1636     4539600 :            (frm_hdr->allow_warped_motion)) // TODO(JS): when scale is added, put: && !av1_is_scaled(&(xd->block_refs[0]->sf))
    1637             :         {
    1638     2398380 :             if (frm_hdr->force_integer_mv)
    1639           0 :                 return OBMC_CAUSAL;
    1640     2398380 :             return WARPED_CAUSAL;
    1641             :         }
    1642    21921300 :         return OBMC_CAUSAL;
    1643             :     } else
    1644     4954540 :         return SIMPLE_TRANSLATION;
    1645             : }
    1646             : 
    1647             : /*********************************************************************
    1648             : * write_motion_mode
    1649             : *   Encodes the Motion Mode (obmc or warped)
    1650             : *********************************************************************/
    1651        9025 : static void write_motion_mode(
    1652             :     FRAME_CONTEXT            *frame_context,
    1653             :     AomWriter               *ec_writer,
    1654             :     BlockSize                 bsize,
    1655             :     MotionMode               motion_mode,
    1656             :     MvReferenceFrame          rf0,
    1657             :     MvReferenceFrame          rf1,
    1658             :     CodingUnit             *cu_ptr,
    1659             :     PictureControlSet      *picture_control_set_ptr)
    1660             : {
    1661        9025 :     const PredictionMode mode = cu_ptr->prediction_unit_array[0].inter_mode;
    1662             : 
    1663             :     MotionMode last_motion_mode_allowed =
    1664        9025 :         motion_mode_allowed(picture_control_set_ptr, cu_ptr, bsize, rf0, rf1, mode);
    1665             : 
    1666        9025 :     switch (last_motion_mode_allowed) {
    1667        5067 :     case SIMPLE_TRANSLATION: break;
    1668         606 :     case OBMC_CAUSAL:
    1669         606 :         aom_write_symbol(
    1670             :             ec_writer,
    1671             : #if OBMC_FLAG
    1672             :             motion_mode == OBMC_CAUSAL,
    1673             : #else
    1674             :             SIMPLE_TRANSLATION, // motion_mode == OBMC_CAUSAL, TODO: support OBMC
    1675             : #endif
    1676         606 :             frame_context->obmc_cdf[bsize],
    1677             :             2);
    1678         606 :         break;
    1679        3352 :     default:
    1680        3352 :         aom_write_symbol(
    1681             :             ec_writer,
    1682             :             motion_mode,
    1683        3352 :             frame_context->motion_mode_cdf[bsize],
    1684             :             MOTION_MODES);
    1685             :     }
    1686             : 
    1687        9025 :     return;
    1688             : }
    1689             : 
    1690             : //****************************************************************************************************//
    1691             : extern  int8_t av1_ref_frame_type(const MvReferenceFrame *const rf);
    1692             : uint16_t compound_mode_ctx_map[3][COMP_NEWMV_CTXS] = {
    1693             :    { 0, 1, 1, 1, 1 },
    1694             :    { 1, 2, 3, 4, 4 },
    1695             :    { 4, 4, 5, 6, 7 },
    1696             : };
    1697             : 
    1698       19449 : static int16_t Av1ModeContextAnalyzer(
    1699             :     const int16_t *const mode_context, const MvReferenceFrame *const rf) {
    1700       19449 :     const int8_t ref_frame = av1_ref_frame_type(rf);
    1701             : 
    1702       19448 :     if (rf[1] <= INTRA_FRAME) return mode_context[ref_frame];
    1703             : 
    1704        7145 :     const int16_t newmv_ctx = mode_context[ref_frame] & NEWMV_CTX_MASK;
    1705        7145 :     const int16_t refmv_ctx =
    1706        7145 :         (mode_context[ref_frame] >> REFMV_OFFSET) & REFMV_CTX_MASK;
    1707        7145 :     assert((refmv_ctx >> 1) < 3);
    1708        7145 :     const int16_t comp_ctx = compound_mode_ctx_map[refmv_ctx >> 1][AOMMIN(
    1709             :         newmv_ctx, COMP_NEWMV_CTXS - 1)];
    1710        7145 :     return comp_ctx;
    1711             : }
    1712             : 
    1713         120 : EbErrorType encode_slice_finish(
    1714             :     EntropyCoder        *entropy_coder_ptr)
    1715             : {
    1716         120 :     EbErrorType return_error = EB_ErrorNone;
    1717             : 
    1718         120 :     aom_stop_encode(&entropy_coder_ptr->ec_writer);
    1719             : 
    1720         120 :     return return_error;
    1721             : }
    1722             : 
    1723         296 : EbErrorType reset_bitstream(
    1724             :     EbPtr bitstream_ptr)
    1725             : {
    1726         296 :     EbErrorType return_error = EB_ErrorNone;
    1727         296 :     OutputBitstreamUnit *output_bitstream_ptr = (OutputBitstreamUnit*)bitstream_ptr;
    1728             : 
    1729         296 :     output_bitstream_reset(
    1730             :         output_bitstream_ptr);
    1731             : 
    1732         296 :     return return_error;
    1733             : }
    1734             : 
    1735         124 : EbErrorType reset_entropy_coder(
    1736             :     EncodeContext            *encode_context_ptr,
    1737             :     EntropyCoder             *entropy_coder_ptr,
    1738             :     uint32_t                      qp,
    1739             :     EB_SLICE                    slice_type)
    1740             : {
    1741         124 :     EbErrorType return_error = EB_ErrorNone;
    1742             : 
    1743             :     (void)encode_context_ptr;
    1744             :     (void)slice_type;
    1745         124 :     eb_av1_default_coef_probs(entropy_coder_ptr->fc, qp);
    1746         124 :     init_mode_probs(entropy_coder_ptr->fc);
    1747             : 
    1748         124 :     return return_error;
    1749             : }
    1750             : 
    1751         176 : EbErrorType copy_rbsp_bitstream_to_payload(
    1752             :     Bitstream *bitstream_ptr,
    1753             :     EbByte      output_buffer,
    1754             :     uint32_t      *output_buffer_index,
    1755             :     uint32_t      *output_buffer_size,
    1756             :     EncodeContext         *encode_context_ptr)
    1757             : {
    1758         176 :     EbErrorType return_error = EB_ErrorNone;
    1759         176 :     OutputBitstreamUnit *output_bitstream_ptr = (OutputBitstreamUnit*)bitstream_ptr->output_bitstream_ptr;
    1760             : 
    1761         176 :     CHECK_REPORT_ERROR(
    1762             :         ((output_bitstream_ptr->written_bits_count >> 3) + (*output_buffer_index) < (*output_buffer_size)),
    1763             :         encode_context_ptr->app_callback_ptr,
    1764             :         EB_ENC_EC_ERROR2);
    1765             : 
    1766         176 :     output_bitstream_rbsp_to_payload(
    1767             :         output_bitstream_ptr,
    1768             :         output_buffer,
    1769             :         output_buffer_index,
    1770             :         output_buffer_size,
    1771             :         0);
    1772             : 
    1773         176 :     return return_error;
    1774             : }
    1775             : 
    1776           6 : static void bitstream_dctor(EbPtr p)
    1777             : {
    1778           6 :     Bitstream *obj = (Bitstream*)p;
    1779           6 :     OutputBitstreamUnit *output_bitstream_ptr = (OutputBitstreamUnit *)obj->output_bitstream_ptr;
    1780           6 :     EB_DELETE(output_bitstream_ptr);
    1781           6 : }
    1782             : 
    1783           6 : EbErrorType bitstream_ctor(
    1784             :     Bitstream *bitstream_ptr,
    1785             :     uint32_t buffer_size)
    1786             : {
    1787           6 :     EbErrorType return_error = EB_ErrorNone;
    1788             :     OutputBitstreamUnit* output_bitstream_ptr;
    1789             : 
    1790           6 :     bitstream_ptr->dctor = bitstream_dctor;
    1791             : 
    1792           6 :     EB_NEW(
    1793             :         output_bitstream_ptr,
    1794             :         output_bitstream_unit_ctor,
    1795             :         buffer_size);
    1796           6 :     bitstream_ptr->output_bitstream_ptr = output_bitstream_ptr;
    1797             : 
    1798           6 :     return return_error;
    1799             : }
    1800             : 
    1801          12 : static void entropy_coder_dctor(EbPtr p)
    1802             : {
    1803          12 :     EntropyCoder *obj = (EntropyCoder *)p;
    1804          12 :     CabacEncodeContext *cabacEncCtxPtr = (CabacEncodeContext*)obj->cabac_encode_context_ptr;
    1805          12 :     OutputBitstreamUnit *output_bitstream_ptr = (OutputBitstreamUnit *)cabacEncCtxPtr->bac_enc_context.m_pc_t_com_bit_if;
    1806             : 
    1807          12 :     EB_DELETE(output_bitstream_ptr);
    1808             : 
    1809          12 :     output_bitstream_ptr = (OutputBitstreamUnit*)obj->ec_output_bitstream_ptr;
    1810          12 :     EB_DELETE(output_bitstream_ptr);
    1811             : 
    1812          12 :     EB_FREE(obj->fc);
    1813          12 :     EB_FREE(obj->cabac_encode_context_ptr);
    1814          12 : }
    1815          12 : EbErrorType entropy_coder_ctor(
    1816             :     EntropyCoder *entropy_coder_ptr,
    1817             :     uint32_t buffer_size)
    1818             : {
    1819          12 :     EbErrorType return_error = EB_ErrorNone;
    1820             :     OutputBitstreamUnit *output_bitstream_ptr;
    1821             : 
    1822          12 :     entropy_coder_ptr->dctor = entropy_coder_dctor;
    1823             : 
    1824          12 :     EB_CALLOC(entropy_coder_ptr->cabac_encode_context_ptr, 1, sizeof(CabacEncodeContext));
    1825             : 
    1826          12 :     EB_MALLOC(entropy_coder_ptr->fc, sizeof(FRAME_CONTEXT));
    1827             : 
    1828             : 
    1829          12 :     EB_NEW(
    1830             :         output_bitstream_ptr,
    1831             :         output_bitstream_unit_ctor,
    1832             :         buffer_size);
    1833             : 
    1834          12 :     entropy_coder_ptr->ec_output_bitstream_ptr = output_bitstream_ptr;
    1835             : 
    1836          12 :     EB_NEW(
    1837             :         output_bitstream_ptr,
    1838             :         output_bitstream_unit_ctor,
    1839             :         buffer_size);
    1840          12 :     ((CabacEncodeContext*)entropy_coder_ptr->cabac_encode_context_ptr)->bac_enc_context.m_pc_t_com_bit_if = output_bitstream_ptr;
    1841          12 :     return return_error;
    1842             : }
    1843             : 
    1844         120 : EbPtr entropy_coder_get_bitstream_ptr(
    1845             :     EntropyCoder *entropy_coder_ptr)
    1846             : {
    1847         120 :     CabacEncodeContext *cabacEncCtxPtr = (CabacEncodeContext*)entropy_coder_ptr->cabac_encode_context_ptr;
    1848         120 :     EbPtr bitstream_ptr = cabacEncCtxPtr->bac_enc_context.m_pc_t_com_bit_if;
    1849             : 
    1850         120 :     return bitstream_ptr;
    1851             : }
    1852             : 
    1853             : //*******************************************************************************************//
    1854             : //*******************************************************************************************//
    1855             : //*******************************************************************************************//
    1856             : //*******************************************************************************************//
    1857             : // aom_integer.c
    1858             : static const size_t kMaximumLeb128Size = 8;
    1859             : static const uint64_t kMaximumLeb128Value = 0xFFFFFFFFFFFFFF;  // 2 ^ 56 - 1
    1860             : 
    1861         596 : size_t eb_aom_uleb_size_in_bytes(uint64_t value) {
    1862         596 :     size_t size = 0;
    1863             :     do {
    1864         730 :         ++size;
    1865         730 :     } while ((value >>= 7) != 0);
    1866         596 :     return size;
    1867             : }
    1868             : 
    1869         298 : int32_t eb_aom_uleb_encode(uint64_t value, size_t available, uint8_t *coded_value,
    1870             :     size_t *coded_size) {
    1871         298 :     const size_t leb_size = eb_aom_uleb_size_in_bytes(value);
    1872         298 :     if (value > kMaximumLeb128Value || leb_size > kMaximumLeb128Size ||
    1873         298 :         leb_size > available || !coded_value || !coded_size) {
    1874           0 :         return -1;
    1875             :     }
    1876             : 
    1877         663 :     for (size_t i = 0; i < leb_size; ++i) {
    1878         365 :         uint8_t byte = value & 0x7f;
    1879         365 :         value >>= 7;
    1880             : 
    1881         365 :         if (value != 0) byte |= 0x80;  // Signal that more bytes follow.
    1882             : 
    1883         365 :         *(coded_value + i) = byte;
    1884             :     }
    1885             : 
    1886         298 :     *coded_size = leb_size;
    1887         298 :     return 0;
    1888             : }
    1889             : 
    1890          58 : int32_t eb_aom_wb_is_byte_aligned(const struct AomWriteBitBuffer *wb) {
    1891          58 :     return (wb->bit_offset % CHAR_BIT == 0);
    1892             : }
    1893             : 
    1894         476 : uint32_t eb_aom_wb_bytes_written(const struct AomWriteBitBuffer *wb) {
    1895         476 :     return wb->bit_offset / CHAR_BIT + (wb->bit_offset % CHAR_BIT > 0);
    1896             : }
    1897             : 
    1898       22863 : void eb_aom_wb_write_bit(struct AomWriteBitBuffer *wb, int32_t bit) {
    1899       22863 :     const int32_t off = (int32_t)wb->bit_offset;
    1900       22863 :     const int32_t p = off / CHAR_BIT;
    1901       22863 :     const int32_t q = CHAR_BIT - 1 - off % CHAR_BIT;
    1902       22863 :     if (q == CHAR_BIT - 1) {
    1903             :         // Zero next char and write bit
    1904        2936 :         wb->bit_buffer[p] = (uint8_t)(bit << q);
    1905             :     }
    1906             :     else {
    1907       19927 :         wb->bit_buffer[p] &= ~(1 << q);
    1908       19927 :         wb->bit_buffer[p] |= bit << q;
    1909             :     }
    1910       22863 :     wb->bit_offset = off + 1;
    1911       22863 : }
    1912             : 
    1913           0 : void eb_aom_wb_overwrite_bit(struct AomWriteBitBuffer *wb, int32_t bit) {
    1914             :     // Do not zero bytes but overwrite exisiting values
    1915           0 :     const int32_t off = (int32_t)wb->bit_offset;
    1916           0 :     const int32_t p = off / CHAR_BIT;
    1917           0 :     const int32_t q = CHAR_BIT - 1 - off % CHAR_BIT;
    1918           0 :     wb->bit_buffer[p] &= ~(1 << q);
    1919           0 :     wb->bit_buffer[p] |= bit << q;
    1920           0 :     wb->bit_offset = off + 1;
    1921           0 : }
    1922             : 
    1923        4602 : void eb_aom_wb_write_literal(struct AomWriteBitBuffer *wb, int32_t data, int32_t bits) {
    1924             :     int32_t bit;
    1925       20968 :     for (bit = bits - 1; bit >= 0; bit--) eb_aom_wb_write_bit(wb, (data >> bit) & 1);
    1926        4602 : }
    1927             : 
    1928           0 : void eb_aom_wb_write_inv_signed_literal(struct AomWriteBitBuffer *wb, int32_t data,
    1929             :     int32_t bits) {
    1930           0 :     eb_aom_wb_write_literal(wb, data, bits + 1);
    1931           0 : }
    1932             : 
    1933             : //*******************************************************************************************//
    1934             : 
    1935       12303 : static void WriteInterMode(
    1936             :     FRAME_CONTEXT       *frameContext,
    1937             :     AomWriter          *ec_writer,
    1938             :     PredictionMode     mode,
    1939             :     const int16_t       mode_ctx,
    1940             :     uint32_t                  cu_origin_x,
    1941             :     uint32_t                  cu_origin_y)
    1942             : {
    1943             :     (void)cu_origin_x;
    1944             :     (void)cu_origin_y;
    1945       12303 :     int16_t newmv_ctx = mode_ctx & NEWMV_CTX_MASK;
    1946       12303 :     assert(newmv_ctx<NEWMV_MODE_CONTEXTS);
    1947       12303 :     aom_write_symbol(ec_writer, mode != NEWMV, frameContext->newmv_cdf[newmv_ctx], 2);
    1948             : 
    1949       12303 :     if (mode != NEWMV) {
    1950        5219 :         const int16_t zeromv_ctx =
    1951        5219 :             (mode_ctx >> GLOBALMV_OFFSET) & GLOBALMV_CTX_MASK;
    1952        5219 :         aom_write_symbol(ec_writer, mode != GLOBALMV, frameContext->zeromv_cdf[zeromv_ctx], 2);
    1953             : 
    1954        5219 :         if (mode != GLOBALMV) {
    1955        4916 :             int16_t refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
    1956        4916 :             assert(refmv_ctx<REFMV_MODE_CONTEXTS);
    1957        4916 :             aom_write_symbol(ec_writer, mode != NEARESTMV, frameContext->refmv_cdf[refmv_ctx], 2);
    1958             :         }
    1959             :     }
    1960       12303 : }
    1961             : 
    1962             : //extern INLINE int8_t av1_ref_frame_type(const MvReferenceFrame *const rf);
    1963             : extern uint8_t av1_drl_ctx(const CandidateMv *ref_mv_stack, int32_t ref_idx);
    1964             : 
    1965       13242 : void WriteDrlIdx(
    1966             :     FRAME_CONTEXT       *frameContext,
    1967             :     AomWriter          *ec_writer,
    1968             :     CodingUnit        *cu_ptr) {
    1969             :     //uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
    1970       13242 :     uint8_t ref_frame_type = cu_ptr->prediction_unit_array[0].ref_frame_type;
    1971       13242 :     MacroBlockD*  xd = cu_ptr->av1xd;
    1972             :     //assert(mbmi->ref_mv_idx < 3);
    1973             : 
    1974             :     //xd->ref_mv_stack[ref_frame][ref_mv_idx].comp_mv;
    1975             : 
    1976       13242 :     const int32_t new_mv = cu_ptr->pred_mode == NEWMV || cu_ptr->pred_mode == NEW_NEWMV;
    1977       13242 :     if (new_mv) {
    1978             :         int32_t idx;
    1979       16293 :         for (idx = 0; idx < 2; ++idx) {
    1980       14210 :             if (xd->ref_mv_count[ref_frame_type] > idx + 1) {
    1981             :                 uint8_t drl_ctx =
    1982       12488 :                     av1_drl_ctx(xd->final_ref_mv_stack, idx);
    1983             : 
    1984       12488 :                 aom_write_symbol(ec_writer, cu_ptr->drl_index != idx, frameContext->drl_cdf[drl_ctx],
    1985             :                     2);
    1986             : 
    1987       12488 :                 if (cu_ptr->drl_index == idx) return;
    1988             :             }
    1989             :         }
    1990        2083 :         return;
    1991             :     }
    1992             : 
    1993        3927 :     if (have_nearmv_in_inter_mode(cu_ptr->pred_mode)) {
    1994             :         int32_t idx;
    1995             :         // TODO(jingning): Temporary solution to compensate the NEARESTMV offset.
    1996        8327 :         for (idx = 1; idx < 3; ++idx) {
    1997        6329 :             if (xd->ref_mv_count[ref_frame_type] > idx + 1) {
    1998             :                 uint8_t drl_ctx =
    1999        3148 :                     av1_drl_ctx(xd->final_ref_mv_stack, idx);
    2000             : 
    2001        3148 :                 aom_write_symbol(ec_writer, cu_ptr->drl_index != (idx - 1),
    2002        3148 :                     frameContext->drl_cdf[drl_ctx], 2);
    2003             : 
    2004        3148 :                 if (cu_ptr->drl_index == (idx - 1)) return;
    2005             :             }
    2006             :         }
    2007        1998 :         return;
    2008             :     }
    2009             : }
    2010             : 
    2011             : extern MvJointType av1_get_mv_joint(int32_t diff[2]);
    2012       18453 : static void encode_mv_component(AomWriter *w, int32_t comp, NmvComponent *mvcomp,
    2013             :     MvSubpelPrecision precision) {
    2014             :     int32_t offset;
    2015       18453 :     const int32_t sign = comp < 0;
    2016       18453 :     const int32_t mag = sign ? -comp : comp;
    2017       18453 :     const int32_t mv_class = av1_get_mv_class(mag - 1, &offset);
    2018       18453 :     const int32_t d = offset >> 3;         // int32_t mv data
    2019       18453 :     const int32_t fr = (offset >> 1) & 3;  // fractional mv data
    2020       18453 :     const int32_t hp = offset & 1;         // high precision mv data
    2021             : 
    2022       18453 :     assert(comp != 0);
    2023             : 
    2024             :     // Sign
    2025       18453 :     aom_write_symbol(w, sign, mvcomp->sign_cdf, 2);
    2026             : 
    2027             :     // Class
    2028       18453 :     aom_write_symbol(w, mv_class, mvcomp->classes_cdf, MV_CLASSES);
    2029             : 
    2030             :     // Integer bits
    2031       18453 :     if (mv_class == MV_CLASS_0)
    2032       17751 :         aom_write_symbol(w, d, mvcomp->class0_cdf, CLASS0_SIZE);
    2033             :     else {
    2034             :         int32_t i;
    2035         702 :         const int32_t n = mv_class + CLASS0_BITS - 1;  // number of bits
    2036        2352 :         for (i = 0; i < n; ++i)
    2037        1650 :             aom_write_symbol(w, (d >> i) & 1, mvcomp->bits_cdf[i], 2);
    2038             :     }
    2039             :     // Fractional bits
    2040       18453 :     if (precision > MV_SUBPEL_NONE) {
    2041       18453 :         aom_write_symbol(
    2042             :             w, fr,
    2043             :             mv_class == MV_CLASS_0 ? mvcomp->class0_fp_cdf[d] : mvcomp->fp_cdf,
    2044             :             MV_FP_SIZE);
    2045             :     }
    2046             : 
    2047             :     // High precision bit
    2048       18453 :     if (precision > MV_SUBPEL_LOW_PRECISION)
    2049        8093 :         aom_write_symbol(
    2050             :             w, hp, mv_class == MV_CLASS_0 ? mvcomp->class0_hp_cdf : mvcomp->hp_cdf,
    2051             :             2);
    2052       18453 : }
    2053             : 
    2054       11617 : MvJointType av1_get_mv_joint_diff(int32_t diff[2]) {
    2055       11617 :     if (diff[0] == 0)
    2056        2582 :         return diff[1] == 0 ? MV_JOINT_ZERO : MV_JOINT_HNZVZ;
    2057             :     else
    2058        9035 :         return diff[1] == 0 ? MV_JOINT_HZVNZ : MV_JOINT_HNZVNZ;
    2059             : }
    2060             : 
    2061       11617 : void eb_av1_encode_mv(
    2062             :     PictureParentControlSet   *pcs_ptr,
    2063             :     AomWriter                  *ec_writer,
    2064             :     const MV *mv,
    2065             :     const MV *ref,
    2066             :     NmvContext *mvctx,
    2067             :     int32_t usehp) {
    2068       11617 :     if (is_mv_valid(mv) == 0)
    2069           0 :         printf("Corrupted MV\n");
    2070             : 
    2071       11617 :     int32_t diff[2] = { mv->row - ref->row, mv->col - ref->col };
    2072       11617 :     const MvJointType j = av1_get_mv_joint_diff(diff);
    2073             : 
    2074       11617 :     if (pcs_ptr->frm_hdr.force_integer_mv)
    2075           0 :         usehp = MV_SUBPEL_NONE;
    2076       11617 :     aom_write_symbol(ec_writer, j, mvctx->joints_cdf, MV_JOINTS);
    2077       11617 :     if (mv_joint_vertical(j))
    2078        9035 :         encode_mv_component(ec_writer, diff[0], &mvctx->comps[0], (MvSubpelPrecision)usehp);
    2079             : 
    2080       11617 :     if (mv_joint_horizontal(j))
    2081        9418 :         encode_mv_component(ec_writer, diff[1], &mvctx->comps[1], (MvSubpelPrecision)usehp);
    2082             : 
    2083             :     // If auto_mv_step_size is enabled then keep track of the largest
    2084             :     // motion vector component used.
    2085             :     //if (cpi->sf.mv.auto_mv_step_size) {
    2086             :     //    uint32_t maxv = AOMMAX(abs(mv->row), abs(mv->col)) >> 3;
    2087             :     //    cpi->max_mv_magnitude = AOMMAX(maxv, cpi->max_mv_magnitude);
    2088             :     //}
    2089       11617 : }
    2090             : 
    2091             : ///InterpFilter av1_extract_interp_filter(uint32_t filters,
    2092             : //    int32_t x_filter) {
    2093             : //    return (InterpFilter)((filters >> (x_filter ? 16 : 0)) & 0xffff);
    2094             : //}
    2095             : #define INTER_FILTER_COMP_OFFSET (SWITCHABLE_FILTERS + 1)
    2096             : #define INTER_FILTER_DIR_OFFSET ((SWITCHABLE_FILTERS + 1) * 2)
    2097             : 
    2098   132076000 : int32_t eb_av1_get_pred_context_switchable_interp(
    2099             :     NeighborArrayUnit     *ref_frame_type_neighbor_array,
    2100             :     MvReferenceFrame rf0,
    2101             :     MvReferenceFrame rf1,
    2102             :     NeighborArrayUnit32     *interpolation_type_neighbor_array,
    2103             :     uint32_t cu_origin_x,
    2104             :     uint32_t cu_origin_y,
    2105             :     //const MacroBlockD *xd,
    2106             :     int32_t dir
    2107             : ) {
    2108   132076000 :     uint32_t interpolationTypeLeftNeighborIndex = get_neighbor_array_unit_left_index32(
    2109             :         interpolation_type_neighbor_array,
    2110             :         cu_origin_y);
    2111   132060000 :     uint32_t interpolationTypeTopNeighborIndex = get_neighbor_array_unit_top_index32(
    2112             :         interpolation_type_neighbor_array,
    2113             :         cu_origin_x);
    2114             : 
    2115   132074000 :     uint32_t rfLeftNeighborIndex = get_neighbor_array_unit_left_index(
    2116             :         ref_frame_type_neighbor_array,
    2117             :         cu_origin_y);
    2118   132221000 :     uint32_t rfTopNeighborIndex = get_neighbor_array_unit_top_index(
    2119             :         ref_frame_type_neighbor_array,
    2120             :         cu_origin_x);
    2121             : 
    2122             :     //const MbModeInfo *const mbmi = xd->mi[0];
    2123   132510000 :     const int32_t ctx_offset =
    2124   132510000 :         (rf1 > INTRA_FRAME) * INTER_FILTER_COMP_OFFSET;
    2125   132510000 :     MvReferenceFrame ref_frame =
    2126             :         (dir < 2) ? rf0 : rf1;
    2127             :     // Note:
    2128             :     // The mode info data structure has a one element border above and to the
    2129             :     // left of the entries corresponding to real macroblocks.
    2130             :     // The prediction flags in these dummy entries are initialized to 0.
    2131   132510000 :     int32_t filter_type_ctx = ctx_offset + (dir & 0x01) * INTER_FILTER_DIR_OFFSET;
    2132   132510000 :     int32_t left_type = SWITCHABLE_FILTERS;
    2133   132510000 :     int32_t above_type = SWITCHABLE_FILTERS;
    2134             : 
    2135   132510000 :     if (cu_origin_x != 0 /*&& interpolation_type_neighbor_array->left_array[interpolationTypeLeftNeighborIndex] != SWITCHABLE_FILTERS*/) {
    2136             :         MvReferenceFrame rf_left[2];
    2137   126459000 :         av1_set_ref_frame(rf_left, ref_frame_type_neighbor_array->left_array[rfLeftNeighborIndex]);
    2138   126429000 :         uint32_t leftNeigh = (uint32_t)interpolation_type_neighbor_array->left_array[interpolationTypeLeftNeighborIndex];
    2139   126429000 :         left_type = (rf_left[0] == ref_frame || rf_left[1] == ref_frame) ? av1_extract_interp_filter(leftNeigh, dir & 0x01) : SWITCHABLE_FILTERS;
    2140             :     }
    2141             :     //get_ref_filter_type(xd->mi[-1], xd, dir, ref_frame);
    2142             : 
    2143   132707000 :     if (cu_origin_y != 0 /*&& interpolation_type_neighbor_array->top_array[interpolationTypeTopNeighborIndex] != SWITCHABLE_FILTERS*/) {
    2144             :         MvReferenceFrame rf_above[2];
    2145   125162000 :         av1_set_ref_frame(rf_above, ref_frame_type_neighbor_array->top_array[rfTopNeighborIndex]);
    2146   125129000 :         uint32_t aboveNeigh = (uint32_t)interpolation_type_neighbor_array->top_array[interpolationTypeTopNeighborIndex];
    2147             : 
    2148   125129000 :         above_type = (rf_above[0] == ref_frame || rf_above[1] == ref_frame) ? av1_extract_interp_filter(aboveNeigh, dir & 0x01) : SWITCHABLE_FILTERS;
    2149             :         //get_ref_filter_type(xd->mi[-xd->mi_stride], xd, dir, ref_frame);
    2150             :     }
    2151             : 
    2152   132906000 :     if (left_type == above_type)
    2153   113135000 :         filter_type_ctx += left_type;
    2154    19770600 :     else if (left_type == SWITCHABLE_FILTERS) {
    2155     5299600 :         assert(above_type != SWITCHABLE_FILTERS);
    2156     5299600 :         filter_type_ctx += above_type;
    2157             :     }
    2158    14471000 :     else if (above_type == SWITCHABLE_FILTERS) {
    2159     6223800 :         assert(left_type != SWITCHABLE_FILTERS);
    2160     6223800 :         filter_type_ctx += left_type;
    2161             :     }
    2162             :     else
    2163     8247220 :         filter_type_ctx += SWITCHABLE_FILTERS;
    2164             :     //  printf("\t %d\t %d\t %d",filter_type_ctx,left_type ,above_type);
    2165             : 
    2166   132906000 :     return filter_type_ctx;
    2167             : }
    2168             : 
    2169       15432 : /*INLINE*/ int32_t is_nontrans_global_motion_EC(
    2170             :     MvReferenceFrame             rf0,
    2171             :     MvReferenceFrame             rf1,
    2172             :     CodingUnit                  *cu_ptr,
    2173             :     BlockSize sb_type,
    2174             :     PictureParentControlSet   *pcs_ptr) {
    2175             :     int32_t ref;
    2176             : 
    2177             :     // First check if all modes are GLOBALMV
    2178       15432 :     if (cu_ptr->pred_mode != GLOBALMV && cu_ptr->pred_mode != GLOBAL_GLOBALMV)
    2179       15432 :         return 0;
    2180             : 
    2181           0 :     if (MIN(mi_size_wide[sb_type], mi_size_high[sb_type]) < 2)
    2182           0 :         return 0;
    2183             : 
    2184             :     // Now check if all global motion is non translational
    2185           0 :     for (ref = 0; ref < 1 + cu_ptr->prediction_unit_array->is_compound; ++ref) {
    2186           0 :         if (pcs_ptr->global_motion[ref ? rf1 : rf0].wmtype == TRANSLATION)
    2187           0 :             return 0;
    2188             :     }
    2189           0 :     return 1;
    2190             : }
    2191       19451 : static int32_t av1_is_interp_needed(
    2192             :     MvReferenceFrame            rf0,
    2193             :     MvReferenceFrame            rf1,
    2194             :     CodingUnit               *cu_ptr,
    2195             :     BlockSize                   bsize,
    2196             :     PictureParentControlSet  *pcs_ptr)
    2197             : {
    2198       19451 :     if (cu_ptr->skip_flag)
    2199           0 :         return 0;
    2200             : 
    2201       19451 :     if (cu_ptr->prediction_unit_array[0].motion_mode == WARPED_CAUSAL)
    2202        4019 :         return 0;
    2203             : 
    2204       15432 :     if (is_nontrans_global_motion_EC(rf0, rf1, cu_ptr, bsize, pcs_ptr))
    2205           0 :         return 0;
    2206             : 
    2207       15432 :     return 1;
    2208             : }
    2209             : 
    2210       19451 : void write_mb_interp_filter(
    2211             :     NeighborArrayUnit     *ref_frame_type_neighbor_array,
    2212             :     BlockSize bsize,
    2213             :     MvReferenceFrame rf0,
    2214             :     MvReferenceFrame rf1,
    2215             :     PictureParentControlSet   *pcs_ptr,
    2216             :     AomWriter                  *ec_writer,
    2217             :     CodingUnit             *cu_ptr,
    2218             :     EntropyCoder *entropy_coder_ptr,
    2219             :     NeighborArrayUnit32     *interpolation_type_neighbor_array,
    2220             :     uint32_t blkOriginX,
    2221             :     uint32_t blkOriginY)
    2222             : {
    2223       19451 :     Av1Common *const cm = pcs_ptr->av1_cm; //&cpi->common;
    2224             :     //const MbModeInfo *const mbmi = xd->mi[0];
    2225             :     //FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
    2226             : 
    2227       19451 :     if (!av1_is_interp_needed(rf0, rf1, cu_ptr, bsize, pcs_ptr)) {
    2228             :         /* assert(mbmi->interp_filters ==
    2229             :                 av1_broadcast_interp_filter(
    2230             :                     av1_unswitchable_filter(cm->interp_filter)));*/
    2231        4019 :         return;
    2232             :     }
    2233       15432 :     if (cm->interp_filter == SWITCHABLE) {
    2234             :         int32_t dir;
    2235       15432 :         for (dir = 0; dir < 2; ++dir) {
    2236             :             // printf("\nP:%d\tX: %d\tY:%d\t %d",(pcs_ptr)->picture_number,blkOriginX,blkOriginY ,((ec_writer)->ec).rng);
    2237       15432 :             const int32_t ctx = eb_av1_get_pred_context_switchable_interp(
    2238             :                 ref_frame_type_neighbor_array,
    2239             :                 rf0,
    2240             :                 rf1,
    2241             :                 interpolation_type_neighbor_array,
    2242             :                 blkOriginX,
    2243             :                 blkOriginY,
    2244             :                 //xd,
    2245             :                 dir
    2246             :             );
    2247       15431 :             InterpFilter filter = av1_extract_interp_filter(cu_ptr->interp_filters, dir);
    2248       15431 :             assert(ctx < SWITCHABLE_FILTER_CONTEXTS);
    2249       15431 :             assert(filter < CDF_SIZE(SWITCHABLE_FILTERS));
    2250       15431 :             aom_write_symbol(ec_writer, filter, /*ec_ctx*/entropy_coder_ptr->fc->switchable_interp_cdf[ctx],
    2251             :                 SWITCHABLE_FILTERS);
    2252             : 
    2253             :             // ++pcs_ptr->interp_filter_selected[0][filter];
    2254       15431 :             if (pcs_ptr->sequence_control_set_ptr->seq_header.enable_dual_filter == 0) return;
    2255             :         }
    2256             :     }
    2257             : }
    2258             : 
    2259        7147 : static void WriteInterCompoundMode(
    2260             :     FRAME_CONTEXT       *frameContext,
    2261             :     AomWriter          *ec_writer,
    2262             :     PredictionMode     mode,
    2263             :     const int16_t       mode_ctx) {
    2264        7147 :     assert(is_inter_compound_mode(mode));
    2265        7147 :     aom_write_symbol(ec_writer, INTER_COMPOUND_OFFSET(mode),
    2266        7147 :         frameContext->inter_compound_mode_cdf[mode_ctx],
    2267             :         INTER_COMPOUND_MODES);
    2268        7147 : }
    2269             : 
    2270      811354 : int32_t eb_av1_get_reference_mode_context(
    2271             :     uint32_t                  cu_origin_x,
    2272             :     uint32_t                  cu_origin_y,
    2273             :     NeighborArrayUnit    *mode_type_neighbor_array,
    2274             :     NeighborArrayUnit    *inter_pred_dir_neighbor_array)
    2275             : {
    2276      811354 :     uint32_t modeTypeLeftNeighborIndex = get_neighbor_array_unit_left_index(
    2277             :         mode_type_neighbor_array,
    2278             :         cu_origin_y);
    2279      811319 :     uint32_t modeTypeTopNeighborIndex = get_neighbor_array_unit_top_index(
    2280             :         mode_type_neighbor_array,
    2281             :         cu_origin_x);
    2282             : 
    2283      811350 :     int32_t ctx = 0;
    2284             : 
    2285             :     // Note:
    2286             :     // The mode info data structure has a one element border above and to the
    2287             :     // left of the entries corresponding to real macroblocks.
    2288             :     // The prediction flags in these dummy entries are initialized to 0.
    2289     1555950 :     if (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] != (uint8_t)INVALID_MODE && mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] != (uint8_t)INVALID_MODE) {  // both edges available
    2290      744602 :         const int32_t topIntra = (mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] == (uint8_t)INTRA_MODE);
    2291      744602 :         const int32_t leftIntra = (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] == (uint8_t)INTRA_MODE);
    2292             :         //if (has_above && has_left) {  // both edges available
    2293      744602 :         if (!(inter_pred_dir_neighbor_array->top_array[modeTypeTopNeighborIndex] == BI_PRED && !topIntra) && !(inter_pred_dir_neighbor_array->left_array[modeTypeLeftNeighborIndex] == BI_PRED && !leftIntra)) {
    2294             :             // neither edge uses comp pred (0/1)
    2295      205772 :             ctx = (inter_pred_dir_neighbor_array->top_array[modeTypeTopNeighborIndex] == UNI_PRED_LIST_1) ^
    2296      205772 :                 (inter_pred_dir_neighbor_array->left_array[modeTypeLeftNeighborIndex] == UNI_PRED_LIST_1);
    2297             :         }
    2298      538830 :         else if (!(inter_pred_dir_neighbor_array->top_array[modeTypeTopNeighborIndex] == BI_PRED && !topIntra)/*has_second_ref(above_mbmi)*/) {
    2299             :             // one of two edges uses comp pred (2/3)
    2300       73600 :             ctx = 2 + ((inter_pred_dir_neighbor_array->top_array[modeTypeTopNeighborIndex] == UNI_PRED_LIST_1) ||
    2301             :                 topIntra);
    2302             :         }
    2303      465230 :         else if (!(inter_pred_dir_neighbor_array->left_array[modeTypeLeftNeighborIndex] == BI_PRED && !leftIntra)/*has_second_ref(left_mbmi)*/) {
    2304             :             // one of two edges uses comp pred (2/3)
    2305       77460 :             ctx = 2 + ((inter_pred_dir_neighbor_array->left_array[modeTypeLeftNeighborIndex] == UNI_PRED_LIST_1) ||
    2306             :                 leftIntra);
    2307             :         }
    2308             :         else {  // both edges use comp pred (4){
    2309      387770 :             ctx = 4;
    2310             :         }
    2311             :     }
    2312       66748 :     else if (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] != (uint8_t)INVALID_MODE) {  // one edge available
    2313             : 
    2314       35457 :         if (!(inter_pred_dir_neighbor_array->left_array[modeTypeLeftNeighborIndex] == BI_PRED && mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] != (uint8_t)INTRA_MODE)/*has_second_ref(edge_mbmi)*/) {
    2315             :             // edge does not use comp pred (0/1)
    2316       20813 :             ctx = (inter_pred_dir_neighbor_array->left_array[modeTypeLeftNeighborIndex] == UNI_PRED_LIST_1);
    2317             :         }
    2318             :         else {
    2319             :             // edge uses comp pred (3)
    2320       14644 :             ctx = 3;
    2321             :         }
    2322             :     }
    2323       31291 :     else if (mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] != (uint8_t)INVALID_MODE) {  // one edge available
    2324             : 
    2325       30046 :         if (!(inter_pred_dir_neighbor_array->top_array[modeTypeTopNeighborIndex] == BI_PRED && mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] != (uint8_t)INTRA_MODE)/*has_second_ref(edge_mbmi)*/) {
    2326             :             // edge does not use comp pred (0/1)
    2327       20405 :             ctx = (inter_pred_dir_neighbor_array->top_array[modeTypeTopNeighborIndex] == UNI_PRED_LIST_1);
    2328             :         }
    2329             :         else {
    2330             :             // edge uses comp pred (3)
    2331        9641 :             ctx = 3;
    2332             :         }
    2333             :     }
    2334             :     else {  // no edges available (1)
    2335        1245 :         ctx = 1;
    2336             :     }
    2337             : 
    2338      811350 :     assert(ctx >= 0 && ctx < COMP_INTER_CONTEXTS);
    2339      811364 :     return ctx;
    2340             : }
    2341             : int av1_get_intra_inter_context(const MacroBlockD *xd);
    2342             : 
    2343             : int av1_get_reference_mode_context_new(const MacroBlockD *xd);
    2344             : 
    2345       17526 : static INLINE AomCdfProb *av1_get_reference_mode_cdf(const MacroBlockD *xd) {
    2346       17526 :     return xd->tile_ctx->comp_inter_cdf[av1_get_reference_mode_context_new(xd)];
    2347             : }
    2348             : 
    2349             : int av1_get_comp_reference_type_context_new(const MacroBlockD *xd);
    2350             : 
    2351             : // == Uni-directional contexts ==
    2352             : 
    2353             : int eb_av1_get_pred_context_uni_comp_ref_p(const MacroBlockD *xd);
    2354             : 
    2355             : int eb_av1_get_pred_context_uni_comp_ref_p1(const MacroBlockD *xd);
    2356             : 
    2357             : int eb_av1_get_pred_context_uni_comp_ref_p2(const MacroBlockD *xd);
    2358             : 
    2359        7149 : static INLINE AomCdfProb *av1_get_comp_reference_type_cdf(
    2360             :     const MacroBlockD *xd) {
    2361        7149 :     const int pred_context = av1_get_comp_reference_type_context_new(xd);
    2362        7148 :     return xd->tile_ctx->comp_ref_type_cdf[pred_context];
    2363             : }
    2364             : 
    2365          13 : static INLINE AomCdfProb *av1_get_pred_cdf_uni_comp_ref_p(
    2366             :     const MacroBlockD *xd) {
    2367          13 :     const int pred_context = eb_av1_get_pred_context_uni_comp_ref_p(xd);
    2368          13 :     return xd->tile_ctx->uni_comp_ref_cdf[pred_context][0];
    2369             : }
    2370             : 
    2371          10 : static INLINE AomCdfProb *av1_get_pred_cdf_uni_comp_ref_p1(
    2372             :     const MacroBlockD *xd) {
    2373          10 :     const int pred_context = eb_av1_get_pred_context_uni_comp_ref_p1(xd);
    2374          10 :     return xd->tile_ctx->uni_comp_ref_cdf[pred_context][1];
    2375             : }
    2376             : 
    2377           2 : static INLINE AomCdfProb *av1_get_pred_cdf_uni_comp_ref_p2(
    2378             :     const MacroBlockD *xd) {
    2379           2 :     const int pred_context = eb_av1_get_pred_context_uni_comp_ref_p2(xd);
    2380           2 :     return xd->tile_ctx->uni_comp_ref_cdf[pred_context][2];
    2381             : }
    2382             : 
    2383        7135 : static INLINE AomCdfProb *av1_get_pred_cdf_comp_ref_p(const MacroBlockD *xd) {
    2384        7135 :     const int pred_context = eb_av1_get_pred_context_comp_ref_p(xd);
    2385        7135 :     return xd->tile_ctx->comp_ref_cdf[pred_context][0];
    2386             : }
    2387             : 
    2388        7132 : static INLINE AomCdfProb *av1_get_pred_cdf_comp_ref_p1(
    2389             :     const MacroBlockD *xd) {
    2390        7132 :     const int pred_context = eb_av1_get_pred_context_comp_ref_p1(xd);
    2391        7132 :     return xd->tile_ctx->comp_ref_cdf[pred_context][1];
    2392             : }
    2393             : 
    2394           3 : static INLINE AomCdfProb *av1_get_pred_cdf_comp_ref_p2(
    2395             :     const MacroBlockD *xd) {
    2396           3 :     const int pred_context = eb_av1_get_pred_context_comp_ref_p2(xd);
    2397           3 :     return xd->tile_ctx->comp_ref_cdf[pred_context][2];
    2398             : }
    2399             : 
    2400        7135 : static INLINE AomCdfProb *av1_get_pred_cdf_comp_bwdref_p(
    2401             :     const MacroBlockD *xd) {
    2402        7135 :     const int pred_context = eb_av1_get_pred_context_comp_bwdref_p(xd);
    2403        7135 :     return xd->tile_ctx->comp_bwdref_cdf[pred_context][0];
    2404             : }
    2405             : 
    2406        7135 : static INLINE AomCdfProb *av1_get_pred_cdf_comp_bwdref_p1(
    2407             :     const MacroBlockD *xd) {
    2408        7135 :     const int pred_context = eb_av1_get_pred_context_comp_bwdref_p1(xd);
    2409        7135 :     return xd->tile_ctx->comp_bwdref_cdf[pred_context][1];
    2410             : }
    2411             : 
    2412    71921000 : int av1_get_comp_reference_type_context_new(const MacroBlockD *xd) {
    2413             :     int pred_context;
    2414    71921000 :     const MbModeInfo *const above_mbmi = xd->above_mbmi;
    2415    71921000 :     const MbModeInfo *const left_mbmi = xd->left_mbmi;
    2416    71921000 :     const int above_in_image = xd->up_available;
    2417    71921000 :     const int left_in_image = xd->left_available;
    2418             : 
    2419   136558000 :     if (above_in_image && left_in_image) {  // both edges available
    2420    64641000 :         const int above_intra = !is_inter_block(&above_mbmi->block_mi);
    2421    64638500 :         const int left_intra = !is_inter_block(&left_mbmi->block_mi);
    2422             : 
    2423    64598100 :         if (above_intra && left_intra) {  // intra/intra
    2424      130386 :             pred_context = 2;
    2425             :         }
    2426    64634300 :         else if (above_intra || left_intra) {  // intra/inter
    2427      166601 :             const MbModeInfo *inter_mbmi = above_intra ? left_mbmi : above_mbmi;
    2428             : 
    2429      166601 :             if (!has_second_ref(inter_mbmi))  // single pred
    2430      152494 :                 pred_context = 2;
    2431             :             else  // comp pred
    2432       14105 :                 pred_context = 1 + 2 * has_uni_comp_refs(inter_mbmi);
    2433             :         }
    2434             :         else {  // inter/inter
    2435    64301100 :             const int a_sg = !has_second_ref(above_mbmi);
    2436    64285800 :             const int l_sg = !has_second_ref(left_mbmi);
    2437    64341900 :             const MvReferenceFrame frfa = above_mbmi->block_mi.ref_frame[0];
    2438    64341900 :             const MvReferenceFrame frfl = left_mbmi->block_mi.ref_frame[0];
    2439             : 
    2440    64341900 :             if (a_sg && l_sg) {  // single/single
    2441     8407920 :                 pred_context = 1 + 2 * (!(IS_BACKWARD_REF_FRAME(frfa) ^
    2442     4203960 :                     IS_BACKWARD_REF_FRAME(frfl)));
    2443             :             }
    2444    66668800 :             else if (l_sg || a_sg) {  // single/comp
    2445     6530850 :                 const int uni_rfc =
    2446     6531760 :                     a_sg ? has_uni_comp_refs(left_mbmi) : has_uni_comp_refs(above_mbmi);
    2447             : 
    2448     6530850 :                 if (!uni_rfc)  // comp bidir
    2449     6523150 :                     pred_context = 1;
    2450             :                 else  // comp unidir
    2451       15394 :                     pred_context = 3 + (!(IS_BACKWARD_REF_FRAME(frfa) ^
    2452        7697 :                         IS_BACKWARD_REF_FRAME(frfl)));
    2453             :             }
    2454             :             else {  // comp/comp
    2455    53606200 :                 const int a_uni_rfc = has_uni_comp_refs(above_mbmi);
    2456    53615700 :                 const int l_uni_rfc = has_uni_comp_refs(left_mbmi);
    2457             : 
    2458    53605100 :                 if (!a_uni_rfc && !l_uni_rfc)  // bidir/bidir
    2459    53547100 :                     pred_context = 0;
    2460       57997 :                 else if (!a_uni_rfc || !l_uni_rfc)  // unidir/bidir
    2461       57233 :                     pred_context = 2;
    2462             :                 else  // unidir/unidir
    2463         764 :                     pred_context =
    2464         764 :                     3 + (!((frfa == BWDREF_FRAME) ^ (frfl == BWDREF_FRAME)));
    2465             :             }
    2466             :         }
    2467             :     }
    2468    14467800 :     else if (above_in_image || left_in_image) {  // one edge available
    2469     7133600 :         const MbModeInfo *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
    2470             : 
    2471     7133600 :         if (!is_inter_block(&edge_mbmi->block_mi)) {  // intra
    2472       80453 :             pred_context = 2;
    2473             :         }
    2474             :         else {                           // inter
    2475     7106200 :             if (!has_second_ref(edge_mbmi))  // single pred
    2476     3487980 :                 pred_context = 2;
    2477             :             else  // comp pred
    2478     3618120 :                 pred_context = 4 * has_uni_comp_refs(edge_mbmi);
    2479             :         }
    2480             :     }
    2481             :     else {  // no edges available
    2482      146398 :         pred_context = 2;
    2483             :     }
    2484             : 
    2485    71971000 :     assert(pred_context >= 0 && pred_context < COMP_REF_TYPE_CONTEXTS);
    2486    71850200 :     return pred_context;
    2487             : }
    2488             : 
    2489             : // Returns a context number for the given MB prediction signal
    2490             : //
    2491             : // Signal the uni-directional compound reference frame pair as either
    2492             : // (BWDREF, ALTREF), or (LAST, LAST2) / (LAST, LAST3) / (LAST, GOLDEN),
    2493             : // conditioning on the pair is known as uni-directional.
    2494             : //
    2495             : // 3 contexts: Voting is used to compare the count of forward references with
    2496             : //             that of backward references from the spatial neighbors.
    2497    15853600 : int eb_av1_get_pred_context_uni_comp_ref_p(const MacroBlockD *xd) {
    2498    15853600 :     const uint8_t *const ref_counts = &xd->neighbors_ref_counts[0];
    2499             : 
    2500             :     // Count of forward references (L, L2, L3, or G)
    2501    15853600 :     const int frf_count = ref_counts[LAST_FRAME] + ref_counts[LAST2_FRAME] +
    2502    15853600 :         ref_counts[LAST3_FRAME] + ref_counts[GOLDEN_FRAME];
    2503             :     // Count of backward references (B or A)
    2504    15853600 :     const int brf_count = ref_counts[BWDREF_FRAME] + ref_counts[ALTREF2_FRAME] +
    2505    15853600 :         ref_counts[ALTREF_FRAME];
    2506             : 
    2507    15853600 :     const int pred_context =
    2508    15853600 :         (frf_count == brf_count) ? 1 : ((frf_count < brf_count) ? 0 : 2);
    2509             : 
    2510    15853600 :     assert(pred_context >= 0 && pred_context < UNI_COMP_REF_CONTEXTS);
    2511    15854200 :     return pred_context;
    2512             : }
    2513             : 
    2514             : // Returns a context number for the given MB prediction signal
    2515             : //
    2516             : // Signal the uni-directional compound reference frame pair as
    2517             : // either (LAST, LAST2), or (LAST, LAST3) / (LAST, GOLDEN),
    2518             : // conditioning on the pair is known as one of the above three.
    2519             : //
    2520             : // 3 contexts: Voting is used to compare the count of LAST2_FRAME with the
    2521             : //             total count of LAST3/GOLDEN from the spatial neighbors.
    2522    13946600 : int eb_av1_get_pred_context_uni_comp_ref_p1(const MacroBlockD *xd) {
    2523    13946600 :     const uint8_t *const ref_counts = &xd->neighbors_ref_counts[0];
    2524             : 
    2525             :     // Count of LAST2
    2526    13946600 :     const int last2_count = ref_counts[LAST2_FRAME];
    2527             :     // Count of LAST3 or GOLDEN
    2528    13946600 :     const int last3_or_gld_count =
    2529    13946600 :         ref_counts[LAST3_FRAME] + ref_counts[GOLDEN_FRAME];
    2530             : 
    2531    13946600 :     const int pred_context = (last2_count == last3_or_gld_count)
    2532             :         ? 1
    2533    13946600 :         : ((last2_count < last3_or_gld_count) ? 0 : 2);
    2534             : 
    2535    13946600 :     assert(pred_context >= 0 && pred_context < UNI_COMP_REF_CONTEXTS);
    2536    13946800 :     return pred_context;
    2537             : }
    2538             : 
    2539             : // Returns a context number for the given MB prediction signal
    2540             : //
    2541             : // Signal the uni-directional compound reference frame pair as
    2542             : // either (LAST, LAST3) or (LAST, GOLDEN),
    2543             : // conditioning on the pair is known as one of the above two.
    2544             : //
    2545             : // 3 contexts: Voting is used to compare the count of LAST3_FRAME with the
    2546             : //             total count of GOLDEN_FRAME from the spatial neighbors.
    2547     8167700 : int eb_av1_get_pred_context_uni_comp_ref_p2(const MacroBlockD *xd) {
    2548     8167700 :     const uint8_t *const ref_counts = &xd->neighbors_ref_counts[0];
    2549             : 
    2550             :     // Count of LAST3
    2551     8167700 :     const int last3_count = ref_counts[LAST3_FRAME];
    2552             :     // Count of GOLDEN
    2553     8167700 :     const int gld_count = ref_counts[GOLDEN_FRAME];
    2554             : 
    2555     8167700 :     const int pred_context =
    2556     8167700 :         (last3_count == gld_count) ? 1 : ((last3_count < gld_count) ? 0 : 2);
    2557             : 
    2558     8167700 :     assert(pred_context >= 0 && pred_context < UNI_COMP_REF_CONTEXTS);
    2559     8167760 :     return pred_context;
    2560             : }
    2561             : 
    2562    96809700 : int av1_get_reference_mode_context_new(const MacroBlockD *xd) {
    2563             :     int ctx;
    2564    96809700 :     const MbModeInfo *const above_mbmi = xd->above_mbmi;
    2565    96809700 :     const MbModeInfo *const left_mbmi = xd->left_mbmi;
    2566    96809700 :     const int has_above = xd->up_available;
    2567    96809700 :     const int has_left = xd->left_available;
    2568             : 
    2569             :     // Note:
    2570             :     // The mode info data structure has a one element border above and to the
    2571             :     // left of the entries corresponding to real macroblocks.
    2572             :     // The prediction flags in these dummy entries are initialized to 0.
    2573    96809700 :     if (has_above && has_left) {  // both edges available
    2574    87213300 :         if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi))
    2575             :             // neither edge uses comp pred (0/1)
    2576    13601800 :             ctx = IS_BACKWARD_REF_FRAME(above_mbmi->block_mi.ref_frame[0]) ^
    2577     6800900 :             IS_BACKWARD_REF_FRAME(left_mbmi->block_mi.ref_frame[0]);
    2578    80405700 :         else if (!has_second_ref(above_mbmi))
    2579             :             // one of two edges uses comp pred (2/3)
    2580     6994400 :             ctx = 2 + (IS_BACKWARD_REF_FRAME(above_mbmi->block_mi.ref_frame[0]) ||
    2581     2675540 :                 !is_inter_block(&above_mbmi->block_mi));
    2582    76082300 :         else if (!has_second_ref(left_mbmi))
    2583             :             // one of two edges uses comp pred (2/3)
    2584     6754410 :             ctx = 2 + (IS_BACKWARD_REF_FRAME(left_mbmi->block_mi.ref_frame[0]) ||
    2585     2270630 :                 !is_inter_block(&left_mbmi->block_mi));
    2586             :         else  // both edges use comp pred (4)
    2587    71629300 :             ctx = 4;
    2588             :     }
    2589    19053800 :     else if (has_above || has_left) {  // one edge available
    2590     9422820 :         const MbModeInfo *edge_mbmi = has_above ? above_mbmi : left_mbmi;
    2591             : 
    2592     9422820 :         if (!has_second_ref(edge_mbmi))
    2593             :             // edge does not use comp pred (0/1)
    2594     4646790 :             ctx = IS_BACKWARD_REF_FRAME(edge_mbmi->block_mi.ref_frame[0]);
    2595             :         else
    2596             :             // edge uses comp pred (3)
    2597     4810660 :             ctx = 3;
    2598             :     }
    2599             :     else {  // no edges available (1)
    2600      173551 :         ctx = 1;
    2601             :     }
    2602    96863800 :     assert(ctx >= 0 && ctx < COMP_INTER_CONTEXTS);
    2603    96710300 :     return ctx;
    2604             : }
    2605      830780 : INLINE void av1_collect_neighbors_ref_counts_new(MacroBlockD *const xd) {
    2606      830780 :     av1_zero(xd->neighbors_ref_counts);
    2607             : 
    2608      830780 :     uint8_t *const ref_counts = xd->neighbors_ref_counts;
    2609             : 
    2610      830780 :     const MbModeInfo *const above_mbmi = xd->above_mbmi;
    2611      830780 :     const MbModeInfo *const left_mbmi = xd->left_mbmi;
    2612      830780 :     const int above_in_image = xd->up_available;
    2613      830780 :     const int left_in_image = xd->left_available;
    2614             : 
    2615             :     // Above neighbor
    2616      830780 :     if (above_in_image && is_inter_block(&above_mbmi->block_mi)) {
    2617      718253 :         ref_counts[above_mbmi->block_mi.ref_frame[0]]++;
    2618      718253 :         if (has_second_ref(above_mbmi))
    2619      482183 :             ref_counts[above_mbmi->block_mi.ref_frame[1]]++;
    2620             :     }
    2621             : 
    2622             :     // Left neighbor
    2623      830774 :     if (left_in_image && is_inter_block(&left_mbmi->block_mi)) {
    2624      722760 :         ref_counts[left_mbmi->block_mi.ref_frame[0]]++;
    2625      722760 :         if (has_second_ref(left_mbmi))
    2626      483484 :             ref_counts[left_mbmi->block_mi.ref_frame[1]]++;
    2627             :     }
    2628      830793 : }
    2629             : 
    2630      811335 : int32_t eb_av1_get_comp_reference_type_context(
    2631             :     uint32_t                  cu_origin_x,
    2632             :     uint32_t                  cu_origin_y,
    2633             :     NeighborArrayUnit    *mode_type_neighbor_array,
    2634             :     NeighborArrayUnit     *inter_pred_dir_neighbor_array) {
    2635      811335 :     int32_t pred_context = 0;
    2636             : 
    2637      811335 :     uint32_t modeTypeLeftNeighborIndex = get_neighbor_array_unit_left_index(
    2638             :         mode_type_neighbor_array,
    2639             :         cu_origin_y);
    2640      811327 :     uint32_t modeTypeTopNeighborIndex = get_neighbor_array_unit_top_index(
    2641             :         mode_type_neighbor_array,
    2642             :         cu_origin_x);
    2643             : 
    2644     1556020 :     if (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] != (uint8_t)INVALID_MODE && mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] != (uint8_t)INVALID_MODE) {  // both edges available
    2645      744634 :         const int32_t above_intra = (mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] == (uint8_t)INTRA_MODE);
    2646      744634 :         const int32_t left_intra = (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] == (uint8_t)INTRA_MODE);
    2647             : 
    2648      744634 :         if (above_intra && left_intra) {  // intra/intra
    2649       68386 :             pred_context = 2;
    2650             :         }
    2651      676248 :         else if (left_intra) {  // Intra & Inter. Left is Intra, check Top
    2652             : 
    2653        3227 :             if (inter_pred_dir_neighbor_array->top_array[modeTypeTopNeighborIndex] != BI_PRED)  // single pred
    2654        3090 :                 pred_context = 2;
    2655             :             else  // comp pred
    2656         137 :                 pred_context = 1 + 2 * 0/* has_uni_comp_refs(inter_mbmi)*/;
    2657             :         }
    2658      673021 :         else if (above_intra) {  // Intra & Inter. Top is Intra, check Left
    2659             : 
    2660        2532 :             if (inter_pred_dir_neighbor_array->left_array[modeTypeLeftNeighborIndex] != BI_PRED)  // single pred
    2661        2275 :                 pred_context = 2;
    2662             :             else  // comp pred
    2663         257 :                 pred_context = 1 + 2 * 0/* has_uni_comp_refs(inter_mbmi)*/;
    2664             :         }
    2665             :         else {  // inter/inter
    2666      670489 :             const int32_t a_sg = (inter_pred_dir_neighbor_array->top_array[modeTypeTopNeighborIndex] != BI_PRED);
    2667      670489 :             const int32_t l_sg = (inter_pred_dir_neighbor_array->left_array[modeTypeLeftNeighborIndex] != BI_PRED);
    2668             :             //const MvReferenceFrame frfa = above_mbmi->ref_frame[0];
    2669             :             //const MvReferenceFrame frfl = left_mbmi->ref_frame[0];
    2670             : 
    2671      670489 :             if (a_sg && l_sg) {  // single/single
    2672      132024 :                 pred_context = 1 + 2 * (!((inter_pred_dir_neighbor_array->top_array[modeTypeTopNeighborIndex] == UNI_PRED_LIST_1) ^
    2673      132024 :                     (inter_pred_dir_neighbor_array->left_array[modeTypeLeftNeighborIndex] == UNI_PRED_LIST_1)));
    2674             :             }
    2675      689158 :             else if (l_sg || a_sg) {  // single/comp
    2676      150693 :                 const int32_t uni_rfc =
    2677             :                     a_sg ? 0 /*has_uni_comp_refs(left_mbmi) */ : 0 /*has_uni_comp_refs(above_mbmi)*/;
    2678             : 
    2679      150693 :                 if (!uni_rfc)  // comp bidir
    2680      150743 :                     pred_context = 1;
    2681             :                 else  // comp unidir
    2682           0 :                     pred_context = 3 + (!((inter_pred_dir_neighbor_array->top_array[modeTypeTopNeighborIndex] == UNI_PRED_LIST_1) ^
    2683           0 :                     (inter_pred_dir_neighbor_array->left_array[modeTypeLeftNeighborIndex] == UNI_PRED_LIST_1)));
    2684             :             }
    2685             :             else {  // comp/comp
    2686      387772 :                 const int32_t a_uni_rfc = 0;// has_uni_comp_refs(above_mbmi);
    2687      387772 :                 const int32_t l_uni_rfc = 0;// has_uni_comp_refs(left_mbmi);
    2688      387772 :                 pred_context = 0;
    2689             : 
    2690      387772 :                 if (!a_uni_rfc && !l_uni_rfc)  // bidir/bidir
    2691      387768 :                     pred_context = 0;
    2692           4 :                 else if (!a_uni_rfc || !l_uni_rfc)  // unidir/bidir
    2693           4 :                     pred_context = 2;
    2694             :                 else  // unidir/unidir
    2695           0 :                     pred_context =
    2696             :                     3 + (!(0 ^ 0));
    2697             :             }
    2698             :         }
    2699             :     }
    2700       66748 :     else if (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] != (uint8_t)INVALID_MODE) {  // one edge available
    2701             : 
    2702       35457 :         if (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] == (uint8_t)INTRA_MODE) {  // intra
    2703        3157 :             pred_context = 2;
    2704             :         }
    2705             :         else {                           // inter
    2706       32300 :             if (inter_pred_dir_neighbor_array->left_array[modeTypeLeftNeighborIndex] != BI_PRED)  // single pred
    2707       17656 :                 pred_context = 2;
    2708             :             else  // comp pred
    2709       14644 :                 pred_context = 4 * 0/*has_uni_comp_refs(edge_mbmi)*/;
    2710             :         }
    2711             :     }
    2712       31291 :     else if (mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] != (uint8_t)INVALID_MODE) {  // one edge available
    2713             : 
    2714       30046 :         if (mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] == (uint8_t)INTRA_MODE) {  // intra
    2715        2931 :             pred_context = 2;
    2716             :         }
    2717             :         else {                           // inter
    2718       27115 :             if (inter_pred_dir_neighbor_array->top_array[modeTypeTopNeighborIndex] != BI_PRED)  // single pred
    2719       17474 :                 pred_context = 2;
    2720             :             else  // comp pred
    2721        9641 :                 pred_context = 4 * 0/*has_uni_comp_refs(edge_mbmi)*/;
    2722             :         }
    2723             :     }
    2724             :     else {  // no edges available
    2725        1245 :         pred_context = 2;
    2726             :     }
    2727             : 
    2728             :     //assert(pred_context >= 0 && pred_context < COMP_REF_TYPE_CONTEXTS);
    2729      811382 :     return pred_context;
    2730             : }
    2731             : 
    2732           0 : void av1_collect_neighbors_ref_counts(
    2733             :     CodingUnit            *cu_ptr,
    2734             :     uint32_t                   cu_origin_x,
    2735             :     uint32_t                   cu_origin_y,
    2736             :     NeighborArrayUnit     *mode_type_neighbor_array,
    2737             :     NeighborArrayUnit     *inter_pred_dir_neighbor_array,
    2738             :     NeighborArrayUnit     *ref_frame_type_neighbor_array) {
    2739           0 :     av1_zero(cu_ptr->av1xd->neighbors_ref_counts);
    2740             : 
    2741           0 :     uint8_t *const ref_counts = cu_ptr->av1xd->neighbors_ref_counts;
    2742             : 
    2743           0 :     uint32_t modeTypeLeftNeighborIndex = get_neighbor_array_unit_left_index(
    2744             :         mode_type_neighbor_array,
    2745             :         cu_origin_y);
    2746           0 :     uint32_t modeTypeTopNeighborIndex = get_neighbor_array_unit_top_index(
    2747             :         mode_type_neighbor_array,
    2748             :         cu_origin_x);
    2749             : 
    2750           0 :     const int32_t topInter = (mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] == (uint8_t)INTER_MODE);
    2751           0 :     const int32_t leftInter = (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] == (uint8_t)INTER_MODE);
    2752             : 
    2753           0 :     const int32_t topInImage = (mode_type_neighbor_array->top_array[modeTypeTopNeighborIndex] != (uint8_t)INVALID_MODE);
    2754           0 :     const int32_t leftInImage = (mode_type_neighbor_array->left_array[modeTypeLeftNeighborIndex] != (uint8_t)INVALID_MODE);
    2755             : 
    2756             :     // Above neighbor
    2757           0 :     if (topInImage && topInter) {
    2758             :         MvReferenceFrame topRfType[2];
    2759           0 :         av1_set_ref_frame(topRfType, ref_frame_type_neighbor_array->top_array[modeTypeTopNeighborIndex]);
    2760           0 :         switch (inter_pred_dir_neighbor_array->top_array[modeTypeTopNeighborIndex]) {
    2761           0 :         case UNI_PRED_LIST_0:
    2762           0 :             ref_counts[topRfType[0]]++;
    2763             : 
    2764           0 :             break;
    2765           0 :         case UNI_PRED_LIST_1:
    2766           0 :             ref_counts[topRfType[0]]++;
    2767           0 :             break;
    2768             : 
    2769           0 :         case BI_PRED:
    2770           0 :             ref_counts[topRfType[0]]++;
    2771           0 :             ref_counts[topRfType[1]]++;
    2772           0 :             break;
    2773           0 :         default:
    2774           0 :             printf("ERROR[AN]: Invalid Pred Direction\n");
    2775           0 :             break;
    2776             :         }
    2777             :     }
    2778             : 
    2779             :     // Left neighbor
    2780           0 :     if (leftInImage && leftInter) {
    2781             :         MvReferenceFrame leftRfType[2];
    2782           0 :         av1_set_ref_frame(leftRfType, ref_frame_type_neighbor_array->left_array[modeTypeLeftNeighborIndex]);
    2783           0 :         switch (inter_pred_dir_neighbor_array->left_array[modeTypeLeftNeighborIndex]) {
    2784           0 :         case UNI_PRED_LIST_0:
    2785           0 :             ref_counts[leftRfType[0]]++;
    2786             : 
    2787           0 :             break;
    2788           0 :         case UNI_PRED_LIST_1:
    2789           0 :             ref_counts[leftRfType[0]]++;
    2790           0 :             break;
    2791             : 
    2792           0 :         case BI_PRED:
    2793           0 :             ref_counts[leftRfType[0]]++;
    2794           0 :             ref_counts[leftRfType[1]]++;
    2795           0 :             break;
    2796           0 :         default:
    2797           0 :             printf("ERROR[AN]: Invalid Pred Direction\n");
    2798           0 :             break;
    2799             :         }
    2800             :     }
    2801           0 : }
    2802             : 
    2803             : #define WRITE_REF_BIT(bname, pname) \
    2804             :   aom_write_symbol(w, bname, av1_get_pred_cdf_##pname(xd), 2)
    2805             : /***************************************************************************************/
    2806             : 
    2807             : // == Common context functions for both comp and single ref ==
    2808             : //
    2809             : // Obtain contexts to signal a reference frame to be either LAST/LAST2 or
    2810             : // LAST3/GOLDEN.
    2811    78844900 : static int32_t get_pred_context_ll2_or_l3gld(const MacroBlockD *xd) {
    2812    78844900 :     const uint8_t *const ref_counts = &xd->neighbors_ref_counts[0];
    2813             : 
    2814             :     // Count of LAST + LAST2
    2815    78844900 :     const int32_t last_last2_count = ref_counts[LAST_FRAME] + ref_counts[LAST2_FRAME];
    2816             :     // Count of LAST3 + GOLDEN
    2817    78844900 :     const int32_t last3_gld_count =
    2818    78844900 :         ref_counts[LAST3_FRAME] + ref_counts[GOLDEN_FRAME];
    2819             : 
    2820    78844900 :     const int32_t pred_context = (last_last2_count == last3_gld_count)
    2821             :         ? 1
    2822    78844900 :         : ((last_last2_count < last3_gld_count) ? 0 : 2);
    2823             : 
    2824    78844900 :     assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
    2825    78874300 :     return pred_context;
    2826             : }
    2827             : 
    2828             : // Obtain contexts to signal a reference frame to be either LAST or LAST2.
    2829    54399700 : static int32_t get_pred_context_last_or_last2(const MacroBlockD *xd) {
    2830    54399700 :     const uint8_t *const ref_counts = &xd->neighbors_ref_counts[0];
    2831             : 
    2832             :     // Count of LAST
    2833    54399700 :     const int32_t last_count = ref_counts[LAST_FRAME];
    2834             :     // Count of LAST2
    2835    54399700 :     const int32_t last2_count = ref_counts[LAST2_FRAME];
    2836             : 
    2837    54399700 :     const int32_t pred_context =
    2838    54399700 :         (last_count == last2_count) ? 1 : ((last_count < last2_count) ? 0 : 2);
    2839             : 
    2840    54399700 :     assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
    2841    54407700 :     return pred_context;
    2842             : }
    2843             : 
    2844             : // Obtain contexts to signal a reference frame to be either LAST3 or GOLDEN.
    2845    24604500 : static int32_t get_pred_context_last3_or_gld(const MacroBlockD *xd) {
    2846    24604500 :     const uint8_t *const ref_counts = &xd->neighbors_ref_counts[0];
    2847             : 
    2848             :     // Count of LAST3
    2849    24604500 :     const int32_t last3_count = ref_counts[LAST3_FRAME];
    2850             :     // Count of GOLDEN
    2851    24604500 :     const int32_t gld_count = ref_counts[GOLDEN_FRAME];
    2852             : 
    2853    24604500 :     const int32_t pred_context =
    2854    24604500 :         (last3_count == gld_count) ? 1 : ((last3_count < gld_count) ? 0 : 2);
    2855             : 
    2856    24604500 :     assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
    2857    24604700 :     return pred_context;
    2858             : }
    2859             : 
    2860             : // Obtain contexts to signal a reference frame be either BWDREF/ALTREF2, or
    2861             : // ALTREF.
    2862    67830600 : static int32_t get_pred_context_brfarf2_or_arf(const MacroBlockD *xd) {
    2863    67830600 :     const uint8_t *const ref_counts = &xd->neighbors_ref_counts[0];
    2864             : 
    2865             :     // Counts of BWDREF, ALTREF2, or ALTREF frames (B, A2, or A)
    2866    67830600 :     const int32_t brfarf2_count =
    2867    67830600 :         ref_counts[BWDREF_FRAME] + ref_counts[ALTREF2_FRAME];
    2868    67830600 :     const int32_t arf_count = ref_counts[ALTREF_FRAME];
    2869             : 
    2870    67830600 :     const int32_t pred_context =
    2871    67830600 :         (brfarf2_count == arf_count) ? 1 : ((brfarf2_count < arf_count) ? 0 : 2);
    2872             : 
    2873    67830600 :     assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
    2874    67859800 :     return pred_context;
    2875             : }
    2876             : 
    2877             : // Obtain contexts to signal a reference frame be either BWDREF or ALTREF2.
    2878    60868600 : static int32_t get_pred_context_brf_or_arf2(const MacroBlockD *xd) {
    2879    60868600 :     const uint8_t *const ref_counts = &xd->neighbors_ref_counts[0];
    2880             : 
    2881             :     // Count of BWDREF frames (B)
    2882    60868600 :     const int32_t brf_count = ref_counts[BWDREF_FRAME];
    2883             :     // Count of ALTREF2 frames (A2)
    2884    60868600 :     const int32_t arf2_count = ref_counts[ALTREF2_FRAME];
    2885             : 
    2886    60868600 :     const int32_t pred_context =
    2887    60868600 :         (brf_count == arf2_count) ? 1 : ((brf_count < arf2_count) ? 0 : 2);
    2888             : 
    2889    60868600 :     assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
    2890    60877100 :     return pred_context;
    2891             : }
    2892             : 
    2893             : // == Context functions for comp ref ==
    2894             : //
    2895             : // Returns a context number for the given MB prediction signal
    2896             : // Signal the first reference frame for a compound mode be either
    2897             : // GOLDEN/LAST3, or LAST/LAST2.
    2898    56258700 : int32_t eb_av1_get_pred_context_comp_ref_p(const MacroBlockD *xd) {
    2899    56258700 :     return get_pred_context_ll2_or_l3gld(xd);
    2900             : }
    2901             : 
    2902             : // Returns a context number for the given MB prediction signal
    2903             : // Signal the first reference frame for a compound mode be LAST,
    2904             : // conditioning on that it is known either LAST/LAST2.
    2905    38404100 : int32_t eb_av1_get_pred_context_comp_ref_p1(const MacroBlockD *xd) {
    2906    38404100 :     return get_pred_context_last_or_last2(xd);
    2907             : }
    2908             : 
    2909             : // Returns a context number for the given MB prediction signal
    2910             : // Signal the first reference frame for a compound mode be GOLDEN,
    2911             : // conditioning on that it is known either GOLDEN or LAST3.
    2912    17937000 : int32_t eb_av1_get_pred_context_comp_ref_p2(const MacroBlockD *xd) {
    2913    17937000 :     return get_pred_context_last3_or_gld(xd);
    2914             : }
    2915             : 
    2916             : // Signal the 2nd reference frame for a compound mode be either
    2917             : // ALTREF, or ALTREF2/BWDREF.
    2918    56230500 : int32_t eb_av1_get_pred_context_comp_bwdref_p(const MacroBlockD *xd) {
    2919    56230500 :     return get_pred_context_brfarf2_or_arf(xd);
    2920             : }
    2921             : 
    2922             : // Signal the 2nd reference frame for a compound mode be either
    2923             : // ALTREF2 or BWDREF.
    2924    50567000 : int32_t eb_av1_get_pred_context_comp_bwdref_p1(const MacroBlockD *xd) {
    2925    50567000 :     return get_pred_context_brf_or_arf2(xd);
    2926             : }
    2927             : 
    2928             : // == Context functions for single ref ==
    2929             : //
    2930             : // For the bit to signal whether the single reference is a forward reference
    2931             : // frame or a backward reference frame.
    2932    34407600 : int32_t eb_av1_get_pred_context_single_ref_p1(const MacroBlockD *xd) {
    2933    34407600 :     const uint8_t *const ref_counts = &xd->neighbors_ref_counts[0];
    2934             : 
    2935             :     // Count of forward reference frames
    2936    34407600 :     const int32_t fwd_count = ref_counts[LAST_FRAME] + ref_counts[LAST2_FRAME] +
    2937    34407600 :         ref_counts[LAST3_FRAME] + ref_counts[GOLDEN_FRAME];
    2938             :     // Count of backward reference frames
    2939    34407600 :     const int32_t bwd_count = ref_counts[BWDREF_FRAME] + ref_counts[ALTREF2_FRAME] +
    2940    34407600 :         ref_counts[ALTREF_FRAME];
    2941             : 
    2942    34407600 :     const int32_t pred_context =
    2943    34407600 :         (fwd_count == bwd_count) ? 1 : ((fwd_count < bwd_count) ? 0 : 2);
    2944             : 
    2945    34407600 :     assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
    2946    34407500 :     return pred_context;
    2947             : }
    2948       12303 : static INLINE AomCdfProb *av1_get_pred_cdf_single_ref_p1(
    2949             :     const MacroBlockD *xd) {
    2950       12303 :     return xd->tile_ctx
    2951       12303 :         ->single_ref_cdf[eb_av1_get_pred_context_single_ref_p1(xd)][0];
    2952             : }
    2953        3506 : static INLINE AomCdfProb *av1_get_pred_cdf_single_ref_p2(
    2954             :     const MacroBlockD *xd) {
    2955        3506 :     return xd->tile_ctx
    2956        3506 :         ->single_ref_cdf[eb_av1_get_pred_context_single_ref_p2(xd)][1];
    2957             : }
    2958        8797 : static INLINE AomCdfProb *av1_get_pred_cdf_single_ref_p3(
    2959             :     const MacroBlockD *xd) {
    2960        8797 :     return xd->tile_ctx
    2961        8797 :         ->single_ref_cdf[eb_av1_get_pred_context_single_ref_p3(xd)][2];
    2962             : }
    2963        8789 : static INLINE AomCdfProb *av1_get_pred_cdf_single_ref_p4(
    2964             :     const MacroBlockD *xd) {
    2965        8789 :     return xd->tile_ctx
    2966        8789 :         ->single_ref_cdf[eb_av1_get_pred_context_single_ref_p4(xd)][3];
    2967             : }
    2968           8 : static INLINE AomCdfProb *av1_get_pred_cdf_single_ref_p5(
    2969             :     const MacroBlockD *xd) {
    2970           8 :     return xd->tile_ctx
    2971           8 :         ->single_ref_cdf[eb_av1_get_pred_context_single_ref_p5(xd)][4];
    2972             : }
    2973        3506 : static INLINE AomCdfProb *av1_get_pred_cdf_single_ref_p6(
    2974             :     const MacroBlockD *xd) {
    2975        3506 :     return xd->tile_ctx
    2976        3506 :         ->single_ref_cdf[eb_av1_get_pred_context_single_ref_p6(xd)][5];
    2977             : }
    2978             : 
    2979             : // For the bit to signal whether the single reference is ALTREF_FRAME or
    2980             : // non-ALTREF backward reference frame, knowing that it shall be either of
    2981             : // these 2 choices.
    2982    11678800 : int32_t eb_av1_get_pred_context_single_ref_p2(const MacroBlockD *xd) {
    2983    11678800 :     return get_pred_context_brfarf2_or_arf(xd);
    2984             : }
    2985             : 
    2986             : // For the bit to signal whether the single reference is LAST3/GOLDEN or
    2987             : // LAST2/LAST, knowing that it shall be either of these 2 choices.
    2988    22750800 : int32_t eb_av1_get_pred_context_single_ref_p3(const MacroBlockD *xd) {
    2989    22750800 :     return get_pred_context_ll2_or_l3gld(xd);
    2990             : }
    2991             : 
    2992             : // For the bit to signal whether the single reference is LAST2_FRAME or
    2993             : // LAST_FRAME, knowing that it shall be either of these 2 choices.
    2994    16073000 : int32_t eb_av1_get_pred_context_single_ref_p4(const MacroBlockD *xd) {
    2995    16073000 :     return get_pred_context_last_or_last2(xd);
    2996             : }
    2997             : 
    2998             : // For the bit to signal whether the single reference is GOLDEN_FRAME or
    2999             : // LAST3_FRAME, knowing that it shall be either of these 2 choices.
    3000     6688380 : int32_t eb_av1_get_pred_context_single_ref_p5(const MacroBlockD *xd) {
    3001     6688380 :     return get_pred_context_last3_or_gld(xd);
    3002             : }
    3003             : 
    3004             : // For the bit to signal whether the single reference is ALTREF2_FRAME or
    3005             : // BWDREF_FRAME, knowing that it shall be either of these 2 choices.
    3006    10357400 : int32_t eb_av1_get_pred_context_single_ref_p6(const MacroBlockD *xd) {
    3007    10357400 :     return get_pred_context_brf_or_arf2(xd);
    3008             : }
    3009             : /***************************************************************************************/
    3010             : 
    3011       19451 : static void write_ref_frames(
    3012             :     FRAME_CONTEXT               *frame_context,
    3013             :     PictureParentControlSet   *pcs_ptr,
    3014             :     const MacroBlockD           *xd,
    3015             :     AomWriter                  *w) {
    3016       19451 :     FrameHeader *frm_hdr = &pcs_ptr->frm_hdr;
    3017       19451 :     const MbModeInfo *const mbmi = &xd->mi[0]->mbmi;
    3018       19451 :     const int is_compound = has_second_ref(mbmi);
    3019             :     UNUSED(frame_context);
    3020             :     {
    3021             :         // does the feature use compound prediction or not
    3022             :         // (if not specified at the frame/segment level)
    3023       19450 :         if (frm_hdr->reference_mode == REFERENCE_MODE_SELECT) {
    3024       18005 :             if (is_comp_ref_allowed(mbmi->block_mi.sb_type))
    3025       17526 :                 aom_write_symbol(w, is_compound, av1_get_reference_mode_cdf(xd), 2);
    3026             :         }
    3027             :         else {
    3028        1445 :             assert((!is_compound) ==
    3029             :                 (frm_hdr->reference_mode == SINGLE_REFERENCE));
    3030             :         }
    3031             : 
    3032       19452 :         if (is_compound) {
    3033        7149 :             const CompReferenceType comp_ref_type = has_uni_comp_refs(mbmi)
    3034             :                 ? UNIDIR_COMP_REFERENCE
    3035        7149 :                 : BIDIR_COMP_REFERENCE;
    3036        7149 :             aom_write_symbol(w, comp_ref_type, av1_get_comp_reference_type_cdf(xd),
    3037             :                 2);
    3038             : 
    3039        7148 :             if (comp_ref_type == UNIDIR_COMP_REFERENCE) {
    3040          13 :                 const int bit = mbmi->block_mi.ref_frame[0] == BWDREF_FRAME;
    3041          13 :                 WRITE_REF_BIT(bit, uni_comp_ref_p);
    3042             : 
    3043          13 :                 if (!bit) {
    3044          10 :                     assert(mbmi->block_mi.ref_frame[0] == LAST_FRAME);
    3045          18 :                     const int bit1 = mbmi->block_mi.ref_frame[1] == LAST3_FRAME ||
    3046           8 :                         mbmi->block_mi.ref_frame[1] == GOLDEN_FRAME;
    3047          10 :                     WRITE_REF_BIT(bit1, uni_comp_ref_p1);
    3048          10 :                     if (bit1) {
    3049           2 :                         const int bit2 = mbmi->block_mi.ref_frame[1] == GOLDEN_FRAME;
    3050           2 :                         WRITE_REF_BIT(bit2, uni_comp_ref_p2);
    3051             :                     }
    3052             :                 }
    3053             :                 else
    3054           3 :                     assert(mbmi->block_mi.ref_frame[1] == ALTREF_FRAME);
    3055          13 :                 return;
    3056             :             }
    3057             : 
    3058        7135 :             assert(comp_ref_type == BIDIR_COMP_REFERENCE);
    3059             : 
    3060       14270 :             const int bit = (mbmi->block_mi.ref_frame[0] == GOLDEN_FRAME ||
    3061        7135 :                 mbmi->block_mi.ref_frame[0] == LAST3_FRAME);
    3062        7135 :             WRITE_REF_BIT(bit, comp_ref_p);
    3063             : 
    3064        7135 :             if (!bit) {
    3065        7132 :                 const int bit1 = mbmi->block_mi.ref_frame[0] == LAST2_FRAME;
    3066        7132 :                 WRITE_REF_BIT(bit1, comp_ref_p1);
    3067             :             }
    3068             :             else {
    3069           3 :                 const int bit2 = mbmi->block_mi.ref_frame[0] == GOLDEN_FRAME;
    3070           3 :                 WRITE_REF_BIT(bit2, comp_ref_p2);
    3071             :             }
    3072             : 
    3073        7135 :             const int bit_bwd = mbmi->block_mi.ref_frame[1] == ALTREF_FRAME;
    3074        7135 :             WRITE_REF_BIT(bit_bwd, comp_bwdref_p);
    3075             : 
    3076        7135 :             if (!bit_bwd)
    3077        7135 :                 WRITE_REF_BIT(mbmi->block_mi.ref_frame[1] == ALTREF2_FRAME, comp_bwdref_p1);
    3078             :         }
    3079             :         else {
    3080       24606 :             const int bit0 = (mbmi->block_mi.ref_frame[0] <= ALTREF_FRAME &&
    3081       12303 :                 mbmi->block_mi.ref_frame[0] >= BWDREF_FRAME);
    3082       12303 :             WRITE_REF_BIT(bit0, single_ref_p1);
    3083             : 
    3084       12303 :             if (bit0) {
    3085        3506 :                 const int bit1 = mbmi->block_mi.ref_frame[0] == ALTREF_FRAME;
    3086        3506 :                 WRITE_REF_BIT(bit1, single_ref_p2);
    3087        3506 :                 if (!bit1)
    3088        3506 :                     WRITE_REF_BIT(mbmi->block_mi.ref_frame[0] == ALTREF2_FRAME, single_ref_p6);
    3089             :             }
    3090             :             else {
    3091       17588 :                 const int bit2 = (mbmi->block_mi.ref_frame[0] == LAST3_FRAME ||
    3092        8791 :                     mbmi->block_mi.ref_frame[0] == GOLDEN_FRAME);
    3093        8797 :                 WRITE_REF_BIT(bit2, single_ref_p3);
    3094        8797 :                 if (!bit2) {
    3095        8789 :                     const int bit3 = mbmi->block_mi.ref_frame[0] != LAST_FRAME;
    3096        8789 :                     WRITE_REF_BIT(bit3, single_ref_p4);
    3097             :                 }
    3098             :                 else {
    3099           8 :                     const int bit4 = mbmi->block_mi.ref_frame[0] != LAST3_FRAME;
    3100           8 :                     WRITE_REF_BIT(bit4, single_ref_p5);
    3101             :                 }
    3102             :             }
    3103             :         }
    3104             :     }
    3105             : }
    3106          60 : static void encode_restoration_mode(PictureParentControlSet *pcs_ptr,
    3107             :     struct AomWriteBitBuffer *wb) {
    3108          60 :     Av1Common* cm = pcs_ptr->av1_cm;
    3109          60 :     FrameHeader *frm_hdr = &pcs_ptr->frm_hdr;
    3110             :     //printf("ERROR[AN]: encode_restoration_mode might not work. Double check the reference code\n");
    3111          60 :     assert(!frm_hdr->all_lossless);
    3112             :     // move out side of the function
    3113             :     //if (!cm->seq_params.enable_restoration) return;
    3114             : 
    3115          60 :     if (frm_hdr->allow_intrabc) return;
    3116             : 
    3117          60 :     const int32_t num_planes = 3;// av1_num_planes(cm);
    3118          60 :     int32_t all_none = 1, chroma_none = 1;
    3119         240 :     for (int32_t p = 0; p < num_planes; ++p) {
    3120             :         //   eb_aom_wb_write_bit(wb, 0);
    3121             :         //   eb_aom_wb_write_bit(wb, 0);
    3122             : 
    3123         180 :         RestorationInfo *rsi = &pcs_ptr->av1_cm->rst_info[p];
    3124             : 
    3125             :         //if (p==0)
    3126             :         //   printf("POC:%i Luma restType:%i\n", pcs_ptr->picture_number, rsi->frame_restoration_type);
    3127             :         //if (p == 1)
    3128             :         //    printf("POC:%i Cb restType:%i\n", pcs_ptr->picture_number, rsi->frame_restoration_type);
    3129             :         //if (p == 2)
    3130             :         //    printf("POC:%i Cr restType:%i\n", pcs_ptr->picture_number, rsi->frame_restoration_type);
    3131             : 
    3132         180 :         if (rsi->frame_restoration_type != RESTORE_NONE) {
    3133          72 :             all_none = 0;
    3134          72 :             chroma_none &= (int32_t)(p == 0);
    3135             :         }
    3136         180 :         switch (rsi->frame_restoration_type) {
    3137         108 :         case RESTORE_NONE:
    3138         108 :             eb_aom_wb_write_bit(wb, 0);
    3139         108 :             eb_aom_wb_write_bit(wb, 0);
    3140         108 :             break;
    3141          27 :         case RESTORE_WIENER:
    3142          27 :             eb_aom_wb_write_bit(wb, 1);
    3143          27 :             eb_aom_wb_write_bit(wb, 0);
    3144          27 :             break;
    3145          29 :         case RESTORE_SGRPROJ:
    3146          29 :             eb_aom_wb_write_bit(wb, 1);
    3147          29 :             eb_aom_wb_write_bit(wb, 1);
    3148          29 :             break;
    3149          16 :         case RESTORE_SWITCHABLE:
    3150          16 :             eb_aom_wb_write_bit(wb, 0);
    3151          16 :             eb_aom_wb_write_bit(wb, 1);
    3152          16 :             break;
    3153           0 :         default: assert(0);
    3154             :         }
    3155             :     }
    3156          60 :     if (!all_none) {
    3157             :         //  assert(cm->seq_params.sb_size == BLOCK_64X64 ||
    3158             :         //      cm->seq_params.sb_size == BLOCK_128X128);
    3159          60 :         const int32_t sb_size = pcs_ptr->sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128 ? 128 : 64;;
    3160          60 :         RestorationInfo *rsi = &pcs_ptr->av1_cm->rst_info[0];
    3161             : 
    3162          60 :         assert(rsi->restoration_unit_size >= sb_size);
    3163             :         assert(RESTORATION_UNITSIZE_MAX == 256);
    3164             : 
    3165          60 :         if (sb_size == 64)
    3166          60 :             eb_aom_wb_write_bit(wb, rsi->restoration_unit_size > 64);
    3167          60 :         if (rsi->restoration_unit_size > 64)
    3168          60 :             eb_aom_wb_write_bit(wb, rsi->restoration_unit_size > 128);
    3169             :     }
    3170             : 
    3171          60 :     if (num_planes > 1) {
    3172          60 :         int32_t s = 1;// AOMMIN(cm->subsampling_x, cm->subsampling_y);
    3173          60 :         if (s && !chroma_none) {
    3174           7 :             eb_aom_wb_write_bit(wb, cm->rst_info[1].restoration_unit_size !=
    3175           7 :                 cm->rst_info[0].restoration_unit_size);
    3176           7 :             assert(cm->rst_info[1].restoration_unit_size ==
    3177             :                 cm->rst_info[0].restoration_unit_size ||
    3178             :                 cm->rst_info[1].restoration_unit_size ==
    3179             :                 (cm->rst_info[0].restoration_unit_size >> s));
    3180           7 :             assert(cm->rst_info[2].restoration_unit_size ==
    3181             :                 cm->rst_info[1].restoration_unit_size);
    3182             :         }
    3183          53 :         else if (!s) {
    3184           0 :             assert(cm->rst_info[1].restoration_unit_size ==
    3185             :                 cm->rst_info[0].restoration_unit_size);
    3186           0 :             assert(cm->rst_info[2].restoration_unit_size ==
    3187             :                 cm->rst_info[1].restoration_unit_size);
    3188             :         }
    3189             :     }
    3190             : }
    3191             : 
    3192             : 
    3193         120 : static void encode_segmentation(PictureParentControlSet *pcsPtr, struct AomWriteBitBuffer *wb) {
    3194         120 :     SegmentationParams *segmentation_params = &pcsPtr->frm_hdr.segmentation_params;
    3195         120 :     eb_aom_wb_write_bit(wb, segmentation_params->segmentation_enabled);
    3196         120 :     if (segmentation_params->segmentation_enabled) {
    3197           0 :         if (!(pcsPtr->frm_hdr.primary_ref_frame==PRIMARY_REF_NONE)) {
    3198           0 :             eb_aom_wb_write_bit(wb, segmentation_params->segmentation_update_map);
    3199           0 :             if (segmentation_params->segmentation_update_map) {
    3200           0 :                 eb_aom_wb_write_bit(wb, segmentation_params->segmentation_temporal_update);
    3201             :             }
    3202           0 :             eb_aom_wb_write_bit(wb, segmentation_params->segmentation_update_map);
    3203             :         }
    3204           0 :         if (segmentation_params->segmentation_update_map) {
    3205           0 :             for (int i = 0; i < MAX_SEGMENTS; i++) {
    3206           0 :                 for (int j = 0; j < SEG_LVL_MAX; j++) {
    3207           0 :                     eb_aom_wb_write_bit(wb, segmentation_params->feature_enabled[i][j]);
    3208           0 :                     if (segmentation_params->feature_enabled[i][j]) {
    3209             :                         //TODO: add clamping
    3210           0 :                         if (segmentation_feature_signed[j]) {
    3211           0 :                             eb_aom_wb_write_inv_signed_literal(wb, segmentation_params->feature_data[i][j],
    3212             :                                                             segmentation_feature_bits[j]);
    3213             :                         } else {
    3214           0 :                             eb_aom_wb_write_literal(wb, segmentation_params->feature_data[i][j],
    3215             :                                                  segmentation_feature_bits[j]);
    3216             :                         }
    3217             :                     }
    3218             :                 }
    3219             :             }
    3220             :         }
    3221             : 
    3222             :     }
    3223             : 
    3224         120 : }
    3225             : 
    3226             : 
    3227         120 : static void encode_loopfilter(PictureParentControlSet *pcs_ptr, struct AomWriteBitBuffer *wb) {
    3228         120 :     FrameHeader *frm_hdr = &pcs_ptr->frm_hdr;
    3229         120 :     assert(!frm_hdr->coded_lossless);
    3230         120 :     if (frm_hdr->allow_intrabc) return;
    3231         120 :     const int32_t num_planes = 3;// av1_num_planes(pcs_ptr);
    3232             : 
    3233         120 :     struct LoopFilter *lf = &frm_hdr->loop_filter_params;
    3234             : 
    3235             :     // Encode the loop filter level and type
    3236         120 :     eb_aom_wb_write_literal(wb, lf->filter_level[0], 6);
    3237         120 :     eb_aom_wb_write_literal(wb, lf->filter_level[1], 6);
    3238         120 :     if (num_planes > 1) {
    3239         120 :         if (lf->filter_level[0] || lf->filter_level[1]) {
    3240          88 :             eb_aom_wb_write_literal(wb, lf->filter_level_u, 6);
    3241          88 :             eb_aom_wb_write_literal(wb, lf->filter_level_v, 6);
    3242             :         }
    3243             :     }
    3244         120 :     eb_aom_wb_write_literal(wb, lf->sharpness_level, 3);
    3245             : 
    3246             :     // Write out loop filter deltas applied at the MB level based on mode or
    3247             :     // ref frame (if they are enabled).
    3248         120 :     eb_aom_wb_write_bit(wb, lf->mode_ref_delta_enabled);
    3249         120 :     if (lf->mode_ref_delta_enabled) {
    3250           0 :         printf("ERROR[AN]: Loop Filter is not supported yet \n");
    3251             :         /* eb_aom_wb_write_bit(wb, lf->mode_ref_delta_update);
    3252             :         if (lf->mode_ref_delta_update) {
    3253             :         const int32_t prime_idx = pcs_ptr->primary_ref_frame;
    3254             :         const int32_t buf_idx =
    3255             :         prime_idx == PRIMARY_REF_NONE ? -1 : cm->frame_refs[prime_idx].idx;
    3256             :         int8_t last_ref_deltas[TOTAL_REFS_PER_FRAME];
    3257             :         if (prime_idx == PRIMARY_REF_NONE || buf_idx < 0) {
    3258             :         av1_set_default_ref_deltas(last_ref_deltas);
    3259             :         } else {
    3260             :         memcpy(last_ref_deltas, cm->buffer_pool->frame_bufs[buf_idx].ref_deltas,
    3261             :         TOTAL_REFS_PER_FRAME);
    3262             :         }
    3263             :         for (i = 0; i < TOTAL_REFS_PER_FRAME; i++) {
    3264             :         const int32_t delta = lf->ref_deltas[i];
    3265             :         const int32_t changed = delta != last_ref_deltas[i];
    3266             :         eb_aom_wb_write_bit(wb, changed);
    3267             :         if (changed) eb_aom_wb_write_inv_signed_literal(wb, delta, 6);
    3268             :         }
    3269             :         int8_t last_mode_deltas[MAX_MODE_LF_DELTAS];
    3270             :         if (prime_idx == PRIMARY_REF_NONE || buf_idx < 0) {
    3271             :         av1_set_default_mode_deltas(last_mode_deltas);
    3272             :         } else {
    3273             :         memcpy(last_mode_deltas,
    3274             :         cm->buffer_pool->frame_bufs[buf_idx].mode_deltas,
    3275             :         MAX_MODE_LF_DELTAS);
    3276             :         }
    3277             : 
    3278             :         for (i = 0; i < MAX_MODE_LF_DELTAS; i++) {
    3279             :         const int32_t delta = lf->mode_deltas[i];
    3280             :         const int32_t changed = delta != last_mode_deltas[i];
    3281             :         eb_aom_wb_write_bit(wb, changed);
    3282             :         if (changed) eb_aom_wb_write_inv_signed_literal(wb, delta, 6);
    3283             :         }
    3284             :         }*/
    3285             :     }
    3286             : }
    3287             : 
    3288         120 : static void encode_cdef(const PictureParentControlSet *pcs_ptr, struct AomWriteBitBuffer *wb) {
    3289             :     //assert(!cm->coded_lossless);
    3290             :     // moved out side
    3291             :     //if (!cm->seq_params.enable_cdef) return;
    3292             : 
    3293         120 :     const FrameHeader *frm_hdr = &pcs_ptr->frm_hdr;
    3294             : 
    3295         120 :     if (frm_hdr->allow_intrabc) return;
    3296             : 
    3297         120 :     const int32_t num_planes = 3;// av1_num_planes(pcs_ptr);
    3298             :     int32_t i;
    3299         120 :     eb_aom_wb_write_literal(wb, frm_hdr->CDEF_params.cdef_damping - 3, 2);
    3300             :     //cdef_pri_damping & cdef_sec_damping consolidated to cdef_damping
    3301             :     //assert(pcs_ptr->cdef_pri_damping == pcs_ptr->cdef_sec_damping);
    3302         120 :     eb_aom_wb_write_literal(wb, frm_hdr->CDEF_params.cdef_bits, 2);
    3303         318 :     for (i = 0; i < pcs_ptr->nb_cdef_strengths; i++) {
    3304         198 :         eb_aom_wb_write_literal(wb, frm_hdr->CDEF_params.cdef_y_strength[i], CDEF_STRENGTH_BITS);
    3305         198 :         if (num_planes > 1)
    3306         198 :             eb_aom_wb_write_literal(wb, frm_hdr->CDEF_params.cdef_uv_strength[i], CDEF_STRENGTH_BITS);
    3307             :     }
    3308             : }
    3309             : 
    3310         360 : static void write_delta_q(struct AomWriteBitBuffer *wb, int32_t delta_q) {
    3311         360 :     if (delta_q != 0) {
    3312           0 :         eb_aom_wb_write_bit(wb, 1);
    3313           0 :         eb_aom_wb_write_inv_signed_literal(wb, delta_q, 6);
    3314             :     }
    3315             :     else
    3316         360 :         eb_aom_wb_write_bit(wb, 0);
    3317         360 : }
    3318             : 
    3319         120 : static void encode_quantization(const PictureParentControlSet *const pcs_ptr,
    3320             :     struct AomWriteBitBuffer *wb) {
    3321         120 :     const int32_t num_planes = 3;//av1_num_planes(cm);
    3322             : 
    3323         120 :     const FrameHeader *frm_hdr = &pcs_ptr->frm_hdr;
    3324         120 :     eb_aom_wb_write_literal(wb, frm_hdr->quantization_params.base_q_idx, QINDEX_BITS);
    3325         120 :     write_delta_q(wb, frm_hdr->quantization_params.delta_q_y_dc);
    3326         120 :     if (num_planes > 1) {
    3327         240 :         int32_t diff_uv_delta = (frm_hdr->quantization_params.delta_q_u_dc != frm_hdr->quantization_params.delta_q_v_dc) ||
    3328         120 :             (frm_hdr->quantization_params.delta_q_u_ac != frm_hdr->quantization_params.delta_q_v_ac);
    3329         120 :         if (pcs_ptr->separate_uv_delta_q) eb_aom_wb_write_bit(wb, diff_uv_delta);
    3330         120 :         write_delta_q(wb, frm_hdr->quantization_params.delta_q_u_dc);
    3331         120 :         write_delta_q(wb, frm_hdr->quantization_params.delta_q_u_ac);
    3332         120 :         if (diff_uv_delta) {
    3333           0 :             write_delta_q(wb, frm_hdr->quantization_params.delta_q_v_dc);
    3334           0 :             write_delta_q(wb, frm_hdr->quantization_params.delta_q_v_ac);
    3335             :         }
    3336             :     }
    3337         120 :     eb_aom_wb_write_bit(wb, frm_hdr->quantization_params.using_qmatrix);
    3338         120 :     if (frm_hdr->quantization_params.using_qmatrix) {
    3339           0 :         eb_aom_wb_write_literal(wb, frm_hdr->quantization_params.qm_y, QM_LEVEL_BITS);
    3340           0 :         eb_aom_wb_write_literal(wb, frm_hdr->quantization_params.qm_u, QM_LEVEL_BITS);
    3341           0 :         if (!pcs_ptr->separate_uv_delta_q)
    3342           0 :             assert(frm_hdr->quantization_params.qm_u == frm_hdr->quantization_params.qm_v);
    3343             :         else
    3344           0 :             eb_aom_wb_write_literal(wb, frm_hdr->quantization_params.qm_v, QM_LEVEL_BITS);
    3345             :     }
    3346         120 : }
    3347             : 
    3348         120 : static void write_tile_info_max_tile(const PictureParentControlSet *const pcs_ptr,
    3349             :     struct AomWriteBitBuffer *wb) {
    3350         120 :     Av1Common * cm = pcs_ptr->av1_cm;
    3351         120 :     eb_aom_wb_write_bit(wb, cm->tiles_info.uniform_tile_spacing_flag);
    3352             : 
    3353         120 :     if (cm->tiles_info.uniform_tile_spacing_flag) {
    3354             :         // Uniform spaced tiles with power-of-two number of rows and columns
    3355             :         // tile columns
    3356         120 :         int32_t ones = cm->log2_tile_cols - cm->tiles_info.min_log2_tile_cols;
    3357         120 :         while (ones--)
    3358           0 :             eb_aom_wb_write_bit(wb, 1);
    3359         120 :         if (cm->log2_tile_cols < cm->tiles_info.max_log2_tile_cols)
    3360         120 :             eb_aom_wb_write_bit(wb, 0);
    3361             :         // rows
    3362         120 :         ones = cm->log2_tile_rows - cm->tiles_info.min_log2_tile_rows;
    3363         120 :         while (ones--)
    3364           0 :             eb_aom_wb_write_bit(wb, 1);
    3365         120 :         if (cm->log2_tile_rows < cm->tiles_info.max_log2_tile_rows)
    3366         120 :             eb_aom_wb_write_bit(wb, 0);
    3367             :     }
    3368             :     else {
    3369             :         // Explicit tiles with configurable tile widths and heights
    3370           0 :         printf("ERROR[AN]:  NON uniform_tile_spacing_flag not supported yet\n");
    3371             :         //// columns
    3372             :         // int sb_size_log2 = pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3373             :         //for (i = 0; i < cm->tile_cols; i++) {
    3374             :         //    size_sb = (cm->tile_col_start_mi[i + 1] - cm->tile_col_start_mi[i]) >> sb_size_log2;
    3375             :         //    wb_write_uniform(wb, AOMMIN(width_sb, cm->max_tile_width_sb),
    3376             :         //        size_sb - 1);
    3377             :         //    width_sb -= size_sb;
    3378             :         //}
    3379             :         //assert(width_sb == 0);
    3380             : 
    3381             :         //// rows
    3382             :         //for (i = 0; i < cm->tile_rows; i++) {
    3383             :         //    size_sb = (cm->tile_row_start_mi[i + 1] - cm->tile_row_start_mi[i]) >> sb_size_log2;
    3384             :         //    wb_write_uniform(wb, AOMMIN(height_sb, cm->max_tile_height_sb),
    3385             :         //        size_sb - 1);
    3386             :         //    height_sb -= size_sb;
    3387             :         //}
    3388             :         //assert(height_sb == 0);
    3389             :     }
    3390         120 : }
    3391             : 
    3392         242 : void eb_av1_get_tile_limits(PictureParentControlSet * pcs_ptr) {
    3393         242 :     Av1Common * cm = pcs_ptr->av1_cm;
    3394             : 
    3395         242 :     int32_t mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2);
    3396         242 :     int32_t mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2);
    3397         242 :     int32_t sb_cols = mi_cols >> pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3398         242 :     int32_t sb_rows = mi_rows >> pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3399             : 
    3400         242 :     int32_t sb_size_log2 = pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2 + MI_SIZE_LOG2;
    3401         242 :     cm->tiles_info.max_tile_width_sb = MAX_TILE_WIDTH >> sb_size_log2;
    3402         242 :     int32_t max_tile_area_sb = MAX_TILE_AREA >> (2 * sb_size_log2);
    3403             : 
    3404         242 :     cm->tiles_info.min_log2_tile_cols = tile_log2(cm->tiles_info.max_tile_width_sb, sb_cols);
    3405         242 :     cm->tiles_info.max_log2_tile_cols = tile_log2(1, AOMMIN(sb_cols, MAX_TILE_COLS));
    3406         242 :     cm->tiles_info.max_log2_tile_rows = tile_log2(1, AOMMIN(sb_rows, MAX_TILE_ROWS));
    3407         242 :     cm->tiles_info.min_log2_tile_rows = 0; // CHKN Tiles
    3408         242 :     cm->tiles_info.min_log2_tiles = tile_log2(max_tile_area_sb, sb_cols * sb_rows);
    3409         242 :     cm->tiles_info.min_log2_tiles = AOMMAX(cm->tiles_info.min_log2_tiles, cm->tiles_info.min_log2_tile_cols);
    3410         242 : }
    3411             : 
    3412         122 : void eb_av1_calculate_tile_cols(PictureParentControlSet * pcs_ptr) {
    3413         122 :     Av1Common *const cm = pcs_ptr->av1_cm;
    3414             : 
    3415         122 :     int mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2);
    3416         122 :     int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2);
    3417         122 :     int sb_cols = mi_cols >> pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3418         122 :     int sb_rows = mi_rows >> pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3419             :     int i;
    3420         122 :     int sb_size_log2 = pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3421             : 
    3422         122 :     if (cm->tiles_info.uniform_tile_spacing_flag) {
    3423             :         int start_sb;
    3424         122 :         int size_sb = ALIGN_POWER_OF_TWO(sb_cols, cm->log2_tile_cols);
    3425         122 :         size_sb >>= cm->log2_tile_cols;
    3426         122 :         assert(size_sb > 0);
    3427         244 :         for (i = 0, start_sb = 0; start_sb < sb_cols; i++) {
    3428         122 :             cm->tiles_info.tile_col_start_mi[i] = start_sb << sb_size_log2;
    3429         122 :             start_sb += size_sb;
    3430             :         }
    3431         122 :         cm->tiles_info.tile_cols = i;
    3432         122 :         cm->tiles_info.tile_col_start_mi[i] = sb_cols << sb_size_log2;
    3433         122 :         cm->tiles_info.min_log2_tile_rows = AOMMAX(cm->tiles_info.min_log2_tiles - cm->log2_tile_cols, 0);
    3434         122 :         cm->tiles_info.max_tile_height_sb = sb_rows >> cm->tiles_info.min_log2_tile_rows;
    3435             : 
    3436         122 :         cm->tile_width = size_sb << pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3437         122 :         cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
    3438             :     }
    3439             :     else {
    3440           0 :         int max_tile_area_sb = (sb_rows * sb_cols);
    3441           0 :         int widest_tile_sb = 1;
    3442           0 :         int sb_size_log2 = pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3443           0 :         cm->log2_tile_cols = tile_log2(1, cm->tiles_info.tile_cols);
    3444           0 :         for (i = 0; i < cm->tiles_info.tile_cols; i++) {
    3445           0 :             int size_sb = (cm->tiles_info.tile_col_start_mi[i + 1] -
    3446           0 :                 cm->tiles_info.tile_col_start_mi[i]) >> sb_size_log2;
    3447           0 :             widest_tile_sb = AOMMAX(widest_tile_sb, size_sb);
    3448             :         }
    3449           0 :         if (cm->tiles_info.min_log2_tiles)
    3450           0 :             max_tile_area_sb >>= (cm->tiles_info.min_log2_tiles + 1);
    3451             : 
    3452           0 :         cm->tiles_info.max_tile_height_sb = AOMMAX(max_tile_area_sb / widest_tile_sb, 1);
    3453             :     }
    3454         122 : }
    3455             : 
    3456         122 : void eb_av1_calculate_tile_rows(PictureParentControlSet * pcs_ptr)
    3457             : {
    3458         122 :     Av1Common *const cm = pcs_ptr->av1_cm;
    3459             : 
    3460         122 :     int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2);
    3461         122 :     int sb_rows = mi_rows >> pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3462             :     int start_sb, size_sb, i;
    3463         122 :     int sb_size_log2 = pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3464             : 
    3465         122 :     if (cm->tiles_info.uniform_tile_spacing_flag) {
    3466         122 :         size_sb = ALIGN_POWER_OF_TWO(sb_rows, cm->log2_tile_rows);
    3467         122 :         size_sb >>= cm->log2_tile_rows;
    3468         122 :         assert(size_sb > 0);
    3469         244 :         for (i = 0, start_sb = 0; start_sb < sb_rows; i++) {
    3470         122 :             cm->tiles_info.tile_row_start_mi[i] = start_sb << sb_size_log2;
    3471         122 :             start_sb += size_sb;
    3472             :         }
    3473         122 :         cm->tiles_info.tile_rows = i;
    3474         122 :         cm->tiles_info.tile_row_start_mi[i] = sb_rows << sb_size_log2;
    3475             : 
    3476         122 :         cm->tile_height = size_sb << pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3477         122 :         cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
    3478             :     }
    3479             :     else
    3480           0 :         cm->log2_tile_rows = tile_log2(1, cm->tiles_info.tile_rows);
    3481         122 : }
    3482             : 
    3483         122 :  void set_tile_info(PictureParentControlSet * pcs_ptr)
    3484             : {
    3485             :      /*  Tiling algorithm:
    3486             :         input : log2_tile_count ==> tile_count = 1<<log2_tile_count
    3487             : 
    3488             :         step1) compute pic_size_in_sb
    3489             :         step2) then round up to the closed n.tile_count.
    3490             :         step3) tile_size = rounded_pic_size_in_sb / tile_count.
    3491             :         step4) we fill tiles of size tile_size until we reach the end of the pic
    3492             : 
    3493             :         Note that: the last tile could have smaller size, and the final number
    3494             :         of tiles could be less than tile_count
    3495             :      */
    3496             : 
    3497         122 :     Av1Common * cm = pcs_ptr->av1_cm;
    3498             :     int i, start_sb;
    3499             :     //to connect later if non uniform tile spacing is needed.
    3500         122 :     int tile_width_count = 0;
    3501         122 :     int tile_height_count= 0;
    3502         122 :     int tile_widths[MAX_TILE_COLS] = {0};
    3503         122 :     int tile_heights[MAX_TILE_ROWS] = { 0 };
    3504             : 
    3505         122 :     eb_av1_get_tile_limits(pcs_ptr);
    3506             : 
    3507             :     // configure tile columns
    3508         122 :     if (tile_width_count == 0 || tile_height_count == 0)
    3509             :     {
    3510         122 :         cm->tiles_info.uniform_tile_spacing_flag = 1;
    3511         122 :         cm->log2_tile_cols = AOMMAX(pcs_ptr->sequence_control_set_ptr->static_config.tile_columns, cm->tiles_info.min_log2_tile_cols);
    3512         122 :         cm->log2_tile_cols = AOMMIN(cm->log2_tile_cols, cm->tiles_info.max_log2_tile_cols);
    3513             :     }
    3514             :     else {
    3515           0 :         int mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2);
    3516           0 :         int sb_cols = mi_cols >> pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3517           0 :         int size_sb, j = 0;
    3518           0 :         int sb_size_log2 = pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3519           0 :         cm->tiles_info.uniform_tile_spacing_flag = 0;
    3520           0 :         for (i = 0, start_sb = 0; start_sb < sb_cols && i < MAX_TILE_COLS; i++) {
    3521           0 :             cm->tiles_info.tile_col_start_mi[i] = start_sb << sb_size_log2;
    3522           0 :             size_sb = tile_widths[j++];
    3523           0 :             if (j >= tile_width_count) j = 0;
    3524           0 :             start_sb += AOMMIN(size_sb, cm->tiles_info.max_tile_width_sb);
    3525             :         }
    3526           0 :         cm->tiles_info.tile_cols = i;
    3527           0 :         cm->tiles_info.tile_col_start_mi[i] = sb_cols << sb_size_log2;
    3528             :     }
    3529         122 :     eb_av1_calculate_tile_cols(pcs_ptr);
    3530             : 
    3531             :     // configure tile rows
    3532         122 :     if (cm->tiles_info.uniform_tile_spacing_flag) {
    3533         122 :         cm->log2_tile_rows = AOMMAX(pcs_ptr->sequence_control_set_ptr->static_config.tile_rows, cm->tiles_info.min_log2_tile_rows);
    3534         122 :         cm->log2_tile_rows = AOMMIN(cm->log2_tile_rows, cm->tiles_info.max_log2_tile_rows);
    3535             :     }
    3536             :     else {
    3537           0 :         int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2);
    3538           0 :         int sb_rows = mi_rows >> pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3539           0 :         int size_sb, j = 0;
    3540           0 :         int sb_size_log2 = pcs_ptr->sequence_control_set_ptr->seq_header.sb_size_log2;
    3541           0 :         for (i = 0, start_sb = 0; start_sb < sb_rows && i < MAX_TILE_ROWS; i++) {
    3542           0 :             cm->tiles_info.tile_row_start_mi[i] = start_sb << sb_size_log2;
    3543           0 :             size_sb = tile_heights[j++];
    3544           0 :             if (j >= tile_height_count) j = 0;
    3545           0 :             start_sb += AOMMIN(size_sb, cm->tiles_info.max_tile_height_sb);
    3546             :         }
    3547           0 :         cm->tiles_info.tile_rows = i;
    3548           0 :         cm->tiles_info.tile_row_start_mi[i] = sb_rows << sb_size_log2;
    3549             :     }
    3550         122 :     eb_av1_calculate_tile_rows(pcs_ptr);
    3551         122 : }
    3552             : 
    3553         120 :  void eb_av1_tile_set_row(TileInfo *tile, TilesInfo *tiles_info,
    3554             :      int32_t mi_rows, int row)
    3555             :  {
    3556         120 :      assert(row < tiles_info->tile_rows);
    3557         120 :      int mi_row_start = tiles_info->tile_row_start_mi[row];
    3558         120 :      int mi_row_end  = tiles_info->tile_row_start_mi[row + 1];
    3559         120 :      tile->tile_row = row;
    3560         120 :      tile->mi_row_start = mi_row_start;
    3561         120 :      tile->mi_row_end = AOMMIN(mi_row_end, mi_rows);
    3562         120 :      tile->tg_horz_boundary = 0;
    3563         120 :      assert(tile->mi_row_end > tile->mi_row_start);
    3564         120 :  }
    3565             : 
    3566         120 :  void eb_av1_tile_set_col(TileInfo *tile, const TilesInfo *tiles_info,
    3567             :      int32_t mi_cols, int col)
    3568             :  {
    3569         120 :      assert(col < tiles_info->tile_cols);
    3570         120 :      int mi_col_start = tiles_info->tile_col_start_mi[col];
    3571         120 :      int mi_col_end = tiles_info->tile_col_start_mi[col + 1];
    3572         120 :      tile->tile_col = col;
    3573         120 :      tile->mi_col_start = mi_col_start;
    3574         120 :      tile->mi_col_end = AOMMIN(mi_col_end, mi_cols);
    3575         120 :      assert(tile->mi_col_end > tile->mi_col_start);
    3576         120 :  }
    3577             : 
    3578         120 : static void write_tile_info(const PictureParentControlSet *const pcs_ptr,
    3579             :     //struct AomWriteBitBuffer *saved_wb,
    3580             :     struct AomWriteBitBuffer *wb) {
    3581         120 :     eb_av1_get_tile_limits((PictureParentControlSet *)pcs_ptr);
    3582         120 :     write_tile_info_max_tile(pcs_ptr, wb);
    3583             : 
    3584         120 :     if (pcs_ptr->av1_cm->tiles_info.tile_rows * pcs_ptr->av1_cm->tiles_info.tile_cols > 1) {
    3585             :         // tile id used for cdf update
    3586           0 :         eb_aom_wb_write_literal(
    3587             :             wb,
    3588           0 :             pcs_ptr->frame_end_cdf_update_mode ? pcs_ptr->av1_cm->tiles_info.tile_rows * pcs_ptr->av1_cm->tiles_info.tile_cols - 1 : 0,
    3589           0 :             pcs_ptr->av1_cm->log2_tile_cols + pcs_ptr->av1_cm->log2_tile_rows);
    3590             :         // Number of bytes in tile size - 1
    3591           0 :         eb_aom_wb_write_literal(wb, 3, 2);
    3592             :     }
    3593         120 : }
    3594             : 
    3595         120 : static void write_render_size(struct AomWriteBitBuffer *wb,
    3596             :                               SequenceControlSet *scs)
    3597             : {
    3598         120 :     uint16_t width = scs->max_input_luma_width;
    3599         120 :     uint16_t render_width = width - scs->max_input_pad_right;
    3600         120 :     uint16_t height = scs->max_input_luma_height;
    3601         120 :     uint16_t render_height = height - scs->max_input_pad_bottom;
    3602         120 :     int render_and_frame_size_different =
    3603         120 :         (width != render_width) || (height != render_height);
    3604         120 :     eb_aom_wb_write_bit(wb, render_and_frame_size_different);
    3605         120 :     if (!render_and_frame_size_different) return;
    3606           0 :     uint32_t render_width_minus_1 = render_width - 1;
    3607           0 :     uint32_t render_height_minus_1 = render_height - 1;
    3608           0 :     eb_aom_wb_write_literal(wb, render_width_minus_1, 16);
    3609           0 :     eb_aom_wb_write_literal(wb, render_height_minus_1, 16);
    3610             : }
    3611             : 
    3612         120 : static void write_frame_size(PictureParentControlSet *pcs_ptr,
    3613             :     int32_t frame_size_override,
    3614             :     struct AomWriteBitBuffer *wb) {
    3615         120 :     SequenceControlSet *scs_ptr = (SequenceControlSet*)pcs_ptr->sequence_control_set_wrapper_ptr->object_ptr;
    3616             :     (void)(*pcs_ptr);
    3617             :     (void)frame_size_override;
    3618             :     //const int32_t coded_width = cm->superres_upscaled_width - 1;
    3619             :     //const int32_t coded_height = cm->superres_upscaled_height - 1;
    3620             : 
    3621             :     //if (frame_size_override) {
    3622             :     //    const SequenceHeader *seq_params = &cm->seq_params;
    3623             :     //    int32_t num_bits_width = seq_params->num_bits_width;
    3624             :     //    int32_t num_bits_height = seq_params->num_bits_height;
    3625             :     //    eb_aom_wb_write_literal(wb, coded_width, num_bits_width);
    3626             :     //    eb_aom_wb_write_literal(wb, coded_height, num_bits_height);
    3627             :     //}
    3628         120 :     if (scs_ptr->seq_header.enable_superres) {
    3629           0 :         printf("ERROR[AN]: enable_superres not supported yet\n");
    3630             :         //write_superres_scale(cm, wb);
    3631             :     }
    3632             : 
    3633         120 :     write_render_size(wb, scs_ptr);
    3634         120 : }
    3635             : 
    3636           2 : static void WriteProfile(BitstreamProfile profile,
    3637             :     struct AomWriteBitBuffer *wb) {
    3638           2 :     assert(profile >= PROFILE_0 && profile < MAX_PROFILES);
    3639           2 :     eb_aom_wb_write_literal(wb, profile, PROFILE_BITS);
    3640           2 : }
    3641             : 
    3642           2 : static void write_bitdepth(SequenceControlSet *scs_ptr/*Av1Common *const cm*/,
    3643             :     struct AomWriteBitBuffer *wb) {
    3644             :     // Profile 0/1: [0] for 8 bit, [1]  10-bit
    3645             :     // Profile   2: [0] for 8 bit, [10] 10-bit, [11] - 12-bit
    3646           2 :     eb_aom_wb_write_bit(wb, scs_ptr->static_config.encoder_bit_depth == EB_8BIT ? 0 : 1);
    3647           2 :     if (scs_ptr->static_config.profile == PROFILE_2 && scs_ptr->static_config.encoder_bit_depth != EB_8BIT) {
    3648           0 :         printf("ERROR[AN]: Profile 2 Not supported\n");
    3649           0 :         eb_aom_wb_write_bit(wb, scs_ptr->static_config.encoder_bit_depth == EB_10BIT ? 0 : 1);
    3650             :     }
    3651           2 : }
    3652           2 : static void write_color_config(
    3653             :     SequenceControlSet *scs_ptr/*Av1Common *const cm*/, struct AomWriteBitBuffer *wb) {
    3654             :     //write_bitdepth(cm, wb);
    3655           2 :     write_bitdepth(scs_ptr, wb);
    3656           2 :     const int32_t is_monochrome = 0;// cm->seq_params.monochrome;
    3657             :     // monochrome bit
    3658           2 :     eb_aom_wb_write_bit(wb, is_monochrome);
    3659             :     //if (cm->profile != PROFILE_1)
    3660             :     //    eb_aom_wb_write_bit(wb, is_monochrome);
    3661             :     //else
    3662             :     //    assert(!is_monochrome);
    3663             :     if (1/*cm->color_primaries == AOM_CICP_CP_UNSPECIFIED &&
    3664             :          cm->transfer_characteristics == AOM_CICP_TC_UNSPECIFIED &&
    3665             :          cm->matrix_coefficients == AOM_CICP_MC_UNSPECIFIED*/) {
    3666           2 :         eb_aom_wb_write_bit(wb, 0);  // No color description present
    3667             :     }
    3668             :     else {
    3669             :         //eb_aom_wb_write_bit(wb, 1);  // Color description present
    3670             :         //eb_aom_wb_write_literal(wb, cm->color_primaries, 8);
    3671             :         //eb_aom_wb_write_literal(wb, cm->transfer_characteristics, 8);
    3672             :         //eb_aom_wb_write_literal(wb, cm->matrix_coefficients, 8);
    3673             :     }
    3674           2 :     if (is_monochrome) {
    3675           0 :         printf("ERROR[AN]: is_monochrome not supported yet\n");
    3676           0 :         return;
    3677             :     }
    3678             :     if (0/*cm->color_primaries == EB_CICP_CP_BT_709 &&
    3679             :          cm->transfer_characteristics == EB_CICP_TC_SRGB &&
    3680             :          cm->matrix_coefficients ==
    3681             :          AOM_CICP_MC_IDENTITY*/) {  // it would be better to remove this
    3682             :          // dependency too
    3683             :          //assert(cm->subsampling_x == 0 && cm->subsampling_y == 0);
    3684             :          //assert(cm->profile == PROFILE_1 ||
    3685             :          //    (cm->profile == PROFILE_2 && cm->bit_depth == AOM_BITS_12));
    3686             :     }
    3687             :     else {
    3688             :         // 0: [16, 235] (i.e. xvYCC), 1: [0, 255]
    3689           2 :         eb_aom_wb_write_bit(wb, 0);
    3690             :         //eb_aom_wb_write_bit(wb, cm->color_range);
    3691             : 
    3692             :         //if (cm->profile == PROFILE_0) {
    3693             :         //    // 420 only
    3694             :         //    assert(cm->subsampling_x == 1 && cm->subsampling_y == 1);
    3695             :         //}
    3696             :         //else if (cm->profile == PROFILE_1) {
    3697             :         //    // 444 only
    3698             :         //    assert(cm->subsampling_x == 0 && cm->subsampling_y == 0);
    3699             :         //}
    3700             :         //else if (cm->profile == PROFILE_2) {
    3701             :         //    if (cm->bit_depth == AOM_BITS_12) {
    3702             :         //        // 420, 444 or 422
    3703             :         //        eb_aom_wb_write_bit(wb, cm->subsampling_x);
    3704             :         //        if (cm->subsampling_x == 0) {
    3705             :         //            assert(cm->subsampling_y == 0 &&
    3706             :         //                "4:4:0 subsampling not allowed in AV1");
    3707             :         //        }
    3708             :         //        else {
    3709             :         //            eb_aom_wb_write_bit(wb, cm->subsampling_y);
    3710             :         //        }
    3711             :         //    }
    3712             :         //    else {
    3713             :         //        // 422 only
    3714             :         //        assert(cm->subsampling_x == 1 && cm->subsampling_y == 0);
    3715             :         //    }
    3716             :         //}
    3717             :         //if (cm->matrix_coefficients == AOM_CICP_MC_IDENTITY) {
    3718             :         //    assert(cm->subsampling_x == 0 && cm->subsampling_y == 0);
    3719             :         //}
    3720           2 :         eb_aom_wb_write_literal(wb, 0, 2);
    3721             :         //if (cm->subsampling_x == 1 && cm->subsampling_y == 1) {
    3722             :         //    eb_aom_wb_write_literal(wb, cm->chroma_sample_position, 2);
    3723             :         //}
    3724             :     }
    3725           2 :     eb_aom_wb_write_bit(wb, 0);
    3726             :     //eb_aom_wb_write_bit(wb, cm->separate_uv_delta_q);
    3727             : }
    3728             : 
    3729           2 : void write_sequence_header(SequenceControlSet *scs_ptr/*Av1Comp *cpi*/, struct AomWriteBitBuffer *wb) {
    3730             :     //    Av1Common *const cm = &cpi->common;
    3731             :     //    SequenceHeader *seq_params = &cm->seq_params;
    3732             :     //
    3733             : 
    3734           2 :     int32_t max_frame_width = scs_ptr->seq_header.max_frame_width;
    3735             :     /*        cpi->oxcf.forced_max_frame_width
    3736             :     ? cpi->oxcf.forced_max_frame_width
    3737             :     : cpi->oxcf.width;*/
    3738           2 :     int32_t max_frame_height = scs_ptr->seq_header.max_frame_height;
    3739             :     /*cpi->oxcf.forced_max_frame_height
    3740             :     ? cpi->oxcf.forced_max_frame_height
    3741             :     : cpi->oxcf.height;*/
    3742             : 
    3743           2 :     eb_aom_wb_write_literal(wb, scs_ptr->seq_header.frame_width_bits - 1, 4);
    3744           2 :     eb_aom_wb_write_literal(wb, scs_ptr->seq_header.frame_height_bits - 1, 4);
    3745           2 :     eb_aom_wb_write_literal(wb, max_frame_width - 1, scs_ptr->seq_header.frame_width_bits);
    3746           2 :     eb_aom_wb_write_literal(wb, max_frame_height - 1, scs_ptr->seq_header.frame_height_bits);
    3747             :     //
    3748             :     /* Placeholder for actually writing to the bitstream */
    3749             : 
    3750           2 :     if (!scs_ptr->seq_header.reduced_still_picture_header) {
    3751             :         //scs_ptr->frame_id_numbers_present_flag = 0;
    3752             :         //    cm->large_scale_tile ? 0 : cm->error_resilient_mode;
    3753             : 
    3754           2 :         eb_aom_wb_write_bit(wb, scs_ptr->seq_header.frame_id_numbers_present_flag);
    3755           2 :         if (scs_ptr->seq_header.frame_id_numbers_present_flag) {
    3756             :             // We must always have delta_frame_id_length < frame_id_length,
    3757             :             // in order for a frame to be referenced with a unique delta.
    3758             :             // Avoid wasting bits by using a coding that enforces this restriction.
    3759           0 :             eb_aom_wb_write_literal(wb, scs_ptr->seq_header.delta_frame_id_length - 2, 4);
    3760           0 :             eb_aom_wb_write_literal(
    3761           0 :                 wb, ((scs_ptr->seq_header.frame_id_length) - (scs_ptr->seq_header.delta_frame_id_length) - 1),
    3762             :                 3);
    3763             :         }
    3764             :     }
    3765             : 
    3766           2 :     eb_aom_wb_write_bit(wb, scs_ptr->seq_header.sb_size == BLOCK_128X128 ? 1 : 0);
    3767             :     //    write_sb_size(seq_params, wb);
    3768           2 :     eb_aom_wb_write_bit(wb, scs_ptr->seq_header.enable_filter_intra);
    3769             : 
    3770           2 :         scs_ptr->seq_header.enable_intra_edge_filter = 1;
    3771           2 :     eb_aom_wb_write_bit(wb, scs_ptr->seq_header.enable_intra_edge_filter);
    3772             : 
    3773           2 :     if (!scs_ptr->seq_header.reduced_still_picture_header) {
    3774           2 :         eb_aom_wb_write_bit(wb, scs_ptr->seq_header.enable_interintra_compound);
    3775           2 :         eb_aom_wb_write_bit(wb, scs_ptr->seq_header.enable_masked_compound);
    3776           2 :         eb_aom_wb_write_bit(wb, scs_ptr->static_config.enable_warped_motion);
    3777           2 :         eb_aom_wb_write_bit(wb, scs_ptr->seq_header.enable_dual_filter);
    3778             : 
    3779           2 :         eb_aom_wb_write_bit(wb, scs_ptr->seq_header.order_hint_info.enable_order_hint);
    3780             : 
    3781           2 :         if (scs_ptr->seq_header.order_hint_info.enable_order_hint) {
    3782           2 :             eb_aom_wb_write_bit(wb, scs_ptr->seq_header.order_hint_info.enable_jnt_comp);
    3783           2 :             eb_aom_wb_write_bit(wb, scs_ptr->seq_header.order_hint_info.enable_ref_frame_mvs);
    3784             :         }
    3785             : 
    3786           2 :         if (scs_ptr->seq_header.seq_force_screen_content_tools == 2)
    3787           2 :             eb_aom_wb_write_bit(wb, 1);
    3788             :         else {
    3789           0 :             eb_aom_wb_write_bit(wb, 0);
    3790           0 :             eb_aom_wb_write_bit(wb, scs_ptr->seq_header.seq_force_screen_content_tools);
    3791             :         }
    3792             :         //
    3793           2 :         if (scs_ptr->seq_header.seq_force_screen_content_tools > 0) {
    3794           2 :             if (scs_ptr->seq_header.seq_force_integer_mv == 2)
    3795           2 :                 eb_aom_wb_write_bit(wb, 1);
    3796             :             else {
    3797           0 :                 eb_aom_wb_write_bit(wb, 0);
    3798           0 :                 eb_aom_wb_write_bit(wb, scs_ptr->seq_header.seq_force_integer_mv);
    3799             :             }
    3800             :         }
    3801             :         else
    3802           0 :             assert(scs_ptr->seq_header.seq_force_integer_mv == 2);
    3803           2 :         if (scs_ptr->seq_header.order_hint_info.enable_order_hint)
    3804           2 :             eb_aom_wb_write_literal(wb, scs_ptr->seq_header.order_hint_info.order_hint_bits - 1, 3);
    3805             :     }
    3806             : 
    3807           2 :     eb_aom_wb_write_bit(wb, scs_ptr->seq_header.enable_superres);
    3808           2 :     eb_aom_wb_write_bit(wb, scs_ptr->seq_header.enable_cdef);
    3809           2 :     eb_aom_wb_write_bit(wb, scs_ptr->seq_header.enable_restoration);
    3810           2 : }
    3811             : 
    3812             : // Recenters a non-negative literal v around a reference r
    3813        4253 : static uint16_t recenter_nonneg(uint16_t r, uint16_t v) {
    3814        4253 :     if (v > (r << 1))
    3815         393 :         return v;
    3816        3860 :     else if (v >= r)
    3817        1814 :         return ((v - r) << 1);
    3818             :     else
    3819        2046 :         return ((r - v) << 1) - 1;
    3820             : }
    3821             : 
    3822             : // Recenters a non-negative literal v in [0, n-1] around a
    3823             : // reference r also in [0, n-1]
    3824        4253 : static uint16_t recenter_finite_nonneg(uint16_t n, uint16_t r, uint16_t v) {
    3825        4253 :     if ((r << 1) <= n)
    3826        3719 :         return recenter_nonneg(r, v);
    3827             :     else
    3828         534 :         return recenter_nonneg(n - 1 - r, n - 1 - v);
    3829             : }
    3830             : 
    3831           0 : int32_t eb_aom_count_primitive_symmetric(int16_t v, uint32_t abs_bits) {
    3832           0 :     return (v == 0 ? 1 : abs_bits + 2);
    3833             : }
    3834             : 
    3835             : // Encodes a value v in [0, n-1] quasi-uniformly
    3836         286 : void eb_aom_write_primitive_quniform(AomWriter *w, uint16_t n, uint16_t v) {
    3837         286 :     if (n <= 1) return;
    3838         286 :     const int32_t l = get_msb(n - 1) + 1;
    3839         286 :     const int32_t m = (1 << l) - n;
    3840         286 :     if (v < m)
    3841         116 :         aom_write_literal(w, v, l - 1);
    3842             :     else {
    3843         170 :         aom_write_literal(w, m + ((v - m) >> 1), l - 1);
    3844         170 :         aom_write_bit(w, (v - m) & 1);
    3845             :     }
    3846             : }
    3847             : 
    3848          10 : static void aom_wb_write_primitive_quniform(struct AomWriteBitBuffer *wb,
    3849             :     uint16_t n, uint16_t v) {
    3850          10 :     if (n <= 1) return;
    3851          10 :     const int32_t l = get_msb(n - 1) + 1;
    3852          10 :     const int32_t m = (1 << l) - n;
    3853          10 :     if (v < m)
    3854          10 :         eb_aom_wb_write_literal(wb, v, l - 1);
    3855             :     else {
    3856           0 :         eb_aom_wb_write_literal(wb, m + ((v - m) >> 1), l - 1);
    3857           0 :         eb_aom_wb_write_bit(wb, (v - m) & 1);
    3858             :     }
    3859             : }
    3860             : 
    3861        1886 : int32_t eb_aom_count_primitive_quniform(uint16_t n, uint16_t v) {
    3862        1886 :     if (n <= 1) return 0;
    3863        1886 :     const int32_t l = get_msb(n - 1) + 1;
    3864        1886 :     const int32_t m = (1 << l) - n;
    3865        1886 :     return v < m ? l - 1 : l;
    3866             : }
    3867             : 
    3868             : // Finite subexponential code that codes a symbol v in [0, n-1] with parameter k
    3869         508 : void eb_aom_write_primitive_subexpfin(AomWriter *w, uint16_t n, uint16_t k,
    3870             :     uint16_t v) {
    3871         508 :     int32_t i = 0;
    3872         508 :     int32_t mk = 0;
    3873         651 :     while (1) {
    3874        1159 :         int32_t b = (i ? k + i - 1 : k);
    3875        1159 :         int32_t a = (1 << b);
    3876        1159 :         if (n <= mk + 3 * a) {
    3877         286 :             eb_aom_write_primitive_quniform(w, (uint16_t)(n - mk), (uint16_t)(v - mk));
    3878         286 :             break;
    3879             :         }
    3880             :         else {
    3881         873 :             int32_t t = (v >= mk + a);
    3882         873 :             aom_write_bit(w, t);
    3883         873 :             if (t) {
    3884         651 :                 i = i + 1;
    3885         651 :                 mk += a;
    3886             :             }
    3887             :             else {
    3888         222 :                 aom_write_literal(w, v - mk, b);
    3889         222 :                 break;
    3890             :             }
    3891             :         }
    3892             :     }
    3893         508 : }
    3894             : 
    3895         452 : static void aom_wb_write_primitive_subexpfin(struct AomWriteBitBuffer *wb,
    3896             :     uint16_t n, uint16_t k,
    3897             :     uint16_t v) {
    3898         452 :     int32_t i = 0;
    3899         452 :     int32_t mk = 0;
    3900        1105 :     while (1) {
    3901        1557 :         int32_t b = (i ? k + i - 1 : k);
    3902        1557 :         int32_t a = (1 << b);
    3903        1557 :         if (n <= mk + 3 * a) {
    3904          10 :             aom_wb_write_primitive_quniform(wb, (uint16_t)(n - mk), (uint16_t)(v - mk));
    3905          10 :             break;
    3906             :         }
    3907             :         else {
    3908        1547 :             int32_t t = (v >= mk + a);
    3909        1547 :             eb_aom_wb_write_bit(wb, t);
    3910        1547 :             if (t) {
    3911        1105 :                 i = i + 1;
    3912        1105 :                 mk += a;
    3913             :             }
    3914             :             else {
    3915         442 :                 eb_aom_wb_write_literal(wb, v - mk, b);
    3916         442 :                 break;
    3917             :             }
    3918             :         }
    3919             :     }
    3920         452 : }
    3921             : 
    3922        3293 : int32_t eb_aom_count_primitive_subexpfin(uint16_t n, uint16_t k, uint16_t v) {
    3923        3293 :     int32_t count = 0;
    3924        3293 :     int32_t i = 0;
    3925        3293 :     int32_t mk = 0;
    3926        6773 :     while (1) {
    3927       10066 :         int32_t b = (i ? k + i - 1 : k);
    3928       10066 :         int32_t a = (1 << b);
    3929       10066 :         if (n <= mk + 3 * a) {
    3930        1886 :             count += eb_aom_count_primitive_quniform((uint16_t)(n - mk), (uint16_t)(v - mk));
    3931        1886 :             break;
    3932             :         }
    3933             :         else {
    3934        8180 :             int32_t t = (v >= mk + a);
    3935        8180 :             count++;
    3936        8180 :             if (t) {
    3937        6773 :                 i = i + 1;
    3938        6773 :                 mk += a;
    3939             :             }
    3940             :             else {
    3941        1407 :                 count += b;
    3942        1407 :                 break;
    3943             :             }
    3944             :         }
    3945             :     }
    3946        3293 :     return count;
    3947             : }
    3948             : // Finite subexponential code that codes a symbol v in[0, n - 1] with parameter k
    3949             : // based on a reference ref also in [0, n-1].
    3950             : // Recenters symbol around r first and then uses a finite subexponential code.
    3951         508 : void eb_aom_write_primitive_refsubexpfin(AomWriter *w, uint16_t n, uint16_t k,
    3952             :     uint16_t ref, uint16_t v) {
    3953         508 :     eb_aom_write_primitive_subexpfin(w, n, k, recenter_finite_nonneg(n, ref, v));
    3954         508 : }
    3955             : 
    3956         452 : static void aom_wb_write_primitive_refsubexpfin(struct AomWriteBitBuffer *wb,
    3957             :     uint16_t n, uint16_t k,
    3958             :     uint16_t ref, uint16_t v) {
    3959         452 :     aom_wb_write_primitive_subexpfin(wb, n, k, recenter_finite_nonneg(n, ref, v));
    3960         452 : }
    3961             : 
    3962         452 : void eb_aom_wb_write_signed_primitive_refsubexpfin(struct AomWriteBitBuffer *wb,
    3963             :     uint16_t n, uint16_t k,
    3964             :     int16_t ref, int16_t v) {
    3965         452 :     ref += n - 1;
    3966         452 :     v += n - 1;
    3967         452 :     const uint16_t scaled_n = (n << 1) - 1;
    3968         452 :     aom_wb_write_primitive_refsubexpfin(wb, scaled_n, k, ref, v);
    3969         452 : }
    3970             : 
    3971        3293 : int32_t eb_aom_count_primitive_refsubexpfin(uint16_t n, uint16_t k, uint16_t ref,
    3972             :     uint16_t v) {
    3973        3293 :     return eb_aom_count_primitive_subexpfin(n, k, recenter_finite_nonneg(n, ref, v));
    3974             : }
    3975             : 
    3976         812 : static void write_global_motion_params(const EbWarpedMotionParams *params,
    3977             :     const EbWarpedMotionParams *ref_params,
    3978             :     struct AomWriteBitBuffer *wb,
    3979             :     int32_t allow_hp) {
    3980         812 :     const TransformationType type = params->wmtype;
    3981         812 :     eb_aom_wb_write_bit(wb, type != IDENTITY);
    3982         812 :     if (type != IDENTITY) {
    3983         113 :         eb_aom_wb_write_bit(wb, type == ROTZOOM);
    3984         113 :         if (type != ROTZOOM) eb_aom_wb_write_bit(wb, type == TRANSLATION);
    3985             :     }
    3986             : 
    3987         812 :     if (type >= ROTZOOM) {
    3988         113 :         int16_t ref2 = (int16_t)((ref_params->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
    3989         113 :         int16_t v2 = (int16_t)((params->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
    3990             : 
    3991         113 :         int16_t ref3 = (int16_t)(ref_params->wmmat[3] >> GM_ALPHA_PREC_DIFF);
    3992         113 :         int16_t v3 = (int16_t)(params->wmmat[3] >> GM_ALPHA_PREC_DIFF);
    3993             : 
    3994         113 :         eb_aom_wb_write_signed_primitive_refsubexpfin(
    3995             :             wb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
    3996             :             ref2/*(ref_params->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS)*/,
    3997             :             v2/*(int16_t)((params->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS))*/);
    3998         113 :         eb_aom_wb_write_signed_primitive_refsubexpfin(
    3999             :             wb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
    4000             :             ref3/*(ref_params->wmmat[3] >> GM_ALPHA_PREC_DIFF)*/,
    4001             :             v3/*(int16_t)(params->wmmat[3] >> GM_ALPHA_PREC_DIFF)*/);
    4002             :     }
    4003             : 
    4004         812 :     if (type >= AFFINE) {
    4005           0 :         int16_t ref4 = (int16_t)(ref_params->wmmat[4] >> GM_ALPHA_PREC_DIFF);
    4006           0 :         int16_t v4 = (int16_t)(params->wmmat[4] >> GM_ALPHA_PREC_DIFF);
    4007             : 
    4008           0 :         int16_t ref5 = (int16_t)((ref_params->wmmat[5] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
    4009           0 :         int16_t v5 = (int16_t)((params->wmmat[5] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
    4010             : 
    4011           0 :         eb_aom_wb_write_signed_primitive_refsubexpfin(
    4012             :             wb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
    4013             :             ref4/*(ref_params->wmmat[4] >> GM_ALPHA_PREC_DIFF)*/,
    4014             :             v4/*(int16_t)(params->wmmat[4] >> GM_ALPHA_PREC_DIFF)*/);
    4015           0 :         eb_aom_wb_write_signed_primitive_refsubexpfin(
    4016             :             wb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
    4017             :             ref5/*(ref_params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -    (1 << GM_ALPHA_PREC_BITS)*/,
    4018             :             v5/*(int16_t)(params->wmmat[5] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS)*/);
    4019             :     }
    4020             : 
    4021         812 :     if (type >= TRANSLATION) {
    4022         113 :         const int32_t trans_bits = (type == TRANSLATION)
    4023           0 :             ? GM_ABS_TRANS_ONLY_BITS - !allow_hp
    4024         113 :             : GM_ABS_TRANS_BITS;
    4025         113 :         const int32_t trans_prec_diff = (type == TRANSLATION)
    4026           0 :             ? GM_TRANS_ONLY_PREC_DIFF + !allow_hp
    4027         113 :             : GM_TRANS_PREC_DIFF;
    4028         113 :         eb_aom_wb_write_signed_primitive_refsubexpfin(
    4029         113 :             wb, (1 << trans_bits) + 1, SUBEXPFIN_K,
    4030         113 :             (int16_t)(ref_params->wmmat[0] >> trans_prec_diff),
    4031         113 :             (int16_t)(params->wmmat[0] >> trans_prec_diff));
    4032         113 :         eb_aom_wb_write_signed_primitive_refsubexpfin(
    4033         113 :             wb, (1 << trans_bits) + 1, SUBEXPFIN_K,
    4034         113 :             (int16_t)(ref_params->wmmat[1] >> trans_prec_diff),
    4035         113 :             (int16_t)(params->wmmat[1] >> trans_prec_diff));
    4036             :     }
    4037         812 : }
    4038         116 : static void WriteGlobalMotion(
    4039             :     PictureParentControlSet *pcs_ptr,
    4040             :     struct AomWriteBitBuffer *wb)
    4041             : 
    4042             : {
    4043             :     int32_t frame;
    4044         116 :     FrameHeader *frm_hdr = &pcs_ptr->frm_hdr;
    4045         928 :     for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
    4046        1624 :         const EbWarpedMotionParams *ref_params = (frm_hdr->primary_ref_frame != PRIMARY_REF_NONE) ?
    4047         812 :             &pcs_ptr->childPcs->ref_global_motion[frame] : &default_warp_params;
    4048         812 :         write_global_motion_params(&pcs_ptr->global_motion[frame], ref_params, wb,
    4049         812 :             frm_hdr->allow_high_precision_mv);
    4050             :         // TODO(sarahparker, debargha): The logic in the commented out code below
    4051             :         // does not work currently and causes mismatches when resize is on.
    4052             :         // Fix it before turning the optimization back on.
    4053             :         /*
    4054             :         Yv12BufferConfig *ref_buf = get_ref_frame_buffer(cpi, frame);
    4055             :         if (cpi->source->y_crop_width == ref_buf->y_crop_width &&
    4056             :         cpi->source->y_crop_height == ref_buf->y_crop_height) {
    4057             :         write_global_motion_params(&cm->global_motion[frame],
    4058             :         &cm->prev_frame->global_motion[frame], wb,
    4059             :         cm->allow_high_precision_mv);
    4060             :         } else {
    4061             :         assert(cm->global_motion[frame].wmtype == IDENTITY &&
    4062             :         "Invalid warp type for frames of different resolutions");
    4063             :         }
    4064             :         */
    4065             :         /*
    4066             :         printf("Frame %d/%d: Enc Ref %d: %d %d %d %d\n",
    4067             :         cm->current_video_frame, cm->show_frame, frame,
    4068             :         cm->global_motion[frame].wmmat[0],
    4069             :         cm->global_motion[frame].wmmat[1], cm->global_motion[frame].wmmat[2],
    4070             :         cm->global_motion[frame].wmmat[3]);
    4071             :         */
    4072             :     }
    4073         116 : }
    4074             : 
    4075           0 : static void write_film_grain_params(PictureParentControlSet *pcs_ptr,
    4076             :     struct AomWriteBitBuffer *wb) {
    4077             : 
    4078           0 :     FrameHeader *frm_hdr = &pcs_ptr->frm_hdr;
    4079           0 :     aom_film_grain_t *pars = &frm_hdr->film_grain_params;
    4080             : 
    4081           0 :     eb_aom_wb_write_bit(wb, pars->apply_grain);
    4082           0 :     if (!pars->apply_grain) return;
    4083             : 
    4084           0 :     eb_aom_wb_write_literal(wb, pars->random_seed, 16);
    4085             : 
    4086           0 :     if (frm_hdr->frame_type == INTER_FRAME) {
    4087           0 :         EbReferenceObject* refObj0 = (EbReferenceObject*)pcs_ptr->childPcs->ref_pic_ptr_array[REF_LIST_0][0]->object_ptr;
    4088           0 :         int32_t ref_idx = 0;
    4089           0 :         pars->update_parameters = 1;
    4090           0 :         if (film_grain_params_equal(&refObj0->film_grain_params, pars)) {
    4091           0 :             pars->update_parameters = 0;
    4092           0 :             ref_idx = get_ref_frame_map_idx(pcs_ptr, LAST_FRAME);
    4093             :         }
    4094           0 :         else if (pcs_ptr->childPcs->slice_type == B_SLICE)
    4095             :         {
    4096           0 :             EbReferenceObject* refObj1 = (EbReferenceObject*)pcs_ptr->childPcs->ref_pic_ptr_array[REF_LIST_1][0]->object_ptr;
    4097           0 :             if (film_grain_params_equal(&refObj1->film_grain_params, pars)) {
    4098           0 :                 pars->update_parameters = 0;
    4099           0 :                 ref_idx = get_ref_frame_map_idx(pcs_ptr, ALTREF_FRAME);  //todo: will it always be ALF_REF in L1?
    4100             :             }
    4101             :         }
    4102           0 :         eb_aom_wb_write_bit(wb, pars->update_parameters);
    4103           0 :         if (!pars->update_parameters) {
    4104           0 :             eb_aom_wb_write_literal(wb, ref_idx, 3);
    4105           0 :             return;
    4106             :         }
    4107             :     }
    4108             :     else
    4109           0 :         pars->update_parameters = 1;
    4110             : 
    4111             :     // Scaling functions parameters
    4112           0 :     eb_aom_wb_write_literal(wb, pars->num_y_points, 4);  // max 14
    4113           0 :     for (int32_t i = 0; i < pars->num_y_points; i++) {
    4114           0 :         eb_aom_wb_write_literal(wb, pars->scaling_points_y[i][0], 8);
    4115           0 :         eb_aom_wb_write_literal(wb, pars->scaling_points_y[i][1], 8);
    4116             :     }
    4117             : 
    4118           0 :     if (!pcs_ptr->sequence_control_set_ptr->seq_header.color_config.mono_chrome)
    4119           0 :         eb_aom_wb_write_bit(wb, pars->chroma_scaling_from_luma);
    4120             :     else
    4121           0 :         pars->chroma_scaling_from_luma = 0;  // for monochrome override to 0
    4122             : 
    4123           0 :     if (pcs_ptr->sequence_control_set_ptr->seq_header.color_config.mono_chrome || pars->chroma_scaling_from_luma ||
    4124             :         // todo: add corresponding check when subsampling variables are present
    4125           0 :         ((pcs_ptr->sequence_control_set_ptr->subsampling_x == 1) &&
    4126           0 :         (pcs_ptr->sequence_control_set_ptr->subsampling_y == 1) &&
    4127           0 :             (pars->num_y_points == 0))) {
    4128           0 :         pars->num_cb_points = 0;
    4129           0 :         pars->num_cr_points = 0;
    4130             :     }
    4131             :     else {
    4132           0 :         eb_aom_wb_write_literal(wb, pars->num_cb_points, 4);  // max 10
    4133           0 :         for (int32_t i = 0; i < pars->num_cb_points; i++) {
    4134           0 :             eb_aom_wb_write_literal(wb, pars->scaling_points_cb[i][0], 8);
    4135           0 :             eb_aom_wb_write_literal(wb, pars->scaling_points_cb[i][1], 8);
    4136             :         }
    4137             : 
    4138           0 :         eb_aom_wb_write_literal(wb, pars->num_cr_points, 4);  // max 10
    4139           0 :         for (int32_t i = 0; i < pars->num_cr_points; i++) {
    4140           0 :             eb_aom_wb_write_literal(wb, pars->scaling_points_cr[i][0], 8);
    4141           0 :             eb_aom_wb_write_literal(wb, pars->scaling_points_cr[i][1], 8);
    4142             :         }
    4143             :     }
    4144             : 
    4145           0 :     eb_aom_wb_write_literal(wb, pars->scaling_shift - 8, 2);  // 8 + value
    4146             : 
    4147             :     // AR coefficients
    4148             :     // Only sent if the corresponsing scaling function has
    4149             :     // more than 0 points
    4150             : 
    4151           0 :     eb_aom_wb_write_literal(wb, pars->ar_coeff_lag, 2);
    4152             : 
    4153           0 :     int32_t num_pos_luma = 2 * pars->ar_coeff_lag * (pars->ar_coeff_lag + 1);
    4154           0 :     int32_t num_pos_chroma = num_pos_luma;
    4155           0 :     if (pars->num_y_points > 0) ++num_pos_chroma;
    4156             : 
    4157           0 :     if (pars->num_y_points)
    4158           0 :         for (int32_t i = 0; i < num_pos_luma; i++)
    4159           0 :             eb_aom_wb_write_literal(wb, pars->ar_coeffs_y[i] + 128, 8);
    4160             : 
    4161           0 :     if (pars->num_cb_points || pars->chroma_scaling_from_luma)
    4162           0 :         for (int32_t i = 0; i < num_pos_chroma; i++)
    4163           0 :             eb_aom_wb_write_literal(wb, pars->ar_coeffs_cb[i] + 128, 8);
    4164             : 
    4165           0 :     if (pars->num_cr_points || pars->chroma_scaling_from_luma)
    4166           0 :         for (int32_t i = 0; i < num_pos_chroma; i++)
    4167           0 :             eb_aom_wb_write_literal(wb, pars->ar_coeffs_cr[i] + 128, 8);
    4168             : 
    4169           0 :     eb_aom_wb_write_literal(wb, pars->ar_coeff_shift - 6, 2);  // 8 + value
    4170             : 
    4171           0 :     eb_aom_wb_write_literal(wb, pars->grain_scale_shift, 2);
    4172             : 
    4173           0 :     if (pars->num_cb_points) {
    4174           0 :         eb_aom_wb_write_literal(wb, pars->cb_mult, 8);
    4175           0 :         eb_aom_wb_write_literal(wb, pars->cb_luma_mult, 8);
    4176           0 :         eb_aom_wb_write_literal(wb, pars->cb_offset, 9);
    4177             :     }
    4178             : 
    4179           0 :     if (pars->num_cr_points) {
    4180           0 :         eb_aom_wb_write_literal(wb, pars->cr_mult, 8);
    4181           0 :         eb_aom_wb_write_literal(wb, pars->cr_luma_mult, 8);
    4182           0 :         eb_aom_wb_write_literal(wb, pars->cr_offset, 9);
    4183             :     }
    4184             : 
    4185           0 :     eb_aom_wb_write_bit(wb, pars->overlap_flag);
    4186             : 
    4187           0 :     eb_aom_wb_write_bit(wb, pars->clip_to_restricted_range);
    4188             : }
    4189             : 
    4190             : // New function based on HLS R18
    4191         176 : static void WriteUncompressedHeaderObu(SequenceControlSet *scs_ptr/*Av1Comp *cpi*/,
    4192             :     PictureParentControlSet *pcs_ptr,
    4193             :     //struct AomWriteBitBuffer *saved_wb,
    4194             :     struct AomWriteBitBuffer *wb,
    4195             :     uint8_t showExisting) {
    4196             :     // Av1Common *const cm = &cpi->common;
    4197             :     // MacroBlockD *const xd = &cpi->td.mb.e_mbd;
    4198             : 
    4199             :     // NOTE: By default all coded frames to be used as a reference
    4200         176 :     pcs_ptr->is_reference_frame = 1;
    4201             : 
    4202         176 :     FrameHeader *frm_hdr = &pcs_ptr->frm_hdr;
    4203         176 :     if (!scs_ptr->seq_header.reduced_still_picture_header) {
    4204         176 :         if (showExisting) {
    4205             :             //printf("ERROR[AN]: show_existing_frame not supported yet\n");
    4206             :             //RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
    4207             :             //const int32_t frame_to_show = cm->ref_frame_map[cpi->show_existing_frame];
    4208             : 
    4209             :             //if (frame_to_show < 0 || frame_bufs[frame_to_show].ref_count < 1) {
    4210             :             //    aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
    4211             :             //        "Buffer %d does not contain a reconstructed frame",
    4212             :             //        frame_to_show);
    4213             :             //}
    4214             :             //ref_cnt_fb(frame_bufs, &cm->new_fb_idx, frame_to_show);
    4215             : 
    4216          56 :             eb_aom_wb_write_bit(wb, 1);  // show_existing_frame
    4217          56 :             eb_aom_wb_write_literal(wb, frm_hdr->show_existing_frame, 3);
    4218          56 :             if (scs_ptr->seq_header.frame_id_numbers_present_flag) {
    4219           0 :                 printf("ERROR[AN]: frame_id_numbers_present_flag not supported yet\n");
    4220             :                 /*int32_t frame_id_len = cm->seq_params.frame_id_length;
    4221             :                 int32_t display_frame_id = cm->ref_frame_id[cpi->show_existing_frame];
    4222             :                 eb_aom_wb_write_literal(wb, display_frame_id, frame_id_len);*/
    4223             :             }
    4224             : 
    4225             :             //        if (cm->reset_decoder_state &&
    4226             :             //            frame_bufs[frame_to_show].frame_type != KEY_FRAME) {
    4227             :             //            aom_internal_error(
    4228             :             //                &cm->error, AOM_CODEC_UNSUP_BITSTREAM,
    4229             :             //                "show_existing_frame to reset state on KEY_FRAME only");
    4230             :             //        }
    4231             : 
    4232          56 :             return;
    4233             :         }
    4234             :         else
    4235         120 :             eb_aom_wb_write_bit(wb, 0);  // show_existing_frame
    4236             :         //frm_hdr->frame_type = pcs_ptr->intra_only ? INTRA_ONLY_FRAME : frm_hdr->frame_type;
    4237             : 
    4238         120 :         eb_aom_wb_write_literal(wb, frm_hdr->frame_type, 2);
    4239             : 
    4240             :         // if (frm_hdr->intra_only) frm_hdr->frame_type = INTRA_ONLY_FRAME;
    4241             : 
    4242         120 :         eb_aom_wb_write_bit(wb, frm_hdr->show_frame);
    4243             : 
    4244         120 :         if (!frm_hdr->show_frame)
    4245          56 :             eb_aom_wb_write_bit(wb, frm_hdr->showable_frame);
    4246         120 :         if (frm_hdr->frame_type == S_FRAME)
    4247           0 :             assert(frm_hdr->error_resilient_mode);
    4248         120 :         else if (!(frm_hdr->frame_type == KEY_FRAME && frm_hdr->show_frame))
    4249         118 :             eb_aom_wb_write_bit(wb, frm_hdr->error_resilient_mode);
    4250             :     }
    4251             : 
    4252         120 :     eb_aom_wb_write_bit(wb, frm_hdr->disable_cdf_update);
    4253             : 
    4254         120 :     if (scs_ptr->seq_header.seq_force_screen_content_tools == 2)
    4255         120 :         eb_aom_wb_write_bit(wb, frm_hdr->allow_screen_content_tools);
    4256             :     else {
    4257           0 :         assert(frm_hdr->allow_screen_content_tools ==
    4258             :             scs_ptr->seq_header.seq_force_screen_content_tools);
    4259             :     }
    4260             : 
    4261         120 :     if (frm_hdr->allow_screen_content_tools) {
    4262           0 :         if (scs_ptr->seq_header.seq_force_integer_mv == 2)
    4263           0 :             eb_aom_wb_write_bit(wb, frm_hdr->force_integer_mv);
    4264             :         else
    4265           0 :             assert(frm_hdr->force_integer_mv == scs_ptr->seq_header.seq_force_integer_mv);
    4266             :     }
    4267             :     else
    4268         120 :         assert(frm_hdr->force_integer_mv == 0);
    4269             : 
    4270         120 :     if (!scs_ptr->seq_header.reduced_still_picture_header) {
    4271         120 :         if (scs_ptr->seq_header.frame_id_numbers_present_flag) {
    4272           0 :             int32_t frame_id_len = scs_ptr->seq_header.frame_id_length;
    4273           0 :             eb_aom_wb_write_literal(wb, frm_hdr->current_frame_id, frame_id_len);
    4274             :         }
    4275             : 
    4276             :         //if (cm->width > cm->seq_params.max_frame_width ||
    4277             :         //    cm->height > cm->seq_params.max_frame_height) {
    4278             :         //    aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
    4279             :         //        "Frame dimensions are larger than the maximum values");
    4280             :         //}
    4281             : 
    4282         120 :         int32_t frame_size_override_flag = 0;
    4283             :         /*        (pcs_ptr->frame_type == S_FRAME) ? 1
    4284             :         : (cm->width != cm->seq_params.max_frame_width ||
    4285             :         cm->height != cm->seq_params.max_frame_height);*/
    4286         120 :         if (frm_hdr->frame_type != S_FRAME) eb_aom_wb_write_bit(wb, frame_size_override_flag);
    4287             : 
    4288         120 :         if (scs_ptr->seq_header.order_hint_info.enable_order_hint)
    4289         120 :             eb_aom_wb_write_literal(wb, (int32_t)pcs_ptr->frame_offset,
    4290         120 :                 scs_ptr->seq_header.order_hint_info.order_hint_bits);
    4291             : 
    4292         120 :         if (!frm_hdr->error_resilient_mode && !frame_is_intra_only(pcs_ptr))
    4293         116 :             eb_aom_wb_write_literal(wb, frm_hdr->primary_ref_frame, PRIMARY_REF_BITS);
    4294             :     }
    4295         120 :     int32_t frame_size_override_flag = 0;
    4296         120 :     if (frm_hdr->frame_type == KEY_FRAME) {
    4297           2 :         if (!frm_hdr->show_frame)
    4298           0 :             eb_aom_wb_write_literal(wb, pcs_ptr->av1_ref_signal.refresh_frame_mask, REF_FRAMES);
    4299             :     }
    4300             :     else {
    4301         118 :         if (frm_hdr->frame_type == INTRA_ONLY_FRAME) {
    4302             :             // pcs_ptr->refresh_frame_mask = get_refresh_mask(cpi);
    4303           2 :             int32_t updated_fb = -1;
    4304           4 :             for (int32_t i = 0; i < REF_FRAMES; i++) {
    4305             :                 // If more than one frame is refreshed, it doesn't matter which one
    4306             :                 // we pick, so pick the first.
    4307           4 :                 if (pcs_ptr->av1_ref_signal.refresh_frame_mask & (1 << i)) {
    4308           2 :                     updated_fb = i;
    4309           2 :                     break;
    4310             :                 }
    4311             :             }
    4312           2 :             assert(updated_fb >= 0);
    4313           2 :             pcs_ptr->fb_of_context_type[pcs_ptr->frame_context_idx] = updated_fb;
    4314             : 
    4315           2 :             eb_aom_wb_write_literal(wb, pcs_ptr->av1_ref_signal.refresh_frame_mask, REF_FRAMES);
    4316             :         }
    4317         116 :         else if (frm_hdr->frame_type == INTER_FRAME || frame_is_sframe(pcs_ptr)) {
    4318             :             //pcs_ptr->refresh_frame_mask = get_refresh_mask(cpi);
    4319         116 :             if (frm_hdr->frame_type == INTER_FRAME)
    4320         116 :                 eb_aom_wb_write_literal(wb, pcs_ptr->av1_ref_signal.refresh_frame_mask, REF_FRAMES);
    4321             :             else
    4322           0 :                 assert(frame_is_sframe(pcs_ptr) && pcs_ptr->av1_ref_signal.refresh_frame_mask == 0xFF);
    4323         116 :             int32_t updated_fb = -1;
    4324         848 :             for (int32_t i = 0; i < REF_FRAMES; i++) {
    4325             :                 // If more than one frame is refreshed, it doesn't matter which one
    4326             :                 // we pick, so pick the first.
    4327         804 :                 if (pcs_ptr->av1_ref_signal.refresh_frame_mask & (1 << i)) {
    4328          72 :                     updated_fb = i;
    4329          72 :                     break;
    4330             :                 }
    4331             :             }
    4332             :             // large scale tile sometimes won't refresh any fbs
    4333         116 :             if (updated_fb >= 0)
    4334          72 :                 pcs_ptr->fb_of_context_type[pcs_ptr->frame_context_idx] = updated_fb;
    4335         116 :             if (!pcs_ptr->av1_ref_signal.refresh_frame_mask) {
    4336             :                 // NOTE: "cpi->refresh_frame_mask == 0" indicates that the coded frame
    4337             :                 //       will not be used as a reference
    4338          44 :                 pcs_ptr->is_reference_frame = 0;
    4339             :             }
    4340             :         }
    4341             :     }
    4342             : 
    4343         120 :     if (frm_hdr->frame_type == KEY_FRAME) {
    4344           2 :         write_frame_size(pcs_ptr, frame_size_override_flag, wb);
    4345             :         //assert(av1_superres_unscaled(cm) ||
    4346             :         //    !(cm->allow_intrabc && NO_FILTER_FOR_IBC));
    4347           2 :         if (frm_hdr->allow_screen_content_tools)
    4348           0 :             eb_aom_wb_write_bit(wb, frm_hdr->allow_intrabc);
    4349             :         // all eight fbs are refreshed, pick one that will live long enough
    4350           2 :         pcs_ptr->fb_of_context_type[REGULAR_FRAME] = 0;
    4351             :     }
    4352             :     else {
    4353         118 :         if (frm_hdr->frame_type == INTRA_ONLY_FRAME) {
    4354           2 :             write_frame_size(pcs_ptr, frame_size_override_flag, wb);
    4355           2 :             if (frm_hdr->allow_screen_content_tools)
    4356           0 :                 eb_aom_wb_write_bit(wb, frm_hdr->allow_intrabc);
    4357             :         }
    4358         116 :         else if (frm_hdr->frame_type == INTER_FRAME || frame_is_sframe(pcs_ptr)) {
    4359             :             MvReferenceFrame ref_frame;
    4360             : 
    4361         116 :             assert(frm_hdr->frame_refs_short_signaling == 0);
    4362             :             // NOTE: Error resilient mode turns off frame_refs_short_signaling
    4363             :             //       automatically.
    4364         116 :             if (scs_ptr->seq_header.order_hint_info.enable_order_hint)
    4365         116 :                 eb_aom_wb_write_bit(wb, frm_hdr->frame_refs_short_signaling);
    4366             : 
    4367         116 :             if (frm_hdr->frame_refs_short_signaling) {
    4368           0 :                 eb_aom_wb_write_literal(wb, get_ref_frame_map_idx(pcs_ptr, LAST_FRAME),
    4369             :                     REF_FRAMES_LOG2);
    4370           0 :                 eb_aom_wb_write_literal(wb, get_ref_frame_map_idx(pcs_ptr, GOLDEN_FRAME),
    4371             :                     REF_FRAMES_LOG2);
    4372             :             }
    4373         928 :             for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
    4374         812 :                 assert(get_ref_frame_map_idx(pcs_ptr, ref_frame) != INVALID_IDX);
    4375         812 :                 if (!frm_hdr->frame_refs_short_signaling)
    4376         812 :                     eb_aom_wb_write_literal(wb, get_ref_frame_map_idx(pcs_ptr, ref_frame),
    4377             :                         REF_FRAMES_LOG2);
    4378             : 
    4379         812 :                 if (scs_ptr->seq_header.frame_id_numbers_present_flag) {
    4380           0 :                     printf("ERROR[AN]: frame_id_numbers_present_flag not supported yet\n");
    4381             :                     //int32_t i = get_ref_frame_map_idx(cpi, ref_frame);
    4382             :                     //int32_t frame_id_len = cm->seq_params.frame_id_length;
    4383             :                     //int32_t diff_len = cm->seq_params.delta_frame_id_length;
    4384             :                     //int32_t delta_frame_id_minus1 =
    4385             :                     //    ((cm->current_frame_id - cm->ref_frame_id[i] +
    4386             :                     //    (1 << frame_id_len)) %
    4387             :                     //    (1 << frame_id_len)) -
    4388             :                     //    1;
    4389             :                     //if (delta_frame_id_minus1 < 0 ||
    4390             :                     //    delta_frame_id_minus1 >= (1 << diff_len))
    4391             :                     //    cm->invalid_delta_frame_id_minus1 = 1;
    4392             :                     //eb_aom_wb_write_literal(wb, delta_frame_id_minus1, diff_len);
    4393             :                 }
    4394             :             }
    4395             : 
    4396         116 :             if (!frm_hdr->error_resilient_mode && frame_size_override_flag) {
    4397           0 :                 printf("ERROR[AN]: frame_size_override_flag not supported yet\n");
    4398             :                 //write_frame_size_with_refs(pcs_ptr, wb);
    4399             :             }
    4400             :             else
    4401         116 :                 write_frame_size(pcs_ptr, frame_size_override_flag, wb);
    4402         116 :             if (frm_hdr->force_integer_mv)
    4403           0 :                 frm_hdr->allow_high_precision_mv = 0;
    4404             :             else
    4405         116 :                 eb_aom_wb_write_bit(wb, frm_hdr->allow_high_precision_mv);
    4406             : #define LOG_SWITCHABLE_FILTERS  2
    4407             : 
    4408             :             // OPT fix_interp_filter(cm, cpi->td.counts);
    4409             :             // write_frame_interp_filter(cm->interp_filter, wb);
    4410         116 :             eb_aom_wb_write_bit(wb, pcs_ptr->av1_cm->interp_filter == SWITCHABLE);
    4411         116 :             if (pcs_ptr->av1_cm->interp_filter != SWITCHABLE)
    4412           0 :                 eb_aom_wb_write_literal(wb, pcs_ptr->av1_cm->interp_filter, LOG_SWITCHABLE_FILTERS);
    4413             : 
    4414         116 :             eb_aom_wb_write_bit(wb, frm_hdr->is_motion_mode_switchable);
    4415         116 :             if (frame_might_allow_ref_frame_mvs(pcs_ptr, scs_ptr))
    4416         116 :                 eb_aom_wb_write_bit(wb, frm_hdr->use_ref_frame_mvs);
    4417             :         }
    4418             :     }
    4419             : 
    4420             :     //if (scs_ptr->frame_id_numbers_present_flag)
    4421             :     //    pcs_ptr->refresh_mask = get_refresh_mask(pcs_ptr);
    4422         120 :     const int32_t might_bwd_adapt =
    4423         120 :         !(scs_ptr->seq_header.reduced_still_picture_header) && !(frm_hdr->disable_cdf_update);
    4424         120 :     if (pcs_ptr->large_scale_tile)
    4425           0 :         pcs_ptr->refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED;
    4426         120 :     if (might_bwd_adapt) {
    4427         120 :         eb_aom_wb_write_bit(
    4428         120 :             wb, pcs_ptr->refresh_frame_context == REFRESH_FRAME_CONTEXT_DISABLED);
    4429             :     }
    4430             : 
    4431         120 :     write_tile_info(pcs_ptr, /*saved_wb,*/ wb);
    4432             : 
    4433         120 :     encode_quantization(pcs_ptr, wb);
    4434         120 :     encode_segmentation(pcs_ptr, wb);
    4435             :     //eb_aom_wb_write_bit(wb, 0);
    4436             :     //encode_segmentation(cm, xd, wb);
    4437             :         //if (pcs_ptr->delta_q_present_flag)
    4438             :            // assert(delta_q_allowed == 1 && frm_hdr->quantisation_params.base_q_idx > 0);
    4439             : 
    4440         120 :     if (frm_hdr->quantization_params.base_q_idx > 0) {
    4441         120 :         eb_aom_wb_write_bit(wb, frm_hdr->delta_q_params.delta_q_present);
    4442         120 :         if (frm_hdr->delta_q_params.delta_q_present) {
    4443             : #if ADD_DELTA_QP_SUPPORT //PART 0
    4444           4 :             eb_aom_wb_write_literal(wb, OD_ILOG_NZ(frm_hdr->delta_q_params.delta_q_res) - 1, 2);
    4445           4 :             pcs_ptr->prev_qindex = frm_hdr->quantization_params.base_q_idx;
    4446           4 :             if (frm_hdr->allow_intrabc)
    4447           0 :                 assert(frm_hdr->delta_lf_params.delta_lf_present == 0);
    4448             :             else
    4449           4 :                 eb_aom_wb_write_bit(wb, frm_hdr->delta_lf_params.delta_lf_present);
    4450           4 :             if (frm_hdr->delta_lf_params.delta_lf_present) {
    4451           0 :                 eb_aom_wb_write_literal(wb, OD_ILOG_NZ(frm_hdr->delta_lf_params.delta_lf_res) - 1, 2);
    4452           0 :                 pcs_ptr->prev_delta_lf_from_base = 0;
    4453           0 :                 eb_aom_wb_write_bit(wb, frm_hdr->delta_lf_params.delta_lf_multi);
    4454           0 :                 const int32_t frame_lf_count =
    4455           0 :                     pcs_ptr->monochrome == 0 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
    4456           0 :                 for (int32_t lf_id = 0; lf_id < frame_lf_count; ++lf_id)
    4457           0 :                     pcs_ptr->prev_delta_lf[lf_id] = 0;
    4458             :             }
    4459             : #else
    4460             :             printf("ERROR[AN]: delta_q_present_flag not supported yet\n");
    4461             : #endif
    4462             :             //                eb_aom_wb_write_literal(wb, OD_ILOG_NZ(frm_hdr->delta_q_params.delta_q_res) - 1, 2);
    4463             :             //                xd->prev_qindex = frm_hdr->quantization_params.base_q_idx;
    4464             :             //                if (cm->allow_intrabc)
    4465             :             //                    assert(frm_hdr->delta_lf_params.delta_lf_present == 0);
    4466             :             //                else
    4467             :             //                    eb_aom_wb_write_bit(wb, frm_hdr->delta_lf_params.delta_lf_present);
    4468             :             //                if (frm_hdr->delta_lf_params.delta_lf_present) {
    4469             :             //                    eb_aom_wb_write_literal(wb, OD_ILOG_NZ(frm_hdr->delta_lf_params.delta_lf_res) - 1, 2);
    4470             :             //                    xd->prev_delta_lf_from_base = 0;
    4471             :             //                    eb_aom_wb_write_bit(wb, frm_hdr->delta_lf_params.delta_lf_multi);
    4472             :             //                    const int32_t frame_lf_count =
    4473             :             //                        av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
    4474             :             //                    for (int32_t lf_id = 0; lf_id < frame_lf_count; ++lf_id)
    4475             :             //                        xd->prev_delta_lf[lf_id] = 0;
    4476             :             //                }
    4477             :         }
    4478             :     }
    4479         120 :     if (frm_hdr->all_lossless) {
    4480           0 :         printf("ERROR[AN]: all_lossless\n");
    4481             :         //assert(av1_superres_unscaled(pcs_ptr));
    4482             :     }
    4483             :     else {
    4484         120 :         if (!frm_hdr->coded_lossless) {
    4485         120 :             encode_loopfilter(pcs_ptr, wb);
    4486         120 :             if (scs_ptr->seq_header.enable_cdef)
    4487         120 :                 encode_cdef(pcs_ptr, wb);
    4488             :         }
    4489             : 
    4490         120 :         if (scs_ptr->seq_header.enable_restoration)
    4491          60 :             encode_restoration_mode(pcs_ptr, wb);
    4492             :     }
    4493             : 
    4494         120 :     eb_aom_wb_write_bit(wb, frm_hdr->tx_mode == TX_MODE_SELECT);
    4495             :     //write_tx_mode(cm, &pcs_ptr->tx_mode, wb);
    4496             : 
    4497         120 :     if (pcs_ptr->allow_comp_inter_inter) {
    4498         116 :         const int32_t use_hybrid_pred = frm_hdr->reference_mode == REFERENCE_MODE_SELECT;
    4499             : 
    4500         116 :         eb_aom_wb_write_bit(wb, use_hybrid_pred);
    4501             :     }
    4502             : 
    4503         120 :     if (pcs_ptr->is_skip_mode_allowed) eb_aom_wb_write_bit(wb, pcs_ptr->skip_mode_flag);
    4504             : 
    4505         120 :     if (frame_might_allow_warped_motion(pcs_ptr, scs_ptr))
    4506         116 :         eb_aom_wb_write_bit(wb, frm_hdr->allow_warped_motion);
    4507             :     else
    4508           4 :         assert(!frm_hdr->allow_warped_motion);
    4509             : 
    4510         120 :     eb_aom_wb_write_bit(wb, frm_hdr->reduced_tx_set);
    4511             : 
    4512         120 :     if (!frame_is_intra_only(pcs_ptr)) {
    4513             :         //  printf("ERROR[AN]: Global motion not supported yet\n");
    4514         116 :         WriteGlobalMotion(pcs_ptr, wb);
    4515             :     }
    4516         120 :     if (scs_ptr->seq_header.film_grain_params_present && (frm_hdr->show_frame || frm_hdr->showable_frame))
    4517           0 :         write_film_grain_params(pcs_ptr, wb);
    4518             : }
    4519             : 
    4520         298 : uint32_t WriteObuHeader(obuType obuType, int32_t obuExtension,
    4521             :     uint8_t *const dst) {
    4522         298 :     struct AomWriteBitBuffer wb = { dst, 0 };
    4523         298 :     uint32_t size = 0;
    4524             : 
    4525         298 :     eb_aom_wb_write_literal(&wb, 0, 1);  // forbidden bit.
    4526         298 :     eb_aom_wb_write_literal(&wb, (int32_t)obuType, 4);
    4527         298 :     eb_aom_wb_write_literal(&wb, obuExtension ? 1 : 0, 1);
    4528         298 :     eb_aom_wb_write_literal(&wb, 1, 1);  // obu_has_payload_length_field
    4529         298 :     eb_aom_wb_write_literal(&wb, 0, 1);  // reserved
    4530             : 
    4531         298 :     if (obuExtension)
    4532           0 :         eb_aom_wb_write_literal(&wb, obuExtension & 0xFF, 8);
    4533         298 :     size = eb_aom_wb_bytes_written(&wb);
    4534         298 :     return size;
    4535             : }
    4536         298 : int32_t WriteUlebObuSize(uint32_t obuHeaderSize, uint32_t obuPayloadSize,
    4537             :     uint8_t *dest) {
    4538         298 :     const uint32_t obuSize = obuPayloadSize;
    4539         298 :     const uint32_t offset = obuHeaderSize;
    4540         298 :     size_t codedObuSize = 0;
    4541             : 
    4542         298 :     if (eb_aom_uleb_encode(obuSize, sizeof(obuSize), dest + offset,
    4543             :         &codedObuSize) != 0) {
    4544           0 :         return AOM_CODEC_ERROR;
    4545             :     }
    4546             : 
    4547         298 :     return AOM_CODEC_OK;
    4548             : }
    4549         178 : static size_t ObuMemMove(
    4550             :     uint32_t obuHeaderSize,
    4551             :     uint32_t obuPayloadSize,
    4552             :     uint8_t *data)
    4553             : {
    4554         178 :     const size_t lengthFieldSize = eb_aom_uleb_size_in_bytes(obuPayloadSize);
    4555         178 :     const uint32_t moveDstOffset =
    4556         178 :         (uint32_t)lengthFieldSize + obuHeaderSize;
    4557         178 :     const uint32_t moveSrcOffset = obuHeaderSize;
    4558         178 :     const uint32_t moveSize = obuPayloadSize;
    4559         178 :     memmove(data + moveDstOffset, data + moveSrcOffset, moveSize);
    4560         178 :     return lengthFieldSize;
    4561             : }
    4562             : 
    4563          58 : static void add_trailing_bits(struct AomWriteBitBuffer *wb) {
    4564          58 :     if (eb_aom_wb_is_byte_aligned(wb))
    4565           2 :         eb_aom_wb_write_literal(wb, 0x80, 8);
    4566             :     else {
    4567             :         // assumes that the other bits are already 0s
    4568          56 :         eb_aom_wb_write_bit(wb, 1);
    4569             :     }
    4570          58 : }
    4571           2 : static void write_bitstream_level(BitstreamLevel bl,
    4572             :     struct AomWriteBitBuffer *wb) {
    4573           2 :     uint8_t seq_level_idx = major_minor_to_seq_level_idx(bl);
    4574           2 :     assert(is_valid_seq_level_idx(seq_level_idx));
    4575           2 :     eb_aom_wb_write_literal(wb, seq_level_idx, LEVEL_BITS);
    4576           2 : }
    4577           2 : static uint32_t WriteSequenceHeaderObu(
    4578             :     SequenceControlSet *scs_ptr,
    4579             :     uint8_t *const dst,
    4580             :     uint8_t numberSpatialLayers)
    4581             : {
    4582           2 :     struct AomWriteBitBuffer wb = { dst, 0 };
    4583           2 :     uint32_t size = 0;
    4584             : 
    4585           2 :     SetBitstreamLevelTier(scs_ptr);
    4586             : 
    4587           2 :     WriteProfile((BitstreamProfile)scs_ptr->static_config.profile, &wb);
    4588             : 
    4589             :     // Still picture or not
    4590           2 :     eb_aom_wb_write_bit(&wb, scs_ptr->seq_header.still_picture);
    4591           2 :     assert(IMPLIES(!scs_ptr->seq_header.still_picture,
    4592             :         !scs_ptr->seq_header.reduced_still_picture_header));
    4593             : 
    4594             :     // whether to use reduced still picture header
    4595           2 :     eb_aom_wb_write_bit(&wb, scs_ptr->seq_header.reduced_still_picture_header);
    4596             : 
    4597           2 :     if (scs_ptr->seq_header.reduced_still_picture_header) {
    4598           0 :         printf("ERROR[AN]: reduced_still_picture_hdr not supported\n");
    4599             :         //write_bitstream_level(cm->seq_params.level[0], &wb);
    4600             :     }
    4601             :     else {
    4602           2 :         eb_aom_wb_write_bit(&wb, scs_ptr->seq_header.timing_info.timing_info_present);  // timing info present flag
    4603             : 
    4604           2 :         if (scs_ptr->seq_header.timing_info.timing_info_present) {
    4605             :             // timing_info
    4606           0 :             printf("ERROR[AN]: timing_info_present not supported\n");
    4607             :             /*write_timing_info_header(cm, &wb);
    4608             :             eb_aom_wb_write_bit(&wb, cm->decoder_model_info_present_flag);
    4609             :             if (cm->decoder_model_info_present_flag) write_decoder_model_info(cm, &wb);*/
    4610             :         }
    4611           2 :         eb_aom_wb_write_bit(&wb, scs_ptr->seq_header.initial_display_delay_present_flag);
    4612             : 
    4613           2 :         uint8_t operating_points_cnt_minus_1 =
    4614             :             numberSpatialLayers > 1 ? numberSpatialLayers - 1 : 0;
    4615           2 :         eb_aom_wb_write_literal(&wb, operating_points_cnt_minus_1,
    4616             :             OP_POINTS_CNT_MINUS_1_BITS);
    4617             :         int32_t i;
    4618           4 :         for (i = 0; i < operating_points_cnt_minus_1 + 1; i++) {
    4619           2 :             eb_aom_wb_write_literal(&wb, scs_ptr->seq_header.operating_point[i].op_idc,
    4620             :                 OP_POINTS_IDC_BITS);
    4621           2 :             write_bitstream_level(scs_ptr->level[i], &wb);
    4622           2 :             if (scs_ptr->level[i].major > 3)
    4623           0 :                 eb_aom_wb_write_bit(&wb, scs_ptr->seq_header.operating_point[i].seq_tier);
    4624           2 :             if (scs_ptr->seq_header.decoder_model_info_present_flag) {
    4625           0 :                 printf("ERROR[AN]: decoder_model_info_present_flag not supported\n");
    4626             :                 //eb_aom_wb_write_bit(&wb,
    4627             :                 //    cm->op_params[i].decoder_model_param_present_flag);
    4628             :                 //if (cm->op_params[i].decoder_model_param_present_flag)
    4629             :                 //    write_dec_model_op_parameters(cm, &wb, i);
    4630             :             }
    4631           2 :             if (scs_ptr->seq_header.initial_display_delay_present_flag) {
    4632           0 :                 printf("ERROR[AN]: display_model_info_present_flag not supported\n");
    4633             :                 //eb_aom_wb_write_bit(&wb,
    4634             :                 //    cm->op_params[i].display_model_param_present_flag);
    4635             :                 //if (cm->op_params[i].display_model_param_present_flag) {
    4636             :                 //    assert(cm->op_params[i].initial_display_delay <= 10);
    4637             :                 //    eb_aom_wb_write_literal(&wb, cm->op_params[i].initial_display_delay - 1,
    4638             :                 //        4);
    4639             :                 //}
    4640             :             }
    4641             :         }
    4642             :     }
    4643           2 :     write_sequence_header(scs_ptr, &wb);
    4644             : 
    4645           2 :     write_color_config(scs_ptr, &wb);
    4646             : 
    4647           2 :     eb_aom_wb_write_bit(&wb, scs_ptr->seq_header.film_grain_params_present);
    4648             : 
    4649           2 :     add_trailing_bits(&wb);
    4650             : 
    4651           2 :     size = eb_aom_wb_bytes_written(&wb);
    4652           2 :     return size;
    4653             : }
    4654         176 : static uint32_t write_tile_group_header(uint8_t *const dst, int startTile,
    4655             :     int endTile, int tiles_log2,
    4656             :     int tile_start_and_end_present_flag)
    4657             : {
    4658         176 :     struct AomWriteBitBuffer wb = { dst, 0 };
    4659         176 :     uint32_t size = 0;
    4660             : 
    4661         176 :     if (!tiles_log2) return size;
    4662           0 :     eb_aom_wb_write_bit(&wb, tile_start_and_end_present_flag);
    4663             : 
    4664           0 :     if (tile_start_and_end_present_flag) {
    4665           0 :         eb_aom_wb_write_literal(&wb, startTile, tiles_log2);
    4666           0 :         eb_aom_wb_write_literal(&wb, endTile, tiles_log2);
    4667             :     }
    4668             : 
    4669           0 :     size = eb_aom_wb_bytes_written(&wb);
    4670           0 :     return size;
    4671             : }
    4672             : 
    4673         176 : static uint32_t WriteFrameHeaderObu(
    4674             :     SequenceControlSet      *scs_ptr,
    4675             :     PictureParentControlSet *pcs_ptr,
    4676             :     uint8_t                   *const dst,
    4677             :     uint8_t showExisting,
    4678             :     int32_t appendTrailingBits
    4679             : )
    4680             : {
    4681         176 :     struct AomWriteBitBuffer wb = { dst, 0 };
    4682         176 :     uint32_t totalSize = 0;
    4683             : 
    4684         176 :     WriteUncompressedHeaderObu(scs_ptr, pcs_ptr,/* saved_wb,*/ &wb, showExisting);
    4685             : 
    4686         176 :     if (appendTrailingBits)
    4687          56 :         add_trailing_bits(&wb);
    4688             : 
    4689         176 :     if (showExisting) {
    4690          56 :         totalSize = eb_aom_wb_bytes_written(&wb);
    4691          56 :         return totalSize;
    4692             :     }
    4693             : 
    4694         120 :     totalSize = eb_aom_wb_bytes_written(&wb);
    4695         120 :     return totalSize;
    4696             : }
    4697             : 
    4698             : /**************************************************
    4699             : * EncodeFrameHeaderHeader
    4700             : **************************************************/
    4701         176 : EbErrorType write_frame_header_av1(
    4702             :     Bitstream *bitstream_ptr,
    4703             :     SequenceControlSet *scs_ptr,
    4704             :     PictureControlSet *pcs_ptr,
    4705             :     uint8_t showExisting)
    4706             : {
    4707         176 :     EbErrorType                 return_error = EB_ErrorNone;
    4708         176 :     OutputBitstreamUnit       *output_bitstream_ptr = (OutputBitstreamUnit*)bitstream_ptr->output_bitstream_ptr;
    4709         176 :     PictureParentControlSet   *parent_pcs_ptr = pcs_ptr->parent_pcs_ptr;
    4710         176 :     uint8_t                     *data = output_bitstream_ptr->buffer_av1;
    4711         176 :     uint32_t obuHeaderSize = 0;
    4712             : 
    4713         176 :     int32_t currDataSize = 0;
    4714             : 
    4715         176 :     const uint8_t obuExtensionHeader = 0;
    4716             : 
    4717             :     // A new tile group begins at this tile.  Write the obu header and
    4718             :     // tile group header
    4719         176 :     const obuType obuType = showExisting ? OBU_FRAME_HEADER : OBU_FRAME;
    4720         176 :     currDataSize =
    4721         176 :         WriteObuHeader(obuType, obuExtensionHeader, data);
    4722         176 :     obuHeaderSize = currDataSize;
    4723             : 
    4724         176 :     currDataSize +=
    4725         176 :         WriteFrameHeaderObu(scs_ptr, parent_pcs_ptr, /*saved_wb,*/ data + currDataSize, showExisting, showExisting);
    4726             : 
    4727         176 :     const int n_log2_tiles = parent_pcs_ptr->av1_cm->log2_tile_rows + parent_pcs_ptr->av1_cm->log2_tile_cols;
    4728         176 :     int tile_start_and_end_present_flag = 0;
    4729             : 
    4730         176 :    currDataSize += write_tile_group_header(data + currDataSize,0,
    4731             :         0, n_log2_tiles, tile_start_and_end_present_flag);
    4732             : 
    4733         176 :     if (!showExisting) {
    4734             :         // Add data from EC stream to Picture Stream.
    4735         120 :         int32_t frameSize = (int32_t)(parent_pcs_ptr->av1_cm->tiles_info.tile_cols*parent_pcs_ptr->av1_cm->tiles_info.tile_rows==1 ? pcs_ptr->entropy_coder_ptr->ec_writer.pos : pcs_ptr->entropy_coder_ptr->ec_frame_size);
    4736         120 :         OutputBitstreamUnit *ec_output_bitstream_ptr = (OutputBitstreamUnit*)pcs_ptr->entropy_coder_ptr->ec_output_bitstream_ptr;
    4737             :         //****************************************************************//
    4738             :         // Copy from EC stream to frame stream
    4739         120 :         memcpy(data + currDataSize, ec_output_bitstream_ptr->buffer_begin_av1, frameSize);
    4740         120 :         currDataSize += (frameSize);
    4741             :     }
    4742         176 :     const uint32_t obuPayloadSize = currDataSize - obuHeaderSize;
    4743             :     const size_t lengthFieldSize =
    4744         176 :         ObuMemMove(obuHeaderSize, obuPayloadSize, data);
    4745         176 :     if (WriteUlebObuSize(obuHeaderSize, obuPayloadSize, data) !=
    4746             :         AOM_CODEC_OK) {
    4747           0 :         assert(0);
    4748             :     }
    4749         176 :     currDataSize += (int32_t)lengthFieldSize;
    4750         176 :     data += currDataSize;
    4751             : 
    4752         176 :     output_bitstream_ptr->buffer_av1 = data;
    4753         176 :     return return_error;
    4754             : }
    4755             : 
    4756             : /**************************************************
    4757             : * encode_sps_av1
    4758             : **************************************************/
    4759           2 : EbErrorType encode_sps_av1(
    4760             :     Bitstream *bitstream_ptr,
    4761             :     SequenceControlSet *scs_ptr)
    4762             : {
    4763           2 :     EbErrorType            return_error = EB_ErrorNone;
    4764           2 :     OutputBitstreamUnit  *output_bitstream_ptr = (OutputBitstreamUnit*)bitstream_ptr->output_bitstream_ptr;
    4765           2 :     uint8_t                *data = output_bitstream_ptr->buffer_av1;
    4766           2 :     uint32_t                obuHeaderSize = 0;
    4767           2 :     uint32_t                obuPayloadSize = 0;
    4768           2 :     const uint8_t enhancementLayersCnt = 0;// cm->enhancementLayersCnt;
    4769             : 
    4770             :     // write sequence header obu if KEY_FRAME, preceded by 4-byte size
    4771           2 :     obuHeaderSize = WriteObuHeader(OBU_SEQUENCE_HEADER, 0, data);
    4772             : 
    4773           2 :     obuPayloadSize = WriteSequenceHeaderObu(scs_ptr,/*cpi,*/ data + obuHeaderSize,
    4774             :         enhancementLayersCnt);
    4775             : 
    4776           2 :     const size_t lengthFieldSize = ObuMemMove(obuHeaderSize, obuPayloadSize, data);
    4777           2 :     if (WriteUlebObuSize(obuHeaderSize, obuPayloadSize, data) !=
    4778             :         AOM_CODEC_OK) {
    4779             :         // return AOM_CODEC_ERROR;
    4780             :     }
    4781             : 
    4782           2 :     data += obuHeaderSize + obuPayloadSize + lengthFieldSize;
    4783           2 :     output_bitstream_ptr->buffer_av1 = data;
    4784           2 :     return return_error;
    4785             : }
    4786             : /**************************************************
    4787             : * encode_td_av1
    4788             : **************************************************/
    4789         120 : EbErrorType encode_td_av1(
    4790             :     uint8_t *output_bitstream_ptr)
    4791             : {
    4792         120 :     EbErrorType              return_error = EB_ErrorNone;
    4793             :     //OutputBitstreamUnit   *output_bitstream_ptr = (OutputBitstreamUnit*)bitstream_ptr->output_bitstream_ptr;
    4794         120 :     assert(output_bitstream_ptr != NULL);
    4795             : 
    4796         120 :     uint8_t                 *data = output_bitstream_ptr;
    4797             : 
    4798             :     // move data and insert OBU_TD preceded by optional 4 byte size
    4799         120 :     uint32_t obu_header_size = 1;
    4800         120 :     const uint32_t obu_payload_size = 0;
    4801         120 :     const size_t length_field_size = eb_aom_uleb_size_in_bytes(obu_payload_size);
    4802             : 
    4803         120 :     obu_header_size = WriteObuHeader(
    4804             :         OBU_TEMPORAL_DELIMITER, 0, data);
    4805             : 
    4806             :     // OBUs are preceded/succeeded by an unsigned leb128 coded integer.
    4807         120 :     if (WriteUlebObuSize(obu_header_size, obu_payload_size, data) != AOM_CODEC_OK)
    4808             :         //return AOM_CODEC_ERROR;
    4809           0 :     data += obu_header_size + obu_payload_size + length_field_size;
    4810         120 :     output_bitstream_ptr = data;
    4811             : 
    4812         120 :     return return_error;
    4813             : }
    4814             : 
    4815             : #if ADD_DELTA_QP_SUPPORT
    4816         239 : static void Av1writeDeltaQindex(
    4817             :     FRAME_CONTEXT *frameContext,
    4818             :     int32_t           delta_qindex,
    4819             :     AomWriter    *w)
    4820             : {
    4821         239 :     int32_t sign = delta_qindex < 0;
    4822         239 :     int32_t abs = sign ? -delta_qindex : delta_qindex;
    4823             :     int32_t rem_bits, thr;
    4824         239 :     int32_t smallval = abs < DELTA_Q_SMALL ? 1 : 0;
    4825             :     //FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
    4826             : 
    4827         239 :     aom_write_symbol(w, AOMMIN(abs, DELTA_Q_SMALL), frameContext->delta_q_cdf,
    4828             :         DELTA_Q_PROBS + 1);
    4829             : 
    4830         239 :     if (!smallval) {
    4831          46 :         rem_bits = OD_ILOG_NZ(abs - 1) - 1;
    4832          46 :         thr = (1 << rem_bits) + 1;
    4833          46 :         aom_write_literal(w, rem_bits - 1, 3);
    4834          46 :         aom_write_literal(w, abs - thr, rem_bits);
    4835             :     }
    4836         239 :     if (abs > 0)
    4837          50 :         aom_write_bit(w, sign);
    4838         239 : }
    4839             : #endif
    4840             : 
    4841       33844 : static void write_cdef(
    4842             :     SequenceControlSet     *seqCSetPtr,
    4843             :     PictureControlSet     *p_pcs_ptr,
    4844             :     //Av1Common *cm,
    4845             :     MacroBlockD *const xd,
    4846             :     AomWriter *w,
    4847             :     int32_t skip, int32_t mi_col, int32_t mi_row)
    4848             : {
    4849             :     (void)xd;
    4850       33844 :     Av1Common *cm = p_pcs_ptr->parent_pcs_ptr->av1_cm;
    4851       33844 :     FrameHeader *frm_hdr = &p_pcs_ptr->parent_pcs_ptr->frm_hdr;
    4852             : 
    4853       33844 :     if (frm_hdr->coded_lossless || frm_hdr->allow_intrabc) {
    4854             :         // Initialize to indicate no CDEF for safety.
    4855           0 :         frm_hdr->CDEF_params.cdef_bits = 0;
    4856           0 :         frm_hdr->CDEF_params.cdef_y_strength[0] = 0;
    4857           0 :         p_pcs_ptr->parent_pcs_ptr->nb_cdef_strengths = 1;
    4858           0 :         frm_hdr->CDEF_params.cdef_uv_strength[0] = 0;
    4859           0 :         return;
    4860             :     }
    4861             : 
    4862       33844 :     const int32_t m = ~((1 << (6 - MI_SIZE_LOG2)) - 1);
    4863       33844 :     const ModeInfo *mi =
    4864       33844 :         p_pcs_ptr->mi_grid_base[(mi_row & m) * cm->mi_stride + (mi_col & m)];
    4865             :     //cm->mi_grid_visible[(mi_row & m) * cm->mi_stride + (mi_col & m)];
    4866             : 
    4867             : // Initialise when at top left part of the superblock
    4868       33844 :     if (!(mi_row & (seqCSetPtr->seq_header.sb_mi_size - 1)) &&
    4869       12109 :         !(mi_col & (seqCSetPtr->seq_header.sb_mi_size - 1))) {  // Top left?
    4870        7200 :         p_pcs_ptr->cdef_preset[0] = p_pcs_ptr->cdef_preset[1] = p_pcs_ptr->cdef_preset[2] =
    4871        7200 :             p_pcs_ptr->cdef_preset[3] = -1;
    4872             :     }
    4873             : 
    4874             :     // Emit CDEF param at first non-skip coding block
    4875       33844 :     const int32_t mask = 1 << (6 - MI_SIZE_LOG2);
    4876       67688 :     const int32_t index = seqCSetPtr->seq_header.sb_size == BLOCK_128X128
    4877           0 :         ? !!(mi_col & mask) + 2 * !!(mi_row & mask)
    4878       33844 :         : 0;
    4879             : 
    4880       33844 :     if (p_pcs_ptr->cdef_preset[index] == -1 && !skip) {
    4881        1435 :         aom_write_literal(w, mi->mbmi.cdef_strength, frm_hdr->CDEF_params.cdef_bits);
    4882        1435 :         p_pcs_ptr->cdef_preset[index] = mi->mbmi.cdef_strength;
    4883             :     }
    4884             : }
    4885             : 
    4886         120 : void eb_av1_reset_loop_restoration(PictureControlSet     *piCSetPtr) {
    4887         480 :     for (int32_t p = 0; p < 3; ++p) {
    4888         360 :         set_default_wiener(piCSetPtr->wiener_info + p);
    4889         360 :         set_default_sgrproj(piCSetPtr->sgrproj_info + p);
    4890             :     }
    4891         120 : }
    4892          65 : static void write_wiener_filter(int32_t wiener_win, const WienerInfo *wiener_info,
    4893             :     WienerInfo *ref_wiener_info, AomWriter *wb) {
    4894          65 :     if (wiener_win == WIENER_WIN)
    4895          57 :         eb_aom_write_primitive_refsubexpfin(
    4896             :             wb, WIENER_FILT_TAP0_MAXV - WIENER_FILT_TAP0_MINV + 1,
    4897             :             WIENER_FILT_TAP0_SUBEXP_K,
    4898          57 :             ref_wiener_info->vfilter[0] - WIENER_FILT_TAP0_MINV,
    4899          57 :             wiener_info->vfilter[0] - WIENER_FILT_TAP0_MINV);
    4900             :     else
    4901           8 :         assert(wiener_info->vfilter[0] == 0 &&
    4902             :             wiener_info->vfilter[WIENER_WIN - 1] == 0);
    4903          65 :     eb_aom_write_primitive_refsubexpfin(
    4904             :         wb, WIENER_FILT_TAP1_MAXV - WIENER_FILT_TAP1_MINV + 1,
    4905             :         WIENER_FILT_TAP1_SUBEXP_K,
    4906          65 :         ref_wiener_info->vfilter[1] - WIENER_FILT_TAP1_MINV,
    4907          65 :         wiener_info->vfilter[1] - WIENER_FILT_TAP1_MINV);
    4908          65 :     eb_aom_write_primitive_refsubexpfin(
    4909             :         wb, WIENER_FILT_TAP2_MAXV - WIENER_FILT_TAP2_MINV + 1,
    4910             :         WIENER_FILT_TAP2_SUBEXP_K,
    4911          65 :         ref_wiener_info->vfilter[2] - WIENER_FILT_TAP2_MINV,
    4912          65 :         wiener_info->vfilter[2] - WIENER_FILT_TAP2_MINV);
    4913          65 :     if (wiener_win == WIENER_WIN)
    4914          57 :         eb_aom_write_primitive_refsubexpfin(
    4915             :             wb, WIENER_FILT_TAP0_MAXV - WIENER_FILT_TAP0_MINV + 1,
    4916             :             WIENER_FILT_TAP0_SUBEXP_K,
    4917          57 :             ref_wiener_info->hfilter[0] - WIENER_FILT_TAP0_MINV,
    4918          57 :             wiener_info->hfilter[0] - WIENER_FILT_TAP0_MINV);
    4919             :     else
    4920           8 :         assert(wiener_info->hfilter[0] == 0 &&
    4921             :             wiener_info->hfilter[WIENER_WIN - 1] == 0);
    4922          65 :     eb_aom_write_primitive_refsubexpfin(
    4923             :         wb, WIENER_FILT_TAP1_MAXV - WIENER_FILT_TAP1_MINV + 1,
    4924             :         WIENER_FILT_TAP1_SUBEXP_K,
    4925          65 :         ref_wiener_info->hfilter[1] - WIENER_FILT_TAP1_MINV,
    4926          65 :         wiener_info->hfilter[1] - WIENER_FILT_TAP1_MINV);
    4927          65 :     eb_aom_write_primitive_refsubexpfin(
    4928             :         wb, WIENER_FILT_TAP2_MAXV - WIENER_FILT_TAP2_MINV + 1,
    4929             :         WIENER_FILT_TAP2_SUBEXP_K,
    4930          65 :         ref_wiener_info->hfilter[2] - WIENER_FILT_TAP2_MINV,
    4931          65 :         wiener_info->hfilter[2] - WIENER_FILT_TAP2_MINV);
    4932          65 :     memcpy(ref_wiener_info, wiener_info, sizeof(*wiener_info));
    4933          65 : }
    4934             : 
    4935          69 : static void write_sgrproj_filter(const SgrprojInfo *sgrproj_info,
    4936             :     SgrprojInfo *ref_sgrproj_info,
    4937             :     AomWriter *wb) {
    4938          69 :     aom_write_literal(wb, sgrproj_info->ep, SGRPROJ_PARAMS_BITS);
    4939          69 :     const SgrParamsType *params = &eb_sgr_params[sgrproj_info->ep];
    4940             : 
    4941          69 :     if (params->r[0] == 0) {
    4942           0 :         assert(sgrproj_info->xqd[0] == 0);
    4943           0 :         eb_aom_write_primitive_refsubexpfin(
    4944             :             wb, SGRPROJ_PRJ_MAX1 - SGRPROJ_PRJ_MIN1 + 1, SGRPROJ_PRJ_SUBEXP_K,
    4945           0 :             (uint16_t)(ref_sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1),
    4946           0 :             (uint16_t)(sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1));
    4947             :     }
    4948          69 :     else if (params->r[1] == 0) {
    4949           4 :         eb_aom_write_primitive_refsubexpfin(
    4950             :             wb, SGRPROJ_PRJ_MAX0 - SGRPROJ_PRJ_MIN0 + 1, SGRPROJ_PRJ_SUBEXP_K,
    4951           4 :             (uint16_t)(ref_sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0),
    4952           4 :             (uint16_t)(sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0));
    4953             :     }
    4954             :     else {
    4955          65 :         eb_aom_write_primitive_refsubexpfin(
    4956             :             wb, SGRPROJ_PRJ_MAX0 - SGRPROJ_PRJ_MIN0 + 1, SGRPROJ_PRJ_SUBEXP_K,
    4957          65 :             (uint16_t)(ref_sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0),
    4958          65 :             (uint16_t)(sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0));
    4959          65 :         eb_aom_write_primitive_refsubexpfin(
    4960             :             wb, SGRPROJ_PRJ_MAX1 - SGRPROJ_PRJ_MIN1 + 1, SGRPROJ_PRJ_SUBEXP_K,
    4961          65 :             (uint16_t)(ref_sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1),
    4962          65 :             (uint16_t)(sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1));
    4963             :     }
    4964             : 
    4965          69 :     memcpy(ref_sgrproj_info, sgrproj_info, sizeof(*sgrproj_info));
    4966          69 : }
    4967         192 : static void loop_restoration_write_sb_coeffs(PictureControlSet     *piCSetPtr, FRAME_CONTEXT           *frameContext, const Av1Common *const cm,
    4968             :     //MacroBlockD *xd,
    4969             :     const RestorationUnitInfo *rui,
    4970             :     AomWriter *const w, int32_t plane/*,
    4971             :     FRAME_COUNTS *counts*/)
    4972             : {
    4973         192 :     const RestorationInfo *rsi = cm->rst_info + plane;
    4974         192 :     RestorationType frame_rtype = rsi->frame_restoration_type;
    4975         192 :     if (frame_rtype == RESTORE_NONE) return;
    4976             : 
    4977             :     //(void)counts;
    4978             : //    assert(!cm->all_lossless);
    4979             : 
    4980         192 :     const int32_t wiener_win = (plane > 0) ? WIENER_WIN_CHROMA : WIENER_WIN;
    4981         192 :     WienerInfo *wiener_info = piCSetPtr->wiener_info + plane;
    4982         192 :     SgrprojInfo *sgrproj_info = piCSetPtr->sgrproj_info + plane;
    4983         192 :     RestorationType unit_rtype = rui->restoration_type;
    4984             : 
    4985         192 :     assert(unit_rtype < CDF_SIZE(RESTORE_SWITCHABLE_TYPES));
    4986             : 
    4987         192 :     if (frame_rtype == RESTORE_SWITCHABLE) {
    4988          48 :         aom_write_symbol(w, unit_rtype, /*xd->tile_ctx->*/frameContext->switchable_restore_cdf,
    4989             :             RESTORE_SWITCHABLE_TYPES);
    4990             : #if CONFIG_ENTROPY_STATS
    4991             :         ++counts->switchable_restore[unit_rtype];
    4992             : #endif
    4993          48 :         switch (unit_rtype) {
    4994          18 :         case RESTORE_WIENER:
    4995          18 :             write_wiener_filter(wiener_win, &rui->wiener_info, wiener_info, w);
    4996             :             //printf("POC:%i plane:%i v:%i %i %i  h:%i %i %i\n", piCSetPtr->picture_number, plane, rui->wiener_info.vfilter[0], rui->wiener_info.vfilter[1], rui->wiener_info.vfilter[2], rui->wiener_info.hfilter[0], rui->wiener_info.hfilter[1], rui->wiener_info.hfilter[2]);
    4997          18 :             break;
    4998          22 :         case RESTORE_SGRPROJ:
    4999          22 :             write_sgrproj_filter(&rui->sgrproj_info, sgrproj_info, w);
    5000             :             //printf("POC:%i plane:%i ep:%i xqd_0:%i  xqd_1:%i\n", piCSetPtr->picture_number, plane, rui->sgrproj_info.ep, rui->sgrproj_info.xqd[0], rui->sgrproj_info.xqd[1]);
    5001          22 :             break;
    5002           8 :         default: assert(unit_rtype == RESTORE_NONE);// printf("POC:%i plane:%i OFF\n", piCSetPtr->picture_number, plane);
    5003           8 :             break;
    5004             :         }
    5005             :     }
    5006         144 :     else if (frame_rtype == RESTORE_WIENER) {
    5007          65 :         aom_write_symbol(w, unit_rtype != RESTORE_NONE,
    5008          65 :             /*xd->tile_ctx->*/frameContext->wiener_restore_cdf, 2);
    5009             : #if CONFIG_ENTROPY_STATS
    5010             :         ++counts->wiener_restore[unit_rtype != RESTORE_NONE];
    5011             : #endif
    5012          65 :         if (unit_rtype != RESTORE_NONE) {
    5013          47 :             write_wiener_filter(wiener_win, &rui->wiener_info, wiener_info, w);
    5014             :             //printf("POC:%i plane:%i v:%i %i %i  h:%i %i %i\n", piCSetPtr->picture_number, plane, rui->wiener_info.vfilter[0], rui->wiener_info.vfilter[1], rui->wiener_info.vfilter[2], rui->wiener_info.hfilter[0], rui->wiener_info.hfilter[1], rui->wiener_info.hfilter[2]);
    5015             :         }
    5016             :         //else
    5017             :             //printf("POC:%i plane:%i OFF\n", piCSetPtr->picture_number, plane);
    5018             :     }
    5019          79 :     else if (frame_rtype == RESTORE_SGRPROJ) {
    5020          79 :         aom_write_symbol(w, unit_rtype != RESTORE_NONE,
    5021          79 :             /*xd->tile_ctx->*/frameContext->sgrproj_restore_cdf, 2);
    5022             : #if CONFIG_ENTROPY_STATS
    5023             :         ++counts->sgrproj_restore[unit_rtype != RESTORE_NONE];
    5024             : #endif
    5025          79 :         if (unit_rtype != RESTORE_NONE) {
    5026          47 :             write_sgrproj_filter(&rui->sgrproj_info, sgrproj_info, w);
    5027             :             //printf("POC:%i plane:%i ep:%i xqd_0:%i  xqd_1:%i\n", piCSetPtr->picture_number, plane, rui->sgrproj_info.ep, rui->sgrproj_info.xqd[0], rui->sgrproj_info.xqd[1]);
    5028             :         }
    5029             :         //else
    5030             :         //    printf("POC:%i plane:%i OFF\n", piCSetPtr->picture_number, plane);
    5031             :     }
    5032             : }
    5033             : 
    5034       33844 : EbErrorType ec_update_neighbors(
    5035             :     PictureControlSet     *picture_control_set_ptr,
    5036             :     EntropyCodingContext  *context_ptr,
    5037             :     uint32_t                 blkOriginX,
    5038             :     uint32_t                 blkOriginY,
    5039             :     CodingUnit            *cu_ptr,
    5040             :     BlockSize                bsize,
    5041             :     EbPictureBufferDesc   *coeff_ptr)
    5042             : {
    5043             :     UNUSED(coeff_ptr);
    5044       33844 :     EbErrorType return_error = EB_ErrorNone;
    5045       33844 :     NeighborArrayUnit     *mode_type_neighbor_array = picture_control_set_ptr->mode_type_neighbor_array;
    5046       33844 :     NeighborArrayUnit     *partition_context_neighbor_array = picture_control_set_ptr->partition_context_neighbor_array;
    5047       33844 :     NeighborArrayUnit     *skip_flag_neighbor_array = picture_control_set_ptr->skip_flag_neighbor_array;
    5048       33844 :     NeighborArrayUnit     *skip_coeff_neighbor_array = picture_control_set_ptr->skip_coeff_neighbor_array;
    5049       33844 :     NeighborArrayUnit     *luma_dc_sign_level_coeff_neighbor_array = picture_control_set_ptr->luma_dc_sign_level_coeff_neighbor_array;
    5050       33844 :     NeighborArrayUnit     *cr_dc_sign_level_coeff_neighbor_array = picture_control_set_ptr->cr_dc_sign_level_coeff_neighbor_array;
    5051       33844 :     NeighborArrayUnit     *cb_dc_sign_level_coeff_neighbor_array = picture_control_set_ptr->cb_dc_sign_level_coeff_neighbor_array;
    5052       33844 :     NeighborArrayUnit     *inter_pred_dir_neighbor_array = picture_control_set_ptr->inter_pred_dir_neighbor_array;
    5053       33844 :     NeighborArrayUnit     *ref_frame_type_neighbor_array = picture_control_set_ptr->ref_frame_type_neighbor_array;
    5054       33844 :     NeighborArrayUnit32   *interpolation_type_neighbor_array = picture_control_set_ptr->interpolation_type_neighbor_array;
    5055       33844 :     const BlockGeom         *blk_geom = get_blk_geom_mds(cu_ptr->mds_idx);
    5056       33843 :     EbBool                   skipCoeff = EB_FALSE;
    5057             :     PartitionContext         partition;
    5058             : 
    5059       33843 :     skipCoeff = cu_ptr->block_has_coeff ? 0 : 1;
    5060             :     // Update the Leaf Depth Neighbor Array
    5061       33843 :     partition.above = partition_context_lookup[bsize].above;
    5062       33843 :     partition.left = partition_context_lookup[bsize].left;
    5063             : 
    5064       33843 :     neighbor_array_unit_mode_write(
    5065             :         partition_context_neighbor_array,
    5066             :         (uint8_t*)&partition,
    5067             :         blkOriginX,
    5068             :         blkOriginY,
    5069       33843 :         blk_geom->bwidth,
    5070       33843 :         blk_geom->bheight,
    5071             :         NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    5072             : 
    5073             :     // Update the Mode Type Neighbor Array
    5074             :     {
    5075       33844 :         uint8_t prediction_mode_flag = (uint8_t)cu_ptr->prediction_mode_flag;
    5076       33844 :         neighbor_array_unit_mode_write(
    5077             :             mode_type_neighbor_array,
    5078             :             &prediction_mode_flag,
    5079             :             blkOriginX,
    5080             :             blkOriginY,
    5081       33844 :             blk_geom->bwidth,
    5082       33844 :             blk_geom->bheight,
    5083             :             NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    5084             :     }
    5085             : 
    5086             :     // Update the Skip Flag Neighbor Array
    5087             :     {
    5088       33841 :         uint8_t skip_flag = (uint8_t)cu_ptr->skip_flag;
    5089       33841 :         neighbor_array_unit_mode_write(
    5090             :             skip_flag_neighbor_array,
    5091             :             (uint8_t*)&skip_flag,
    5092             :             blkOriginX,
    5093             :             blkOriginY,
    5094       33841 :             blk_geom->bwidth,
    5095       33841 :             blk_geom->bheight,
    5096             :             NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    5097             :     }
    5098             : 
    5099             :     // Update the Skip Coeff Neighbor Array
    5100             :     {
    5101             :         //
    5102       33845 :         neighbor_array_unit_mode_write(
    5103             :             skip_coeff_neighbor_array,
    5104             :             (uint8_t*)&skipCoeff,
    5105             :             blkOriginX,
    5106             :             blkOriginY,
    5107       33845 :             blk_geom->bwidth,
    5108       33845 :             blk_geom->bheight,
    5109             :             NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    5110             :     }
    5111             : 
    5112       33844 :     if (skipCoeff)
    5113             :     {
    5114       21547 :         uint8_t dc_sign_level_coeff = 0;
    5115             : 
    5116       21547 :         neighbor_array_unit_mode_write(
    5117             :             luma_dc_sign_level_coeff_neighbor_array,
    5118             :             (uint8_t*)&dc_sign_level_coeff,
    5119             :             blkOriginX,
    5120             :             blkOriginY,
    5121       21547 :             blk_geom->bwidth,
    5122       21547 :             blk_geom->bheight,
    5123             :             NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    5124             : 
    5125       21543 :         if (blk_geom->has_uv)
    5126       21232 :             neighbor_array_unit_mode_write(
    5127             :                 cb_dc_sign_level_coeff_neighbor_array,
    5128             :                 (uint8_t*)&dc_sign_level_coeff,
    5129       21232 :                 ((blkOriginX >> 3) << 3) >> 1,
    5130       21232 :                 ((blkOriginY >> 3) << 3) >> 1,
    5131       21232 :                 blk_geom->bwidth_uv,
    5132       21232 :                 blk_geom->bheight_uv,
    5133             :                 NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    5134             : 
    5135       21545 :         if (blk_geom->has_uv)
    5136       21234 :             neighbor_array_unit_mode_write(
    5137             :                 cr_dc_sign_level_coeff_neighbor_array,
    5138             :                 (uint8_t*)&dc_sign_level_coeff,
    5139       21234 :                 ((blkOriginX >> 3) << 3) >> 1,
    5140       21234 :                 ((blkOriginY >> 3) << 3) >> 1,
    5141       21234 :                 blk_geom->bwidth_uv,
    5142       21234 :                 blk_geom->bheight_uv,
    5143             :                 NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    5144             : 
    5145       21545 :         context_ptr->coded_area_sb += blk_geom->bwidth * blk_geom->bheight;
    5146             : 
    5147       21545 :         if (blk_geom->has_uv)
    5148       21234 :             context_ptr->coded_area_sb_uv += blk_geom->bwidth_uv * blk_geom->bheight_uv;
    5149             :     }
    5150             : 
    5151             :     // Update the Inter Pred Type Neighbor Array
    5152             :     {
    5153       33842 :         uint8_t inter_pred_direction_index = (uint8_t)cu_ptr->prediction_unit_array->inter_pred_direction_index;
    5154       33842 :         neighbor_array_unit_mode_write(
    5155             :             inter_pred_dir_neighbor_array,
    5156             :             (uint8_t*)&(inter_pred_direction_index),
    5157             :             blkOriginX,
    5158             :             blkOriginY,
    5159       33842 :             blk_geom->bwidth,
    5160       33842 :             blk_geom->bheight,
    5161             :             NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    5162             :     }
    5163             : 
    5164             :     // Update the refFrame Type Neighbor Array
    5165             :     {
    5166       33840 :         uint8_t ref_frame_type = (uint8_t)cu_ptr->prediction_unit_array[0].ref_frame_type;
    5167       33840 :         neighbor_array_unit_mode_write(
    5168             :             ref_frame_type_neighbor_array,
    5169             :             (uint8_t*)&(ref_frame_type),
    5170             :             blkOriginX,
    5171             :             blkOriginY,
    5172       33840 :             blk_geom->bwidth,
    5173       33840 :             blk_geom->bheight,
    5174             :             NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    5175             :     }
    5176             : 
    5177             :     // Update the interpolation Type Neighbor Array
    5178             :     {
    5179       33840 :         uint32_t interpolationType = cu_ptr->interp_filters;
    5180       33840 :         neighbor_array_unit_mode_write32(
    5181             :             interpolation_type_neighbor_array,
    5182             :             interpolationType,
    5183             :             blkOriginX,
    5184             :             blkOriginY,
    5185       33840 :             blk_geom->bwidth,
    5186       33840 :             blk_geom->bheight,
    5187             :             NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    5188             :     }
    5189       33841 :     return return_error;
    5190             : }
    5191             : 
    5192             : #if !PAL_SUP
    5193             : static INLINE int av1_allow_palette(int allow_screen_content_tools,
    5194             :     BlockSize sb_type) {
    5195             :     return allow_screen_content_tools && block_size_wide[sb_type] <= 64 &&
    5196             :         block_size_high[sb_type] <= 64 && sb_type >= BLOCK_8X8;
    5197             : }
    5198             : 
    5199             : static INLINE int av1_get_palette_bsize_ctx(BlockSize bsize) {
    5200             :     return num_pels_log2_lookup[bsize] - num_pels_log2_lookup[BLOCK_8X8];
    5201             : }
    5202             : #else
    5203   477513000 : int av1_allow_palette(int allow_screen_content_tools,
    5204             :     BlockSize sb_type) {
    5205           0 :     return allow_screen_content_tools && block_size_wide[sb_type] <= 64 &&
    5206   477513000 :         block_size_high[sb_type] <= 64 && sb_type >= BLOCK_8X8;
    5207             : }
    5208           0 : int av1_get_palette_bsize_ctx(BlockSize bsize) {
    5209           0 :     return num_pels_log2_lookup[bsize] - num_pels_log2_lookup[BLOCK_8X8];
    5210             : }
    5211             : void av1_tokenize_color_map(FRAME_CONTEXT *frameContext,CodingUnit*cu_ptr, int plane,
    5212             :     TOKENEXTRA **t, BlockSize bsize, TxSize tx_size,
    5213             :     COLOR_MAP_TYPE type, int allow_update_cdf);
    5214             : void av1_get_block_dimensions(BlockSize bsize, int plane,
    5215             :     const MacroBlockD *xd, int *width,
    5216             :     int *height,
    5217             :     int *rows_within_bounds,
    5218             :     int *cols_within_bounds);
    5219             : int eb_get_palette_cache(const MacroBlockD *const xd, int plane,
    5220             :     uint16_t *cache);
    5221             : int av1_index_color_cache(const uint16_t *color_cache, int n_cache,
    5222             :     const uint16_t *colors, int n_colors,
    5223             :     uint8_t *cache_color_found, int *out_cache_colors);
    5224             : 
    5225           0 : int av1_get_palette_mode_ctx(const MacroBlockD *xd) {
    5226           0 :     const MbModeInfo *const above_mi = xd->above_mbmi;
    5227           0 :     const MbModeInfo *const left_mi = xd->left_mbmi;
    5228           0 :     int ctx = 0;
    5229           0 :     if (above_mi) ctx += (above_mi->palette_mode_info.palette_size[0] > 0);
    5230           0 :     if (left_mi) ctx += (left_mi->palette_mode_info.palette_size[0] > 0);
    5231           0 :     return ctx;
    5232             : }
    5233             : // Transmit color values with delta encoding. Write the first value as
    5234             : // literal, and the deltas between each value and the previous one. "min_val" is
    5235             : // the smallest possible value of the deltas.
    5236           0 : static AOM_INLINE void delta_encode_palette_colors(const int *colors, int num,
    5237             :     int bit_depth, int min_val,
    5238             :     AomWriter *w) {
    5239           0 :     if (num <= 0) return;
    5240           0 :     assert(colors[0] < (1 << bit_depth));
    5241           0 :     aom_write_literal(w, colors[0], bit_depth);
    5242           0 :     if (num == 1) return;
    5243           0 :     int max_delta = 0;
    5244             :     int deltas[PALETTE_MAX_SIZE];
    5245           0 :     memset(deltas, 0, sizeof(deltas));
    5246           0 :     for (int i = 1; i < num; ++i) {
    5247           0 :         assert(colors[i] < (1 << bit_depth));
    5248           0 :         const int delta = colors[i] - colors[i - 1];
    5249           0 :         deltas[i - 1] = delta;
    5250           0 :         assert(delta >= min_val);
    5251           0 :         if (delta > max_delta) max_delta = delta;
    5252             :     }
    5253           0 :     const int min_bits = bit_depth - 3;
    5254           0 :     int bits = AOMMAX(av1_ceil_log2(max_delta + 1 - min_val), min_bits);
    5255           0 :     assert(bits <= bit_depth);
    5256           0 :     int range = (1 << bit_depth) - colors[0] - min_val;
    5257           0 :     aom_write_literal(w, bits - min_bits, 2);
    5258           0 :     for (int i = 0; i < num - 1; ++i) {
    5259           0 :         aom_write_literal(w, deltas[i] - min_val, bits);
    5260           0 :         range -= deltas[i];
    5261           0 :         bits = AOMMIN(bits, av1_ceil_log2(range));
    5262             :     }
    5263             : }
    5264             : 
    5265           0 : static INLINE int get_unsigned_bits(unsigned int num_values) {
    5266           0 :     return num_values > 0 ? get_msb(num_values) + 1 : 0;
    5267             : }
    5268           0 : static INLINE void write_uniform(AomWriter *w, int n, int v) {
    5269           0 :     const int l = get_unsigned_bits(n);
    5270           0 :     const int m = (1 << l) - n;
    5271           0 :     if (l == 0) return;
    5272           0 :     if (v < m) {
    5273           0 :         aom_write_literal(w, v, l - 1);
    5274             :     }
    5275             :     else {
    5276           0 :         aom_write_literal(w, m + ((v - m) >> 1), l - 1);
    5277           0 :         aom_write_literal(w, (v - m) & 1, 1);
    5278             :     }
    5279             : }
    5280           0 : int write_uniform_cost(int n, int v) {
    5281           0 :     const int l = get_unsigned_bits(n);
    5282           0 :     const int m = (1 << l) - n;
    5283           0 :     if (l == 0) return 0;
    5284           0 :     if (v < m)
    5285           0 :         return av1_cost_literal(l - 1);
    5286             :     else
    5287           0 :         return av1_cost_literal(l);
    5288             : }
    5289             : // Transmit luma palette color values. First signal if each color in the color
    5290             : // cache is used. Those colors that are not in the cache are transmitted with
    5291             : // delta encoding.
    5292           0 : static AOM_INLINE void write_palette_colors_y(
    5293             :     const MacroBlockD *const xd, const PaletteModeInfo *const pmi,
    5294             :     int bit_depth, AomWriter *w) {
    5295           0 :     const int n = pmi->palette_size[0];
    5296             :     uint16_t color_cache[2 * PALETTE_MAX_SIZE];
    5297           0 :     const int n_cache = eb_get_palette_cache(xd, 0, color_cache);
    5298             :     int out_cache_colors[PALETTE_MAX_SIZE];
    5299             :     uint8_t cache_color_found[2 * PALETTE_MAX_SIZE];
    5300             :     const int n_out_cache =
    5301           0 :         av1_index_color_cache(color_cache, n_cache, pmi->palette_colors, n,
    5302             :             cache_color_found, out_cache_colors);
    5303           0 :     int n_in_cache = 0;
    5304           0 :     for (int i = 0; i < n_cache && n_in_cache < n; ++i) {
    5305           0 :         const int found = cache_color_found[i];
    5306           0 :         aom_write_bit(w, found);
    5307           0 :         n_in_cache += found;
    5308             :     }
    5309           0 :     assert(n_in_cache + n_out_cache == n);
    5310           0 :     delta_encode_palette_colors(out_cache_colors, n_out_cache, bit_depth, 1, w);
    5311           0 : }
    5312           0 : static inline void pack_map_tokens(AomWriter *w, const TOKENEXTRA **tp,
    5313             :     int n, int num) {
    5314           0 :     const TOKENEXTRA *p = *tp;
    5315           0 :     write_uniform(w, n, p->token);  // The first color index.
    5316           0 :     ++p;
    5317           0 :     --num;
    5318           0 :     for (int i = 0; i < num; ++i) {
    5319           0 :         aom_write_symbol(w, p->token, p->color_map_cdf, n);
    5320           0 :         ++p;
    5321             :     }
    5322           0 :     *tp = p;
    5323           0 : }
    5324             : #endif
    5325           0 : static void write_palette_mode_info(
    5326             : #if PAL_SUP
    5327             :     PictureParentControlSet     *ppcs,
    5328             : #endif
    5329             :     FRAME_CONTEXT           *ec_ctx,
    5330             :     CodingUnit            *cu_ptr,
    5331             :     BlockSize bsize,
    5332             :     int mi_row,
    5333             :     int mi_col, AomWriter *w)
    5334             : {
    5335           0 :     const uint32_t intra_luma_mode = cu_ptr->pred_mode;
    5336           0 :     uint32_t intra_chroma_mode = cu_ptr->prediction_unit_array->intra_chroma_mode;
    5337             : 
    5338           0 :     const int num_planes = 3;// av1_num_planes(cm);
    5339             : 
    5340             : #if PAL_SUP
    5341           0 :     const PaletteModeInfo *const pmi = &cu_ptr->palette_info.pmi;
    5342           0 :     const int bsize_ctx = av1_get_palette_bsize_ctx(bsize);
    5343           0 :     assert(bsize_ctx >= 0);
    5344           0 :     if (intra_luma_mode == DC_PRED) {
    5345           0 :         const int n =  pmi->palette_size[0];
    5346           0 :         const int palette_y_mode_ctx = av1_get_palette_mode_ctx(cu_ptr->av1xd);
    5347           0 :         aom_write_symbol(
    5348             :             w, n > 0,
    5349           0 :             ec_ctx->palette_y_mode_cdf[bsize_ctx][palette_y_mode_ctx], 2);
    5350           0 :         if (n > 0) {
    5351           0 :             aom_write_symbol(w, n - PALETTE_MIN_SIZE,
    5352           0 :                 ec_ctx->palette_y_size_cdf[bsize_ctx],
    5353             :                 PALETTE_SIZES);
    5354           0 :             write_palette_colors_y(cu_ptr->av1xd, pmi, ppcs->sequence_control_set_ptr->static_config.encoder_bit_depth, w);
    5355             :         }
    5356             :     }
    5357             : 
    5358             : #else
    5359             :     //const BLOCK_SIZE bsize = mbmi->sb_type;
    5360             :     //assert(av1_allow_palette(cm->allow_screen_content_tools, bsize));
    5361             :    // const PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
    5362             :     const int bsize_ctx = av1_get_palette_bsize_ctx(bsize);
    5363             :     assert(bsize_ctx >= 0);
    5364             :     if (intra_luma_mode == DC_PRED) {
    5365             :         const int n = 0;// pmi->palette_size[0];
    5366             :         const int palette_y_mode_ctx = 0;// av1_get_palette_mode_ctx(xd);
    5367             :         aom_write_symbol(
    5368             :             w, n > 0,
    5369             :             ec_ctx->palette_y_mode_cdf[bsize_ctx][palette_y_mode_ctx], 2);
    5370             :         if (n > 0) {
    5371             :             //aom_write_symbol(w, n - PALETTE_MIN_SIZE,
    5372             :             //    xd->tile_ctx->palette_y_size_cdf[bsize_ctx],
    5373             :             //    PALETTE_SIZES);
    5374             :             //write_palette_colors_y(xd, pmi, cm->seq_params.bit_depth, w);
    5375             :         }
    5376             :     }
    5377             : #endif
    5378           0 :     const int uv_dc_pred =
    5379           0 :         num_planes > 1 && intra_chroma_mode == UV_DC_PRED &&
    5380           0 :         is_chroma_reference(mi_row, mi_col, bsize, 1, 1);
    5381           0 :     if (uv_dc_pred) {
    5382           0 :         const int n = 0;// pmi->palette_size[1];
    5383             : #if PAL_SUP
    5384           0 :         assert(pmi->palette_size[1] == 0);//remove when chroma is on
    5385           0 :         const int palette_uv_mode_ctx =  (pmi->palette_size[0] > 0);
    5386             : #else
    5387             :         const int palette_uv_mode_ctx = 0;// (pmi->palette_size[0] > 0);
    5388             : #endif
    5389           0 :         aom_write_symbol(w, n > 0,
    5390           0 :             ec_ctx->palette_uv_mode_cdf[palette_uv_mode_ctx], 2);
    5391             :         if (n > 0) {
    5392             :             /*           aom_write_symbol(w, n - PALETTE_MIN_SIZE,
    5393             :                            xd->tile_ctx->palette_uv_size_cdf[bsize_ctx],
    5394             :                            PALETTE_SIZES);
    5395             :                        write_palette_colors_uv(xd, pmi, cm->seq_params.bit_depth, w);*/
    5396             :         }
    5397             :     }
    5398           0 : }
    5399           0 : void eb_av1_encode_dv(AomWriter *w, const MV *mv, const MV *ref,
    5400             :     NmvContext *mvctx) {
    5401             :     // DV and ref DV should not have sub-pel.
    5402           0 :     assert((mv->col & 7) == 0);
    5403           0 :     assert((mv->row & 7) == 0);
    5404           0 :     assert((ref->col & 7) == 0);
    5405           0 :     assert((ref->row & 7) == 0);
    5406           0 :     const MV diff = { mv->row - ref->row, mv->col - ref->col };
    5407           0 :     const MvJointType j = av1_get_mv_joint((int32_t*)&diff);
    5408             : 
    5409           0 :     aom_write_symbol(w, j, mvctx->joints_cdf, MV_JOINTS);
    5410           0 :     if (mv_joint_vertical(j))
    5411           0 :         encode_mv_component(w, diff.row, &mvctx->comps[0], MV_SUBPEL_NONE);
    5412             : 
    5413           0 :     if (mv_joint_horizontal(j))
    5414           0 :         encode_mv_component(w, diff.col, &mvctx->comps[1], MV_SUBPEL_NONE);
    5415           0 : }
    5416             : 
    5417   478863000 : int av1_allow_intrabc(const Av1Common *const cm) {
    5418   478863000 :     return (cm->p_pcs_ptr->slice_type == I_SLICE && cm->p_pcs_ptr->frm_hdr.allow_screen_content_tools && cm->p_pcs_ptr->frm_hdr.allow_intrabc);
    5419             : }
    5420             : 
    5421           0 : static void write_intrabc_info(
    5422             :     FRAME_CONTEXT           *ec_ctx,
    5423             :     CodingUnit            *cu_ptr,
    5424             :     AomWriter *w) {
    5425           0 :     int use_intrabc = cu_ptr->av1xd->use_intrabc;
    5426           0 :     aom_write_symbol(w, use_intrabc, ec_ctx->intrabc_cdf, 2);
    5427           0 :     if (use_intrabc) {
    5428             :         //assert(mbmi->mode == DC_PRED);
    5429             :         //assert(mbmi->uv_mode == UV_DC_PRED);
    5430             :         //assert(mbmi->motion_mode == SIMPLE_TRANSLATION);
    5431           0 :         IntMv dv_ref = cu_ptr->predmv[0];// mbmi_ext->ref_mv_stack[INTRA_FRAME][0].this_mv;
    5432             :         MV mv;
    5433           0 :         mv.row = cu_ptr->prediction_unit_array[0].mv[INTRA_FRAME].y;
    5434           0 :         mv.col = cu_ptr->prediction_unit_array[0].mv[INTRA_FRAME].x;
    5435             : 
    5436           0 :         eb_av1_encode_dv(w, &mv, &dv_ref.as_mv, &ec_ctx->ndvc);
    5437             :     }
    5438           0 : }
    5439             : 
    5440             : 
    5441        9512 : static INLINE int block_signals_txsize(BlockSize bsize) {
    5442        9512 :     return bsize > BLOCK_4X4;
    5443             : }
    5444             : 
    5445        1563 : static INLINE int get_vartx_max_txsize(/*const MbModeInfo *xd,*/ BlockSize bsize,
    5446             :     int plane) {
    5447             :     /* if (xd->lossless[xd->mi[0]->segment_id]) return TX_4X4;*/
    5448        1563 :     const TxSize max_txsize = max_txsize_rect_lookup[bsize];
    5449        1563 :     if (plane == 0) return max_txsize;            // luma
    5450           0 :     return av1_get_adjusted_tx_size(max_txsize);  // chroma
    5451             : }
    5452        2437 : static INLINE int max_block_wide(const MacroBlockD *xd, BlockSize bsize,
    5453             :     int plane) {
    5454        2437 :     int max_blocks_wide = block_size_wide[bsize];
    5455        2437 :     const struct macroblockd_plane *const pd = &xd->plane[plane];
    5456             : 
    5457        2437 :     if (xd->mb_to_right_edge < 0)
    5458           0 :         max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
    5459             : 
    5460             :     // Scale the width in the transform block unit.
    5461        2437 :     return max_blocks_wide >> tx_size_wide_log2[0];
    5462             : }
    5463             : 
    5464        2437 : static INLINE int max_block_high(const MacroBlockD *xd, BlockSize bsize,
    5465             :     int plane) {
    5466        2437 :     int max_blocks_high = block_size_high[bsize];
    5467        2437 :     const struct macroblockd_plane *const pd = &xd->plane[plane];
    5468             : 
    5469        2437 :     if (xd->mb_to_bottom_edge < 0)
    5470           0 :         max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
    5471             : 
    5472             :     // Scale the height in the transform block unit.
    5473        2437 :     return max_blocks_high >> tx_size_high_log2[0];
    5474             : }
    5475        2111 : static INLINE void txfm_partition_update(TXFM_CONTEXT *above_ctx,
    5476             :     TXFM_CONTEXT *left_ctx,
    5477             :     TxSize tx_size, TxSize txb_size) {
    5478        2111 :     BlockSize bsize = txsize_to_bsize[txb_size];
    5479        2111 :     int bh = mi_size_high[bsize];
    5480        2111 :     int bw = mi_size_wide[bsize];
    5481        2111 :     uint8_t txw = tx_size_wide[tx_size];
    5482        2111 :     uint8_t txh = tx_size_high[tx_size];
    5483             :     int i;
    5484        7299 :     for (i = 0; i < bh; ++i) left_ctx[i] = txh;
    5485        7299 :     for (i = 0; i < bw; ++i) above_ctx[i] = txw;
    5486        2111 : }
    5487        2429 : static INLINE TxSize get_sqr_tx_size(int tx_dim) {
    5488        2429 :     switch (tx_dim) {
    5489          27 :     case 128:
    5490          27 :     case 64: return TX_64X64; break;
    5491         125 :     case 32: return TX_32X32; break;
    5492        1523 :     case 16: return TX_16X16; break;
    5493         754 :     case 8: return TX_8X8; break;
    5494           0 :     default: return TX_4X4;
    5495             :     }
    5496             : }
    5497        2429 : static INLINE int txfm_partition_context(TXFM_CONTEXT *above_ctx,
    5498             :     TXFM_CONTEXT *left_ctx,
    5499             :     BlockSize bsize, TxSize tx_size) {
    5500        2429 :     const uint8_t txw = tx_size_wide[tx_size];
    5501        2429 :     const uint8_t txh = tx_size_high[tx_size];
    5502        2429 :     const int above = *above_ctx < txw;
    5503        2429 :     const int left = *left_ctx < txh;
    5504        2429 :     int category = TXFM_PARTITION_CONTEXTS;
    5505             : 
    5506             :     // dummy return, not used by others.
    5507        2429 :     if (tx_size <= TX_4X4) return 0;
    5508             : 
    5509             :     TxSize max_tx_size =
    5510        2429 :         get_sqr_tx_size(AOMMAX(block_size_wide[bsize], block_size_high[bsize]));
    5511             : 
    5512        2429 :     if (max_tx_size >= TX_8X8) {
    5513        2429 :         category =
    5514        2429 :             (txsize_sqr_up_map[tx_size] != max_tx_size && max_tx_size > TX_8X8) +
    5515        2429 :             (TX_SIZES - 1 - max_tx_size) * 2;
    5516             :     }
    5517        2429 :     assert(category != TXFM_PARTITION_CONTEXTS);
    5518        2429 :     return category * 3 + above + left;
    5519             : }
    5520             : 
    5521        2437 : static void write_tx_size_vartx(MacroBlockD *xd, const MbModeInfo *mbmi,
    5522             :     TxSize tx_size, int depth, int blk_row,
    5523             :     int blk_col, FRAME_CONTEXT *ec_ctx, AomWriter *w) {
    5524             :     //FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
    5525        2437 :     const int max_blocks_high = max_block_high(xd, mbmi->block_mi.sb_type, 0);
    5526        2437 :     const int max_blocks_wide = max_block_wide(xd, mbmi->block_mi.sb_type, 0);
    5527             : 
    5528        2437 :     if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
    5529             : 
    5530        2437 :     if (depth == MAX_VARTX_DEPTH) {
    5531           8 :         txfm_partition_update(xd->above_txfm_context + blk_col,
    5532           8 :             xd->left_txfm_context + blk_row, tx_size, tx_size);
    5533           8 :         return;
    5534             :     }
    5535             : 
    5536        2429 :     const int ctx = txfm_partition_context(xd->above_txfm_context + blk_col,
    5537        2429 :         xd->left_txfm_context + blk_row,
    5538        2429 :         mbmi->block_mi.sb_type, tx_size);
    5539        2429 :     const int write_txfm_partition = (tx_size == tx_depth_to_tx_size[mbmi->tx_depth][mbmi->block_mi.sb_type]);
    5540             : 
    5541        2429 :     if (write_txfm_partition) {
    5542        1959 :         aom_write_symbol(w, 0, ec_ctx->txfm_partition_cdf[ctx], 2);
    5543             : 
    5544        1959 :         txfm_partition_update(xd->above_txfm_context + blk_col,
    5545        1959 :             xd->left_txfm_context + blk_row, tx_size, tx_size);
    5546             :     }
    5547             :     else {
    5548         470 :         const TxSize sub_txs = sub_tx_size_map[tx_size];
    5549         470 :         const int bsw = tx_size_wide_unit[sub_txs];
    5550         470 :         const int bsh = tx_size_high_unit[sub_txs];
    5551             : 
    5552         470 :         aom_write_symbol(w, 1, ec_ctx->txfm_partition_cdf[ctx], 2);
    5553             : 
    5554         470 :         if (sub_txs == TX_4X4) {
    5555         144 :             txfm_partition_update(xd->above_txfm_context + blk_col,
    5556         144 :                 xd->left_txfm_context + blk_row, sub_txs, tx_size);
    5557         144 :             return;
    5558             :         }
    5559             : 
    5560         326 :         assert(bsw > 0 && bsh > 0);
    5561         878 :         for (int row = 0; row < tx_size_high_unit[tx_size]; row += bsh)
    5562        1426 :             for (int col = 0; col < tx_size_wide_unit[tx_size]; col += bsw) {
    5563         874 :                 int offsetr = blk_row + row;
    5564         874 :                 int offsetc = blk_col + col;
    5565         874 :                 write_tx_size_vartx(xd, mbmi, sub_txs, depth + 1, offsetr, offsetc, ec_ctx, w);
    5566             :             }
    5567             :     }
    5568             : }
    5569             : 
    5570        9200 : static INLINE void set_txfm_ctx(TXFM_CONTEXT *txfm_ctx, uint8_t txs, int len) {
    5571             :     int i;
    5572       35252 :     for (i = 0; i < len; ++i) txfm_ctx[i] = txs;
    5573        9200 : }
    5574             : 
    5575        4600 : static INLINE void set_txfm_ctxs(TxSize tx_size, int n8_w, int n8_h, int skip,
    5576             :     const MacroBlockD *xd) {
    5577        4600 :     uint8_t bw = tx_size_wide[tx_size];
    5578        4600 :     uint8_t bh = tx_size_high[tx_size];
    5579             : 
    5580        4600 :     if (skip) {
    5581         907 :         bw = n8_w * MI_SIZE;
    5582         907 :         bh = n8_h * MI_SIZE;
    5583             :     }
    5584             : 
    5585        4600 :     set_txfm_ctx(xd->above_txfm_context, bw, n8_w);
    5586        4600 :     set_txfm_ctx(xd->left_txfm_context, bh, n8_h);
    5587        4600 : }
    5588        3349 : static INLINE int tx_size_to_depth(TxSize tx_size, BlockSize bsize) {
    5589        3349 :     TxSize ctx_size = max_txsize_rect_lookup[bsize];
    5590        3349 :     int depth = 0;
    5591        4705 :     while (tx_size != ctx_size) {
    5592        1356 :         depth++;
    5593        1356 :         ctx_size = sub_tx_size_map[ctx_size];
    5594        1356 :         assert(depth <= MAX_TX_DEPTH);
    5595             :     }
    5596        3349 :     return depth;
    5597             : }
    5598             : 
    5599             : // Returns a context number for the given MB prediction signal
    5600             : // The mode info data structure has a one element border above and to the
    5601             : // left of the entries corresponding to real blocks.
    5602             : // The prediction flags in these dummy entries are initialized to 0.
    5603        3349 : static INLINE int get_tx_size_context(const MacroBlockD *xd) {
    5604        3349 :     const ModeInfo *mi = xd->mi[0];
    5605        3349 :     const MbModeInfo *mbmi = &mi->mbmi;
    5606        3349 :     const MbModeInfo *const above_mbmi = xd->above_mbmi;
    5607        3349 :     const MbModeInfo *const left_mbmi = xd->left_mbmi;
    5608        3349 :     const TxSize max_tx_size = max_txsize_rect_lookup[mbmi->block_mi.sb_type];
    5609        3349 :     const int max_tx_wide = tx_size_wide[max_tx_size];
    5610        3349 :     const int max_tx_high = tx_size_high[max_tx_size];
    5611        3349 :     const int has_above = xd->up_available;
    5612        3349 :     const int has_left = xd->left_available;
    5613             : 
    5614        3349 :     int above = xd->above_txfm_context[0] >= max_tx_wide;
    5615        3349 :     int left = xd->left_txfm_context[0] >= max_tx_high;
    5616             : 
    5617        3349 :     if (has_above)
    5618        3204 :         if (is_inter_block(&above_mbmi->block_mi))
    5619         107 :             above = block_size_wide[above_mbmi->block_mi.sb_type] >= max_tx_wide;
    5620             : 
    5621        3349 :     if (has_left)
    5622        3179 :         if (is_inter_block(&left_mbmi->block_mi))
    5623          99 :             left = block_size_high[left_mbmi->block_mi.sb_type] >= max_tx_high;
    5624             : 
    5625        3349 :     if (has_above && has_left)
    5626        3037 :         return (above + left);
    5627         312 :     else if (has_above)
    5628         167 :         return above;
    5629         145 :     else if (has_left)
    5630         142 :         return left;
    5631             :     else
    5632           3 :         return 0;
    5633             : }
    5634        3349 : static void write_selected_tx_size(
    5635             :     const MacroBlockD *xd,
    5636             :     FRAME_CONTEXT *ec_ctx,
    5637             :     AomWriter *w) {
    5638        3349 :     const ModeInfo *const mi = xd->mi[0];
    5639        3349 :     const MbModeInfo *const mbmi = &mi->mbmi;
    5640        3349 :     const BlockSize bsize = mbmi->block_mi.sb_type;
    5641             : 
    5642        3349 :     if (block_signals_txsize(bsize)) {
    5643        3349 :         const TxSize tx_size = mbmi->tx_size;
    5644        3349 :         const int tx_size_ctx = get_tx_size_context(xd);
    5645        3349 :         const int depth = tx_size_to_depth(tx_size, bsize);
    5646        3349 :         const int max_depths = bsize_to_max_depth(bsize);
    5647        3349 :         const int32_t tx_size_cat = bsize_to_tx_size_cat(bsize);
    5648             : 
    5649        3349 :         assert(depth >= 0 && depth <= max_depths);
    5650        3349 :         assert(!is_inter_block(&mbmi->block_mi));
    5651        3349 :         assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(/*xd,*/ mbmi)));
    5652             : 
    5653        3349 :         aom_write_symbol(w, depth, ec_ctx->tx_size_cdf[tx_size_cat][tx_size_ctx],
    5654             :             max_depths + 1);
    5655             :     }
    5656        3349 : }
    5657        6163 : static EbErrorType av1_code_tx_size(
    5658             :     FRAME_CONTEXT    *ec_ctx,
    5659             :     AomWriter        *w,
    5660             :     MacroBlockD      *xd,
    5661             :     const MbModeInfo *mbmi,
    5662             :     TxMode            tx_mode,
    5663             :     BlockSize         bsize,
    5664             :     uint8_t           skip) {
    5665        6163 :     EbErrorType return_error = EB_ErrorNone;
    5666        6163 :     int is_inter_tx = is_inter_block(&mbmi->block_mi) || is_intrabc_block(&mbmi->block_mi);
    5667             :     //int skip = mbmi->skip;
    5668             :     //int segment_id = 0;// mbmi->segment_id;
    5669        6163 :     if (tx_mode == TX_MODE_SELECT && block_signals_txsize(bsize) &&
    5670        2466 :         !(is_inter_tx && skip) /*&& !xd->lossless[segment_id]*/) {
    5671        4912 :         if (is_inter_tx) {  // This implies skip flag is 0.
    5672        1563 :             const TxSize max_tx_size = get_vartx_max_txsize(/*xd,*/ bsize, 0);
    5673        1563 :             const int txbh = tx_size_high_unit[max_tx_size];
    5674        1563 :             const int txbw = tx_size_wide_unit[max_tx_size];
    5675        1563 :             const int width = block_size_wide[bsize] >> tx_size_wide_log2[0];
    5676        1563 :             const int height = block_size_high[bsize] >> tx_size_high_log2[0];
    5677             :             int idx, idy;
    5678        3126 :             for (idy = 0; idy < height; idy += txbh)
    5679        3126 :                 for (idx = 0; idx < width; idx += txbw)
    5680        1563 :                     write_tx_size_vartx(xd, mbmi, max_tx_size, 0, idy, idx, ec_ctx, w);
    5681             :         }
    5682             :         else {
    5683        3349 :             write_selected_tx_size(xd, ec_ctx, w);
    5684        3349 :             set_txfm_ctxs(mbmi->tx_size, xd->n8_w, xd->n8_h, 0, xd);
    5685             :         }
    5686             :     }
    5687             :     else {
    5688        2235 :         set_txfm_ctxs(mbmi->tx_size, xd->n8_w, xd->n8_h,
    5689         984 :             skip && is_inter_block(&mbmi->block_mi), xd);
    5690             :     }
    5691             : 
    5692        6163 :     return return_error;
    5693             : }
    5694             : 
    5695     9199400 : void set_mi_row_col(
    5696             :     PictureControlSet       *picture_control_set_ptr,
    5697             :     MacroBlockD             *xd,
    5698             :     TileInfo *              tile,
    5699             :     int                     mi_row,
    5700             :     int                     bh,
    5701             :     int                     mi_col,
    5702             :     int                     bw,
    5703             :     uint32_t                mi_stride,
    5704             :     int                     mi_rows,
    5705             :     int                     mi_cols) {
    5706     9199400 :     xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
    5707     9199400 :     xd->mb_to_bottom_edge = ((mi_rows - bh - mi_row) * MI_SIZE) * 8;
    5708     9199400 :     xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
    5709     9199400 :     xd->mb_to_right_edge = ((mi_cols - bw - mi_col) * MI_SIZE) * 8;
    5710             : 
    5711     9199400 :     xd->mi_stride = mi_stride;
    5712             : 
    5713             :     // Are edges available for intra prediction?
    5714     9199400 :     xd->up_available = (mi_row > tile->mi_row_start);
    5715     9199400 :     xd->left_available = (mi_col > tile->mi_col_start);
    5716     9199400 :     const int32_t offset = mi_row * mi_stride + mi_col;
    5717     9199400 :     xd->mi = picture_control_set_ptr->mi_grid_base + offset;
    5718             : 
    5719     9199400 :     if (xd->up_available)
    5720     8801530 :         xd->above_mbmi = &xd->mi[-xd->mi_stride]->mbmi;
    5721             :     else
    5722      397866 :         xd->above_mbmi = NULL;
    5723             : 
    5724     9199400 :     if (xd->left_available)
    5725     8855270 :         xd->left_mbmi = &xd->mi[-1]->mbmi;
    5726             :     else
    5727      344130 :         xd->left_mbmi = NULL;
    5728             : 
    5729     9199400 :     xd->n8_h = bh;
    5730     9199400 :     xd->n8_w = bw;
    5731     9199400 :     xd->is_sec_rect = 0;
    5732     9199400 :     if (xd->n8_w < xd->n8_h) {
    5733             :         // Only mark is_sec_rect as 1 for the last block.
    5734             :         // For PARTITION_VERT_4, it would be (0, 0, 0, 1);
    5735             :         // For other partitions, it would be (0, 1).
    5736     2932170 :         if (!((mi_col + xd->n8_w) & (xd->n8_h - 1))) xd->is_sec_rect = 1;
    5737             :     }
    5738             : 
    5739     9199400 :     if (xd->n8_w > xd->n8_h)
    5740     2855650 :         if (mi_row & (xd->n8_w - 1)) xd->is_sec_rect = 1;
    5741     9199400 : }
    5742             : 
    5743        6163 : void code_tx_size(
    5744             :     PictureControlSet *pcsPtr,
    5745             :     uint32_t           cu_origin_x,
    5746             :     uint32_t           cu_origin_y,
    5747             :     CodingUnit        *cu_ptr,
    5748             :     const BlockGeom   *blk_geom,
    5749             :     NeighborArrayUnit *txfm_context_array,
    5750             :     FRAME_CONTEXT     *ec_ctx,
    5751             :     AomWriter         *w,
    5752             :     uint8_t            skip) {
    5753        6163 :     uint32_t txfm_context_left_index = get_neighbor_array_unit_left_index(
    5754             :         txfm_context_array,
    5755             :         cu_origin_y);
    5756        6163 :     uint32_t txfm_context_above_index = get_neighbor_array_unit_top_index(
    5757             :         txfm_context_array,
    5758             :         cu_origin_x);
    5759        6163 :     TxMode tx_mode = pcsPtr->parent_pcs_ptr->frm_hdr.tx_mode;
    5760        6163 :     Av1Common  *cm = pcsPtr->parent_pcs_ptr->av1_cm;
    5761        6163 :     MacroBlockD *xd = cu_ptr->av1xd;
    5762        6163 :     TileInfo * tile = &xd->tile;
    5763        6163 :     int32_t mi_row = cu_origin_y >> MI_SIZE_LOG2;
    5764        6163 :     int32_t mi_col = cu_origin_x >> MI_SIZE_LOG2;
    5765        6163 :     BlockSize bsize = blk_geom->bsize;
    5766        6163 :     const int32_t bw = mi_size_wide[bsize];
    5767        6163 :     const int32_t bh = mi_size_high[bsize];
    5768        6163 :     uint32_t mi_stride = pcsPtr->mi_stride;
    5769        6163 :     set_mi_row_col(
    5770             :         pcsPtr,
    5771             :         xd,
    5772             :         tile,
    5773             :         mi_row,
    5774             :         bh,
    5775             :         mi_col,
    5776             :         bw,
    5777             :         mi_stride,
    5778             :         cm->mi_rows,
    5779             :         cm->mi_cols);
    5780             : 
    5781        6163 :     const MbModeInfo *const mbmi = &xd->mi[0]->mbmi;
    5782        6163 :     xd->above_txfm_context = &txfm_context_array->top_array[txfm_context_above_index];
    5783        6163 :     xd->left_txfm_context = &txfm_context_array->left_array[txfm_context_left_index];
    5784             : 
    5785        6163 :     av1_code_tx_size(
    5786             :         ec_ctx,
    5787             :         w,
    5788             :         xd,
    5789             :         mbmi,
    5790             :         tx_mode,
    5791             :         bsize,
    5792             :         skip);
    5793        6163 : }
    5794             : 
    5795           0 : static INLINE int get_segment_id(Av1Common *cm,
    5796             :                                const uint8_t *segment_ids,
    5797             :                                BlockSize bsize,
    5798             :                                int mi_row, int mi_col) {
    5799           0 :     const int mi_offset = mi_row * cm->mi_cols + mi_col;
    5800           0 :     const int bw = mi_size_wide[bsize];
    5801           0 :     const int bh = mi_size_high[bsize];
    5802           0 :     const int xmis = AOMMIN(cm->mi_cols - mi_col, bw);
    5803           0 :     const int ymis = AOMMIN(cm->mi_rows - mi_row, bh);
    5804           0 :     int x, y, segment_id = MAX_SEGMENTS;
    5805             : 
    5806           0 :     for (y = 0; y < ymis; ++y)
    5807           0 :         for (x = 0; x < xmis; ++x)
    5808           0 :             segment_id =
    5809           0 :                     AOMMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
    5810             : 
    5811           0 :     assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
    5812           0 :     return segment_id;
    5813             : }
    5814             : 
    5815           0 : int get_spatial_seg_prediction(PictureControlSet *picture_control_set_ptr,
    5816             :                                uint32_t blkOriginX,
    5817             :                                uint32_t blkOriginY,
    5818             :                                int *cdf_index) {
    5819             : 
    5820           0 :     int prev_ul = -1;  // top left segment_id
    5821           0 :     int prev_l = -1;   // left segment_id
    5822           0 :     int prev_u = -1;   // top segment_id
    5823             : 
    5824           0 :     uint32_t mi_col = blkOriginX >> MI_SIZE_LOG2;
    5825           0 :     uint32_t mi_row = blkOriginY >> MI_SIZE_LOG2;
    5826             : 
    5827           0 :     EbBool left_available = mi_col > 0 ? EB_TRUE : EB_FALSE;
    5828           0 :     EbBool up_available = mi_row > 0 ? EB_TRUE : EB_FALSE;
    5829           0 :     Av1Common *cm = picture_control_set_ptr->parent_pcs_ptr->av1_cm;
    5830           0 :     SegmentationNeighborMap *segmentation_map = picture_control_set_ptr->segmentation_neighbor_map;
    5831             : 
    5832             : //    SVT_LOG("Left available = %d, Up Available = %d ", left_available, up_available);
    5833             : 
    5834           0 :     if ((up_available) && (left_available))
    5835           0 :         prev_ul = get_segment_id(cm, segmentation_map->data, BLOCK_4X4, mi_row - 1, mi_col - 1);
    5836             : 
    5837           0 :     if (up_available)
    5838           0 :         prev_u = get_segment_id(cm, segmentation_map->data, BLOCK_4X4, mi_row - 1, mi_col - 0);
    5839             : 
    5840           0 :     if (left_available)
    5841           0 :         prev_l = get_segment_id(cm, segmentation_map->data, BLOCK_4X4, mi_row - 0, mi_col - 1);
    5842             : 
    5843             :     // Pick CDF index based on number of matching/out-of-bounds segment IDs.
    5844           0 :     if (prev_ul < 0 || prev_u < 0 || prev_l < 0) /* Edge case */
    5845           0 :         *cdf_index = 0;
    5846           0 :     else if ((prev_ul == prev_u) && (prev_ul == prev_l))
    5847           0 :         *cdf_index = 2;
    5848           0 :     else if ((prev_ul == prev_u) || (prev_ul == prev_l) || (prev_u == prev_l))
    5849           0 :         *cdf_index = 1;
    5850             :     else
    5851           0 :         *cdf_index = 0;
    5852             : 
    5853             :     // If 2 or more are identical returns that as predictor, otherwise prev_l.
    5854           0 :     if (prev_u == -1)  // edge case
    5855           0 :         return prev_l == -1 ? 0 : prev_l;
    5856           0 :     if (prev_l == -1)  // edge case
    5857           0 :         return prev_u;
    5858           0 :     return (prev_ul == prev_u) ? prev_u : prev_l;
    5859             : 
    5860             : }
    5861             : 
    5862             : 
    5863           0 : int eb_av1_neg_interleave(int x, int ref, int max) {
    5864           0 :     assert(x < max);
    5865           0 :     const int diff = x - ref;
    5866           0 :     if (!ref) return x;
    5867           0 :     if (ref >= (max - 1)) return -x + max - 1;
    5868           0 :     if (2 * ref < max) {
    5869           0 :         if (abs(diff) <= ref) {
    5870           0 :             if (diff > 0)
    5871           0 :                 return (diff << 1) - 1;
    5872             :             else
    5873           0 :                 return ((-diff) << 1);
    5874             :         }
    5875           0 :         return x;
    5876             :     } else {
    5877           0 :         if (abs(diff) < (max - ref)) {
    5878           0 :             if (diff > 0)
    5879           0 :                 return (diff << 1) - 1;
    5880             :             else
    5881           0 :                 return ((-diff) << 1);
    5882             :         }
    5883           0 :         return (max - x) - 1;
    5884             :     }
    5885             : }
    5886             : 
    5887             : 
    5888           0 : int av1_get_pred_context_seg_id(PictureControlSet *picture_control_set_ptr,
    5889             :                                 CodingUnit *cu_ptr,
    5890             :                                 uint32_t blkOriginX,
    5891             :                                 uint32_t blkOriginY) {
    5892           0 :     NeighborArrayUnit *seg_id_pred_neighbor_array = picture_control_set_ptr->segmentation_id_pred_array;
    5893           0 :     uint32_t top_idx = get_neighbor_array_unit_top_index(seg_id_pred_neighbor_array, blkOriginX);
    5894           0 :     uint32_t left_idx = get_neighbor_array_unit_left_index(seg_id_pred_neighbor_array, blkOriginY);
    5895             : 
    5896           0 :     const int above_pred = cu_ptr->av1xd->up_available ? seg_id_pred_neighbor_array->top_array[top_idx] : 0;
    5897           0 :     const int left_pred = cu_ptr->av1xd->left_available ? seg_id_pred_neighbor_array->left_array[left_idx] : 0;
    5898           0 :     return above_pred + left_pred;
    5899             : }
    5900             : 
    5901           0 : AomCdfProb *av1_get_pred_cdf_seg_id(PictureControlSet *picture_control_set_ptr,
    5902             :                                       FRAME_CONTEXT *frameContext,
    5903             :                                       CodingUnit *cu_ptr,
    5904             :                                       uint32_t blkOriginX,
    5905             :                                       uint32_t blkOriginY) {
    5906           0 :     struct segmentation_probs *segp = &frameContext->seg;
    5907           0 :     return segp->spatial_pred_seg_cdf[av1_get_pred_context_seg_id(picture_control_set_ptr, cu_ptr, blkOriginX, blkOriginY)];
    5908             : }
    5909             : 
    5910           0 : static INLINE void update_segmentation_map(PictureControlSet *picture_control_set_ptr,
    5911             :                                            BlockSize bsize,
    5912             :                                            uint32_t blkOriginX,
    5913             :                                            uint32_t blkOriginY,
    5914             :                                            uint8_t segment_id){
    5915             : 
    5916           0 :     Av1Common *cm = picture_control_set_ptr->parent_pcs_ptr->av1_cm;
    5917           0 :     uint8_t *segment_ids = picture_control_set_ptr->segmentation_neighbor_map->data;
    5918           0 :     uint32_t mi_col = blkOriginX >> MI_SIZE_LOG2;
    5919           0 :     uint32_t mi_row = blkOriginY >> MI_SIZE_LOG2;
    5920           0 :     const int mi_offset = mi_row * cm->mi_cols + mi_col;
    5921           0 :     const int bw = mi_size_wide[bsize];
    5922           0 :     const int bh = mi_size_high[bsize];
    5923           0 :     const int xmis = AOMMIN((int)(cm->mi_cols - mi_col), bw);
    5924           0 :     const int ymis = AOMMIN((int)(cm->mi_rows - mi_row), bh);
    5925             :     int x, y;
    5926             : 
    5927           0 :     for (y = 0; y < ymis; ++y)
    5928           0 :         for (x = 0; x < xmis; ++x)
    5929           0 :             segment_ids[mi_offset + y * cm->mi_cols + x] = segment_id;
    5930             : 
    5931           0 : }
    5932             : 
    5933           0 : void write_segment_id(PictureControlSet *picture_control_set_ptr,
    5934             :                       FRAME_CONTEXT *frameContext,
    5935             :                       AomWriter *ecWriter,
    5936             :                       BlockSize bsize,
    5937             :                       uint32_t blkOriginX,
    5938             :                       uint32_t blkOriginY,
    5939             :                       CodingUnit *cu_ptr,
    5940             :                       EbBool skip_coeff) {
    5941             : 
    5942           0 :     SegmentationParams *segmentationParams = &picture_control_set_ptr->parent_pcs_ptr->frm_hdr.segmentation_params;
    5943           0 :     if (!segmentationParams->segmentation_enabled)
    5944           0 :         return;
    5945             :     int cdf_num;
    5946           0 :     const int pred = get_spatial_seg_prediction(picture_control_set_ptr, blkOriginX, blkOriginY, &cdf_num);
    5947           0 :     if (skip_coeff) {
    5948             : //        SVT_LOG("BlockY = %d, BlockX = %d \n", blkOriginY>>2, blkOriginX>>2);
    5949           0 :         update_segmentation_map(picture_control_set_ptr, bsize, blkOriginX, blkOriginY, pred);
    5950           0 :         cu_ptr->segment_id = pred;
    5951           0 :         return;
    5952             :     }
    5953           0 :     const int coded_id = eb_av1_neg_interleave(cu_ptr->segment_id, pred, segmentationParams->last_active_seg_id + 1);
    5954           0 :     struct segmentation_probs *segp = &frameContext->seg;
    5955           0 :     AomCdfProb *pred_cdf = segp->spatial_pred_seg_cdf[cdf_num];
    5956           0 :     aom_write_symbol(ecWriter, coded_id, pred_cdf, MAX_SEGMENTS);
    5957           0 :     update_segmentation_map(picture_control_set_ptr, bsize, blkOriginX, blkOriginY, cu_ptr->segment_id);
    5958             : //    SVT_LOG("BlockY = %d, BlockX = %d, Segmentation  pred = %d, skip_coeff = %d, coded_id = %d, pred_cdf = %d \n", blkOriginY>>2, blkOriginX>>2, pred, skip_coeff, coded_id, *pred_cdf);
    5959             : }
    5960             : 
    5961             : 
    5962       57921 : void write_inter_segment_id(PictureControlSet *picture_control_set_ptr,
    5963             :                             FRAME_CONTEXT *frameContext,
    5964             :                             AomWriter *ecWriter,
    5965             :                             const BlockGeom *blockGeom,
    5966             :                             uint32_t blkOriginX,
    5967             :                             uint32_t blkOriginY,
    5968             :                             CodingUnit *cu_ptr,
    5969             :                             EbBool skip,
    5970             :                             int pre_skip) {
    5971       57921 :     SegmentationParams *segmentationParams = &picture_control_set_ptr->parent_pcs_ptr->frm_hdr.segmentation_params;
    5972       57921 :     if (!segmentationParams->segmentation_enabled)
    5973       57922 :         return;
    5974             : 
    5975           0 :     if (segmentationParams->segmentation_update_map) {
    5976           0 :         if (pre_skip) {
    5977           0 :             if (!segmentationParams->seg_id_pre_skip)
    5978           0 :                 return;
    5979             :         } else {
    5980           0 :             if (segmentationParams->seg_id_pre_skip)
    5981           0 :                 return;
    5982           0 :             if (skip) {
    5983           0 :                 write_segment_id(picture_control_set_ptr, frameContext, ecWriter, blockGeom->bsize, blkOriginX,
    5984             :                                  blkOriginY, cu_ptr, 1);
    5985           0 :                 if (segmentationParams->segmentation_temporal_update){
    5986           0 :                     printf("ERROR: Temporal update is not supported yet! \n");
    5987           0 :                     assert(0);
    5988             : //                    cu_ptr->seg_id_predicted = 0;
    5989             :                 }
    5990           0 :                 return;
    5991             :             }
    5992             :         }
    5993             : 
    5994           0 :         if (segmentationParams->segmentation_temporal_update) {
    5995           0 :             printf("ERROR: Temporal update is not supported yet! \n");
    5996           0 :             assert(0);
    5997             : //            const int pred_flag = cu_ptr->seg_id_predicted;
    5998             : //            aom_cdf_prob *pred_cdf = av1_get_pred_cdf_seg_id(picture_control_set_ptr, frameContext, cu_ptr, blkOriginX, blkOriginY);
    5999             : //            aom_write_symbol(ecWriter, pred_flag, pred_cdf, 2);
    6000             : //            if (!pred_flag) {
    6001             : //                WriteSegmentId(picture_control_set_ptr, frameContext, ecWriter, blockGeom->bsize, blkOriginX, blkOriginY, cu_ptr, 0);
    6002             : //            }
    6003             : //            if (pred_flag) {2
    6004             : //                update_segmentation_map(picture_control_set_ptr, blockGeom->bsize, blkOriginX, blkOriginY, cu_ptr->segment_id);
    6005             : //            }
    6006             : //            neighbor_array_unit_mode_write(
    6007             : //                    picture_control_set_ptr->segmentation_id_pred_array,
    6008             : //                    &(cu_ptr->segment_id),
    6009             : //                    blkOriginX,
    6010             : //                    blkOriginY,
    6011             : //                    blockGeom->bwidth,
    6012             : //                    blockGeom->bheight,
    6013             : //                    NEIGHBOR_ARRAY_UNIT_FULL_MASK);
    6014             : 
    6015             :         } else {
    6016           0 :             write_segment_id(picture_control_set_ptr, frameContext, ecWriter, blockGeom->bsize, blkOriginX, blkOriginY,
    6017             :                              cu_ptr, 0);
    6018             :         }
    6019             : 
    6020             : 
    6021             :     }
    6022             : 
    6023             : 
    6024             : }
    6025             : 
    6026             : #if II_COMP_FLAG
    6027        9107 : static INLINE int is_interintra_allowed_bsize(const BlockSize bsize) {
    6028        9107 :     return (bsize >= BLOCK_8X8) && (bsize <= BLOCK_32X32);
    6029             : }
    6030             : 
    6031        5770 : static INLINE int is_interintra_allowed_mode(const PredictionMode mode) {
    6032        5770 :     return (mode >= SINGLE_INTER_MODE_START) && (mode < SINGLE_INTER_MODE_END);
    6033             : }
    6034             : 
    6035        3692 : static INLINE int is_interintra_allowed_ref(const MvReferenceFrame rf[2]) {
    6036        3692 :     return (rf[0] > INTRA_FRAME) && (rf[1] <= INTRA_FRAME);
    6037             : }
    6038             : 
    6039        9107 : static INLINE int is_interintra_allowed(const MbModeInfo *mbmi) {
    6040       14877 :   return is_interintra_allowed_bsize(mbmi->block_mi.sb_type) &&
    6041       14877 :          is_interintra_allowed_mode(mbmi->block_mi.mode) &&
    6042        3692 :          is_interintra_allowed_ref(mbmi->block_mi.ref_frame);
    6043             : }
    6044             : 
    6045             : int is_interintra_wedge_used(BlockSize sb_type);
    6046             : #endif
    6047             : 
    6048       33844 : EbErrorType write_modes_b(
    6049             :     PictureControlSet     *picture_control_set_ptr,
    6050             :     EntropyCodingContext  *context_ptr,
    6051             :     EntropyCoder          *entropy_coder_ptr,
    6052             :     LargestCodingUnit     *tb_ptr,
    6053             :     CodingUnit            *cu_ptr,
    6054             :     EbPictureBufferDesc   *coeff_ptr)
    6055             : {
    6056             :     UNUSED(tb_ptr);
    6057       33844 :     EbErrorType return_error = EB_ErrorNone;
    6058       33844 :     FRAME_CONTEXT           *frameContext = entropy_coder_ptr->fc;
    6059       33844 :     AomWriter              *ec_writer = &entropy_coder_ptr->ec_writer;
    6060       33844 :     SequenceControlSet     *sequence_control_set_ptr = (SequenceControlSet*)picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
    6061       33844 :     FrameHeader *frm_hdr = &picture_control_set_ptr->parent_pcs_ptr->frm_hdr;
    6062             : 
    6063       33844 :     NeighborArrayUnit     *mode_type_neighbor_array = picture_control_set_ptr->mode_type_neighbor_array;
    6064       33844 :     NeighborArrayUnit     *intra_luma_mode_neighbor_array = picture_control_set_ptr->intra_luma_mode_neighbor_array;
    6065       33844 :     NeighborArrayUnit     *skip_flag_neighbor_array = picture_control_set_ptr->skip_flag_neighbor_array;
    6066       33844 :     NeighborArrayUnit     *skip_coeff_neighbor_array = picture_control_set_ptr->skip_coeff_neighbor_array;
    6067       33844 :     NeighborArrayUnit     *luma_dc_sign_level_coeff_neighbor_array = picture_control_set_ptr->luma_dc_sign_level_coeff_neighbor_array;
    6068       33844 :     NeighborArrayUnit     *cr_dc_sign_level_coeff_neighbor_array = picture_control_set_ptr->cr_dc_sign_level_coeff_neighbor_array;
    6069       33844 :     NeighborArrayUnit     *cb_dc_sign_level_coeff_neighbor_array = picture_control_set_ptr->cb_dc_sign_level_coeff_neighbor_array;
    6070       33844 :     NeighborArrayUnit     *ref_frame_type_neighbor_array = picture_control_set_ptr->ref_frame_type_neighbor_array;
    6071       33844 :     NeighborArrayUnit32   *interpolation_type_neighbor_array = picture_control_set_ptr->interpolation_type_neighbor_array;
    6072       33844 :     NeighborArrayUnit     *txfm_context_array = picture_control_set_ptr->txfm_context_array;
    6073       33844 :     const BlockGeom          *blk_geom = get_blk_geom_mds(cu_ptr->mds_idx);
    6074       33845 :     uint32_t blkOriginX = context_ptr->sb_origin_x + blk_geom->origin_x;
    6075       33845 :     uint32_t blkOriginY = context_ptr->sb_origin_y + blk_geom->origin_y;
    6076       33845 :     BlockSize bsize = blk_geom->bsize;
    6077       33845 :     EbBool                   skipCoeff = EB_FALSE;
    6078       33845 :     skipCoeff = cu_ptr->block_has_coeff ? 0 : 1;
    6079             : 
    6080       33845 : assert(bsize < BlockSizeS_ALL);
    6081       33842 :     int32_t mi_row = blkOriginY >> MI_SIZE_LOG2;
    6082       33842 :     int32_t mi_col = blkOriginX >> MI_SIZE_LOG2;
    6083       33842 :     int mi_stride = picture_control_set_ptr->parent_pcs_ptr->av1_cm->mi_stride;
    6084       33842 :     const int32_t offset = mi_row * mi_stride + mi_col;
    6085       33842 :     cu_ptr->av1xd->mi = picture_control_set_ptr->parent_pcs_ptr->av1_cm->pcs_ptr->mi_grid_base + offset;
    6086       33842 :     ModeInfo *mi_ptr = *cu_ptr->av1xd->mi;
    6087             : 
    6088       33842 :     cu_ptr->av1xd->tile.mi_col_start = tb_ptr->tile_info.mi_col_start;
    6089       33842 :     cu_ptr->av1xd->tile.mi_col_end = tb_ptr->tile_info.mi_col_end;
    6090       33842 :     cu_ptr->av1xd->tile.mi_row_start = tb_ptr->tile_info.mi_row_start;
    6091       33842 :     cu_ptr->av1xd->tile.mi_row_end = tb_ptr->tile_info.mi_row_end;
    6092       33842 :     cu_ptr->av1xd->up_available = (mi_row > tb_ptr->tile_info.mi_row_start);
    6093       33842 :     cu_ptr->av1xd->left_available = (mi_col > tb_ptr->tile_info.mi_col_start);
    6094       33842 :     if (cu_ptr->av1xd->up_available)
    6095       31649 :         cu_ptr->av1xd->above_mbmi = &mi_ptr[-mi_stride].mbmi;
    6096             :     else
    6097        2193 :         cu_ptr->av1xd->above_mbmi = NULL;
    6098       33842 :     if (cu_ptr->av1xd->left_available)
    6099       31865 :         cu_ptr->av1xd->left_mbmi = &mi_ptr[-1].mbmi;
    6100             :     else
    6101        1977 :         cu_ptr->av1xd->left_mbmi = NULL;
    6102       33842 :     cu_ptr->av1xd->tile_ctx = frameContext;
    6103       33842 :     if (picture_control_set_ptr->slice_type == I_SLICE) {
    6104             :         //const int32_t skip = write_skip(cm, xd, mbmi->segment_id, mi, w)
    6105             : 
    6106        4876 :         if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.segmentation_params.segmentation_enabled &&
    6107           0 :             picture_control_set_ptr->parent_pcs_ptr->frm_hdr.segmentation_params.seg_id_pre_skip)
    6108           0 :             write_segment_id(picture_control_set_ptr, frameContext, ec_writer, blk_geom->bsize, blkOriginX, blkOriginY,
    6109             :                              cu_ptr,
    6110             :                              skipCoeff);
    6111             : 
    6112        4876 :         EncodeSkipCoeffAv1(
    6113             :             frameContext,
    6114             :             ec_writer,
    6115             :             skipCoeff,
    6116             :             blkOriginX,
    6117             :             blkOriginY,
    6118             :             skip_coeff_neighbor_array);
    6119             : 
    6120        4876 :         if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.segmentation_params.segmentation_enabled &&
    6121           0 :             !picture_control_set_ptr->parent_pcs_ptr->frm_hdr.segmentation_params.seg_id_pre_skip)
    6122           0 :             write_segment_id(picture_control_set_ptr, frameContext, ec_writer, blk_geom->bsize, blkOriginX, blkOriginY,
    6123             :                              cu_ptr,
    6124             :                              skipCoeff);
    6125             : 
    6126        4876 :         write_cdef(
    6127             :             sequence_control_set_ptr,
    6128             :             picture_control_set_ptr,
    6129             :             cu_ptr->av1xd,
    6130             :             ec_writer,
    6131             :             skipCoeff,
    6132        4876 :             blkOriginX >> MI_SIZE_LOG2,
    6133        4876 :             blkOriginY >> MI_SIZE_LOG2);
    6134             : 
    6135             : #if ADD_DELTA_QP_SUPPORT //PART 1
    6136        4876 :         if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.delta_q_params.delta_q_present) {
    6137        4876 :             int32_t current_q_index = quantizer_to_qindex[cu_ptr->qp];
    6138        5747 :             int32_t super_block_upper_left = (((blkOriginY >> 2) & (sequence_control_set_ptr->seq_header.sb_mi_size - 1)) == 0) &&
    6139         871 :                 (((blkOriginX >> 2) & (sequence_control_set_ptr->seq_header.sb_mi_size - 1)) == 0);
    6140        4876 :             if ((bsize != sequence_control_set_ptr->seq_header.sb_size || skipCoeff == 0) && super_block_upper_left) {
    6141         239 :                 assert(current_q_index > 0);
    6142         239 :                 int32_t reduced_delta_qindex = (current_q_index - picture_control_set_ptr->parent_pcs_ptr->prev_qindex) / frm_hdr->delta_q_params.delta_q_res;
    6143             : 
    6144             :                 //write_delta_qindex(xd, reduced_delta_qindex, w);
    6145         239 :                 Av1writeDeltaQindex(
    6146             :                     frameContext,
    6147             :                     reduced_delta_qindex,
    6148             :                     ec_writer);
    6149             :                 /*if (picture_control_set_ptr->picture_number == 0){
    6150             :                 printf("%d\t%d\t%d\t%d\n",
    6151             :                 blkOriginX,
    6152             :                 blkOriginY,
    6153             :                 current_q_index,
    6154             :                 picture_control_set_ptr->parent_pcs_ptr->prev_qindex);
    6155             :                 }*/
    6156         239 :                 picture_control_set_ptr->parent_pcs_ptr->prev_qindex = current_q_index;
    6157             :             }
    6158             :         }
    6159             : #endif
    6160             : 
    6161             :         {
    6162        4876 :             const uint32_t intra_luma_mode = cu_ptr->pred_mode;
    6163        4876 :             uint32_t intra_chroma_mode = cu_ptr->prediction_unit_array->intra_chroma_mode;
    6164             : 
    6165        4876 :             if (av1_allow_intrabc(picture_control_set_ptr->parent_pcs_ptr->av1_cm))
    6166           0 :                 write_intrabc_info(frameContext, cu_ptr, ec_writer);
    6167             : 
    6168        4876 :             if (cu_ptr->av1xd->use_intrabc == 0)
    6169        4876 :             EncodeIntraLumaModeAv1(
    6170             :                 frameContext,
    6171             :                 ec_writer,
    6172             :                 cu_ptr,
    6173             :                 blkOriginX,
    6174             :                 blkOriginY,
    6175             :                 bsize,
    6176             :                 intra_luma_mode,
    6177             :                 mode_type_neighbor_array,
    6178             :                 intra_luma_mode_neighbor_array);
    6179             : 
    6180        4876 :             neighbor_array_unit_mode_write(
    6181             :                 intra_luma_mode_neighbor_array,
    6182             :                 (uint8_t*)&intra_luma_mode,
    6183             :                 blkOriginX,
    6184             :                 blkOriginY,
    6185        4876 :                 blk_geom->bwidth,
    6186        4876 :                 blk_geom->bheight,
    6187             :                 NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    6188             : 
    6189        4876 :             if (cu_ptr->av1xd->use_intrabc == 0)
    6190        4876 :                 if (blk_geom->has_uv)
    6191        3977 :                     EncodeIntraChromaModeAv1(
    6192             :                         frameContext,
    6193             :                         ec_writer,
    6194             :                         cu_ptr,
    6195             :                         bsize,
    6196             :                         intra_luma_mode,
    6197             :                         intra_chroma_mode,
    6198        3977 :                         blk_geom->bwidth <= 32 && blk_geom->bheight <= 32);
    6199             : 
    6200        4876 :             if (cu_ptr->av1xd->use_intrabc == 0 && av1_allow_palette(frm_hdr->allow_screen_content_tools, blk_geom->bsize))
    6201           0 :                 write_palette_mode_info(
    6202             : #if PAL_SUP
    6203           0 :                     picture_control_set_ptr->parent_pcs_ptr,
    6204             : #endif
    6205             :                     frameContext,
    6206             :                     cu_ptr,
    6207           0 :                     blk_geom->bsize,
    6208           0 :                     blkOriginY >> MI_SIZE_LOG2,
    6209           0 :                     blkOriginX >> MI_SIZE_LOG2,
    6210             :                     ec_writer);
    6211             : 
    6212             : #if FILTER_INTRA_FLAG
    6213             : #if PAL_SUP
    6214        4876 :     if (cu_ptr->av1xd->use_intrabc == 0 && av1_filter_intra_allowed(sequence_control_set_ptr->seq_header.enable_filter_intra, bsize,cu_ptr->palette_info.pmi.palette_size[0], intra_luma_mode)) {
    6215             : #else
    6216             :             if (cu_ptr->av1xd->use_intrabc == 0 &&  av1_filter_intra_allowed(sequence_control_set_ptr->seq_header.enable_filter_intra,bsize, intra_luma_mode)) {
    6217             : #endif
    6218        1496 :                 aom_write_symbol(ec_writer, cu_ptr->filter_intra_mode != FILTER_INTRA_MODES,
    6219        1496 :                     frameContext->filter_intra_cdfs[bsize], 2);
    6220        1496 :                 if (cu_ptr->filter_intra_mode != FILTER_INTRA_MODES) {
    6221        1105 :                     aom_write_symbol(ec_writer, cu_ptr->filter_intra_mode, frameContext->filter_intra_mode_cdf,
    6222             :                         FILTER_INTRA_MODES);
    6223             :                 }
    6224             :             }
    6225             : #endif
    6226             : #if PAL_SUP
    6227        4876 :         if(cu_ptr->av1xd->use_intrabc == 0)
    6228             :         {
    6229        4876 :             assert(cu_ptr->palette_info.pmi.palette_size[1] == 0);
    6230        4876 :             TOKENEXTRA *tok = context_ptr->tok;
    6231       14628 :             for (int plane = 0; plane < 2; ++plane) {
    6232        9752 :                 const uint8_t palette_size_plane =
    6233             :                     cu_ptr->palette_info.pmi.palette_size[plane];
    6234        9752 :                 if (palette_size_plane > 0) {
    6235           0 :                     const MbModeInfo *const mbmi = &cu_ptr->av1xd->mi[0]->mbmi;
    6236           0 :                     av1_tokenize_color_map(frameContext, cu_ptr, plane, &tok, bsize, mbmi->tx_size,
    6237             :                         PALETTE_MAP, 0); //NO CDF update in entropy, the update will take place in arithmetic encode
    6238             : 
    6239           0 :                     assert(cu_ptr->av1xd->use_intrabc == 0);
    6240           0 :                     assert(av1_allow_palette(picture_control_set_ptr->parent_pcs_ptr->frm_hdr.allow_screen_content_tools, blk_geom->bsize));
    6241             :                     int rows, cols;
    6242           0 :                     av1_get_block_dimensions(blk_geom->bsize, plane, cu_ptr->av1xd, NULL, NULL, &rows,
    6243             :                         &cols);
    6244           0 :                     pack_map_tokens(ec_writer, (const TOKENEXTRA **)(&context_ptr->tok), palette_size_plane, rows * cols);
    6245             :                     //advance the pointer
    6246           0 :                     context_ptr->tok = tok;
    6247             :                 }
    6248             :             }
    6249             :         }
    6250             : #endif
    6251        4876 :             if (frm_hdr->tx_mode == TX_MODE_SELECT) {
    6252        3112 :                 code_tx_size(
    6253             :                     picture_control_set_ptr,
    6254             :                     blkOriginX,
    6255             :                     blkOriginY,
    6256             :                     cu_ptr,
    6257             :                     blk_geom,
    6258             :                     txfm_context_array,
    6259             :                     frameContext,
    6260             :                     ec_writer,
    6261             :                     skipCoeff);
    6262             :             }
    6263        4876 :             if (!skipCoeff) {
    6264        4175 :                 Av1EncodeCoeff1D(
    6265             :                     picture_control_set_ptr,
    6266             :                     context_ptr,
    6267             :                     frameContext,
    6268             :                     ec_writer,
    6269             :                     cu_ptr,
    6270             :                     blkOriginX,
    6271             :                     blkOriginY,
    6272             :                     intra_luma_mode,
    6273             :                     bsize,
    6274             :                     coeff_ptr,
    6275             :                     luma_dc_sign_level_coeff_neighbor_array,
    6276             :                     cr_dc_sign_level_coeff_neighbor_array,
    6277             :                     cb_dc_sign_level_coeff_neighbor_array);
    6278             :             }
    6279             :         }
    6280             :     }
    6281             :     else {
    6282       28966 :         write_inter_segment_id(picture_control_set_ptr, frameContext, ec_writer, blk_geom, blkOriginX, blkOriginY,
    6283             :                                cu_ptr,
    6284             :                                0, 1);
    6285       28966 :         if (picture_control_set_ptr->parent_pcs_ptr->skip_mode_flag && is_comp_ref_allowed(bsize)) {
    6286       20149 :             EncodeSkipModeAv1(
    6287             :                 frameContext,
    6288             :                 ec_writer,
    6289       20149 :                 cu_ptr->skip_flag,
    6290             :                 blkOriginX,
    6291             :                 blkOriginY,
    6292             :                 skip_flag_neighbor_array);
    6293             :         }
    6294       28968 :         if (!picture_control_set_ptr->parent_pcs_ptr->skip_mode_flag && cu_ptr->skip_flag)
    6295           0 :             printf("ERROR[AN]: SKIP not supported\n");
    6296       28968 :         if (!cu_ptr->skip_flag) {
    6297             :             //const int32_t skip = write_skip(cm, xd, mbmi->segment_id, mi, w);
    6298       20993 :             EncodeSkipCoeffAv1(
    6299             :                 frameContext,
    6300             :                 ec_writer,
    6301             :                 skipCoeff,
    6302             :                 blkOriginX,
    6303             :                 blkOriginY,
    6304             :                 skip_coeff_neighbor_array);
    6305             :         }
    6306             : 
    6307       28967 :         write_inter_segment_id(picture_control_set_ptr, frameContext, ec_writer, blk_geom, blkOriginX, blkOriginY,
    6308             :                                cu_ptr,
    6309             :                                skipCoeff, 0);
    6310       28968 :         write_cdef(
    6311             :             sequence_control_set_ptr,
    6312             :             picture_control_set_ptr, /*cm,*/
    6313             :             cu_ptr->av1xd,
    6314             :             ec_writer,
    6315       28968 :             cu_ptr->skip_flag ? 1 : skipCoeff,
    6316       28968 :             blkOriginX >> MI_SIZE_LOG2,
    6317       28968 :             blkOriginY >> MI_SIZE_LOG2);
    6318             : #if ADD_DELTA_QP_SUPPORT//PART 2
    6319       28968 :         if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.delta_q_params.delta_q_present) {
    6320           0 :             int32_t current_q_index = quantizer_to_qindex[cu_ptr->qp];
    6321           0 :             int32_t super_block_upper_left = (((blkOriginY >> 2) & (sequence_control_set_ptr->seq_header.sb_mi_size - 1)) == 0) && (((blkOriginX >> 2) & (sequence_control_set_ptr->seq_header.sb_mi_size - 1)) == 0);
    6322           0 :             if ((bsize != sequence_control_set_ptr->seq_header.sb_size || skipCoeff == 0) && super_block_upper_left) {
    6323           0 :                 assert(current_q_index > 0);
    6324           0 :                 int32_t reduced_delta_qindex = (current_q_index - picture_control_set_ptr->parent_pcs_ptr->prev_qindex) / frm_hdr->delta_q_params.delta_q_res;
    6325           0 :                 Av1writeDeltaQindex(
    6326             :                     frameContext,
    6327             :                     reduced_delta_qindex,
    6328             :                     ec_writer);
    6329           0 :                 picture_control_set_ptr->parent_pcs_ptr->prev_qindex = current_q_index;
    6330             :             }
    6331             :         }
    6332             : 
    6333             : #endif
    6334       28968 :         if (frm_hdr->tx_mode == TX_MODE_SELECT) {
    6335        3051 :             if (cu_ptr->skip_flag) {
    6336           0 :                 code_tx_size(
    6337             :                     picture_control_set_ptr,
    6338             :                     blkOriginX,
    6339             :                     blkOriginY,
    6340             :                     cu_ptr,
    6341             :                     blk_geom,
    6342             :                     txfm_context_array,
    6343             :                     frameContext,
    6344             :                     ec_writer,
    6345           0 :                     cu_ptr->skip_flag);
    6346             :             }
    6347             :         }
    6348       28968 :         if (!cu_ptr->skip_flag) {
    6349             :             //write_is_inter(cm, xd, mbmi->segment_id, w, is_inter)
    6350       20992 :             EncodePredModeAv1(
    6351             :                 frameContext,
    6352             :                 ec_writer,
    6353       20992 :                 cu_ptr->prediction_mode_flag,
    6354             :                 blkOriginX,
    6355             :                 blkOriginY,
    6356             :                 mode_type_neighbor_array);
    6357             : 
    6358       20993 :             if (cu_ptr->prediction_mode_flag == INTRA_MODE) {
    6359        1542 :                 uint32_t intra_luma_mode = cu_ptr->pred_mode;
    6360        1542 :                 uint32_t intra_chroma_mode = cu_ptr->prediction_unit_array->intra_chroma_mode;
    6361             : 
    6362        1542 :                 EncodeIntraLumaModeNonKeyAv1(
    6363             :                     frameContext,
    6364             :                     ec_writer,
    6365             :                     cu_ptr,
    6366             :                     bsize,
    6367             :                     intra_luma_mode);
    6368             : 
    6369        1542 :                 neighbor_array_unit_mode_write(
    6370             :                     intra_luma_mode_neighbor_array,
    6371             :                     (uint8_t*)&intra_luma_mode,
    6372             :                     blkOriginX,
    6373             :                     blkOriginY,
    6374        1542 :                     blk_geom->bwidth,
    6375        1542 :                     blk_geom->bheight,
    6376             :                     NEIGHBOR_ARRAY_UNIT_TOP_AND_LEFT_ONLY_MASK);
    6377             : 
    6378        1542 :                 if (blk_geom->has_uv)
    6379        1370 :                     EncodeIntraChromaModeAv1(
    6380             :                         frameContext,
    6381             :                         ec_writer,
    6382             :                         cu_ptr,
    6383             :                         bsize,
    6384             :                         intra_luma_mode,
    6385             :                         intra_chroma_mode,
    6386        1370 :                         blk_geom->bwidth <= 32 && blk_geom->bheight <= 32);
    6387             : #if PAL_SUP
    6388        1542 :                 if ( av1_allow_palette(picture_control_set_ptr->parent_pcs_ptr->frm_hdr.allow_screen_content_tools, blk_geom->bsize))
    6389           0 :                     write_palette_mode_info(
    6390           0 :                         picture_control_set_ptr->parent_pcs_ptr,
    6391             :                         frameContext,
    6392             :                         cu_ptr,
    6393           0 :                         blk_geom->bsize,
    6394           0 :                         blkOriginY >> MI_SIZE_LOG2,
    6395           0 :                         blkOriginX >> MI_SIZE_LOG2,
    6396             :                         ec_writer);
    6397             : #endif
    6398             : #if FILTER_INTRA_FLAG
    6399             : #if PAL_SUP
    6400        1542 :     if ( av1_filter_intra_allowed(sequence_control_set_ptr->seq_header.enable_filter_intra, bsize, cu_ptr->palette_info.pmi.palette_size[0], intra_luma_mode)) {
    6401             : #else
    6402             :                 if (av1_filter_intra_allowed(sequence_control_set_ptr->seq_header.enable_filter_intra,bsize, intra_luma_mode)) {
    6403             : #endif
    6404         355 :                     aom_write_symbol(ec_writer, cu_ptr->filter_intra_mode != FILTER_INTRA_MODES,
    6405         355 :                        frameContext->filter_intra_cdfs[bsize], 2);
    6406         355 :                     if (cu_ptr->filter_intra_mode != FILTER_INTRA_MODES) {
    6407         276 :                         aom_write_symbol(ec_writer, cu_ptr->filter_intra_mode, frameContext->filter_intra_mode_cdf,
    6408             :                             FILTER_INTRA_MODES);
    6409             :                     }
    6410             :                 }
    6411             : #endif
    6412             :             }
    6413             :             else {
    6414       19451 :                 av1_collect_neighbors_ref_counts_new(cu_ptr->av1xd);
    6415             : 
    6416       19451 :                 write_ref_frames(
    6417             :                     frameContext,
    6418       19451 :                     picture_control_set_ptr->parent_pcs_ptr,
    6419       19451 :                     cu_ptr->av1xd,
    6420             :                     ec_writer);
    6421             : 
    6422             :                 MvReferenceFrame rf[2];
    6423       19451 :                 av1_set_ref_frame(rf, cu_ptr->prediction_unit_array[0].ref_frame_type);
    6424       19449 :                 int16_t mode_ctx = Av1ModeContextAnalyzer(cu_ptr->inter_mode_ctx, rf);
    6425       19448 :                 PredictionMode inter_mode = (PredictionMode)cu_ptr->prediction_unit_array[0].inter_mode;
    6426       19448 :                 const int32_t is_compound = (cu_ptr->prediction_unit_array[0].inter_pred_direction_index == BI_PRED);
    6427             : 
    6428             :                 // If segment skip is not enabled code the mode.
    6429             :                 if (1) {
    6430       19448 :                     if (is_inter_compound_mode(inter_mode)) {
    6431        7147 :                         WriteInterCompoundMode(
    6432             :                             frameContext,
    6433             :                             ec_writer,
    6434             :                             inter_mode,
    6435             :                             mode_ctx);
    6436             :                     }
    6437       12301 :                     else if (is_inter_singleref_mode(inter_mode))
    6438       12303 :                         WriteInterMode(
    6439             :                             frameContext,
    6440             :                             ec_writer,
    6441             :                             inter_mode,
    6442             :                             mode_ctx,
    6443             :                             blkOriginX,
    6444             :                             blkOriginY);
    6445             : 
    6446       19450 :                     if (inter_mode == NEWMV || inter_mode == NEW_NEWMV || have_nearmv_in_inter_mode(inter_mode)) {
    6447       13241 :                         WriteDrlIdx(
    6448             :                             frameContext,
    6449             :                             ec_writer,
    6450             :                             cu_ptr);
    6451             :                     }
    6452             :                 }
    6453             : 
    6454       28766 :                 if (inter_mode == NEWMV || inter_mode == NEW_NEWMV) {
    6455             :                     IntMv ref_mv;
    6456             : 
    6457       20861 :                     for (uint8_t ref = 0; ref < 1 + is_compound; ++ref) {
    6458       11546 :                         NmvContext *nmvc = &frameContext->nmvc;
    6459       11546 :                         ref_mv = cu_ptr->predmv[ref];
    6460             : 
    6461             :                         MV mv;
    6462       11546 :                         mv.row = cu_ptr->prediction_unit_array[0].mv[ref].y;
    6463       11546 :                         mv.col = cu_ptr->prediction_unit_array[0].mv[ref].x;
    6464       11546 :                         if (cu_ptr->prediction_unit_array[0].inter_pred_direction_index == UNI_PRED_LIST_1)
    6465             :                         {
    6466        2268 :                             mv.row = cu_ptr->prediction_unit_array[0].mv[1].y;
    6467        2268 :                             mv.col = cu_ptr->prediction_unit_array[0].mv[1].x;
    6468             :                         }
    6469             : 
    6470       11546 :                         eb_av1_encode_mv(
    6471       11546 :                             picture_control_set_ptr->parent_pcs_ptr,
    6472             :                             ec_writer,
    6473             :                             &mv,
    6474             :                             &ref_mv.as_mv,
    6475             :                             nmvc,
    6476       11546 :                             frm_hdr->allow_high_precision_mv);
    6477             :                     }
    6478             :                 }
    6479       10186 :                 else if (inter_mode == NEAREST_NEWMV || inter_mode == NEAR_NEWMV) {
    6480          50 :                     NmvContext *nmvc = &frameContext->nmvc;
    6481          50 :                     IntMv ref_mv = cu_ptr->predmv[1];
    6482             : 
    6483             :                     MV mv;
    6484          50 :                     mv.row = cu_ptr->prediction_unit_array[0].mv[1].y;
    6485          50 :                     mv.col = cu_ptr->prediction_unit_array[0].mv[1].x;
    6486             : 
    6487          50 :                     eb_av1_encode_mv(
    6488          50 :                         picture_control_set_ptr->parent_pcs_ptr,
    6489             :                         ec_writer,
    6490             :                         &mv,
    6491             :                         &ref_mv.as_mv,
    6492             :                         nmvc,
    6493          50 :                         frm_hdr->allow_high_precision_mv);
    6494             :                 }
    6495       10086 :                 else if (inter_mode == NEW_NEARESTMV || inter_mode == NEW_NEARMV) {
    6496          21 :                     NmvContext *nmvc = &frameContext->nmvc;
    6497          21 :                     IntMv ref_mv = cu_ptr->predmv[0];
    6498             : 
    6499             :                     MV mv;
    6500          21 :                     mv.row = cu_ptr->prediction_unit_array[0].mv[0].y;
    6501          21 :                     mv.col = cu_ptr->prediction_unit_array[0].mv[0].x;
    6502             : 
    6503          21 :                     eb_av1_encode_mv(
    6504          21 :                         picture_control_set_ptr->parent_pcs_ptr,
    6505             :                         ec_writer,
    6506             :                         &mv,
    6507             :                         &ref_mv.as_mv,
    6508             :                         nmvc,
    6509          21 :                         frm_hdr->allow_high_precision_mv);
    6510             :                 }
    6511             : #if II_COMP_FLAG
    6512             : 
    6513       19451 :                 MbModeInfo *mbmi = &mi_ptr->mbmi;
    6514             : 
    6515       19451 :                 if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.reference_mode != COMPOUND_REFERENCE &&
    6516       28558 :                     sequence_control_set_ptr->seq_header.enable_interintra_compound &&
    6517        9107 :                     is_interintra_allowed(mbmi)) {
    6518             : 
    6519        3692 :                     if (cu_ptr->is_interintra_used)
    6520             :                     {
    6521          82 :                         rf[1] = INTRA_FRAME;
    6522          82 :                          mbmi->block_mi.ref_frame[1] = INTRA_FRAME;
    6523             :                     }
    6524             : 
    6525             : 
    6526        3692 :                   const int interintra = cu_ptr->is_interintra_used;
    6527        3692 :                   const int bsize_group = size_group_lookup[bsize];
    6528        3692 :                   aom_write_symbol(ec_writer, cu_ptr->is_interintra_used, frameContext->interintra_cdf[bsize_group], 2);
    6529        3692 :                   if (interintra) {
    6530          82 :                     aom_write_symbol(ec_writer, cu_ptr->interintra_mode,
    6531          82 :                                      frameContext->interintra_mode_cdf[bsize_group],
    6532             :                                      INTERINTRA_MODES);
    6533          82 :                     if (is_interintra_wedge_used(bsize)) {
    6534          82 :                       aom_write_symbol(ec_writer, cu_ptr->use_wedge_interintra,
    6535          82 :                                        frameContext->wedge_interintra_cdf[bsize], 2);
    6536          82 :                       if (cu_ptr->use_wedge_interintra) {
    6537          22 :                         aom_write_symbol(ec_writer, cu_ptr->interintra_wedge_index,
    6538          22 :                                          frameContext->wedge_idx_cdf[bsize], 16);
    6539             :                       }
    6540             :                     }
    6541             :                   }
    6542             :                 }
    6543             : 
    6544             : #endif
    6545       19451 :                 if (frm_hdr->is_motion_mode_switchable
    6546        9107 :                     && rf[1] != INTRA_FRAME) {
    6547        9025 :                     write_motion_mode(
    6548             :                         frameContext,
    6549             :                         ec_writer,
    6550             :                         bsize,
    6551        9025 :                         cu_ptr->prediction_unit_array[0].motion_mode,
    6552        9025 :                         rf[0],
    6553        9025 :                         rf[1],
    6554             :                         cu_ptr,
    6555             :                         picture_control_set_ptr);
    6556             :                 }
    6557             :                 // First write idx to indicate current compound inter prediction mode group
    6558             :                 // Group A (0): dist_wtd_comp, compound_average
    6559             :                 // Group B (1): interintra, compound_diffwtd, wedge
    6560             : #if !II_COMP_FLAG
    6561             :                 MbModeInfo *mbmi = &mi_ptr->mbmi;
    6562             : #endif
    6563       19451 :                 if (has_second_ref(mbmi)) {
    6564             : 
    6565       14296 :                     const int masked_compound_used = is_any_masked_compound_used(bsize) &&
    6566        7148 :                         sequence_control_set_ptr->seq_header.enable_masked_compound;
    6567             : 
    6568        7148 :                     if (masked_compound_used) {
    6569        4146 :                         const int ctx_comp_group_idx = get_comp_group_idx_context_enc(cu_ptr->av1xd);
    6570        4146 :                         aom_write_symbol(ec_writer, cu_ptr->comp_group_idx,
    6571        4146 :                             frameContext->comp_group_idx_cdf[ctx_comp_group_idx], 2);
    6572             :                     }
    6573             :                     else {
    6574        3002 :                         assert(cu_ptr->comp_group_idx == 0);
    6575             :                     }
    6576             : 
    6577        7148 :                     if (cu_ptr->comp_group_idx == 0) {
    6578        6959 :                         if (cu_ptr->compound_idx)
    6579        5656 :                             assert(cu_ptr->interinter_comp.type == COMPOUND_AVERAGE);
    6580             : 
    6581        6959 :                         if (sequence_control_set_ptr->seq_header.order_hint_info.enable_jnt_comp) {
    6582        3957 :                             const int comp_index_ctx = get_comp_index_context_enc(
    6583        3957 :                                 picture_control_set_ptr->parent_pcs_ptr,
    6584        3957 :                                 picture_control_set_ptr->parent_pcs_ptr->cur_order_hint,// cur_frame_index,
    6585        3957 :                                 picture_control_set_ptr->parent_pcs_ptr->ref_order_hint[rf[0] - 1],// bck_frame_index,
    6586        3957 :                                 picture_control_set_ptr->parent_pcs_ptr->ref_order_hint[rf[1] - 1],// fwd_frame_index,
    6587        3957 :                                 cu_ptr->av1xd);
    6588        3957 :                             aom_write_symbol(ec_writer, cu_ptr->compound_idx,
    6589        3957 :                                 frameContext->compound_index_cdf[comp_index_ctx], 2);
    6590             :                         }
    6591             :                         else {
    6592        3002 :                             assert(cu_ptr->compound_idx == 1);
    6593             :                         }
    6594             :                     }
    6595             :                     else {
    6596         189 :                         assert(picture_control_set_ptr->parent_pcs_ptr->frm_hdr.reference_mode != SINGLE_REFERENCE &&
    6597             :                             is_inter_compound_mode(mbmi->block_mi.mode) &&
    6598             :                             cu_ptr->prediction_unit_array[0].motion_mode == SIMPLE_TRANSLATION);
    6599         189 :                         assert(masked_compound_used);
    6600             :                         // compound_diffwtd, wedge
    6601         189 :                         assert(cu_ptr->interinter_comp.type == COMPOUND_WEDGE ||
    6602             :                             cu_ptr->interinter_comp.type == COMPOUND_DIFFWTD);
    6603             : 
    6604         189 :                         if (is_interinter_compound_used(COMPOUND_WEDGE, bsize))
    6605         132 :                             aom_write_symbol(ec_writer, cu_ptr->interinter_comp.type - COMPOUND_WEDGE,
    6606         132 :                                 frameContext->compound_type_cdf[bsize],
    6607             :                                 MASKED_COMPOUND_TYPES);
    6608             : 
    6609         189 :                         if (cu_ptr->interinter_comp.type == COMPOUND_WEDGE) {
    6610          60 :                             assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize));
    6611          60 :                             aom_write_symbol(ec_writer, cu_ptr->interinter_comp.wedge_index,
    6612          60 :                                 frameContext->wedge_idx_cdf[bsize], 16);
    6613          60 :                             aom_write_bit(ec_writer, cu_ptr->interinter_comp.wedge_sign);
    6614             :                         }
    6615             :                         else {
    6616         129 :                             assert(cu_ptr->interinter_comp.type == COMPOUND_DIFFWTD);
    6617         129 :                             aom_write_literal(ec_writer, cu_ptr->interinter_comp.mask_type,
    6618             :                                 MAX_DIFFWTD_MASK_BITS);
    6619             :                         }
    6620             :                     }
    6621             :                 }
    6622             :                 // No filter for Global MV
    6623       19451 :                 write_mb_interp_filter(
    6624             :                     ref_frame_type_neighbor_array,
    6625             :                     bsize,
    6626       19451 :                     rf[0],
    6627       19451 :                     rf[1],
    6628       19451 :                     picture_control_set_ptr->parent_pcs_ptr,
    6629             :                     ec_writer,
    6630             :                     cu_ptr,
    6631             :                     entropy_coder_ptr,
    6632             :                     interpolation_type_neighbor_array,
    6633             :                     blkOriginX,
    6634             :                     blkOriginY
    6635             :                 );
    6636             :             }
    6637             : #if PAL_SUP
    6638             :             {
    6639       20992 :                 assert(cu_ptr->palette_info.pmi.palette_size[1] == 0);
    6640       20992 :                 TOKENEXTRA *tok = context_ptr->tok;
    6641       62978 :                 for (int plane = 0; plane < 2 ; ++plane) {
    6642       41986 :                     const uint8_t palette_size_plane =
    6643             :                         cu_ptr->palette_info.pmi.palette_size[plane];
    6644       41986 :                     if (palette_size_plane > 0) {
    6645           0 :                         const MbModeInfo *const mbmi = &cu_ptr->av1xd->mi[0]->mbmi;
    6646           0 :                         av1_tokenize_color_map(frameContext, cu_ptr, plane, &tok, bsize, mbmi->tx_size,
    6647             :                             PALETTE_MAP, 0); //NO CDF update in entropy, the update will take place in arithmetic encode
    6648           0 :                         assert(cu_ptr->av1xd->use_intrabc == 0);
    6649           0 :                         assert(av1_allow_palette(picture_control_set_ptr->parent_pcs_ptr->frm_hdr.allow_screen_content_tools, blk_geom->bsize));
    6650             :                         int rows, cols;
    6651           0 :                         av1_get_block_dimensions(blk_geom->bsize, plane, cu_ptr->av1xd, NULL, NULL, &rows,
    6652             :                             &cols);
    6653           0 :                         pack_map_tokens(ec_writer, (const TOKENEXTRA **)(&context_ptr->tok), palette_size_plane, rows * cols);
    6654             :                         //advance the pointer
    6655           0 :                         context_ptr->tok = tok;
    6656             :                     }
    6657             :                 }
    6658             :             }
    6659             : #endif
    6660       20992 :             if (frm_hdr->tx_mode == TX_MODE_SELECT) {
    6661        3051 :                 code_tx_size(
    6662             :                     picture_control_set_ptr,
    6663             :                     blkOriginX,
    6664             :                     blkOriginY,
    6665             :                     cu_ptr,
    6666             :                     blk_geom,
    6667             :                     txfm_context_array,
    6668             :                     frameContext,
    6669             :                     ec_writer,
    6670             :                     skipCoeff);
    6671             :             }
    6672       20992 :             if (!skipCoeff) {
    6673        8123 :                 uint32_t intra_luma_mode = DC_PRED;
    6674        8123 :                 if (cu_ptr->prediction_mode_flag == INTRA_MODE)
    6675        1397 :                     intra_luma_mode = (uint32_t)cu_ptr->pred_mode;
    6676             : 
    6677             :                 {
    6678        8123 :                     Av1EncodeCoeff1D(
    6679             :                         picture_control_set_ptr,
    6680             :                         context_ptr,
    6681             :                         frameContext,
    6682             :                         ec_writer,
    6683             :                         cu_ptr,
    6684             :                         blkOriginX,
    6685             :                         blkOriginY,
    6686             :                         intra_luma_mode,
    6687             :                         bsize,
    6688             :                         coeff_ptr,
    6689             :                         luma_dc_sign_level_coeff_neighbor_array,
    6690             :                         cr_dc_sign_level_coeff_neighbor_array,
    6691             :                         cb_dc_sign_level_coeff_neighbor_array);
    6692             :                 }
    6693             :             }
    6694             :         }
    6695             :     }
    6696             :     // Update the neighbors
    6697       33844 :     ec_update_neighbors(
    6698             :         picture_control_set_ptr,
    6699             :         context_ptr,
    6700             :         blkOriginX,
    6701             :         blkOriginY,
    6702             :         cu_ptr,
    6703             :         bsize,
    6704             :         coeff_ptr);
    6705             : 
    6706             : #if PAL_SUP
    6707       33841 :     if (svt_av1_allow_palette(picture_control_set_ptr->parent_pcs_ptr->palette_mode, blk_geom->bsize)) {
    6708           0 :         assert(cu_ptr->palette_info.color_idx_map != NULL && "free palette:Null");
    6709           0 :         free(cu_ptr->palette_info.color_idx_map);
    6710           0 :         cu_ptr->palette_info.color_idx_map = NULL;
    6711             :     }
    6712             : #endif
    6713       33841 :     return return_error;
    6714             : }
    6715             : /**********************************************
    6716             : * Write sb
    6717             : **********************************************/
    6718        7200 : EB_EXTERN EbErrorType write_sb(
    6719             :     EntropyCodingContext  *context_ptr,
    6720             :     LargestCodingUnit     *tb_ptr,
    6721             :     PictureControlSet     *picture_control_set_ptr,
    6722             :     EntropyCoder          *entropy_coder_ptr,
    6723             :     EbPictureBufferDesc   *coeff_ptr)
    6724             : {
    6725        7200 :     EbErrorType return_error = EB_ErrorNone;
    6726        7200 :     FRAME_CONTEXT           *frameContext = entropy_coder_ptr->fc;
    6727        7200 :     AomWriter              *ec_writer = &entropy_coder_ptr->ec_writer;
    6728        7200 :     SequenceControlSet     *sequence_control_set_ptr = (SequenceControlSet*)picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
    6729        7200 :     NeighborArrayUnit     *partition_context_neighbor_array = picture_control_set_ptr->partition_context_neighbor_array;
    6730             : 
    6731             :     // CU Varaiables
    6732             :     const BlockGeom          *blk_geom;
    6733             :     CodingUnit             *cu_ptr;
    6734        7200 :     uint32_t                    cu_index = 0;
    6735        7200 :     uint32_t                    final_cu_index = 0;
    6736             :     uint32_t                    cu_origin_x;
    6737             :     uint32_t                    cu_origin_y;
    6738             :     BlockSize                bsize;
    6739             : 
    6740        7200 :     context_ptr->coded_area_sb = 0;
    6741        7200 :     context_ptr->coded_area_sb_uv = 0;
    6742        7200 :     EbBool checkCuOutOfBound = EB_FALSE;
    6743             : 
    6744        7200 :     SbGeom * sb_geom = &sequence_control_set_ptr->sb_geom[tb_ptr->index];// .block_is_inside_md_scan[blk_index])
    6745             : 
    6746        7200 :     if (!(sb_geom->is_complete_sb))
    6747        1200 :         checkCuOutOfBound = EB_TRUE;
    6748             :     do {
    6749      263098 :         EbBool codeCuCond = EB_TRUE; // Code cu only if it is inside the picture
    6750             : 
    6751      263098 :         cu_ptr = &tb_ptr->final_cu_arr[final_cu_index];
    6752             : 
    6753      263098 :         blk_geom = get_blk_geom_mds(cu_index); // AMIR to be replaced with /*cu_ptr->mds_idx*/
    6754             : 
    6755      263057 :         bsize = blk_geom->bsize;
    6756      263057 :         assert(bsize < BlockSizeS_ALL);
    6757      263057 :         cu_origin_x = context_ptr->sb_origin_x + blk_geom->origin_x;
    6758      263057 :         cu_origin_y = context_ptr->sb_origin_y + blk_geom->origin_y;
    6759      263057 :         if (checkCuOutOfBound) {
    6760      237844 :             if (blk_geom->shape != PART_N)
    6761      135936 :                 blk_geom = get_blk_geom_mds(blk_geom->sqi_mds);
    6762      237880 :             codeCuCond = EB_FALSE;
    6763      237880 :             if (((cu_origin_x + blk_geom->bwidth / 2 < sequence_control_set_ptr->seq_header.max_frame_width) || (cu_origin_y + blk_geom->bheight / 2 < sequence_control_set_ptr->seq_header.max_frame_height)) &&
    6764      237154 :                 cu_origin_x < sequence_control_set_ptr->seq_header.max_frame_width && cu_origin_y < sequence_control_set_ptr->seq_header.max_frame_height)
    6765       14116 :                 codeCuCond = EB_TRUE;
    6766             :         }
    6767             : 
    6768      263093 :         if (codeCuCond) {
    6769       39365 :             uint32_t blkOriginX = cu_origin_x;
    6770       39365 :             uint32_t blkOriginY = cu_origin_y;
    6771             : 
    6772       39365 :             const int32_t hbs = mi_size_wide[bsize] >> 1;
    6773       39365 :             const int32_t quarter_step = mi_size_wide[bsize] >> 2;
    6774       39365 :             Av1Common* cm = picture_control_set_ptr->parent_pcs_ptr->av1_cm;
    6775       39365 :             int32_t mi_row = blkOriginY >> MI_SIZE_LOG2;
    6776       39365 :             int32_t mi_col = blkOriginX >> MI_SIZE_LOG2;
    6777             : 
    6778       39365 :             if (bsize >= BLOCK_8X8) {
    6779      156039 :                 for (int32_t plane = 0; plane < 3; ++plane) {
    6780             :                     int32_t rcol0, rcol1, rrow0, rrow1, tile_tl_idx;
    6781      117016 :                     if (eb_av1_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize,
    6782             :                         &rcol0, &rcol1, &rrow0, &rrow1,
    6783             :                         &tile_tl_idx)) {
    6784         192 :                         const int32_t rstride = cm->rst_info[plane].horz_units_per_tile;
    6785         384 :                         for (int32_t rrow = rrow0; rrow < rrow1; ++rrow) {
    6786         384 :                             for (int32_t rcol = rcol0; rcol < rcol1; ++rcol) {
    6787         192 :                                 const int32_t runit_idx = tile_tl_idx + rcol + rrow * rstride;
    6788         192 :                                 const RestorationUnitInfo *rui =
    6789         192 :                                     &cm->rst_info[plane].unit_info[runit_idx];
    6790         192 :                                 loop_restoration_write_sb_coeffs(picture_control_set_ptr, frameContext, cm, /*xd,*/ rui, ec_writer, plane);
    6791             :                             }
    6792             :                         }
    6793             :                     }
    6794             :                 }
    6795             : 
    6796             :                 // Code Split Flag
    6797       39023 :                 EncodePartitionAv1(
    6798             :                     sequence_control_set_ptr,
    6799             :                     frameContext,
    6800             :                     ec_writer,
    6801             :                     bsize,
    6802       39023 :                     tb_ptr->cu_partition_array[cu_index],
    6803             :                     blkOriginX,
    6804             :                     blkOriginY,
    6805             :                     partition_context_neighbor_array);
    6806             :             }
    6807             : 
    6808       39373 :             switch (tb_ptr->cu_partition_array[cu_index]) {
    6809       26434 :             case PARTITION_NONE:
    6810       26434 :                 write_modes_b(
    6811             :                     picture_control_set_ptr,
    6812             :                     context_ptr,
    6813             :                     entropy_coder_ptr,
    6814             :                     tb_ptr,
    6815             :                     cu_ptr,
    6816             :                     coeff_ptr);
    6817       26431 :                 break;
    6818             : 
    6819         782 :             case PARTITION_HORZ:
    6820         782 :                 write_modes_b(
    6821             :                     picture_control_set_ptr,
    6822             :                     context_ptr,
    6823             :                     entropy_coder_ptr,
    6824             :                     tb_ptr,
    6825             :                     cu_ptr,
    6826             :                     coeff_ptr);
    6827             : 
    6828         782 :                 if (mi_row + hbs < cm->mi_rows) {
    6829         782 :                     final_cu_index++;
    6830         782 :                     cu_ptr = &tb_ptr->final_cu_arr[final_cu_index];
    6831         782 :                     write_modes_b(
    6832             :                         picture_control_set_ptr,
    6833             :                         context_ptr,
    6834             :                         entropy_coder_ptr,
    6835             :                         tb_ptr,
    6836             :                         cu_ptr,
    6837             :                         coeff_ptr);
    6838             :                 }
    6839         782 :                 break;
    6840             : 
    6841         635 :             case PARTITION_VERT:
    6842         635 :                 write_modes_b(
    6843             :                     picture_control_set_ptr,
    6844             :                     context_ptr,
    6845             :                     entropy_coder_ptr,
    6846             :                     tb_ptr,
    6847             :                     cu_ptr,
    6848             :                     coeff_ptr);
    6849         635 :                 if (mi_col + hbs < cm->mi_cols) {
    6850         635 :                     final_cu_index++;
    6851         635 :                     cu_ptr = &tb_ptr->final_cu_arr[final_cu_index];
    6852         635 :                     write_modes_b(
    6853             :                         picture_control_set_ptr,
    6854             :                         context_ptr,
    6855             :                         entropy_coder_ptr,
    6856             :                         tb_ptr,
    6857             :                         cu_ptr,
    6858             :                         coeff_ptr);
    6859             :                 }
    6860         635 :                 break;
    6861       10168 :             case PARTITION_SPLIT:
    6862       10168 :                 break;
    6863         174 :             case PARTITION_HORZ_A:
    6864         174 :                 write_modes_b(
    6865             :                     picture_control_set_ptr,
    6866             :                     context_ptr,
    6867             :                     entropy_coder_ptr,
    6868             :                     tb_ptr,
    6869             :                     cu_ptr,
    6870             :                     coeff_ptr);
    6871             : 
    6872         174 :                 final_cu_index++;
    6873         174 :                 cu_ptr = &tb_ptr->final_cu_arr[final_cu_index];
    6874         174 :                 write_modes_b(
    6875             :                     picture_control_set_ptr,
    6876             :                     context_ptr,
    6877             :                     entropy_coder_ptr,
    6878             :                     tb_ptr,
    6879             :                     cu_ptr,
    6880             :                     coeff_ptr);
    6881             : 
    6882         174 :                 final_cu_index++;
    6883         174 :                 cu_ptr = &tb_ptr->final_cu_arr[final_cu_index];
    6884         174 :                 write_modes_b(
    6885             :                     picture_control_set_ptr,
    6886             :                     context_ptr,
    6887             :                     entropy_coder_ptr,
    6888             :                     tb_ptr,
    6889             :                     cu_ptr,
    6890             :                     coeff_ptr);
    6891             : 
    6892         174 :                 break;
    6893         166 :             case PARTITION_HORZ_B:
    6894         166 :                 write_modes_b(
    6895             :                     picture_control_set_ptr,
    6896             :                     context_ptr,
    6897             :                     entropy_coder_ptr,
    6898             :                     tb_ptr,
    6899             :                     cu_ptr,
    6900             :                     coeff_ptr);
    6901             : 
    6902         166 :                 final_cu_index++;
    6903         166 :                 cu_ptr = &tb_ptr->final_cu_arr[final_cu_index];
    6904         166 :                 write_modes_b(
    6905             :                     picture_control_set_ptr,
    6906             :                     context_ptr,
    6907             :                     entropy_coder_ptr,
    6908             :                     tb_ptr,
    6909             :                     cu_ptr,
    6910             :                     coeff_ptr);
    6911             : 
    6912         166 :                 final_cu_index++;
    6913         166 :                 cu_ptr = &tb_ptr->final_cu_arr[final_cu_index];
    6914         166 :                 write_modes_b(
    6915             :                     picture_control_set_ptr,
    6916             :                     context_ptr,
    6917             :                     entropy_coder_ptr,
    6918             :                     tb_ptr,
    6919             :                     cu_ptr,
    6920             :                     coeff_ptr);
    6921             : 
    6922         166 :                 break;
    6923         308 :             case PARTITION_VERT_A:
    6924         308 :                 write_modes_b(
    6925             :                     picture_control_set_ptr,
    6926             :                     context_ptr,
    6927             :                     entropy_coder_ptr,
    6928             :                     tb_ptr,
    6929             :                     cu_ptr,
    6930             :                     coeff_ptr);
    6931             : 
    6932         308 :                 final_cu_index++;
    6933         308 :                 cu_ptr = &tb_ptr->final_cu_arr[final_cu_index];
    6934         308 :                 write_modes_b(
    6935             :                     picture_control_set_ptr,
    6936             :                     context_ptr,
    6937             :                     entropy_coder_ptr,
    6938             :                     tb_ptr,
    6939             :                     cu_ptr,
    6940             :                     coeff_ptr);
    6941             : 
    6942         308 :                 final_cu_index++;
    6943         308 :                 cu_ptr = &tb_ptr->final_cu_arr[final_cu_index];
    6944         308 :                 write_modes_b(
    6945             :                     picture_control_set_ptr,
    6946             :                     context_ptr,
    6947             :                     entropy_coder_ptr,
    6948             :                     tb_ptr,
    6949             :                     cu_ptr,
    6950             :                     coeff_ptr);
    6951             : 
    6952         308 :                 break;
    6953         192 :             case PARTITION_VERT_B:
    6954         192 :                 write_modes_b(
    6955             :                     picture_control_set_ptr,
    6956             :                     context_ptr,
    6957             :                     entropy_coder_ptr,
    6958             :                     tb_ptr,
    6959             :                     cu_ptr,
    6960             :                     coeff_ptr);
    6961             : 
    6962         192 :                 final_cu_index++;
    6963         192 :                 cu_ptr = &tb_ptr->final_cu_arr[final_cu_index];
    6964         192 :                 write_modes_b(
    6965             :                     picture_control_set_ptr,
    6966             :                     context_ptr,
    6967             :                     entropy_coder_ptr,
    6968             :                     tb_ptr,
    6969             :                     cu_ptr,
    6970             :                     coeff_ptr);
    6971             : 
    6972         192 :                 final_cu_index++;
    6973         192 :                 cu_ptr = &tb_ptr->final_cu_arr[final_cu_index];
    6974         192 :                 write_modes_b(
    6975             :                     picture_control_set_ptr,
    6976             :                     context_ptr,
    6977             :                     entropy_coder_ptr,
    6978             :                     tb_ptr,
    6979             :                     cu_ptr,
    6980             :                     coeff_ptr);
    6981             : 
    6982         192 :                 break;
    6983         229 :             case PARTITION_HORZ_4:
    6984        1145 :                 for (int32_t i = 0; i < 4; ++i) {
    6985         916 :                     int32_t this_mi_row = mi_row + i * quarter_step;
    6986         916 :                     if (i > 0 && this_mi_row >= cm->mi_rows) break;
    6987             : 
    6988         916 :                     if (i > 0) {
    6989         687 :                         final_cu_index++;
    6990         687 :                         cu_ptr = &tb_ptr->final_cu_arr[final_cu_index];
    6991             :                     }
    6992         916 :                     write_modes_b(
    6993             :                         picture_control_set_ptr,
    6994             :                         context_ptr,
    6995             :                         entropy_coder_ptr,
    6996             :                         tb_ptr,
    6997             :                         cu_ptr,
    6998             :                         coeff_ptr);
    6999             :                 }
    7000         229 :                 break;
    7001         285 :             case PARTITION_VERT_4:
    7002        1425 :                 for (int32_t i = 0; i < 4; ++i) {
    7003        1140 :                     int32_t this_mi_col = mi_col + i * quarter_step;
    7004        1140 :                     if (i > 0 && this_mi_col >= cm->mi_cols) break;
    7005        1140 :                     if (i > 0) {
    7006         855 :                         final_cu_index++;
    7007         855 :                         cu_ptr = &tb_ptr->final_cu_arr[final_cu_index];
    7008             :                     }
    7009        1140 :                     write_modes_b(
    7010             :                         picture_control_set_ptr,
    7011             :                         context_ptr,
    7012             :                         entropy_coder_ptr,
    7013             :                         tb_ptr,
    7014             :                         cu_ptr,
    7015             :                         coeff_ptr);
    7016             :                 }
    7017         285 :                 break;
    7018           0 :             default: assert(0);
    7019             :             }
    7020             : 
    7021       39370 :             if (tb_ptr->cu_partition_array[cu_index] != PARTITION_SPLIT) {
    7022       29202 :                 final_cu_index++;
    7023       29202 :                 cu_index += ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    7024             :             }
    7025             :             else
    7026       10168 :                 cu_index += d1_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    7027             :         }
    7028             :         else
    7029      223728 :             ++cu_index;
    7030      263098 :     } while (cu_index < sequence_control_set_ptr->max_block_cnt);
    7031        7200 :     return return_error;
    7032             : }

Generated by: LCOV version 1.14