Commit 7512abae authored by Frank Bossen's avatar Frank Bossen
Browse files

Merge branch 'fix_1464_sn_subpic_id_len' into 'master'

Fix #1464: Non-conforming values of sn_subpic_id_len_minus1

See merge request jvet/VVCSoftware_VTM!2021
parents 089336bb 57c25d73
......@@ -807,7 +807,7 @@ void EncGOP::xCreatePerPictureSEIMessages (int picInGOP, SEIMessages& seiMessage
}
}
void EncGOP::xCreateScalableNestingSEI(SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t>& subpicIDs)
void EncGOP::xCreateScalableNestingSEI(SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t>& subpicIDs, uint16_t maxSubpicIdInPic)
{
SEIMessages tmpMessages;
while (!nestedSeiMessages.empty())
......@@ -816,7 +816,7 @@ void EncGOP::xCreateScalableNestingSEI(SEIMessages& seiMessages, SEIMessages& ne
nestedSeiMessages.pop_front();
tmpMessages.push_back(sei);
SEIScalableNesting *nestingSEI = new SEIScalableNesting();
m_seiEncoder.initSEIScalableNesting(nestingSEI, tmpMessages, targetOLSs, targetLayers, subpicIDs);
m_seiEncoder.initSEIScalableNesting(nestingSEI, tmpMessages, targetOLSs, targetLayers, subpicIDs, maxSubpicIdInPic);
seiMessages.push_back(nestingSEI);
tmpMessages.clear();
}
......@@ -3543,6 +3543,9 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
std::string subPicDigest;
if (numSubpics > 1 && m_pcCfg->getSubpicDecodedPictureHashType() != HASHTYPE_NONE )
{
std::vector<uint16_t> subPicIdsInPic;
xGetSubpicIdsInPic(subPicIdsInPic, pcPic->cs->sps, pps);
uint16_t maxSubpicIdInPic = subPicIdsInPic.size() == 0 ? 0 : *std::max_element(subPicIdsInPic.begin(), subPicIdsInPic.end());
for (int subPicIdx = 0; subPicIdx < numSubpics; subPicIdx++)
{
const SubPic& subpic = pps->getSubPic(subPicIdx);
......@@ -3555,7 +3558,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
const std::vector<uint16_t> subPicIds = { (uint16_t)subpic.getSubPicID() };
std::vector<int> targetOLS;
std::vector<int> targetLayers = {pcPic->layerId};
xCreateScalableNestingSEI(trailingSeiMessages, nestedSEI, targetOLS, targetLayers, subPicIds);
xCreateScalableNestingSEI(trailingSeiMessages, nestedSEI, targetOLS, targetLayers, subPicIds, maxSubpicIdInPic);
}
}
......@@ -3608,34 +3611,13 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
const PPS* pps = pcSlice->getPPS();
std::vector<uint16_t> subpicIDs;
if (sps->getSubPicInfoPresentFlag())
{
if(sps->getSubPicIdMappingExplicitlySignalledFlag())
{
if(sps->getSubPicIdMappingPresentFlag())
{
subpicIDs = sps->getSubPicIds();
}
else
{
subpicIDs = pps->getSubPicIds();
}
}
else
{
const int numSubPics = sps->getNumSubPics();
subpicIDs.resize(numSubPics);
for (int i = 0 ; i < numSubPics; i++)
{
subpicIDs[i] = (uint16_t) i;
}
}
}
xGetSubpicIdsInPic(subpicIDs, sps, pps);
uint16_t maxSubpicIdInPic = subpicIDs.size() == 0 ? 0 : *std::max_element(subpicIDs.begin(), subpicIDs.end());
// Note (KJS): Using targetOLS = 0, 1 is as random as encapsulating the same SEIs in scalable nesting.
// This can just be seen as example regarding how to write scalable nesting, not what to write.
std::vector<int> targetOLS = {0, 1};
std::vector<int> targetLayers;
xCreateScalableNestingSEI(leadingSeiMessages, nestedSeiMessages, targetOLS, targetLayers, subpicIDs);
xCreateScalableNestingSEI(leadingSeiMessages, nestedSeiMessages, targetOLS, targetLayers, subpicIDs, maxSubpicIdInPic);
}
xWriteLeadingSEIMessages( leadingSeiMessages, duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS(), duData );
......@@ -3886,6 +3868,35 @@ void EncGOP::xGetBuffer( PicList& rcListPic,
return;
}
void EncGOP::xGetSubpicIdsInPic(std::vector<uint16_t>& subpicIDs, const SPS* sps, const PPS* pps)
{
subpicIDs.clear();
if (sps->getSubPicInfoPresentFlag())
{
if(sps->getSubPicIdMappingExplicitlySignalledFlag())
{
if(sps->getSubPicIdMappingPresentFlag())
{
subpicIDs = sps->getSubPicIds();
}
else
{
subpicIDs = pps->getSubPicIds();
}
}
else
{
const int numSubPics = sps->getNumSubPics();
subpicIDs.resize(numSubPics);
for (int i = 0 ; i < numSubPics; i++)
{
subpicIDs[i] = (uint16_t) i;
}
}
}
}
#if ENABLE_QPA
#ifndef BETA
......
......@@ -267,6 +267,7 @@ protected:
void xPicInitLMCS (Picture *pic, PicHeader *picHeader, Slice *slice);
void xGetBuffer ( PicList& rcListPic, std::list<PelUnitBuf*>& rcListPicYuvRecOut,
int iNumPicRcvd, int iTimeOffset, Picture*& rpcPic, int pocCurr, bool isField );
void xGetSubpicIdsInPic(std::vector<uint16_t>& subpicIDs, const SPS* sps, const PPS* pps);
#if JVET_O0756_CALCULATE_HDRMETRICS
void xCalculateHDRMetrics ( Picture* pcPic, double deltaE[hdrtoolslib::NB_REF_WHITE], double psnrL[hdrtoolslib::NB_REF_WHITE]);
......@@ -307,7 +308,7 @@ protected:
void xUpdateDuData(AccessUnit &testAU, std::deque<DUData> &duData);
void xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUData> &duData, const SPS *sps);
void xUpdateDuInfoSEI(SEIMessages &duInfoSeiMessages, SEIPictureTiming *pictureTimingSEI, int maxSubLayers);
void xCreateScalableNestingSEI(SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t>& subpicIDs);
void xCreateScalableNestingSEI(SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t>& subpicIDs, uint16_t maxSubpicIdInPic);
void xWriteSEI (NalUnitType naluType, SEIMessages& seiMessages, AccessUnit &accessUnit, AccessUnit::iterator &auPos, int temporalId);
void xWriteSEISeparately (NalUnitType naluType, SEIMessages& seiMessages, AccessUnit &accessUnit, AccessUnit::iterator &auPos, int temporalId);
void xClearSEIs(SEIMessages& seiMessages, bool deleteMessages);
......
......@@ -398,7 +398,7 @@ void SEIEncoder::initSEISampleAspectRatioInfo(SEISampleAspectRatioInfo* seiSampl
//! Note: The SEI message structures input into this function will become part of the scalable nesting SEI and will be
//! automatically freed, when the nesting SEI is disposed.
// either targetOLS or targetLayer should be active, call with empty vector for the inactive mode
void SEIEncoder::initSEIScalableNesting(SEIScalableNesting *scalableNestingSEI, SEIMessages &nestedSEIs, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t> &subpictureIDs)
void SEIEncoder::initSEIScalableNesting(SEIScalableNesting *scalableNestingSEI, SEIMessages &nestedSEIs, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t> &subpictureIDs, uint16_t maxSubpicIdInPic)
{
CHECK(!(m_isInitialized), "Scalable Nesting SEI already initialized ");
CHECK(!(scalableNestingSEI != NULL), "No Scalable Nesting SEI object passed");
......@@ -443,8 +443,8 @@ void SEIEncoder::initSEIScalableNesting(SEIScalableNesting *scalableNestingSEI,
scalableNestingSEI->m_snSubpicFlag = 1;
scalableNestingSEI->m_snNumSubpics = (uint32_t) subpictureIDs.size();
scalableNestingSEI->m_snSubpicId = subpictureIDs;
scalableNestingSEI->m_snSubpicIdLen = max(1, ceilLog2((*std::max_element(subpictureIDs.begin(), subpictureIDs.end())) + 1));
CHECK ( scalableNestingSEI->m_snSubpicIdLen > 15, "Subpicture ID too large. Length must be <= 15 bits");
scalableNestingSEI->m_snSubpicIdLen = max(1, ceilLog2(maxSubpicIdInPic + 1));
CHECK ( scalableNestingSEI->m_snSubpicIdLen > 16, "Subpicture ID too large. Length must be <= 16 bits");
}
scalableNestingSEI->m_nestedSEIs.clear();
for (SEIMessages::iterator it = nestedSEIs.begin(); it != nestedSEIs.end(); it++)
......
......@@ -72,7 +72,7 @@ public:
#if U0033_ALTERNATIVE_TRANSFER_CHARACTERISTICS_SEI
void initSEIAlternativeTransferCharacteristics(SEIAlternativeTransferCharacteristics *sei);
#endif
void initSEIScalableNesting(SEIScalableNesting *scalableNestingSEI, SEIMessages &nestedSEIs, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t> &subpictureIDs);
void initSEIScalableNesting(SEIScalableNesting *scalableNestingSEI, SEIMessages &nestedSEIs, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t> &subpictureIDs, uint16_t maxSubpicIdInPic);
void initDecodedPictureHashSEI(SEIDecodedPictureHash *sei, PelUnitBuf& pic, std::string &rHashString, const BitDepths &bitDepths);
void initSEIErp(SEIEquirectangularProjection *sei);
void initSEISphereRotation(SEISphereRotation *sei);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment