Newer
Older

Karsten Suehring
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.
*

Karsten Suehring
committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
* 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 SEIread.cpp
\brief reading funtionality for SEI messages
*/
#include "CommonLib/CommonDef.h"
#include "CommonLib/BitStream.h"
#include "CommonLib/SEI.h"
#include "CommonLib/Slice.h"
#include "VLCReader.h"
#include "SEIread.h"
#include "CommonLib/Picture.h"
#include "CommonLib/dtrace_next.h"
#include <iomanip>
//! \ingroup DecoderLib
//! \{
void SEIReader::sei_read_scode(std::ostream *pOS, uint32_t length, int& code, const char *pSymbolName)
{
READ_SCODE(length, code, pSymbolName);
if (pOS)
{
(*pOS) << " " << std::setw(55) << pSymbolName << ": " << code << "\n";
}
}
void SEIReader::sei_read_code(std::ostream *pOS, uint32_t length, uint32_t &ruiCode, const char *pSymbolName)

Karsten Suehring
committed
{

Karsten Suehring
committed
if (pOS)
{
(*pOS) << " " << std::setw(55) << pSymbolName << ": " << ruiCode << "\n";
}
}
void SEIReader::sei_read_uvlc(std::ostream *pOS, uint32_t& ruiCode, const char *pSymbolName)
{
READ_UVLC(ruiCode, pSymbolName);
if (pOS)
{
(*pOS) << " " << std::setw(55) << pSymbolName << ": " << ruiCode << "\n";
}
}
void SEIReader::sei_read_svlc(std::ostream *pOS, int& ruiCode, const char *pSymbolName)
{
READ_SVLC(ruiCode, pSymbolName);
if (pOS)
{
(*pOS) << " " << std::setw(55) << pSymbolName << ": " << ruiCode << "\n";
}
}
void SEIReader::sei_read_flag(std::ostream *pOS, uint32_t& ruiCode, const char *pSymbolName)
{
READ_FLAG(ruiCode, pSymbolName);
if (pOS)
{
(*pOS) << " " << std::setw(55) << pSymbolName << ": " << (ruiCode?1:0) << "\n";
}
}
void SEIReader::sei_read_string(std::ostream* os, std::string& code, const char* symbolName)
{
READ_STRING(code, symbolName);
if (os)
{
(*os) << " " << std::setw(55) << symbolName << ": " << code << "\n";
}
}

Karsten Suehring
committed
static inline void output_sei_message_header(SEI &sei, std::ostream *pDecodedMessageOutputStream, uint32_t payloadSize)
{
if (pDecodedMessageOutputStream)
{
std::string seiMessageHdr(SEI::getSEIMessageString(sei.payloadType())); seiMessageHdr+=" SEI message";
(*pDecodedMessageOutputStream) << std::setfill('-') << std::setw((int) seiMessageHdr.size()) << "-"
<< std::setfill(' ') << "\n"
<< seiMessageHdr << " (" << payloadSize << " bytes)"
<< "\n";

Karsten Suehring
committed
}
}
#undef READ_CODE

Karsten Suehring
committed
#undef READ_SVLC
#undef READ_UVLC
#undef READ_FLAG
/**
* unmarshal a single SEI message from bitstream bs
*/

Karsten Suehring
committed
// note: for independent parsing no parameter set should not be required here
void SEIReader::parseSEImessage(InputBitstream* bs, SEIMessages& seis, const NalUnitType nalUnitType, const uint32_t nuh_layer_id, const uint32_t temporalId, const VPS *vps, const SPS *sps, HRD &hrd, std::ostream *pDecodedMessageOutputStream)

Karsten Suehring
committed
{
SEIMessages seiListInCurNalu;

Karsten Suehring
committed
setBitstream(bs);
CHECK(m_pcBitstream->getNumBitsUntilByteAligned(), "Bitstream not aligned");

Karsten Suehring
committed
do
{
xReadSEImessage(seis, nalUnitType, nuh_layer_id, temporalId, vps, sps, hrd, pDecodedMessageOutputStream);
seiListInCurNalu.push_back(seis.back());

Karsten Suehring
committed
/* SEI messages are an integer number of bytes, something has failed
* in the parsing if bitstream not byte-aligned */
CHECK(m_pcBitstream->getNumBitsUntilByteAligned(), "Bitstream not aligned");
}
while (m_pcBitstream->getNumBitsLeft() > 8);
const SEIMessages fillerData = getSeisByType(seiListInCurNalu, SEI::PayloadType::FILLER_PAYLOAD);
CHECK(fillerData.size() > 0 && fillerData.size() != seiListInCurNalu.size(), "When an SEI NAL unit contains an SEI message with payloadType equal to filler payload, the SEI NAL unit shall not contain any other SEI message with payloadType not equal to filler payload");
const SEIMessages pictureTiming = getSeisByType(seiListInCurNalu, SEI::PayloadType::PICTURE_TIMING);
CHECK(hrd.getGeneralHrdParameters().getGeneralSamePicTimingInAllOlsFlag() && pictureTiming.size() > 0 && pictureTiming.size() != seiListInCurNalu.size(),

Karsten Suehring
committed
"When general_same_pic_timing_in_all_ols_flag is equal to 1 [...], and when an SEI NAL unit contains a non-scalable-nested SEI message with "
"payloadType equal to 1 (PT), the SEI NAL unit shall not contain any other SEI message with payloadType not equal 1.");

Karsten Suehring
committed
xReadRbspTrailingBits();
}
void SEIReader::parseAndExtractSEIScalableNesting(InputBitstream *bs, const NalUnitType nalUnitType,
const uint32_t nuh_layer_id, const VPS *vps, const SPS *sps, HRD &hrd,
uint32_t payloadSize, std::vector<SeiPayload> *seiList)
xParseSEIScalableNestingBinary((SEIScalableNesting &) *sei, nalUnitType, nuh_layer_id, payloadSize, vps, sps, hrd,
nullptr, seiList);
int payloadBitsRemaining = getBitstream()->getNumBitsLeft();
if (payloadBitsRemaining) /* more_data_in_payload() */
{
for (; payloadBitsRemaining > 9; payloadBitsRemaining--)
{
uint32_t reservedPayloadExtensionData;
sei_read_code(nullptr, 1, reservedPayloadExtensionData, "reserved_payload_extension_data");
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
}
/* 2 */
int finalBits = getBitstream()->peekBits(payloadBitsRemaining);
int finalPayloadBits = 0;
for (int mask = 0xff; finalBits & (mask >> finalPayloadBits); finalPayloadBits++)
{
continue;
}
/* 3 */
for (; payloadBitsRemaining > 9 - finalPayloadBits; payloadBitsRemaining--)
{
uint32_t reservedPayloadExtensionData;
sei_read_flag ( 0, reservedPayloadExtensionData, "reserved_payload_extension_data");
}
uint32_t dummy;
sei_read_flag( 0, dummy, "payload_bit_equal_to_one"); payloadBitsRemaining--;
while (payloadBitsRemaining)
{
sei_read_flag( 0, dummy, "payload_bit_equal_to_zero"); payloadBitsRemaining--;
}
}
delete sei;
}
void SEIReader::getSEIDecodingUnitInfoDuiIdx(InputBitstream* bs, const NalUnitType nalUnitType, const uint32_t nuh_layer_id, HRD &hrd, uint32_t payloadSize, int& duiIdx)
{
bp = hrd.getBufferingPeriodSEI();
if (!bp)
{
// msg( WARNING, "Warning: Found Decoding unit information SEI message, but no active buffering period is available. Ignoring.");
}
else
{
InputBitstream bs2(*bs);
setBitstream(&bs2);
xParseSEIDecodingUnitInfo((SEIDecodingUnitInfo &) *sei, payloadSize, *bp, nuh_layer_id, nullptr);
duiIdx = ((SEIDecodingUnitInfo&)*sei).m_decodingUnitIdx;
delete sei;
setBitstream(bs);
}
}
void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType, const uint32_t nuh_layer_id, const uint32_t temporalId, const VPS *vps, const SPS *sps, HRD &hrd, std::ostream *pDecodedMessageOutputStream)

