Newer
Older
Martin Pettersson
committed
/* The copyright in this software is being made available under the BSD
* 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
* 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.
*/

Karsten Suehring
committed
/** \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"

Karsten Suehring
committed
// ====================================================================================================================
// Protected member functions
// ====================================================================================================================

Karsten Suehring
committed
#if ENABLE_TRACING || RExt__DECODER_DEBUG_BIT_STATISTICS
void VLCReader::xReadCode( const uint32_t length, uint32_t& value, const char *symbolName )

Karsten Suehring
committed
#else
void VLCReader::xReadCode( const uint32_t length, uint32_t& value, const char* )

Karsten Suehring
committed
#endif
{
CHECK(length == 0, "Reading a code of length '0'");
m_pcBitstream->read(length, value);

Karsten Suehring
committed
#if RExt__DECODER_DEBUG_BIT_STATISTICS
CodingStatistics::IncrementStatisticEP(symbolName, length, value);

Karsten Suehring
committed
#endif
#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 );

Karsten Suehring
committed
#if ENABLE_TRACING || RExt__DECODER_DEBUG_BIT_STATISTICS
void VLCReader::xReadUvlc(uint32_t& value, const char *symbolName )

Karsten Suehring
committed
#else
void VLCReader::xReadUvlc(uint32_t& value, const char* )

Karsten Suehring
committed
#endif
{
uint32_t suffix = 0;
uint32_t prefixBit = 0;
m_pcBitstream->read( 1, prefixBit );

Karsten Suehring
committed
#if RExt__DECODER_DEBUG_BIT_STATISTICS

Karsten Suehring
committed
#endif

Karsten Suehring
committed
{

Karsten Suehring
committed

Karsten Suehring
committed
{

Karsten Suehring
committed
}
m_pcBitstream->read(length, suffix);
suffix += (1 << length) - 1;

Karsten Suehring
committed
#if RExt__DECODER_DEBUG_BIT_STATISTICS

Karsten Suehring
committed
#endif
}

Karsten Suehring
committed
#if RExt__DECODER_DEBUG_BIT_STATISTICS
CodingStatistics::IncrementStatisticEP(symbolName, int(totalLen), value);
#endif
#if ENABLE_TRACING
DTRACE( g_trace_ctx, D_HEADER, "%-50s ue(v) : %u\n", symbolName, value );

Karsten Suehring
committed
#endif
}
#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

Karsten Suehring
committed
{
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
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 );

Karsten Suehring
committed
#endif
}
#if ENABLE_TRACING || RExt__DECODER_DEBUG_BIT_STATISTICS
void VLCReader::xReadFlag( uint32_t& value, const char *symbolName )

Karsten Suehring
committed
#else
void VLCReader::xReadFlag( uint32_t& value, const char* )

Karsten Suehring
committed
#endif
{

Karsten Suehring
committed
#if RExt__DECODER_DEBUG_BIT_STATISTICS
CodingStatistics::IncrementStatisticEP(symbolName, 1, int(/*ruiCode*/0));
#endif
#if ENABLE_TRACING
DTRACE( g_trace_ctx, D_HEADER, "%-50s u(1) : %d\n", symbolName, value );

Karsten Suehring
committed
#endif
}
#if ENABLE_TRACING || RExt__DECODER_DEBUG_BIT_STATISTICS
void VLCReader::xReadString( std::string& valueOut, const char *symbolName )
#else
void VLCReader::xReadString( std::string& valueOut, const char* )
#endif
{
std::string value( "" );;
{
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
valueOut = value;
}
#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");
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
}

Karsten Suehring
committed
void VLCReader::xReadRbspTrailingBits()
{
uint32_t bit;

Karsten Suehring
committed
int cnt = 0;
while (m_pcBitstream->getNumBitsUntilByteAligned())
{
xReadFlag( bit, "rbsp_alignment_zero_bit");

Karsten Suehring
committed
cnt++;
}
CHECK(cnt >= 8, "Read more than '8' trailing bits");
}
Zhipin Deng
committed
void AUDReader::parseAccessUnitDelimiter(InputBitstream* bs, uint32_t &audIrapOrGdrAuFlag, uint32_t &picType)

Karsten Suehring
committed
{
setBitstream(bs);
#if ENABLE_TRACING
xTraceAccessUnitDelimiter();
#endif
xReadFlag (audIrapOrGdrAuFlag, "aud_irap_or_gdr_au_flag");
xReadCode (3, picType, "pic_type");

Karsten Suehring
committed
xReadRbspTrailingBits();
}

Karsten Suehring
committed
{
setBitstream(bs);
#if ENABLE_TRACING
xTraceFillerData();
#endif
uint32_t ffByte;
fdSize = 0;

Karsten Suehring
committed
{

Karsten Suehring
committed
fdSize++;
}
xReadRbspTrailingBits();
}
// ====================================================================================================================
// Constructor / destructor / create / destroy
// ====================================================================================================================
HLSyntaxReader::HLSyntaxReader()
{
}
HLSyntaxReader::~HLSyntaxReader()
{

Karsten Suehring
committed

Karsten Suehring
committed
// ====================================================================================================================
// Public member functions
// ====================================================================================================================
void HLSyntaxReader::copyRefPicList(SPS* sps, ReferencePictureList* sourceRpl, ReferencePictureList* destRpl)
destRpl->setNumberOfShorttermPictures(sourceRpl->getNumberOfShorttermPictures());
destRpl->setNumberOfInterLayerPictures(sps->getInterLayerPresentFlag() ? sourceRpl->getNumberOfInterLayerPictures()
: 0);
destRpl->setLtrpInSliceHeaderFlag(sourceRpl->getLtrpInSliceHeaderFlag());
destRpl->setNumberOfLongtermPictures(sourceRpl->getNumberOfLongtermPictures());
destRpl->setNumberOfLongtermPictures(0);
uint32_t numRefPic = destRpl->getNumRefEntries();
destRpl->setRefPicIdentifier(ii, sourceRpl->getRefPicIdentifier(ii), sourceRpl->isRefPicLongterm(ii),
sourceRpl->isInterLayerRefPic(ii), sourceRpl->getInterLayerRefPicIdx(ii));
void HLSyntaxReader::parseRefPicList(SPS* sps, ReferencePictureList* rpl, int rplIdx)
xReadUvlc(code, "num_ref_entries[ listIdx ][ rplsIdx ]");
uint32_t numStrp = 0;
uint32_t numLtrp = 0;
uint32_t numIlrp = 0;
Philip Cowan
committed
if (sps->getLongTermRefsPresent() && numRefPic > 0 && rplIdx != -1)
Philip Cowan
committed
{
xReadFlag(code, "ltrp_in_slice_header_flag[ listIdx ][ rplsIdx ]");
Philip Cowan
committed
rpl->setLtrpInSliceHeaderFlag(code);
}
Zhipin Deng
committed
else if(sps->getLongTermRefsPresent())
Zhipin Deng
committed
rpl->setLtrpInSliceHeaderFlag( 1 );
Philip Cowan
committed
int prevDelta = MAX_INT;
int deltaValue = 0;
bool firstSTRP = true;
Philip Cowan
committed
uint32_t isInterLayerRefPic = 0;
xReadFlag( isInterLayerRefPic, "inter_layer_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]" );
xReadUvlc( code, "ilrp_idx[ listIdx ][ rplsIdx ][ i ]" );
{
xReadFlag(code, "st_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]");
}
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++;
xReadCode(sps->getBitsForPOC(), code, "poc_lsb_lt[listIdx][rplsIdx][j]");
}
rpl->setRefPicIdentifier(ii, code, isLongTerm, false, 0);
numLtrp++;
}
rpl->setNumberOfShorttermPictures(numStrp);
rpl->setNumberOfLongtermPictures(numLtrp);

Karsten Suehring
committed

Karsten Suehring
committed
{
#if ENABLE_TRACING

Karsten Suehring
committed
#endif

Karsten Suehring
committed
xReadCode(6, uiCode, "pps_pic_parameter_set_id");

Karsten Suehring
committed
CHECK(uiCode > 63, "PPS id exceeds boundary (63)");

Karsten Suehring
committed
xReadCode(4, uiCode, "pps_seq_parameter_set_id");

Karsten Suehring
committed
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 );
Jonatan Samuelsson-Allendes
committed
if (uiCode != 0)
{
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);
Jonatan Samuelsson-Allendes
committed
}
xReadFlag( uiCode, "pps_scaling_window_explicit_signalling_flag" );
Philippe de Lagrange
committed
pcPPS->setExplicitScalingWindowFlag( uiCode );
{
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 );
else
{
pcPPS->getScalingWindow() = pcPPS->getConformanceWindow();
}

