Skip to content
Snippets Groups Projects
VLCReader.cpp 208 KiB
Newer Older
  • Learn to ignore specific revisions
  • /* The copyright in this software is being made available under the BSD
    
    Hendry's avatar
    Hendry committed
    * License, included below. This software may be subject to other third party
    * and contributor rights, including patent rights, and no such rights are
    * granted under this license.
    *
    
    * Copyright (c) 2010-2025, ITU/ISO/IEC
    
    Hendry's avatar
    Hendry committed
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions are met:
    *
    *  * Redistributions of source code must retain the above copyright notice,
    *    this list of conditions and the following disclaimer.
    *  * Redistributions in binary form must reproduce the above copyright notice,
    *    this list of conditions and the following disclaimer in the documentation
    *    and/or other materials provided with the distribution.
    *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
    *    be used to endorse or promote products derived from this software without
    *    specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
    * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
    * THE POSSIBILITY OF SUCH DAMAGE.
    */
    
    
    /** \file     VLCWReader.cpp
     *  \brief    Reader for high level syntax
     */
    
    //! \ingroup DecoderLib
    //! \{
    
    #include "VLCReader.h"
    
    #include "CommonLib/CommonDef.h"
    #include "CommonLib/dtrace_next.h"
    #if RExt__DECODER_DEBUG_BIT_STATISTICS
    #include "CommonLib/CodingStatistics.h"
    #endif
    #include "CommonLib/AdaptiveLoopFilter.h"
    
    #include "CommonLib/ProfileTierLevel.h"
    
    // ====================================================================================================================
    // Protected member functions
    // ====================================================================================================================
    
    #if ENABLE_TRACING || RExt__DECODER_DEBUG_BIT_STATISTICS
    void  VLCReader::xReadCode( const uint32_t length, uint32_t& value, const char *symbolName )
    
    void  VLCReader::xReadCode( const uint32_t length, uint32_t& value, const char* )
    
      CHECK(length == 0, "Reading a code of length '0'");
      m_pcBitstream->read(length, value);
    
    #if RExt__DECODER_DEBUG_BIT_STATISTICS
    
      CodingStatistics::IncrementStatisticEP(symbolName, length, value);
    
    #if ENABLE_TRACING
      if (length < 10)
      {
    
        DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d)  : %u\n", symbolName, length, value );
    
        DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %u\n", symbolName, length, value );
    
    #if ENABLE_TRACING || RExt__DECODER_DEBUG_BIT_STATISTICS
    void  VLCReader::xReadUvlc(uint32_t& value, const char *symbolName )
    
    void  VLCReader::xReadUvlc(uint32_t& value, const char* )
    
      uint32_t suffix    = 0;
      uint32_t prefixBit = 0;
      m_pcBitstream->read( 1, prefixBit );
    
    Taoran Lu's avatar
    Taoran Lu committed
    
    
    Hendry's avatar
    Hendry committed
      uint32_t totalLen=1;
    
      if( 0 == prefixBit )
    
        uint32_t length = 0;
    
        while( prefixBit == 0 )
    
          m_pcBitstream->read( 1, prefixBit );
    
          length++;
    
        m_pcBitstream->read(length, suffix);
        suffix += (1 << length) - 1;
    
        totalLen += length + length;
    
      value = suffix;
    
    
      CodingStatistics::IncrementStatisticEP(symbolName, int(totalLen), value);
    #endif
    
    #if ENABLE_TRACING
      DTRACE( g_trace_ctx, D_HEADER, "%-50s ue(v) : %u\n", symbolName, value );
    
    #if ENABLE_TRACING || RExt__DECODER_DEBUG_BIT_STATISTICS
    
    void  VLCReader::xReadSvlc( int& value, const char *symbolName )
    
    #else
    void  VLCReader::xReadSvlc( int& value, const char* )
    #endif
    
      uint32_t prefixBit = 0;
      uint32_t suffix = 0;
    
    #if RExt__DECODER_DEBUG_BIT_STATISTICS
      uint32_t totalLen=1;
    #endif
    
      m_pcBitstream->read(1, prefixBit);
    
      if (0 == prefixBit)
      {
        uint32_t length = 0;
    
        while ( prefixBit == 0 )
        {
          m_pcBitstream->read(1, prefixBit);
          length++;
        }
    
        m_pcBitstream->read(length, suffix);
    
        suffix += (1 << length);
        value = (suffix & 1) ? -(int) (suffix >> 1) : (int) (suffix >> 1);
    
    #if RExt__DECODER_DEBUG_BIT_STATISTICS
        totalLen += length + length;
    #endif
      }
      else
      {
        value = 0;
      }
    #if RExt__DECODER_DEBUG_BIT_STATISTICS
      CodingStatistics::IncrementStatisticEP(symbolName, int(totalLen), suffix);
    #endif
    
    
    #if ENABLE_TRACING
      DTRACE( g_trace_ctx, D_HEADER, "%-50s se(v) : %d\n", symbolName, value );
    
    #if ENABLE_TRACING || RExt__DECODER_DEBUG_BIT_STATISTICS
    void VLCReader::xReadFlag( uint32_t& value, const char *symbolName )
    
    void VLCReader::xReadFlag( uint32_t& value, const char* )
    
      m_pcBitstream->read( 1, value );
    
    
      CodingStatistics::IncrementStatisticEP(symbolName, 1, int(/*ruiCode*/0));
    #endif
    
    #if ENABLE_TRACING
      DTRACE( g_trace_ctx, D_HEADER, "%-50s u(1)  : %d\n", symbolName, value );
    
    
    #if ENABLE_TRACING || RExt__DECODER_DEBUG_BIT_STATISTICS
    
    void VLCReader::xReadString( std::string& valueOut, const char *symbolName )
    
    void VLCReader::xReadString( std::string& valueOut, const char*  )
    
      uint32_t code;
    
      std::string value( "" );;
    
        m_pcBitstream->read(8, code);
    
        if (code != 0)
        {
          value += (char) code;
        }
      } while (code != 0);
    
    
    #if ENABLE_TRACING
      DTRACE(g_trace_ctx, D_HEADER, "%-50s u(1)  : %s\n", symbolName, value.c_str());
    #endif
    
    }
    
    #if RExt__DECODER_DEBUG_BIT_STATISTICS || ENABLE_TRACING
    void VLCReader::xReadSCode (const uint32_t length, int& value, const char *symbolName )
    #else
    void VLCReader::xReadSCode (const uint32_t length, int& value, const char* )
    #endif
    {
      uint32_t val;
    
      CHECK ( length < 1 || length > 32, "Syntax element length must be in range 1..32");
    
      m_pcBitstream->read (length, val);
    
      value = length>=32 ? int(val) : ( (-int( val & (uint32_t(1)<<(length-1)))) | int(val) );
    
    
    #if RExt__DECODER_DEBUG_BIT_STATISTICS
      CodingStatistics::IncrementStatisticEP(symbolName, length, value);
    #endif
    #if ENABLE_TRACING
      if (length < 10)
      {
        DTRACE( g_trace_ctx, D_HEADER, "%-50s i(%d)  : %d\n", symbolName, length, value );
    
      else
      {
        DTRACE( g_trace_ctx, D_HEADER, "%-50s i(%d) : %d\n", symbolName, length, value );
      }
    #endif
    
      xReadFlag( bit, "rbsp_stop_one_bit");
    
    Hendry's avatar
    Hendry committed
      CHECK(bit!=1, "Trailing bit not '1'");
    
      int cnt = 0;
      while (m_pcBitstream->getNumBitsUntilByteAligned())
      {
    
        xReadFlag( bit, "rbsp_alignment_zero_bit");
    
    Hendry's avatar
    Hendry committed
        CHECK(bit!=0, "Alignment bit is not '0'");
    
        cnt++;
      }
      CHECK(cnt >= 8, "Read more than '8' trailing bits");
    }
    
    
    void AUDReader::parseAccessUnitDelimiter(InputBitstream* bs, uint32_t &audIrapOrGdrAuFlag, uint32_t &picType)
    
    {
      setBitstream(bs);
    
    #if ENABLE_TRACING
      xTraceAccessUnitDelimiter();
    #endif
    
    
      xReadFlag (audIrapOrGdrAuFlag, "aud_irap_or_gdr_au_flag");
      xReadCode (3, picType, "pic_type");
    
    Hendry's avatar
    Hendry committed
    void FDReader::parseFillerData(InputBitstream* bs, uint32_t &fdSize)
    
    {
      setBitstream(bs);
    #if ENABLE_TRACING
      xTraceFillerData();
    #endif
      uint32_t ffByte;
      fdSize = 0;
    
    Hendry's avatar
    Hendry committed
      while( m_pcBitstream->getNumBitsLeft() >8 )
    
        xReadCode (8, ffByte, "ff_byte");
    
    Hendry's avatar
    Hendry committed
        CHECK(ffByte!=0xff, "Invalid filler data : not '0xff'");
    
        fdSize++;
      }
      xReadRbspTrailingBits();
    }
    
    // ====================================================================================================================
    // Constructor / destructor / create / destroy
    // ====================================================================================================================
    
    
    Hendry's avatar
    Hendry committed
    HLSyntaxReader::HLSyntaxReader()
    {
    }
    
    HLSyntaxReader::~HLSyntaxReader()
    {
    
    Hendry's avatar
    Hendry committed
    }
    
    
    // ====================================================================================================================
    // Public member functions
    // ====================================================================================================================
    
    
    void HLSyntaxReader::copyRefPicList(SPS* sps, ReferencePictureList* sourceRpl, ReferencePictureList* destRpl)
    
      destRpl->setNumberOfShorttermPictures(sourceRpl->getNumberOfShorttermPictures());
    
      destRpl->setNumberOfInterLayerPictures(sps->getInterLayerPresentFlag() ? sourceRpl->getNumberOfInterLayerPictures()
                                                                             : 0);
    
    Hendry's avatar
    Hendry committed
      if( sps->getLongTermRefsPresent() )
    
        destRpl->setLtrpInSliceHeaderFlag(sourceRpl->getLtrpInSliceHeaderFlag());
        destRpl->setNumberOfLongtermPictures(sourceRpl->getNumberOfLongtermPictures());
    
    Hendry's avatar
    Hendry committed
      else
    
        destRpl->setNumberOfLongtermPictures(0);
    
      uint32_t numRefPic = destRpl->getNumRefEntries();
    
    Hendry's avatar
    Hendry committed
      for( int ii = 0; ii < numRefPic; ii++ )
    
        destRpl->setRefPicIdentifier(ii, sourceRpl->getRefPicIdentifier(ii), sourceRpl->isRefPicLongterm(ii),
                                     sourceRpl->isInterLayerRefPic(ii), sourceRpl->getInterLayerRefPicIdx(ii));
    
    Zhipin Deng's avatar
    Zhipin Deng committed
    void HLSyntaxReader::parseRefPicList(SPS* sps, ReferencePictureList* rpl, int rplIdx)
    
    Hendry's avatar
    Hendry committed
    {
      uint32_t code;
    
      xReadUvlc(code, "num_ref_entries[ listIdx ][ rplsIdx ]");
    
    Hendry's avatar
    Hendry committed
      uint32_t numRefPic = code;
    
    Hendry's avatar
    Hendry committed
      uint32_t numStrp = 0;
      uint32_t numLtrp = 0;
      uint32_t numIlrp = 0;
    
      if (sps->getLongTermRefsPresent() && numRefPic > 0 && rplIdx != -1)
    
        xReadFlag(code, "ltrp_in_slice_header_flag[ listIdx ][ rplsIdx ]");
    
    Zhipin Deng's avatar
    Zhipin Deng committed
      {
    
    Zhipin Deng's avatar
    Zhipin Deng committed
      }
    
    Hendry's avatar
    Hendry committed
      bool isLongTerm;
    
    Hendry's avatar
    Hendry committed
      int prevDelta = MAX_INT;
      int deltaValue = 0;
      bool firstSTRP = true;
    
    Hendry's avatar
    Hendry committed
      rpl->setInterLayerPresentFlag( sps->getInterLayerPresentFlag() );
    
    Hendry's avatar
    Hendry committed
      for (int ii = 0; ii < numRefPic; ii++)
      {
    
        uint32_t isInterLayerRefPic = 0;
    
    
    Hendry's avatar
    Hendry committed
        if( rpl->getInterLayerPresentFlag() )
    
          xReadFlag( isInterLayerRefPic, "inter_layer_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]" );
    
    Hendry's avatar
    Hendry committed
          if( isInterLayerRefPic )
    
            xReadUvlc( code, "ilrp_idx[ listIdx ][ rplsIdx ][ i ]" );
    
    Hendry's avatar
    Hendry committed
            rpl->setRefPicIdentifier( ii, 0, true, true, code );
    
    Hendry's avatar
    Hendry committed
        if( !isInterLayerRefPic )
    
    Hendry's avatar
    Hendry committed
          isLongTerm = false;
    
          if (sps->getLongTermRefsPresent())
    
            xReadFlag(code, "st_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]");
    
            isLongTerm = (code == 1) ? false : true;
    
    
          if (!isLongTerm)
    
            xReadUvlc(code, "abs_delta_poc_st[ listIdx ][ rplsIdx ][ i ]");
    
            if ((!sps->getUseWP() && !sps->getUseWPBiPred()) || (ii == 0))
            {
              code++;
            }
            int readValue = code;
            if (readValue > 0)
            {
    
              xReadFlag(code, "strp_entry_sign_flag[ listIdx ][ rplsIdx ][ i ]");
    
              if (code)
              {
                readValue = -readValue;
              }
            }
            if (firstSTRP)
            {
              firstSTRP = false;
              prevDelta = deltaValue = readValue;
            }
            else
            {
              deltaValue = prevDelta + readValue;
              prevDelta  = deltaValue;
            }
    
            rpl->setRefPicIdentifier(ii, deltaValue, isLongTerm, false, 0);
            numStrp++;
    
            if (!rpl->getLtrpInSliceHeaderFlag())
            {
    
              xReadCode(sps->getBitsForPOC(), code, "poc_lsb_lt[listIdx][rplsIdx][j]");
    
            }
            rpl->setRefPicIdentifier(ii, code, isLongTerm, false, 0);
            numLtrp++;
    
    Hendry's avatar
    Hendry committed
      }
      rpl->setNumberOfShorttermPictures(numStrp);
      rpl->setNumberOfLongtermPictures(numLtrp);
    
    Hendry's avatar
    Hendry committed
      rpl->setNumberOfInterLayerPictures( numIlrp );
    
    Hendry's avatar
    Hendry committed
    void HLSyntaxReader::parsePPS( PPS* pcPPS )
    
    Hendry's avatar
    Hendry committed
      xTracePPSHeader ();
    
    Hendry's avatar
    Hendry committed
      uint32_t  uiCode;
    
    Hendry's avatar
    Hendry committed
      int   iCode;
    
      xReadCode(6, uiCode, "pps_pic_parameter_set_id");
    
      CHECK(uiCode > 63, "PPS id exceeds boundary (63)");
    
    Hendry's avatar
    Hendry committed
      pcPPS->setPPSId (uiCode);
    
      xReadCode(4, uiCode, "pps_seq_parameter_set_id");
    
    Hendry's avatar
    Hendry committed
      pcPPS->setSPSId (uiCode);
    
      xReadFlag( uiCode, "pps_mixed_nalu_types_in_pic_flag" );       pcPPS->setMixedNaluTypesInPicFlag( uiCode == 1 );
    
      xReadUvlc( uiCode, "pps_pic_width_in_luma_samples" );          pcPPS->setPicWidthInLumaSamples( uiCode );
      xReadUvlc( uiCode, "pps_pic_height_in_luma_samples" );         pcPPS->setPicHeightInLumaSamples( uiCode );
      xReadFlag( uiCode, "pps_conformance_window_flag");
    
      pcPPS->setConformanceWindowFlag( uiCode );
    
    Hendry's avatar
    Hendry committed
        Window& conf = pcPPS->getConformanceWindow();
    
        xReadUvlc(uiCode, "pps_conf_win_left_offset");               conf.setWindowLeftOffset(uiCode);
        xReadUvlc(uiCode, "pps_conf_win_right_offset");              conf.setWindowRightOffset(uiCode);
        xReadUvlc(uiCode, "pps_conf_win_top_offset");                conf.setWindowTopOffset(uiCode);
        xReadUvlc(uiCode, "pps_conf_win_bottom_offset");             conf.setWindowBottomOffset(uiCode);
    
      xReadFlag( uiCode, "pps_scaling_window_explicit_signalling_flag" );
    
      pcPPS->setExplicitScalingWindowFlag( uiCode );
    
    Hendry's avatar
    Hendry committed
      if( uiCode != 0 )
    
      {
        Window &scalingWindow = pcPPS->getScalingWindow();
    
        xReadSvlc( iCode, "pps_scaling_win_left_offset" );               scalingWindow.setWindowLeftOffset( iCode );
        xReadSvlc( iCode, "pps_scaling_win_right_offset" );              scalingWindow.setWindowRightOffset( iCode );
        xReadSvlc( iCode, "pps_scaling_win_top_offset" );                scalingWindow.setWindowTopOffset( iCode );
        xReadSvlc( iCode, "pps_scaling_win_bottom_offset" );             scalingWindow.setWindowBottomOffset( iCode );
    
        pcPPS->getScalingWindow() = pcPPS->getConformanceWindow();
    
      xReadFlag( uiCode, "pps_output_flag_present_flag" );                    pcPPS->setOutputFlagPresentFlag( uiCode==1 );
    
      xReadFlag( uiCode, "pps_no_pic_partition_flag");                     pcPPS->setNoPicPartitionFlag(uiCode == 1);
      xReadFlag( uiCode, "pps_subpic_id_mapping_present_flag" );           pcPPS->setSubPicIdMappingInPpsFlag( uiCode != 0 );
    
    Hendry's avatar
    Hendry committed
      if( pcPPS->getSubPicIdMappingInPpsFlag() )
    
    spaluri's avatar
    spaluri committed
        if( !pcPPS->getNoPicPartitionFlag() )
        {
    
          xReadUvlc(uiCode, "pps_num_subpics_minus1");                         pcPPS->setNumSubPics(uiCode + 1);
    
    spaluri's avatar
    spaluri committed
        }
        else
        {
          pcPPS->setNumSubPics(1);
        }
    
    Hendry's avatar
    Hendry committed
        CHECK( uiCode > MAX_NUM_SUB_PICS-1,  "Number of sub-pictures exceeds limit");
    
        xReadUvlc( uiCode, "pps_subpic_id_len_minus1" );                       pcPPS->setSubPicIdLen( uiCode + 1 );
    
    Hendry's avatar
    Hendry committed
        CHECK( uiCode > 15, "Invalid pps_subpic_id_len_minus1 signalled");
    
        CHECK((1 << pcPPS->getSubPicIdLen()) < pcPPS->getNumSubPics(), "pps_subpic_id_len exceeds valid range");
    
    Hendry's avatar
    Hendry committed
        for( int picIdx = 0; picIdx < pcPPS->getNumSubPics( ); picIdx++ )
    
          xReadCode( pcPPS->getSubPicIdLen( ), uiCode, "pps_subpic_id[i]" );   pcPPS->setSubPicId( picIdx, uiCode );
    
    Hendry's avatar
    Hendry committed
      if(!pcPPS->getNoPicPartitionFlag())
    
      {
        int colIdx, rowIdx;
        pcPPS->resetTileSliceInfo();
    
        // CTU size - required to match size in SPS
    
        xReadCode(2, uiCode, "pps_log2_ctu_size_minus5");                 pcPPS->setLog2CtuSize(uiCode + 5);
    
        CHECK(uiCode > 2, "pps_log2_ctu_size_minus5 must be less than or equal to 2");
    
        // number of explicit tile columns/rows
    
        xReadUvlc( uiCode, "pps_num_exp_tile_columns_minus1" );               pcPPS->setNumExpTileColumns( uiCode + 1 );
        xReadUvlc( uiCode, "pps_num_exp_tile_rows_minus1" );                  pcPPS->setNumExpTileRows( uiCode + 1 );
    
    Hendry's avatar
    Hendry committed
        CHECK(pcPPS->getNumExpTileColumns() > MAX_TILE_COLS,              "Number of explicit tile columns exceeds valid range");
    
        // tile sizes
    
    Hendry's avatar
    Hendry committed
        for( colIdx = 0; colIdx < pcPPS->getNumExpTileColumns(); colIdx++ )
    
          xReadUvlc( uiCode, "pps_tile_column_width_minus1[i]" );             pcPPS->addTileColumnWidth( uiCode + 1 );
    
          CHECK(uiCode  > (pcPPS->getPicWidthInCtu()-1),                 "The value of pps_tile_column_width_minus1[i] shall be in the range of 0 to PicWidthInCtbY-1, inclusive");
    
    Hendry's avatar
    Hendry committed
        for( rowIdx = 0; rowIdx < pcPPS->getNumExpTileRows(); rowIdx++ )
    
          xReadUvlc( uiCode, "pps_tile_row_height_minus1[i]" );               pcPPS->addTileRowHeight( uiCode + 1 );
    
          CHECK(uiCode > (pcPPS->getPicHeightInCtu() - 1),                "The value of pps_tile_row_height_minus shall be in the range of 0 to PicHeightInCtbY-1, inclusive");
    
        }
        pcPPS->initTiles();
        // rectangular slice signalling
    
        if (pcPPS->getNumTiles() > 1)
        {
    
          xReadCode(1, uiCode, "pps_loop_filter_across_tiles_enabled_flag");    pcPPS->setLoopFilterAcrossTilesEnabledFlag(uiCode == 1);
          xReadCode(1, uiCode, "pps_rect_slice_flag");
    
          pcPPS->setLoopFilterAcrossTilesEnabledFlag(false);
    
          uiCode = 1;
        }
        pcPPS->setRectSliceFlag(uiCode == 1);
    
        if (pcPPS->getRectSliceFlag())
    
          xReadFlag(uiCode, "pps_single_slice_per_subpic_flag");            pcPPS->setSingleSlicePerSubPicFlag(uiCode == 1);
    
        else
        {
          pcPPS->setSingleSlicePerSubPicFlag(0);
        }
    
        if (pcPPS->getRectSliceFlag() && !(pcPPS->getSingleSlicePerSubPicFlag()))
    
        {
          int32_t tileIdx = 0;
    
    
          xReadUvlc( uiCode, "pps_num_slices_in_pic_minus1" );                pcPPS->setNumSlicesInPic( uiCode + 1 );
    
    Hendry's avatar
    Hendry committed
          CHECK(pcPPS->getNumSlicesInPic() > MAX_SLICES,                  "Number of slices in picture exceeds valid range");
    
          if ((pcPPS->getNumSlicesInPic() - 1) > 1)
    
            xReadCode(1, uiCode, "pps_tile_idx_delta_present_flag");
    
            pcPPS->setTileIdxDeltaPresentFlag(uiCode == 1);
          }
          else
          {
            pcPPS->setTileIdxDeltaPresentFlag(0);
          }
    
          pcPPS->initRectSlices();
    
          // read rectangular slice parameters
    
    Hendry's avatar
    Hendry committed
          for( int i = 0; i < pcPPS->getNumSlicesInPic()-1; i++ )
    
    Hendry's avatar
    Hendry committed
            pcPPS->setSliceTileIdx( i, tileIdx );
    
    
            // complete tiles within a single slice
    
    spaluri's avatar
    spaluri committed
            if( ( tileIdx % pcPPS->getNumTileColumns() ) != pcPPS->getNumTileColumns() - 1 )
            {
    
              xReadUvlc( uiCode, "pps_slice_width_in_tiles_minus1[i]" );
    
    spaluri's avatar
    spaluri committed
              pcPPS->setSliceWidthInTiles ( i, uiCode + 1 );
            }
            else
            {
              pcPPS->setSliceWidthInTiles( i, 1 );
            }
    
    
            if( tileIdx / pcPPS->getNumTileColumns() != pcPPS->getNumTileRows() - 1  &&
    
    Frank Bossen's avatar
    Frank Bossen committed
             ( pcPPS->getTileIdxDeltaPresentFlag() || tileIdx % pcPPS->getNumTileColumns() == 0 ) )
    
    spaluri's avatar
    spaluri committed
            {
    
              xReadUvlc( uiCode, "pps_slice_height_in_tiles_minus1[i]" );
    
    spaluri's avatar
    spaluri committed
              pcPPS->setSliceHeightInTiles( i, uiCode + 1 );
            }
            else
            {
    
              if( ( tileIdx / pcPPS->getNumTileColumns() ) == pcPPS->getNumTileRows() - 1 )
    
    spaluri's avatar
    spaluri committed
              {
                pcPPS->setSliceHeightInTiles( i, 1 );
              }
              else
              {
                pcPPS->setSliceHeightInTiles( i, pcPPS->getSliceHeightInTiles( i - 1 ) );
              }
    
    
            // multiple slices within a single tile special case
    
    Hendry's avatar
    Hendry committed
            if( pcPPS->getSliceWidthInTiles(i) == 1 && pcPPS->getSliceHeightInTiles(i) == 1 )
    
    Hendry's avatar
    Hendry committed
            {
    
    Hendry's avatar
    Hendry committed
              if( pcPPS->getTileRowHeight(tileIdx / pcPPS->getNumTileColumns()) > 1 )
    
    Hendry's avatar
    Hendry committed
              {
    
                xReadUvlc(uiCode, "pps_num_exp_slices_in_tile[i]");
    
    Hendry's avatar
    Hendry committed
                if (uiCode == 0)
    
    Hendry's avatar
    Hendry committed
                  pcPPS->setNumSlicesInTile(i, 1);
                  pcPPS->setSliceHeightInCtu(i, pcPPS->getTileRowHeight(tileIdx / pcPPS->getNumTileColumns()));
    
    Hendry's avatar
    Hendry committed
                else
    
    Hendry's avatar
    Hendry committed
                  uint32_t numExpSliceInTile = uiCode;
                  uint32_t remTileRowHeight  = pcPPS->getTileRowHeight(tileIdx / pcPPS->getNumTileColumns());
                  int j = 0;
    
    Kai Zhang's avatar
    Kai Zhang committed
    
                  for( ; j < numExpSliceInTile; j++ )
    
    Hendry's avatar
    Hendry committed
                  {
    
                    xReadUvlc(uiCode, "pps_exp_slice_height_in_ctus_minus1[i]");
    
    Hendry's avatar
    Hendry committed
                    pcPPS->setSliceHeightInCtu(i + j, uiCode + 1);
                    remTileRowHeight -= (uiCode + 1);
                  }
                  uint32_t uniformSliceHeight = uiCode + 1;
    
                  while( remTileRowHeight >= uniformSliceHeight )
                  {
                    pcPPS->setSliceHeightInCtu(i + j, uniformSliceHeight);
                    remTileRowHeight -= uniformSliceHeight;
                    j++;
                  }
                  if( remTileRowHeight > 0 )
                  {
                    pcPPS->setSliceHeightInCtu(i + j, remTileRowHeight);
                    j++;
                  }
                  for( int k = 0; k < j; k++ )
                  {
                    pcPPS->setNumSlicesInTile(i + k, j);
                    pcPPS->setSliceWidthInTiles(i + k, 1);
                    pcPPS->setSliceHeightInTiles(i + k, 1);
                    pcPPS->setSliceTileIdx(i + k, tileIdx);
                  }
                  i += (j - 1);
    
    Hendry's avatar
    Hendry committed
              }
              else
              {
                pcPPS->setNumSlicesInTile(i, 1);
                pcPPS->setSliceHeightInCtu(i, pcPPS->getTileRowHeight(tileIdx / pcPPS->getNumTileColumns()));
    
    Hendry's avatar
    Hendry committed
              }
            }
    
            // tile index offset to start of next slice
    
    Hendry's avatar
    Hendry committed
            if( i < pcPPS->getNumSlicesInPic()-1 )
    
              if( pcPPS->getTileIdxDeltaPresentFlag() )
    
    Hendry's avatar
    Hendry committed
                int32_t  tileIdxDelta;
    
                xReadSvlc( tileIdxDelta, "pps_tile_idx_delta[i]" );
    
                tileIdx += tileIdxDelta;
    
                CHECK( tileIdx < 0 || tileIdx >= pcPPS->getNumTiles(), "Invalid pps_tile_idx_delta.");
    
    Hendry's avatar
    Hendry committed
                tileIdx += pcPPS->getSliceWidthInTiles( i );
                if( tileIdx % pcPPS->getNumTileColumns() == 0)
    
    Hendry's avatar
    Hendry committed
                  tileIdx += (pcPPS->getSliceHeightInTiles( i ) - 1) * pcPPS->getNumTileColumns();
    
    Hendry's avatar
    Hendry committed
          pcPPS->setSliceTileIdx(pcPPS->getNumSlicesInPic()-1, tileIdx );
    
        if (pcPPS->getRectSliceFlag() == 0 || pcPPS->getSingleSlicePerSubPicFlag() || pcPPS->getNumSlicesInPic() > 1)
        {
    
          xReadCode(1, uiCode, "pps_loop_filter_across_slices_enabled_flag");   pcPPS->setLoopFilterAcrossSlicesEnabledFlag( uiCode == 1 );
    
      xReadFlag( uiCode,   "pps_cabac_init_present_flag" );            pcPPS->setCabacInitPresentFlag( uiCode ? true : false );
    
      xReadUvlc(uiCode, "pps_num_ref_idx_default_active_minus1[0]");
    
    Frank Bossen's avatar
    Frank Bossen committed
      CHECK(uiCode >= MAX_NUM_ACTIVE_REF,
            "The value of pps_num_ref_idx_default_active_minus1[0] shall be in the range of 0 to 14, inclusive");
    
    Frank Bossen's avatar
    Frank Bossen committed
      pcPPS->setNumRefIdxDefaultActive(REF_PIC_LIST_0, uiCode + 1);
    
      xReadUvlc(uiCode, "pps_num_ref_idx_default_active_minus1[1]");
    
    Frank Bossen's avatar
    Frank Bossen committed
      CHECK(uiCode >= MAX_NUM_ACTIVE_REF,
            "The value of pps_num_ref_idx_default_active_minus1[1] shall be in the range of 0 to 14, inclusive");
    
    Frank Bossen's avatar
    Frank Bossen committed
      pcPPS->setNumRefIdxDefaultActive(REF_PIC_LIST_1, uiCode + 1);
    
      xReadFlag(uiCode, "pps_rpl1_idx_present_flag");
    
    Hendry's avatar
    Hendry committed
      pcPPS->setRpl1IdxPresentFlag(uiCode);
    
      xReadFlag( uiCode, "pps_weighted_pred_flag" );          // Use of Weighting Prediction (P_SLICE)
    
      pcPPS->setUseWP( uiCode==1 );
    
      xReadFlag( uiCode, "pps_weighted_bipred_flag" );         // Use of Bi-Directional Weighting Prediction (B_SLICE)
    
      pcPPS->setWPBiPred( uiCode==1 );
    
      xReadFlag(uiCode, "pps_ref_wraparound_enabled_flag");           pcPPS->setWrapAroundEnabledFlag( uiCode ? true : false );
    
      if (pcPPS->getWrapAroundEnabledFlag())
      {
    
        xReadUvlc(uiCode, "pps_ref_wraparound_offset");
    
        pcPPS->setPicWidthMinusWrapAroundOffset(uiCode);
      }
      else
      {
        pcPPS->setPicWidthMinusWrapAroundOffset(0);
      }
    
    Hendry's avatar
    Hendry committed
    
    
      xReadSvlc(iCode, "pps_init_qp_minus26" );                            pcPPS->setPicInitQPMinus26(iCode);
      xReadFlag( uiCode, "pps_cu_qp_delta_enabled_flag" );            pcPPS->setUseDQP( uiCode ? true : false );
      xReadFlag(uiCode, "pps_chroma_tool_offsets_present_flag");
    
      pcPPS->setPPSChromaToolFlag(uiCode ? true : false);
      if (pcPPS->getPPSChromaToolFlag())
      {
    
        xReadSvlc(iCode, "pps_cb_qp_offset");
    
        pcPPS->setQpOffset(COMPONENT_Cb, iCode);
        CHECK(pcPPS->getQpOffset(COMPONENT_Cb) < -12, "Invalid Cb QP offset");
        CHECK(pcPPS->getQpOffset(COMPONENT_Cb) > 12, "Invalid Cb QP offset");
    
        xReadSvlc(iCode, "pps_cr_qp_offset");
    
        pcPPS->setQpOffset(COMPONENT_Cr, iCode);
        CHECK(pcPPS->getQpOffset(COMPONENT_Cr) < -12, "Invalid Cr QP offset");
        CHECK(pcPPS->getQpOffset(COMPONENT_Cr) > 12, "Invalid Cr QP offset");
    
    U-EU\bray's avatar
    v1  
    U-EU\bray committed
    
    
        xReadFlag(uiCode, "pps_joint_cbcr_qp_offset_present_flag");
    
        pcPPS->setJointCbCrQpOffsetPresentFlag(uiCode ? true : false);
    
        if (pcPPS->getJointCbCrQpOffsetPresentFlag())
        {
    
          xReadSvlc(iCode, "pps_joint_cbcr_qp_offset_value");
    
        }
        else
        {
          iCode = 0;
        }
        pcPPS->setQpOffset(JOINT_CbCr, iCode);
    
        CHECK(pcPPS->getQpOffset(JOINT_CbCr) < -12, "Invalid CbCr QP offset");
        CHECK(pcPPS->getQpOffset(JOINT_CbCr) > 12, "Invalid CbCr QP offset");
    
        CHECK(MAX_NUM_COMPONENT > 3, "Invalid maximal number of components");
    
        xReadFlag(uiCode, "pps_slice_chroma_qp_offsets_present_flag");
    
        pcPPS->setSliceChromaQpFlag(uiCode ? true : false);
    
        xReadFlag(uiCode, "pps_cu_chroma_qp_offset_list_enabled_flag");
    
        if (uiCode == 0)
    
    Hendry's avatar
    Hendry committed
        {
    
          pcPPS->clearChromaQpOffsetList();
        }
        else
        {
          uint32_t tableSizeMinus1 = 0;
    
          xReadUvlc(tableSizeMinus1, "pps_chroma_qp_offset_list_len_minus1");
    
          CHECK(tableSizeMinus1 >= MAX_QP_OFFSET_LIST_SIZE, "Table size exceeds maximum");
    
          for (int cuChromaQpOffsetIdx = 0; cuChromaQpOffsetIdx <= (tableSizeMinus1); cuChromaQpOffsetIdx++)
    
    Hendry's avatar
    Hendry committed
          {
    
            int cbOffset;
            int crOffset;
            int jointCbCrOffset;
    
            xReadSvlc(cbOffset, "pps_cb_qp_offset_list[i]");
    
            CHECK(cbOffset < -12 || cbOffset > 12, "Invalid chroma QP offset");
    
            xReadSvlc(crOffset, "pps_cr_qp_offset_list[i]");
    
            CHECK(crOffset < -12 || crOffset > 12, "Invalid chroma QP offset");
            if (pcPPS->getJointCbCrQpOffsetPresentFlag())
            {
    
              xReadSvlc(jointCbCrOffset, "pps_joint_cbcr_qp_offset_list[i]");
    
            }
            else
            {
              jointCbCrOffset = 0;
            }
            CHECK(jointCbCrOffset < -12 || jointCbCrOffset > 12, "Invalid chroma QP offset");
            // table uses +1 for index (see comment inside the function)
            pcPPS->setChromaQpOffsetListEntry(cuChromaQpOffsetIdx + 1, cbOffset, crOffset, jointCbCrOffset);
    
    U-EU\bray's avatar
    v1  
    U-EU\bray committed
          }
    
          CHECK(pcPPS->getChromaQpOffsetListLen() != tableSizeMinus1 + 1, "Invalid chroma QP offset list length");
    
      }
      else
      {
        pcPPS->setQpOffset(COMPONENT_Cb, 0);
        pcPPS->setQpOffset(COMPONENT_Cr, 0);
        pcPPS->setJointCbCrQpOffsetPresentFlag(0);
        pcPPS->setSliceChromaQpFlag(0);
        pcPPS->clearChromaQpOffsetList();
      }
    
      xReadFlag( uiCode, "pps_deblocking_filter_control_present_flag" );       pcPPS->setDeblockingFilterControlPresentFlag( uiCode ? true : false );
    
    Hendry's avatar
    Hendry committed
      if(pcPPS->getDeblockingFilterControlPresentFlag())
    
        xReadFlag( uiCode, "pps_deblocking_filter_override_enabled_flag" );    pcPPS->setDeblockingFilterOverrideEnabledFlag( uiCode ? true : false );
        xReadFlag( uiCode, "pps_deblocking_filter_disabled_flag" );        pcPPS->setPPSDeblockingFilterDisabledFlag(uiCode ? true : false );
    
        if (!pcPPS->getNoPicPartitionFlag() && pcPPS->getDeblockingFilterOverrideEnabledFlag())
        {
    
          xReadFlag(uiCode, "pps_dbf_info_in_ph_flag");
    
          pcPPS->setDbfInfoInPhFlag(uiCode ? true : false);
        }
        else
        {
          pcPPS->setDbfInfoInPhFlag(false);
        }
    
    Hendry's avatar
    Hendry committed
        if(!pcPPS->getPPSDeblockingFilterDisabledFlag())
    
          xReadSvlc( iCode, "pps_beta_offset_div2" );                    pcPPS->setDeblockingFilterBetaOffsetDiv2( iCode );
    
    Hendry's avatar
    Hendry committed
          CHECK(  pcPPS->getDeblockingFilterBetaOffsetDiv2() < -12 ||
                  pcPPS->getDeblockingFilterBetaOffsetDiv2() > 12, "Invalid deblocking filter configuration" );
    
    
          xReadSvlc( iCode, "pps_tc_offset_div2");                       pcPPS->setDeblockingFilterTcOffsetDiv2( iCode );
    
    Hendry's avatar
    Hendry committed
          CHECK(  pcPPS->getDeblockingFilterTcOffsetDiv2() < -12 ||
                  pcPPS->getDeblockingFilterTcOffsetDiv2() > 12, "Invalid deblocking filter configuration" );
    
    
          if( pcPPS->getPPSChromaToolFlag() )
          {
    
            xReadSvlc( iCode, "pps_cb_beta_offset_div2" );                   pcPPS->setDeblockingFilterCbBetaOffsetDiv2( iCode );
    
            CHECK( pcPPS->getDeblockingFilterCbBetaOffsetDiv2() < -12 ||
              pcPPS->getDeblockingFilterCbBetaOffsetDiv2() > 12, "Invalid deblocking filter configuration" );
    
    Hendry's avatar
    Hendry committed
    
    
            xReadSvlc( iCode, "pps_cb_tc_offset_div2" );                     pcPPS->setDeblockingFilterCbTcOffsetDiv2( iCode );
    
            CHECK( pcPPS->getDeblockingFilterCbTcOffsetDiv2() < -12 ||
              pcPPS->getDeblockingFilterCbTcOffsetDiv2() > 12, "Invalid deblocking filter configuration" );
    
    Hendry's avatar
    Hendry committed
    
    
            xReadSvlc( iCode, "pps_cr_beta_offset_div2") ;                   pcPPS->setDeblockingFilterCrBetaOffsetDiv2( iCode );
    
            CHECK( pcPPS->getDeblockingFilterCrBetaOffsetDiv2() < -12 ||
              pcPPS->getDeblockingFilterCrBetaOffsetDiv2() > 12, "Invalid deblocking filter configuration" );
    
    Hendry's avatar
    Hendry committed
    
    
            xReadSvlc( iCode, "pps_cr_tc_offset_div2" );                     pcPPS->setDeblockingFilterCrTcOffsetDiv2( iCode );
    
            CHECK(pcPPS->getDeblockingFilterCrTcOffsetDiv2() < -12 ||
              pcPPS->getDeblockingFilterCrTcOffsetDiv2() > 12, "Invalid deblocking filter configuration");
          }
          else
          {
            pcPPS->setDeblockingFilterCbBetaOffsetDiv2 ( pcPPS->getDeblockingFilterBetaOffsetDiv2() );
            pcPPS->setDeblockingFilterCbTcOffsetDiv2   ( pcPPS->getDeblockingFilterTcOffsetDiv2()   );
            pcPPS->setDeblockingFilterCrBetaOffsetDiv2 ( pcPPS->getDeblockingFilterBetaOffsetDiv2() );
            pcPPS->setDeblockingFilterCrTcOffsetDiv2   ( pcPPS->getDeblockingFilterTcOffsetDiv2()   );
          }
    
      else
      {
        pcPPS->setDeblockingFilterOverrideEnabledFlag(false);
    
        pcPPS->setDbfInfoInPhFlag(false);
    
    Hendry's avatar
    Hendry committed
    
    
        xReadFlag(uiCode, "pps_rpl_info_in_ph_flag");                    pcPPS->setRplInfoInPhFlag(uiCode ? true : false);
        xReadFlag(uiCode, "pps_sao_info_in_ph_flag");                    pcPPS->setSaoInfoInPhFlag(uiCode ? true : false);
        xReadFlag(uiCode, "pps_alf_info_in_ph_flag");                    pcPPS->setAlfInfoInPhFlag(uiCode ? true : false);
    
        if ((pcPPS->getUseWP() || pcPPS->getWPBiPred()) && pcPPS->getRplInfoInPhFlag())
        {
    
          xReadFlag(uiCode, "pps_wp_info_in_ph_flag");                   pcPPS->setWpInfoInPhFlag(uiCode ? true : false);
    
        xReadFlag(uiCode, "pps_qp_delta_info_in_ph_flag");               pcPPS->setQpDeltaInfoInPhFlag(uiCode ? true : false);
    
        pcPPS->setRplInfoInPhFlag(false);
        pcPPS->setSaoInfoInPhFlag(false);
    
        pcPPS->setAlfInfoInPhFlag(false);
        pcPPS->setWpInfoInPhFlag(false);
        pcPPS->setQpDeltaInfoInPhFlag(false);
      }
    
      xReadFlag( uiCode, "pps_picture_header_extension_present_flag");
    
    Brian Heng's avatar
    Brian Heng committed
      pcPPS->setPictureHeaderExtensionPresentFlag(uiCode);
    
      xReadFlag( uiCode, "pps_slice_header_extension_present_flag");
    
      pcPPS->setSliceHeaderExtensionPresentFlag(uiCode);
    
    
      xReadFlag( uiCode, "pps_extension_flag");
    
        while (xMoreRbspData())
        {
    
          xReadFlag(uiCode, "pps_extension_data_flag");
    
    Hendry's avatar
    Hendry committed
    void HLSyntaxReader::parseAPS( APS* aps )
    
    Hendry's avatar
    Hendry committed
    {
    
    #if ENABLE_TRACING
      xTraceAPSHeader();
    #endif
    
    
    Hendry's avatar
    Hendry committed
      uint32_t  code;
    
      xReadCode(3, code, "aps_params_type");
    
      aps->setAPSType(ApsType(code));
    
    Hendry's avatar
    Hendry committed
    
    
      xReadCode(5, code, "adaptation_parameter_set_id");
    
    Fabrice Le Léannec's avatar
    Fabrice Le Léannec committed
      uint32_t codeApsChromaPresentFlag;
    
      xReadFlag(codeApsChromaPresentFlag, "aps_chroma_present_flag");
    
    Fabrice Le Léannec's avatar
    Fabrice Le Léannec committed
      aps->chromaPresentFlag = codeApsChromaPresentFlag;
    
      const ApsType apsType = aps->getAPSType();
    
    
      if (apsType == ApsType::ALF)
    
    Hendry's avatar
    Hendry committed
        parseAlfAps( aps );
    
      else if (apsType == ApsType::LMCS)
    
    Hendry's avatar
    Hendry committed
        parseLmcsAps( aps );
    
      else if (apsType == ApsType::SCALING_LIST)
    
    Hendry's avatar
    Hendry committed
        parseScalingListAps( aps );
    
      xReadFlag(code, "aps_extension_flag");
    
      if (code)
      {
        while (xMoreRbspData())
        {
    
          xReadFlag(code, "aps_extension_data_flag");
    
    Hendry's avatar
    Hendry committed
    }
    
    Hendry's avatar
    Hendry committed
    void HLSyntaxReader::parseAlfAps( APS* aps )
    
    Hendry's avatar
    Hendry committed
      uint32_t  code;
    
      AlfParam param = aps->getAlfAPSParam();
    
      param.enabledFlag[COMPONENT_Y] = param.enabledFlag[COMPONENT_Cb] = param.enabledFlag[COMPONENT_Cr] = true;
    
      xReadFlag(code, "alf_luma_new_filter");
    
      param.newFilterFlag[ChannelType::LUMA] = code;
    
    
      if (aps->chromaPresentFlag)
      {
    
        xReadFlag(code, "alf_chroma_new_filter");
    
        param.newFilterFlag[ChannelType::CHROMA] = code;
    
    Fabrice Le Léannec's avatar
    Fabrice Le Léannec committed
      {
    
        param.newFilterFlag[ChannelType::CHROMA] = 0;
    
    Fabrice Le Léannec's avatar
    Fabrice Le Léannec committed
      }
    
      CcAlfFilterParam ccAlfParam = aps->getCcAlfAPSParam();
    
      if (aps->chromaPresentFlag)
      {
    
        xReadFlag(code, "alf_cc_cb_filter_signal_flag");
    
        ccAlfParam.newCcAlfFilter[COMPONENT_Cb - 1] = code;
    
    Fabrice Le Léannec's avatar
    Fabrice Le Léannec committed
      {
    
        ccAlfParam.newCcAlfFilter[COMPONENT_Cb - 1] = 0;
    
    Fabrice Le Léannec's avatar
    Fabrice Le Léannec committed
      }
    
      if (aps->chromaPresentFlag)
      {
    
        xReadFlag(code, "alf_cc_cr_filter_signal_flag");
    
        ccAlfParam.newCcAlfFilter[COMPONENT_Cr - 1] = code;
    
    Fabrice Le Léannec's avatar
    Fabrice Le Léannec committed
      {
    
        ccAlfParam.newCcAlfFilter[COMPONENT_Cr - 1] = 0;
    
    Fabrice Le Léannec's avatar
    Fabrice Le Léannec committed
      }
    
      CHECK(param.newFilterFlag[ChannelType::LUMA] == 0 && param.newFilterFlag[ChannelType::CHROMA] == 0
    
              && ccAlfParam.newCcAlfFilter[COMPONENT_Cb - 1] == 0 && ccAlfParam.newCcAlfFilter[COMPONENT_Cr - 1] == 0,
            "bitstream conformance error: one of alf_luma_filter_signal_flag, alf_chroma_filter_signal_flag, "
            "alf_cross_component_cb_filter_signal_flag, and alf_cross_component_cr_filter_signal_flag shall be nonzero");
    
      if (param.newFilterFlag[ChannelType::LUMA])
    
        xReadFlag(code, "alf_luma_clip");
    
        param.nonLinearFlag[ChannelType::LUMA] = code ? true : false;
    
        xReadUvlc(code, "alf_luma_num_filters_signalled_minus1");
    
        param.numLumaFilters = code + 1;
        if (param.numLumaFilters > 1)
        {
    
    Hendry's avatar
    Hendry committed
          const int length =  ceilLog2(param.numLumaFilters);
    
          for (int i = 0; i < MAX_NUM_ALF_CLASSES; i++)
          {
    
            xReadCode(length, code, "alf_luma_coeff_delta_idx");
    
            param.filterCoeffDeltaIdx[i] = code;
          }
        }
        else
        {
          memset(param.filterCoeffDeltaIdx, 0, sizeof(param.filterCoeffDeltaIdx));
        }
    
    Hendry's avatar
    Hendry committed
        alfFilter( param, false, 0 );
    
      if (param.newFilterFlag[ChannelType::CHROMA])
    
        xReadFlag(code, "alf_nonlinear_enable_flag_chroma");
    
        param.nonLinearFlag[ChannelType::CHROMA] = code ? true : false;
    
        if constexpr (ALF_MAX_NUM_ALTERNATIVES_CHROMA > 1)
    
          xReadUvlc( code, "alf_chroma_num_alts_minus1" );