Karsten Suehring
committed
{
#if ENABLE_TRACING
xTraceSEIHeader();
#endif
int payloadType = 0;
uint32_t val = 0;
do
{
sei_read_code(nullptr, 8, val, "payload_type");

Karsten Suehring
committed
payloadType += val;
} while (val==0xFF);
uint32_t payloadSize = 0;
do
{
sei_read_code(nullptr, 8, val, "payload_size");

Karsten Suehring
committed
payloadSize += val;
} while (val==0xFF);
#if ENABLE_TRACING
xTraceSEIMessageType((SEI::PayloadType)payloadType);
#endif
/* extract the payload for this single SEI message.
* This allows greater safety in erroneous parsing of an SEI message
* from affecting subsequent messages.
* After parsing the payload, bs needs to be restored as the primary
* bitstream.
*/
InputBitstream *bs = getBitstream();
setBitstream(bs->extractSubstream(payloadSize * 8));
SEI *sei = nullptr;
const SEIBufferingPeriod *bp = nullptr;

Karsten Suehring
committed
if(nalUnitType == NAL_UNIT_PREFIX_SEI)
{
switch (SEI::PayloadType(payloadType))

Karsten Suehring
committed
{
case SEI::PayloadType::FILLER_PAYLOAD:
sei = new SEIFillerPayload;
xParseSEIFillerPayload((SEIFillerPayload&) *sei, payloadSize, pDecodedMessageOutputStream);
break;
case SEI::PayloadType::USER_DATA_UNREGISTERED:

Karsten Suehring
committed
sei = new SEIuserDataUnregistered;
xParseSEIuserDataUnregistered((SEIuserDataUnregistered&) *sei, payloadSize, pDecodedMessageOutputStream);
break;
case SEI::PayloadType::DECODING_UNIT_INFO:
bp = hrd.getBufferingPeriodSEI();
if (!bp)
{
msg( WARNING, "Warning: Found Decoding unit information SEI message, but no active buffering period is available. Ignoring.");
}
else
{
sei = new SEIDecodingUnitInfo;
xParseSEIDecodingUnitInfo((SEIDecodingUnitInfo&) *sei, payloadSize, *bp, temporalId, pDecodedMessageOutputStream);
}

Karsten Suehring
committed
break;
case SEI::PayloadType::BUFFERING_PERIOD:

Karsten Suehring
committed
sei = new SEIBufferingPeriod;
xParseSEIBufferingPeriod((SEIBufferingPeriod&) *sei, payloadSize, pDecodedMessageOutputStream);

Karsten Suehring
committed
hrd.setBufferingPeriodSEI((SEIBufferingPeriod*) sei);

Karsten Suehring
committed
break;
case SEI::PayloadType::PICTURE_TIMING:
bp = hrd.getBufferingPeriodSEI();
if (!bp)

Karsten Suehring
committed
{
msg(WARNING,
"Warning: Found Picture timing SEI message, but no active buffering period is available. Ignoring.");
}
else
{
sei = new SEIPictureTiming;
xParseSEIPictureTiming((SEIPictureTiming &) *sei, payloadSize, temporalId, *bp, pDecodedMessageOutputStream);
hrd.setPictureTimingSEI((SEIPictureTiming *) sei);

Karsten Suehring
committed
}

Karsten Suehring
committed
break;
case SEI::PayloadType::SCALABLE_NESTING:
xParseSEIScalableNesting((SEIScalableNesting &) *sei, nalUnitType, nuh_layer_id, payloadSize, vps, sps, hrd,
pDecodedMessageOutputStream);
case SEI::PayloadType::FRAME_FIELD_INFO:
xParseSEIFrameFieldinfo((SEIFrameFieldInfo &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::DEPENDENT_RAP_INDICATION:
sei = new SEIDependentRAPIndication;
xParseSEIDependentRAPIndication((SEIDependentRAPIndication &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::EXTENDED_DRAP_INDICATION:
xParseSEIExtendedDrapIndication((SEIExtendedDrapIndication &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::FRAME_PACKING:

Karsten Suehring
committed
sei = new SEIFramePacking;
xParseSEIFramePacking((SEIFramePacking &) *sei, payloadSize, pDecodedMessageOutputStream);

Karsten Suehring
committed
break;
case SEI::PayloadType::DISPLAY_ORIENTATION:
xParseSEIDisplayOrientation((SEIDisplayOrientation &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::ANNOTATED_REGIONS:
sei = new SEIAnnotatedRegions;
xParseSEIAnnotatedRegions((SEIAnnotatedRegions &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::PARAMETER_SETS_INCLUSION_INDICATION:
Rickard Sjöberg
committed
sei = new SEIParameterSetsInclusionIndication;
xParseSEIParameterSetsInclusionIndication((SEIParameterSetsInclusionIndication &) *sei, payloadSize,
pDecodedMessageOutputStream);
Rickard Sjöberg
committed
break;
case SEI::PayloadType::MASTERING_DISPLAY_COLOUR_VOLUME:

Karsten Suehring
committed
sei = new SEIMasteringDisplayColourVolume;
xParseSEIMasteringDisplayColourVolume((SEIMasteringDisplayColourVolume &) *sei, payloadSize,
pDecodedMessageOutputStream);

Karsten Suehring
committed
break;
case SEI::PayloadType::ALTERNATIVE_TRANSFER_CHARACTERISTICS:

Karsten Suehring
committed
sei = new SEIAlternativeTransferCharacteristics;
xParseSEIAlternativeTransferCharacteristics((SEIAlternativeTransferCharacteristics &) *sei, payloadSize,
pDecodedMessageOutputStream);

Karsten Suehring
committed
break;
case SEI::PayloadType::EQUIRECTANGULAR_PROJECTION:
sei = new SEIEquirectangularProjection;
xParseSEIEquirectangularProjection((SEIEquirectangularProjection &) *sei, payloadSize,
pDecodedMessageOutputStream);
case SEI::PayloadType::SPHERE_ROTATION:
sei = new SEISphereRotation;
xParseSEISphereRotation((SEISphereRotation &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::OMNI_VIEWPORT:
sei = new SEIOmniViewport;
xParseSEIOmniViewport((SEIOmniViewport &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::REGION_WISE_PACKING:
sei = new SEIRegionWisePacking;
xParseSEIRegionWisePacking((SEIRegionWisePacking &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::GENERALIZED_CUBEMAP_PROJECTION:
sei = new SEIGeneralizedCubemapProjection;
xParseSEIGeneralizedCubemapProjection((SEIGeneralizedCubemapProjection &) *sei, payloadSize,
pDecodedMessageOutputStream);
case SEI::PayloadType::SCALABILITY_DIMENSION_INFO:
sei = new SEIScalabilityDimensionInfo;
xParseSEIScalabilityDimensionInfo((SEIScalabilityDimensionInfo &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::GREEN_METADATA:
xParseSEIGreenMetadataInfo((SEIGreenMetadataInfo &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::MULTIVIEW_ACQUISITION_INFO:
sei = new SEIMultiviewAcquisitionInfo;
xParseSEIMultiviewAcquisitionInfo((SEIMultiviewAcquisitionInfo &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::MULTIVIEW_VIEW_POSITION:
sei = new SEIMultiviewViewPosition;
xParseSEIMultiviewViewPosition((SEIMultiviewViewPosition &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::ALPHA_CHANNEL_INFO:
sei = new SEIAlphaChannelInfo;
xParseSEIAlphaChannelInfo((SEIAlphaChannelInfo &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::DEPTH_REPRESENTATION_INFO:
sei = new SEIDepthRepresentationInfo;
xParseSEIDepthRepresentationInfo((SEIDepthRepresentationInfo &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::SUBPICTURE_LEVEL_INFO:
sei = new SEISubpicureLevelInfo;
xParseSEISubpictureLevelInfo((SEISubpicureLevelInfo &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::SAMPLE_ASPECT_RATIO_INFO:
sei = new SEISampleAspectRatioInfo;
xParseSEISampleAspectRatioInfo((SEISampleAspectRatioInfo &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::USER_DATA_REGISTERED_ITU_T_T35:
xParseSEIUserDataRegistered((SEIUserDataRegistered &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::FILM_GRAIN_CHARACTERISTICS:
xParseSEIFilmGrainCharacteristics((SEIFilmGrainCharacteristics &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::CONTENT_LIGHT_LEVEL_INFO:
xParseSEIContentLightLevelInfo((SEIContentLightLevelInfo &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::AMBIENT_VIEWING_ENVIRONMENT:
xParseSEIAmbientViewingEnvironment((SEIAmbientViewingEnvironment &) *sei, payloadSize,
pDecodedMessageOutputStream);
case SEI::PayloadType::CONTENT_COLOUR_VOLUME:
xParseSEIContentColourVolume((SEIContentColourVolume &) *sei, payloadSize, pDecodedMessageOutputStream);
case SEI::PayloadType::COLOUR_TRANSFORM_INFO:
sei = new SEIColourTransformInfo;
xParseSEIColourTransformInfo((SEIColourTransformInfo &) *sei, payloadSize, pDecodedMessageOutputStream);
#if JVET_T0056_SEI_MANIFEST
case SEI::PayloadType::SEI_MANIFEST:
xParseSEISEIManifest((SEIManifest&) *sei, payloadSize, pDecodedMessageOutputStream);
break;
#endif
#if JVET_T0056_SEI_PREFIX_INDICATION
case SEI::PayloadType::SEI_PREFIX_INDICATION:
sei = new SEIPrefixIndication;
xParseSEISEIPrefixIndication((SEIPrefixIndication&) *sei, payloadSize, pDecodedMessageOutputStream);
#endif
case SEI::PayloadType::CONSTRAINED_RASL_ENCODING:
sei = new SEIConstrainedRaslIndication;
xParseSEIConstrainedRaslIndication((SEIConstrainedRaslIndication &) *sei, payloadSize,
pDecodedMessageOutputStream);
case SEI::PayloadType::SHUTTER_INTERVAL_INFO:
Jeeva Raj A
committed
sei = new SEIShutterIntervalInfo;
xParseSEIShutterInterval((SEIShutterIntervalInfo &) *sei, payloadSize, pDecodedMessageOutputStream);
Jeeva Raj A
committed
break;
case SEI::PayloadType::NEURAL_NETWORK_POST_FILTER_CHARACTERISTICS:
sei = new SEINeuralNetworkPostFilterCharacteristics;
xParseSEINNPostFilterCharacteristics((SEINeuralNetworkPostFilterCharacteristics &) *sei, payloadSize, sps,
pDecodedMessageOutputStream);
#if JVET_AB0049
nnpfcValues.push_back(((SEINeuralNetworkPostFilterCharacteristics*)sei)->m_id);
#endif
case SEI::PayloadType::NEURAL_NETWORK_POST_FILTER_ACTIVATION:
sei = new SEINeuralNetworkPostFilterActivation;
xParseSEINNPostFilterActivation((SEINeuralNetworkPostFilterActivation &) *sei, payloadSize,
pDecodedMessageOutputStream);
nnpfcProcessed = false;
CHECK(nnpfcValues.size() == 0, "At leaset one NNPFC SEI message should precede NNPFA")
for(int i=0; i<nnpfcValues.size(); ++i)
{
if(((SEINeuralNetworkPostFilterCharacteristics*)sei)->m_id == nnpfcValues[i])
{
nnpfcProcessed = true;
}
}
CHECK(!nnpfcProcessed, "No NNPFC, no NNPFA")
nnpfcProcessed = false;
#endif
case SEI::PayloadType::PHASE_INDICATION:
sei = new SEIPhaseIndication;
xParseSEIPhaseIndication((SEIPhaseIndication &) *sei, payloadSize, pDecodedMessageOutputStream);
break;
case SEI::PayloadType::SEI_PROCESSING_ORDER:
sei = new SEIProcessingOrderInfo;
xParseSEIProcessingOrder((SEIProcessingOrderInfo &) *sei, payloadSize, pDecodedMessageOutputStream);

Karsten Suehring
committed
default:
for (uint32_t i = 0; i < payloadSize; i++)
{
uint32_t seiByte;
sei_read_code(nullptr, 8, seiByte, "unknown prefix SEI payload byte");

Karsten Suehring
committed
}
msg(WARNING, "Unknown prefix SEI message (payloadType = %d) was found!\n", payloadType);

Karsten Suehring
committed
if (pDecodedMessageOutputStream)
{
(*pDecodedMessageOutputStream) << "Unknown prefix SEI message (payloadType = " << payloadType
<< ") was found!\n";

Karsten Suehring
committed
}
break;
}
}
else
{
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
switch (SEI::PayloadType(payloadType))
{
case SEI::PayloadType::USER_DATA_UNREGISTERED:
sei = new SEIuserDataUnregistered;
xParseSEIuserDataUnregistered((SEIuserDataUnregistered &) *sei, payloadSize, pDecodedMessageOutputStream);
break;
case SEI::PayloadType::DECODED_PICTURE_HASH:
sei = new SEIDecodedPictureHash;
xParseSEIDecodedPictureHash((SEIDecodedPictureHash &) *sei, payloadSize, pDecodedMessageOutputStream);
break;
case SEI::PayloadType::SCALABLE_NESTING:
sei = new SEIScalableNesting;
xParseSEIScalableNesting((SEIScalableNesting &) *sei, nalUnitType, nuh_layer_id, payloadSize, vps, sps, hrd,
pDecodedMessageOutputStream);
break;
case SEI::PayloadType::FILLER_PAYLOAD:
sei = new SEIFillerPayload;
xParseSEIFillerPayload((SEIFillerPayload &) *sei, payloadSize, pDecodedMessageOutputStream);
break;
default:
for (uint32_t i = 0; i < payloadSize; i++)
{
uint32_t seiByte;
sei_read_code(nullptr, 8, seiByte, "unknown suffix SEI payload byte");
}
msg(WARNING, "Unknown suffix SEI message (payloadType = %d) was found!\n", payloadType);
if (pDecodedMessageOutputStream)
{
(*pDecodedMessageOutputStream) << "Unknown suffix SEI message (payloadType = " << payloadType
<< ") was found!\n";
}
break;

Karsten Suehring
committed
}
}

Karsten Suehring
committed
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
{
seis.push_back(sei);
}
/* By definition the underlying bitstream terminates in a byte-aligned manner.
* 1. Extract all bar the last MIN(bitsremaining,nine) bits as reserved_payload_extension_data
* 2. Examine the final 8 bits to determine the payload_bit_equal_to_one marker
* 3. Extract the remainingreserved_payload_extension_data bits.
*
* If there are fewer than 9 bits available, extract them.
*/
int payloadBitsRemaining = getBitstream()->getNumBitsLeft();
if (payloadBitsRemaining) /* more_data_in_payload() */
{
for (; payloadBitsRemaining > 9; payloadBitsRemaining--)
{
uint32_t reservedPayloadExtensionData;
sei_read_code ( pDecodedMessageOutputStream, 1, reservedPayloadExtensionData, "reserved_payload_extension_data");
}
/* 2 */
int finalBits = getBitstream()->peekBits(payloadBitsRemaining);
int finalPayloadBits = 0;
for (int mask = 0xff; finalBits & (mask >> finalPayloadBits); finalPayloadBits++)
{
continue;
}
/* 3 */
for (; payloadBitsRemaining > 9 - finalPayloadBits; payloadBitsRemaining--)
{
uint32_t reservedPayloadExtensionData;
sei_read_flag ( 0, reservedPayloadExtensionData, "reserved_payload_extension_data");
}
uint32_t dummy;
sei_read_flag( 0, dummy, "payload_bit_equal_to_one"); payloadBitsRemaining--;
while (payloadBitsRemaining)
{
sei_read_flag( 0, dummy, "payload_bit_equal_to_zero"); payloadBitsRemaining--;
}
}
/* restore primary bitstream for sei_message */
delete getBitstream();
setBitstream(bs);
}
void SEIReader::xParseSEIFillerPayload(SEIFillerPayload &sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
{
output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
CHECK(val != 0xff, "ff_byte shall be a byte having the value 0xFF");

Karsten Suehring
committed
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
/**
* parse bitstream bs and unpack a user_data_unregistered SEI message
* of payloasSize bytes into sei.
*/
void SEIReader::xParseSEIuserDataUnregistered(SEIuserDataUnregistered &sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
{
CHECK(payloadSize < ISO_IEC_11578_LEN, "Payload too small");
uint32_t val;
output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
for (uint32_t i = 0; i < ISO_IEC_11578_LEN; i++)
{
sei_read_code( pDecodedMessageOutputStream, 8, val, "uuid_iso_iec_11578");
sei.uuid_iso_iec_11578[i] = val;
}
sei.userDataLength = payloadSize - ISO_IEC_11578_LEN;
if (!sei.userDataLength)
{
sei.userData = 0;
return;
}
sei.userData = new uint8_t[sei.userDataLength];
for (uint32_t i = 0; i < sei.userDataLength; i++)
{
sei_read_code(nullptr, 8, val, "user_data_payload_byte");

Karsten Suehring
committed
sei.userData[i] = val;
}
if (pDecodedMessageOutputStream)
{
(*pDecodedMessageOutputStream) << " User data payload size: " << sei.userDataLength << "\n";
}
}
Jeeva Raj A
committed
void SEIReader::xParseSEIShutterInterval(SEIShutterIntervalInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
{
int32_t i;
uint32_t val;
output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
sei_read_code(pDecodedMessageOutputStream, 32, val, "sii_time_scale"); sei.m_siiTimeScale = val;
sei_read_flag(pDecodedMessageOutputStream, val, "fixed_shutter_interval_within_clvs_flag"); sei.m_siiFixedSIwithinCLVS = val;
if (sei.m_siiFixedSIwithinCLVS)
{
sei_read_code(pDecodedMessageOutputStream, 32, val, "sii_num_units_in_shutter_interval"); sei.m_siiNumUnitsInShutterInterval = val;
}
else
{
sei_read_code(pDecodedMessageOutputStream, 3, val, "sii_max_sub_layers_minus1 "); sei.m_siiMaxSubLayersMinus1 = val;
sei.m_siiSubLayerNumUnitsInSI.resize(sei.m_siiMaxSubLayersMinus1 + 1);
for (i = 0; i <= sei.m_siiMaxSubLayersMinus1; i++)
{
sei_read_code(pDecodedMessageOutputStream, 32, val, "sub_layer_num_units_in_shutter_interval[ i ]");
sei.m_siiSubLayerNumUnitsInSI[i] = val;
}
}
}
void SEIReader::xParseSEIProcessingOrder(SEIProcessingOrderInfo& sei, uint32_t payloadSize, std::ostream *decodedMessageOutputStream)
{
uint32_t i,b;
uint32_t NumSEIMessages, val;
output_sei_message_header(sei, decodedMessageOutputStream, payloadSize);
//Here payload is in Bytes, Since "sei_payloadType" is 2 Bytes + "sei_payloadOrder" is 1 Byte so total = 3 Bytes
//To get Number of SEI messages, just do payloadSize/3
NumSEIMessages = payloadSize / 3;
sei.m_posPayloadType.resize(NumSEIMessages);
sei.m_posProcessingOrder.resize(NumSEIMessages);
for(i=0,b=0; b < payloadSize; i++,b+=3)
{
sei_read_code(decodedMessageOutputStream, 16, val, "sei_payloadType[i]");
sei.m_posPayloadType[i] = val;
#if JVET_AB0069_SEI_PROCESSING_ORDER
sei_read_code(decodedMessageOutputStream, 16, val, "sei_processingOrder[i]");
#else
sei_read_code(decodedMessageOutputStream, 8, val, "sei_processingOrder[i]");
sei.m_posProcessingOrder[i] = val;
}
}

Karsten Suehring
committed
/**
* parse bitstream bs and unpack a decoded picture hash SEI message
* of payloadSize bytes into sei.
*/
void SEIReader::xParseSEIDecodedPictureHash(SEIDecodedPictureHash& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
{
uint32_t bytesRead = 0;
output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
uint32_t val;
Martin Pettersson
committed
sei_read_code( pDecodedMessageOutputStream, 8, val, "dph_sei_hash_type");

Karsten Suehring
committed
sei.method = static_cast<HashType>(val); bytesRead++;
sei_read_code( pDecodedMessageOutputStream, 1, val, "dph_sei_single_component_flag");
sei.singleCompFlag = val;
sei_read_code( pDecodedMessageOutputStream, 7, val, "dph_sei_reserved_zero_7bits");
bytesRead++;
uint32_t expectedSize =
(sei.singleCompFlag ? 1 : 3) * (sei.method == HashType::MD5 ? 16 : (sei.method == HashType::CRC ? 2 : 4));
CHECK ((payloadSize - bytesRead) != expectedSize, "The size of the decoded picture hash does not match the expected size.");

Karsten Suehring
committed
const char *traceString="\0";
switch (sei.method)
{
case HashType::MD5:
traceString = "picture_md5";
break;
case HashType::CRC:
traceString = "picture_crc";
break;
case HashType::CHECKSUM:
traceString = "picture_checksum";
break;
default:
THROW("Unknown hash type");
break;

Karsten Suehring
committed
}
if (pDecodedMessageOutputStream)
{
(*pDecodedMessageOutputStream) << " " << std::setw(55) << traceString << ": " << std::hex << std::setfill('0');
}
sei.m_pictureHash.hash.clear();
for(;bytesRead < payloadSize; bytesRead++)
{

Karsten Suehring
committed
sei.m_pictureHash.hash.push_back((uint8_t)val);
if (pDecodedMessageOutputStream)
{
(*pDecodedMessageOutputStream) << std::setw(2) << val;
}
}
if (pDecodedMessageOutputStream)
{
(*pDecodedMessageOutputStream) << std::dec << std::setfill(' ') << "\n";
}
}

Karsten Suehring
committed
void SEIReader::xParseSEIScalableNesting(SEIScalableNesting& sei, const NalUnitType nalUnitType, const uint32_t nuhLayerId, uint32_t payloadSize, const VPS* vps, const SPS* sps, HRD &hrd, std::ostream* decodedMessageOutputStream)

Karsten Suehring
committed
uint32_t symbol;

Karsten Suehring
committed
output_sei_message_header(sei, decodedMessageOutputStream, payloadSize);

Karsten Suehring
committed
sei_read_flag(decodedMessageOutputStream, symbol, "sn_ols_flag"); sei.m_snOlsFlag = symbol;
sei_read_flag(decodedMessageOutputStream, symbol, "sn_subpic_flag"); sei.m_snSubpicFlag = symbol;

Karsten Suehring
committed
if (sei.m_snOlsFlag)

Karsten Suehring
committed
sei_read_uvlc(decodedMessageOutputStream, symbol, "sn_num_olss_minus1"); sei.m_snNumOlssMinus1 = symbol;
for (uint32_t i = 0; i <= sei.m_snNumOlssMinus1; i++)

Karsten Suehring
committed
sei_read_uvlc(decodedMessageOutputStream, symbol, "sn_ols_idx_delta_minus1[i]"); sei.m_snOlsIdxDeltaMinus1[i] = symbol;

Karsten Suehring
committed
for (uint32_t i = 0; i <= sei.m_snNumOlssMinus1; i++)

Karsten Suehring
committed
sei.m_snOlsIdx[i] = sei.m_snOlsIdxDeltaMinus1[i];

Karsten Suehring
committed
sei.m_snOlsIdx[i] = sei.m_snOlsIdxDeltaMinus1[i] + sei.m_snOlsIdxDeltaMinus1[i - 1] + 1;

Karsten Suehring
committed
if (vps && vps->getVPSId() != 0)

Karsten Suehring
committed
uint32_t lowestLayerId = MAX_UINT;

Karsten Suehring
committed
for (uint32_t olsIdxForSEI = 0; olsIdxForSEI <= sei.m_snNumOlssMinus1; olsIdxForSEI++)

Karsten Suehring
committed
int olsIdx = sei.m_snOlsIdx[olsIdxForSEI];

Karsten Suehring
committed
for (int layerIdx = 0; layerIdx < vps->getNumLayersInOls(olsIdx); layerIdx++)

Karsten Suehring
committed
if (lowestLayerId > vps->getLayerIdInOls(olsIdx, layerIdx))
{
lowestLayerId = vps->getLayerIdInOls(olsIdx, layerIdx);
}

Karsten Suehring
committed
CHECK(lowestLayerId!= nuhLayerId, "nuh_layer_id is not equal to the lowest layer among Olss that the scalable SEI applies");

Karsten Suehring
committed
sei_read_flag(decodedMessageOutputStream, symbol, "sn_all_layers_flag"); sei.m_snAllLayersFlag = symbol;
if (!sei.m_snAllLayersFlag)

Karsten Suehring
committed
sei_read_uvlc(decodedMessageOutputStream, symbol, "sn_num_layers_minus1"); sei.m_snNumLayersMinus1 = symbol;
sei.m_snLayerId[0] = nuhLayerId;
for (uint32_t i = 1; i <= sei.m_snNumLayersMinus1; i++)

Karsten Suehring
committed
sei_read_code(decodedMessageOutputStream, 6, symbol, "sn_layer_id[i]"); sei.m_snLayerId[i] = symbol;
if (sei.m_snSubpicFlag)
{
sei_read_uvlc(decodedMessageOutputStream, symbol, "sn_num_subpics_minus1"); sei.m_snNumSubpics = symbol + 1;
sei_read_uvlc(decodedMessageOutputStream, symbol, "sn_subpic_id_len_minus1"); sei.m_snSubpicIdLen = symbol + 1;
sei.m_snSubpicId.resize(sei.m_snNumSubpics);
for (uint32_t i = 0; i < sei.m_snNumSubpics; i++)
{
sei_read_code(decodedMessageOutputStream, sei.m_snSubpicIdLen, symbol, "sn_subpic_id[i]"); sei.m_snSubpicId[i] = symbol;
}
}
sei_read_uvlc(decodedMessageOutputStream, symbol, "sn_num_seis_minus1"); sei.m_snNumSEIs = symbol + 1;
CHECK (sei.m_snNumSEIs > 64, "The value of sn_num_seis_minus1 shall be in the range of 0 to 63");
// byte alignment
while (m_pcBitstream->getNumBitsRead() % 8 != 0)
{

Karsten Suehring
committed
sei_read_flag(decodedMessageOutputStream, symbol, "sn_zero_bit");
// read nested SEI messages
for (int32_t i=0; i<sei.m_snNumSEIs; i++)
{
SEIMessages tmpSEIs;
xReadSEImessage(tmpSEIs, nalUnitType, nuhLayerId, 0, vps, sps, m_nestedHrd, decodedMessageOutputStream);
if (tmpSEIs.front()->payloadType() == SEI::PayloadType::BUFFERING_PERIOD)
{
SEIBufferingPeriod *bp = (SEIBufferingPeriod*) tmpSEIs.front();
m_nestedHrd.setBufferingPeriodSEI(bp);

Karsten Suehring
committed
const SEIBufferingPeriod *nonNestedBp = hrd.getBufferingPeriodSEI();
if (nonNestedBp)
{
checkBPSyntaxElementLength(nonNestedBp, bp);
}
}
sei.m_nestedSEIs.push_back(tmpSEIs.front());
tmpSEIs.clear();
}
xCheckScalableNestingConstraints(sei, nalUnitType, vps);
if (decodedMessageOutputStream)
{
(*decodedMessageOutputStream) << "End of scalable nesting SEI message\n";
}
}
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
void SEIReader::xParseSEIGreenMetadataInfo(SEIGreenMetadataInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
{
uint32_t code;
output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
sei_read_code(pDecodedMessageOutputStream, 8, code, "green_metadata_type");
sei.m_greenMetadataType = code;
printf("GREEN MPEG Output: \n");
printf("Metadata Type: %i\n", sei.m_greenMetadataType);
switch (sei.m_greenMetadataType)
{
case 0:
sei_read_code(pDecodedMessageOutputStream, 4, code, "period_type");
sei.m_periodType = code;
sei_read_code(pDecodedMessageOutputStream, 3, code, "granularity_type");
sei.m_greenMetadataGranularityType = code;
sei_read_code(pDecodedMessageOutputStream, 1, code, "extended_representation_flag");
sei.m_greenMetadataExtendedRepresentation = code;
printf ("Period Type: %i\n",sei.m_periodType);
printf ("Granularity Type: %i\n",sei.m_greenMetadataGranularityType);
printf ("Extended Representation Flag Type: %i\n",sei.m_greenMetadataExtendedRepresentation);
if (sei.m_periodType == 2)
{
sei_read_code(pDecodedMessageOutputStream, 16, code, "num_seconds");
sei.m_numSeconds = code;
printf ("Number of Seconds: %i\n",sei.m_numSeconds);
}
else if (sei.m_periodType == 3)
{
sei_read_code(pDecodedMessageOutputStream, 16, code, "num_pictures");
sei.m_numPictures = code;
printf ("Number of Pictures: %i\n",sei.m_numPictures);
}
if (sei.m_greenMetadataGranularityType == 0)
{
sei_read_code(pDecodedMessageOutputStream, 8, code, "portion_non_zero_blocks_area");
sei.m_greenComplexityMetrics.portionNonZeroBlocksArea = code;
sei_read_code(pDecodedMessageOutputStream, 8, code, "portion_non_zero_transform_coefficients_area");
sei.m_greenComplexityMetrics.portionNonZeroTransformCoefficientsArea = code;
sei_read_code(pDecodedMessageOutputStream, 8, code, "portion_intra_predicted_blocks_area");
sei.m_greenComplexityMetrics.portionIntraPredictedBlocksArea = code;
sei_read_code(pDecodedMessageOutputStream, 8, code, "portion_deblocking_instances");
sei.m_greenComplexityMetrics.portionDeblockingInstances = code;
sei_read_code(pDecodedMessageOutputStream, 8, code, "portion_alf_instances");
sei.m_greenComplexityMetrics.portionAlfInstances = code;
printf ("Portion Non Zero Blocks Area: %i\n",sei.m_greenComplexityMetrics.portionNonZeroBlocksArea);
printf ("Portion Non Zero Transform Coefficients Area: %i\n",sei.m_greenComplexityMetrics.portionNonZeroTransformCoefficientsArea);
printf ("Portion Intra Predicted Blocks Area: %i\n",sei.m_greenComplexityMetrics.portionIntraPredictedBlocksArea);
printf ("Portion Deblocking Instances: %i\n",sei.m_greenComplexityMetrics.portionDeblockingInstances);
printf ("Portion ALF Instances: %i\n",sei.m_greenComplexityMetrics.portionAlfInstances);
if(sei.m_greenMetadataExtendedRepresentation == 1)
{
if(sei.m_greenComplexityMetrics.portionNonZeroBlocksArea != 0)
{
sei_read_code(pDecodedMessageOutputStream, 8, code, "portion_non_zero_4_8_16_blocks_area");
sei.m_greenComplexityMetrics.portionNonZero_4_8_16BlocksArea = code;
sei_read_code(pDecodedMessageOutputStream, 8, code, "portion_non_zero_32_64_128_blocks_area");
sei.m_greenComplexityMetrics.portionNonZero_32_64_128BlocksArea = code;
sei_read_code(pDecodedMessageOutputStream, 8, code, "portion_non_zero_256_512_1024_blocks_area");
sei.m_greenComplexityMetrics.portionNonZero_256_512_1024BlocksArea = code;
sei_read_code(pDecodedMessageOutputStream, 8, code, "portion_non_zero_2048_4096_blocks_area");
sei.m_greenComplexityMetrics.portionNonZero_2048_4096BlocksArea = code;
printf ("Portion Non Zero 4/8/16 Blocks Area: %i\n",sei.m_greenComplexityMetrics.portionNonZero_4_8_16BlocksArea);
printf ("Portion Non Zero 32/64/128 Blocks Area: %i\n",sei.m_greenComplexityMetrics.portionNonZero_32_64_128BlocksArea);
printf ("Portion Non Zero 256/512/1024 Blocks Area: %i\n",sei.m_greenComplexityMetrics.portionNonZero_256_512_1024BlocksArea);
printf ("Portion Non Zero 2048/4096 Blocks Area: %i\n",sei.m_greenComplexityMetrics.portionNonZero_2048_4096BlocksArea);
}
if(sei.m_greenComplexityMetrics.portionIntraPredictedBlocksArea < 255)
{
sei_read_code(pDecodedMessageOutputStream, 8, code, "portion_bi_and_gpm_predicted_blocks_area");
sei.m_greenComplexityMetrics.portionBiAndGpmPredictedBlocksArea = code;
sei_read_code(pDecodedMessageOutputStream, 8, code, "portion_bdof_blocks_area");
sei.m_greenComplexityMetrics.portionBdofBlocksArea = code;
printf ("Portion BI and GPM Predicted Blocks Area: %i\n",sei.m_greenComplexityMetrics.portionBiAndGpmPredictedBlocksArea);
printf ("Portion BDOF Blocks Area: %i\n",sei.m_greenComplexityMetrics.portionBdofBlocksArea);
}
sei_read_code(pDecodedMessageOutputStream, 8, code, "portion_sao_instances");
sei.m_greenComplexityMetrics.portionSaoInstances = code;
printf ("Portion SAO Instances: %i\n",sei.m_greenComplexityMetrics.portionSaoInstances);
}
}
break;
case 1:
sei_read_code(pDecodedMessageOutputStream, 16, code, "xsd_subpic_number_minus1");
sei.m_xsdSubpicNumberMinus1 = code;
printf("XSD Subpic Number of Metrics: %i\n", sei.m_xsdSubpicNumberMinus1 + 1);
int xsdSubpicIdc;
int xsdMetricNumberMinus1;
for (int i = 0; i <= sei.m_xsdSubpicNumberMinus1; i++)
{
sei_read_code(pDecodedMessageOutputStream, 16, code, "xsd_subpic_idc[i]");
xsdSubpicIdc = code;
printf("XSD Subpic Idc[i]: %i\n", xsdSubpicIdc);
sei_read_code(pDecodedMessageOutputStream, 8, code, "xsd_metric_number_minus1[i]");
xsdMetricNumberMinus1 = code;
printf("XSD Metric Number Minus1[i]: %i\n", xsdMetricNumberMinus1);
int xsdMetricType;
int xsdMetricValue;
for (int j = 0; j <= xsdMetricNumberMinus1; j++)
{
sei_read_code(pDecodedMessageOutputStream, 8, code, "xsd_metric_type[i][j]");
xsdMetricType = code;
sei_read_code(pDecodedMessageOutputStream, 16, code, "xsd_metric_value[i][j]");
xsdMetricValue = code;
switch (xsdMetricType)
{
case 0: //PSNR
sei.m_xsdMetricValuePSNR = code;
printf("PSNR value: %0.2f\n", (double(xsdMetricValue)/100.0));
break;
case 1: //SSIM
sei.m_xsdMetricValueSSIM = code;
printf("SSIM value: %0.2f\n", double(xsdMetricValue/100.0));
break;
case 2: //W-PSNR
sei.m_xsdMetricValueWPSNR = code;
printf("W-PSNR value: %0.2f\n", double(xsdMetricValue/100.0));
break;
case 3: //WS-PSNR
sei.m_xsdMetricValueWSPSNR = code;
printf("WS-PSNR value: %0.2f\n", double(xsdMetricValue/100.0));
break;
default: //User Defined
break;
}
}
}
break;
}
}
void SEIReader::xParseSEIScalableNestingBinary(SEIScalableNesting &sei, const NalUnitType nalUnitType,
const uint32_t nuhLayerId, uint32_t payloadSize, const VPS *vps,
const SPS *sps, HRD &hrd, std::ostream *decodedMessageOutputStream,
std::vector<SeiPayload> *seiList)
{
uint32_t symbol;
SEIMessages seis;
output_sei_message_header(sei, decodedMessageOutputStream, payloadSize);
sei_read_flag(decodedMessageOutputStream, symbol, "sn_ols_flag"); sei.m_snOlsFlag = symbol;
sei_read_flag(decodedMessageOutputStream, symbol, "sn_subpic_flag"); sei.m_snSubpicFlag = symbol;
if (sei.m_snOlsFlag)
{
sei_read_uvlc(decodedMessageOutputStream, symbol, "sn_num_olss_minus1"); sei.m_snNumOlssMinus1 = symbol;
for (uint32_t i = 0; i <= sei.m_snNumOlssMinus1; i++)
{
sei_read_uvlc(decodedMessageOutputStream, symbol, "sn_ols_idx_delta_minus1[i]"); sei.m_snOlsIdxDeltaMinus1[i] = symbol;
}