Karsten Suehring
committed
xReadFlag( uiCode, "pps_output_flag_present_flag" ); pcPPS->setOutputFlagPresentFlag( uiCode==1 );

Karsten Suehring
committed
xReadFlag( uiCode, "pps_no_pic_partition_flag"); pcPPS->setNoPicPartitionFlag(uiCode == 1);
xReadFlag( uiCode, "pps_subpic_id_mapping_present_flag" ); pcPPS->setSubPicIdMappingInPpsFlag( uiCode != 0 );
xReadUvlc(uiCode, "pps_num_subpics_minus1"); pcPPS->setNumSubPics(uiCode + 1);
}
else
{
pcPPS->setNumSubPics(1);
}
CHECK( uiCode > MAX_NUM_SUB_PICS-1, "Number of sub-pictures exceeds limit");
xReadUvlc( uiCode, "pps_subpic_id_len_minus1" ); pcPPS->setSubPicIdLen( uiCode + 1 );
CHECK((1 << pcPPS->getSubPicIdLen()) < pcPPS->getNumSubPics(), "pps_subpic_id_len exceeds valid range");
xReadCode( pcPPS->getSubPicIdLen( ), uiCode, "pps_subpic_id[i]" ); pcPPS->setSubPicId( picIdx, uiCode );
{
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");
xReadUvlc( uiCode, "pps_num_exp_tile_columns_minus1" ); pcPPS->setNumExpTileColumns( uiCode + 1 );
xReadUvlc( uiCode, "pps_num_exp_tile_rows_minus1" ); pcPPS->setNumExpTileRows( uiCode + 1 );
CHECK(pcPPS->getNumExpTileColumns() > MAX_TILE_COLS, "Number of explicit tile columns exceeds valid range");
xReadUvlc( uiCode, "pps_tile_column_width_minus1[i]" ); pcPPS->addTileColumnWidth( uiCode + 1 );
Martin Pettersson
committed
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");
xReadUvlc( uiCode, "pps_tile_row_height_minus1[i]" ); pcPPS->addTileRowHeight( uiCode + 1 );
Martin Pettersson
committed
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
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()))
xReadUvlc( uiCode, "pps_num_slices_in_pic_minus1" ); pcPPS->setNumSlicesInPic( uiCode + 1 );
CHECK(pcPPS->getNumSlicesInPic() > MAX_SLICES, "Number of slices in picture exceeds valid range");
if ((pcPPS->getNumSlicesInPic() - 1) > 1)
Philip Cowan
committed
{
xReadCode(1, uiCode, "pps_tile_idx_delta_present_flag");
Philip Cowan
committed
pcPPS->setTileIdxDeltaPresentFlag(uiCode == 1);
}
else
{
pcPPS->setTileIdxDeltaPresentFlag(0);
}
if( ( tileIdx % pcPPS->getNumTileColumns() ) != pcPPS->getNumTileColumns() - 1 )
{
xReadUvlc( uiCode, "pps_slice_width_in_tiles_minus1[i]" );
pcPPS->setSliceWidthInTiles ( i, uiCode + 1 );
}
else
{
pcPPS->setSliceWidthInTiles( i, 1 );
}
if( tileIdx / pcPPS->getNumTileColumns() != pcPPS->getNumTileRows() - 1 &&
( pcPPS->getTileIdxDeltaPresentFlag() || tileIdx % pcPPS->getNumTileColumns() == 0 ) )
xReadUvlc( uiCode, "pps_slice_height_in_tiles_minus1[i]" );
pcPPS->setSliceHeightInTiles( i, uiCode + 1 );
}
else
{
if( ( tileIdx / pcPPS->getNumTileColumns() ) == pcPPS->getNumTileRows() - 1 )
{
pcPPS->setSliceHeightInTiles( i, 1 );
}
else
{
pcPPS->setSliceHeightInTiles( i, pcPPS->getSliceHeightInTiles( i - 1 ) );
}
// multiple slices within a single tile special case
if( pcPPS->getSliceWidthInTiles(i) == 1 && pcPPS->getSliceHeightInTiles(i) == 1 )
if( pcPPS->getTileRowHeight(tileIdx / pcPPS->getNumTileColumns()) > 1 )
xReadUvlc(uiCode, "pps_num_exp_slices_in_tile[i]");
pcPPS->setNumSlicesInTile(i, 1);
pcPPS->setSliceHeightInCtu(i, pcPPS->getTileRowHeight(tileIdx / pcPPS->getNumTileColumns()));
uint32_t numExpSliceInTile = uiCode;
uint32_t remTileRowHeight = pcPPS->getTileRowHeight(tileIdx / pcPPS->getNumTileColumns());
int j = 0;
xReadUvlc(uiCode, "pps_exp_slice_height_in_ctus_minus1[i]");
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);
}
else
{
pcPPS->setNumSlicesInTile(i, 1);
pcPPS->setSliceHeightInCtu(i, pcPPS->getTileRowHeight(tileIdx / pcPPS->getNumTileColumns()));

Karsten Suehring
committed
if( pcPPS->getTileIdxDeltaPresentFlag() )
xReadSvlc( tileIdxDelta, "pps_tile_idx_delta[i]" );
Martin Pettersson
committed
CHECK( tileIdx < 0 || tileIdx >= pcPPS->getNumTiles(), "Invalid pps_tile_idx_delta.");
tileIdx += pcPPS->getSliceWidthInTiles( i );
if( tileIdx % pcPPS->getNumTileColumns() == 0)
tileIdx += (pcPPS->getSliceHeightInTiles( i ) - 1) * pcPPS->getNumTileColumns();
Shia-Ta Hsiang
committed
if (pcPPS->getRectSliceFlag() == 0 || pcPPS->getSingleSlicePerSubPicFlag() || pcPPS->getNumSlicesInPic() > 1)
{
xReadCode(1, uiCode, "pps_loop_filter_across_slices_enabled_flag"); pcPPS->setLoopFilterAcrossSlicesEnabledFlag( uiCode == 1 );
Shia-Ta Hsiang
committed
}
else
{
pcPPS->setLoopFilterAcrossSlicesEnabledFlag( false );
}
Zhipin Deng
committed
else
{
pcPPS->setSingleSlicePerSubPicFlag(1);
}

Karsten Suehring
committed
xReadFlag( uiCode, "pps_cabac_init_present_flag" ); pcPPS->setCabacInitPresentFlag( uiCode ? true : false );

Karsten Suehring
committed
xReadUvlc(uiCode, "pps_num_ref_idx_default_active_minus1[0]");
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");
pcPPS->setNumRefIdxDefaultActive(REF_PIC_LIST_0, uiCode + 1);

Karsten Suehring
committed
xReadUvlc(uiCode, "pps_num_ref_idx_default_active_minus1[1]");
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");
pcPPS->setNumRefIdxDefaultActive(REF_PIC_LIST_1, uiCode + 1);

Karsten Suehring
committed
xReadFlag(uiCode, "pps_rpl1_idx_present_flag");
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);
}
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())
{
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");

Karsten Suehring
committed
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");
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);

