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.
*
* Copyright (c) 2010-2024, ITU/ISO/IEC

Karsten Suehring
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.
*/
#include "CommonLib/CommonDef.h"
#include "CommonLib/SEI.h"
#include "EncGOP.h"
#include "EncLib.h"

Karsten Suehring
committed
uint32_t calcMD5(const CPelUnitBuf& pic, PictureHash &digest, const BitDepths &bitDepths);
uint32_t calcCRC(const CPelUnitBuf& pic, PictureHash &digest, const BitDepths &bitDepths);
uint32_t calcChecksum(const CPelUnitBuf& pic, PictureHash &digest, const BitDepths &bitDepths);
std::string hashToString(const PictureHash &digest, int numChar);
//! \ingroup EncoderLib
//! \{
void SEIEncoder::initSEIFramePacking(SEIFramePacking *seiFramePacking, int currPicNum)
{
CHECK(!(m_isInitialized), "Unspecified error");
CHECK(!(seiFramePacking != nullptr), "Unspecified error");

Karsten Suehring
committed
seiFramePacking->m_arrangementId = m_pcCfg->getFramePackingArrangementSEIId();
seiFramePacking->m_arrangementCancelFlag = 0;
seiFramePacking->m_arrangementType = m_pcCfg->getFramePackingArrangementSEIType();
CHECK(!((seiFramePacking->m_arrangementType > 2) && (seiFramePacking->m_arrangementType < 6) ), "Unspecified error");
seiFramePacking->m_quincunxSamplingFlag = m_pcCfg->getFramePackingArrangementSEIQuincunx();
seiFramePacking->m_contentInterpretationType = m_pcCfg->getFramePackingArrangementSEIInterpretation();
seiFramePacking->m_spatialFlippingFlag = 0;
seiFramePacking->m_frame0FlippedFlag = 0;
seiFramePacking->m_fieldViewsFlag = (seiFramePacking->m_arrangementType == 2);
seiFramePacking->m_currentFrameIsFrame0Flag = ((seiFramePacking->m_arrangementType == 5) && (currPicNum&1) );
seiFramePacking->m_frame0SelfContainedFlag = 0;
seiFramePacking->m_frame1SelfContainedFlag = 0;
seiFramePacking->m_frame0GridPositionX = 0;
seiFramePacking->m_frame0GridPositionY = 0;
seiFramePacking->m_frame1GridPositionX = 0;
seiFramePacking->m_frame1GridPositionY = 0;
seiFramePacking->m_arrangementReservedByte = 0;
seiFramePacking->m_arrangementPersistenceFlag = true;
seiFramePacking->m_upsampledAspectRatio = 0;
}
Rickard Sjöberg
committed
void SEIEncoder::initSEIParameterSetsInclusionIndication(SEIParameterSetsInclusionIndication* seiParameterSetsInclusionIndication)
{
CHECK(!(m_isInitialized), "Unspecified error");
CHECK(!(seiParameterSetsInclusionIndication != nullptr), "Unspecified error");
Rickard Sjöberg
committed
seiParameterSetsInclusionIndication->m_selfContainedClvsFlag = m_pcCfg->getSelfContainedClvsFlag();
}
void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod* bp, bool noLeadingPictures)