Karsten Suehring
committed
CHECK(pcPPS->getQpOffset(JOINT_CbCr) < -12, "Invalid CbCr QP offset");
CHECK(pcPPS->getQpOffset(JOINT_CbCr) > 12, "Invalid CbCr QP offset");

Karsten Suehring
committed
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");
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++)
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);
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 );

Karsten Suehring
committed
{
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);
}

Karsten Suehring
committed
{
xReadSvlc( iCode, "pps_beta_offset_div2" ); pcPPS->setDeblockingFilterBetaOffsetDiv2( iCode );
CHECK( pcPPS->getDeblockingFilterBetaOffsetDiv2() < -12 ||
pcPPS->getDeblockingFilterBetaOffsetDiv2() > 12, "Invalid deblocking filter configuration" );
xReadSvlc( iCode, "pps_tc_offset_div2"); pcPPS->setDeblockingFilterTcOffsetDiv2( iCode );
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" );
xReadSvlc( iCode, "pps_cb_tc_offset_div2" ); pcPPS->setDeblockingFilterCbTcOffsetDiv2( iCode );
CHECK( pcPPS->getDeblockingFilterCbTcOffsetDiv2() < -12 ||
pcPPS->getDeblockingFilterCbTcOffsetDiv2() > 12, "Invalid deblocking filter configuration" );
xReadSvlc( iCode, "pps_cr_beta_offset_div2") ; pcPPS->setDeblockingFilterCrBetaOffsetDiv2( iCode );
CHECK( pcPPS->getDeblockingFilterCrBetaOffsetDiv2() < -12 ||
pcPPS->getDeblockingFilterCrBetaOffsetDiv2() > 12, "Invalid deblocking filter configuration" );
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() );
}