Karsten Suehring
committed
{

Karsten Suehring
committed
CHECK(!(m_isInitialized), "bufferingPeriodSEI already initialized");
CHECK(bp == nullptr, "Need a bufferingPeriodSEI for initialization (got nullptr)");
const uint32_t initialCpbRemovalDelay = (90000 / 2); // 0.5 sec
bp->maxSublayers = m_pcCfg->getMaxTempLayer();
bp->cpbCount = 1;
for (auto hrdType: { HrdType::NAL, HrdType::VCL })
{
bp->hasHrdParams[hrdType] = true;
for (int sublayerIdx = 0; sublayerIdx < bp->maxSublayers; sublayerIdx++)
{
for (int j = 0; j < bp->cpbCount; j++)
{
bp->initialCpbRemoval[hrdType][sublayerIdx][j] = { initialCpbRemovalDelay, initialCpbRemovalDelay };
}
}
}
// We don't set concatenation_flag here. max_initial_removal_delay_for_concatenation depends on the usage scenario.
// The parameters could be added to config file, but as long as the initialisation of generic buffering parameters is
// not controllable, it does not seem to make sense to provide settings for these.
bp->concatenation = false;
bp->maxInitialRemovalDelayForConcatenation = initialCpbRemovalDelay;

Karsten Suehring
committed
bp->hasDuHrdParams = m_pcCfg->getNoPicPartitionFlag() == false;
bp->duCpbParamsInPicTimingSei = !m_pcCfg->getDecodingUnitInfoSEIEnabled();
bp->cpbInitialRemovalDelayLength = 16; // assuming 0.5 sec, log2( 90,000 * 0.5 ) = 16-bit

Karsten Suehring
committed
// Note: The following parameters require some knowledge about the GOP structure.
// Using getIntraPeriod() should be avoided though, because it assumes certain GOP
// properties, which are only valid in CTC.
// Still copying this setting from HM for consistency, improvements welcome
bool isRandomAccess = m_pcCfg->getIntraPeriod() > 0;
if( isRandomAccess )
{
bp->cpbRemovalDelayLength = 6; // 32 = 2^5 (plus 1)
bp->dpbOutputDelayLength = 6; // 32 + 3 = 2^6

Karsten Suehring
committed
}
else
{
bp->cpbRemovalDelayLength = 9; // max. 2^10
bp->dpbOutputDelayLength = 9; // max. 2^10

Karsten Suehring
committed
}
bp->duCpbRemovalDelayIncrementLength = 7; // ceil( log2( tick_divisor_minus2 + 2 ) )
bp->dpbOutputDelayDuLength = bp->dpbOutputDelayLength + bp->duCpbRemovalDelayIncrementLength;

Karsten Suehring
committed
//for the concatenation, it can be set to one during splicing.
//since the temporal layer HRDParameters is not ready, we assumed it is fixed
bp->cpbRemovalDelayDelta = 1;
if (m_pcCfg->getBpDeltasGOPStructure())
{
switch (m_pcCfg->getGOPSize())
{
case 8:
if (noLeadingPictures)
{
bp->cpbRemovalDelayDeltaVals = { 1, 2, 3, 6, 7 };
}
else
{
bp->cpbRemovalDelayDeltaVals = { 1, 2, 3 };
}
break;
case 16:
if (noLeadingPictures)
{
bp->cpbRemovalDelayDeltaVals = { 1, 2, 3, 4, 6, 7, 9, 14, 15 };
}
{
bp->cpbRemovalDelayDeltaVals = { 1, 2, 3, 6, 7 };
}
break;
default:
THROW("cpbRemovalDelayDelta not applicable for the GOP size");
break;
}
}
bp->cpbRemovalDelayDeltaVals.clear();
}
bp->hasSublayerDpbOutputOffsets = true;
const uint32_t lastSublayer = bp->maxSublayers - 1;
for (int sublayerIdx = 0; sublayerIdx <= lastSublayer; sublayerIdx++)
{
bp->dpbOutputTidOffset[sublayerIdx] =
std::max<int>(m_pcCfg->getMaxNumReorderPics(sublayerIdx) * (1 << (lastSublayer - sublayerIdx))
- m_pcCfg->getMaxNumReorderPics(lastSublayer),
0);
// A commercial encoder should track the buffer state for all layers and sub-layers
// to ensure CPB conformance. Such tracking is required for calculating alternative
// CPB parameters.
// Unfortunately VTM does not have such tracking. Thus we cannot encode alternative
bp->hasAltCpbParams = false;
bp->useAltCpbParams = false;

Karsten Suehring
committed
}
void SEIEncoder::initSEIErp(SEIEquirectangularProjection* seiEquirectangularProjection)
{
CHECK(!(m_isInitialized), "seiEquirectangularProjection already initialized");
CHECK(!(seiEquirectangularProjection != nullptr), "Need a seiEquirectangularProjection for initialization (got nullptr)");
seiEquirectangularProjection->m_erpCancelFlag = m_pcCfg->getErpSEICancelFlag();
if (!seiEquirectangularProjection->m_erpCancelFlag)
{
seiEquirectangularProjection->m_erpPersistenceFlag = m_pcCfg->getErpSEIPersistenceFlag();
seiEquirectangularProjection->m_erpGuardBandFlag = m_pcCfg->getErpSEIGuardBandFlag();
if (seiEquirectangularProjection->m_erpGuardBandFlag == 1)
{
seiEquirectangularProjection->m_erpGuardBandType = m_pcCfg->getErpSEIGuardBandType();
Loading
Loading full blame...