Karsten Suehring
committed
}
}
else
{
pcPPS->setDeblockingFilterOverrideEnabledFlag(false);
pcPPS->setDbfInfoInPhFlag(false);
}
Jonatan Samuelsson-Allendes
committed
if (!pcPPS->getNoPicPartitionFlag())
{
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);
Jonatan Samuelsson-Allendes
committed
if ((pcPPS->getUseWP() || pcPPS->getWPBiPred()) && pcPPS->getRplInfoInPhFlag())
{
xReadFlag(uiCode, "pps_wp_info_in_ph_flag"); pcPPS->setWpInfoInPhFlag(uiCode ? true : false);
Jonatan Samuelsson-Allendes
committed
}
else
{
pcPPS->setWpInfoInPhFlag(false);
}
xReadFlag(uiCode, "pps_qp_delta_info_in_ph_flag"); pcPPS->setQpDeltaInfoInPhFlag(uiCode ? true : false);
Jonatan Samuelsson-Allendes
committed
}
else
{
Jonatan Samuelsson-Allendes
committed
pcPPS->setRplInfoInPhFlag(false);
pcPPS->setSaoInfoInPhFlag(false);
Jonatan Samuelsson-Allendes
committed
pcPPS->setAlfInfoInPhFlag(false);
pcPPS->setWpInfoInPhFlag(false);
pcPPS->setQpDeltaInfoInPhFlag(false);
}
Sheng-Yen Lin
committed
xReadFlag( uiCode, "pps_picture_header_extension_present_flag");
pcPPS->setPictureHeaderExtensionPresentFlag(uiCode);
xReadFlag( uiCode, "pps_slice_header_extension_present_flag");

Karsten Suehring
committed
pcPPS->setSliceHeaderExtensionPresentFlag(uiCode);

Karsten Suehring
committed
if (uiCode)
{
xReadFlag(uiCode, "pps_extension_data_flag");

Karsten Suehring
committed
}
xReadRbspTrailingBits();
}
#if ENABLE_TRACING
xTraceAPSHeader();
#endif
xReadCode(5, code, "adaptation_parameter_set_id");
Hendry
committed
aps->setAPSId(code);
xReadFlag(codeApsChromaPresentFlag, "aps_chroma_present_flag");
const ApsType apsType = aps->getAPSType();
else if (apsType == ApsType::SCALING_LIST)
if (code)
{
while (xMoreRbspData())
{
xReadFlag(code, "aps_extension_data_flag");
}
}
xReadRbspTrailingBits();
AlfParam param = aps->getAlfAPSParam();
param.reset();
param.enabledFlag[COMPONENT_Y] = param.enabledFlag[COMPONENT_Cb] = param.enabledFlag[COMPONENT_Cr] = true;
param.newFilterFlag[ChannelType::LUMA] = code;
param.newFilterFlag[ChannelType::CHROMA] = code;
param.newFilterFlag[ChannelType::CHROMA] = 0;
CcAlfFilterParam ccAlfParam = aps->getCcAlfAPSParam();
xReadFlag(code, "alf_cc_cb_filter_signal_flag");
ccAlfParam.newCcAlfFilter[COMPONENT_Cb - 1] = code;
ccAlfParam.newCcAlfFilter[COMPONENT_Cb - 1] = 0;
xReadFlag(code, "alf_cc_cr_filter_signal_flag");
ccAlfParam.newCcAlfFilter[COMPONENT_Cr - 1] = code;
ccAlfParam.newCcAlfFilter[COMPONENT_Cr - 1] = 0;
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");
param.nonLinearFlag[ChannelType::LUMA] = code ? true : false;
xReadUvlc(code, "alf_luma_num_filters_signalled_minus1");
param.numLumaFilters = code + 1;
if (param.numLumaFilters > 1)
{
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));
}
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" );