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
* 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 EncLib.cpp
\brief encoder class
*/
#include "EncLib.h"
#include "EncModeCtrl.h"
#include "AQp.h"
#include "EncCu.h"
#include "CommonLib/Picture.h"
#include "CommonLib/CommonDef.h"
#include "CommonLib/ChromaFormat.h"
#if ENABLE_SPLIT_PARALLELISM
#include <omp.h>
#endif
#include "CommonLib/ProfileLevelTier.h"

Karsten Suehring
committed
//! \ingroup EncoderLib
//! \{
// ====================================================================================================================
// Constructor / destructor / create / destroy
// ====================================================================================================================
EncLib::EncLib( EncLibCommon* encLibCommon )
: m_cListPic( encLibCommon->getPictureBuffer() )
, m_cEncALF( encLibCommon->getApsIdStart() )
, m_spsMap( encLibCommon->getSpsMap() )
, m_ppsMap( encLibCommon->getPpsMap() )
, m_apsMap( encLibCommon->getApsMap() )
, m_AUWriterIf( nullptr )

Karsten Suehring
committed
#if JVET_J0090_MEMORY_BANDWITH_MEASURE
, m_cacheModel()
#endif
, m_scalinglistAPS( nullptr )
, m_doPlt( true )
, m_vps( encLibCommon->getVPS() )

Karsten Suehring
committed
{
m_iPOCLast = -1;
m_iNumPicRcvd = 0;
m_uiNumAllPicCoded = 0;
m_iMaxRefPicNum = 0;
#if ENABLE_SIMD_OPT_BUFFER && defined(TARGET_SIMD_X86)

Karsten Suehring
committed
g_pelBufOP.initPelBufOpsX86();
#endif
#if JVET_O0756_CALCULATE_HDRMETRICS
m_metricTime = std::chrono::milliseconds(0);
#endif
memset(m_apss, 0, sizeof(m_apss));

Karsten Suehring
committed
}
EncLib::~EncLib()
{
}

Karsten Suehring
committed
{
m_iPOCLast = m_compositeRefEnabled ? -2 : -1;

Karsten Suehring
committed
// create processing unit classes
m_cGOPEncoder. create( );

Karsten Suehring
committed
#if ENABLE_SPLIT_PARALLELISM
m_numCuEncStacks = m_numSplitThreads == 1 ? 1 : NUM_RESERVERD_SPLIT_JOBS;
#else
m_numCuEncStacks = 1;
#endif
m_cCuEncoder = new EncCu [m_numCuEncStacks];
m_cInterSearch = new InterSearch [m_numCuEncStacks];
m_cIntraSearch = new IntraSearch [m_numCuEncStacks];
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
m_bilateralFilter = new BilateralFilter [m_numCuEncStacks];
#endif

Karsten Suehring
committed
m_cTrQuant = new TrQuant [m_numCuEncStacks];
m_CABACEncoder = new CABACEncoder [m_numCuEncStacks];
m_cRdCost = new RdCost [m_numCuEncStacks];

Karsten Suehring
committed
for( int jId = 0; jId < m_numCuEncStacks; jId++ )
{
m_cCuEncoder[jId]. create( this );
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
}
#else
m_cCuEncoder. create( this );
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
#endif
#if JVET_J0090_MEMORY_BANDWITH_MEASURE
m_cInterSearch.cacheAssign( &m_cacheModel );
#endif
m_cLoopFilter.create(floorLog2(m_maxCUWidth) - MIN_CU_LOG2);

Karsten Suehring
committed
m_cLoopFilter.initEncPicYuvBuffer(m_chromaFormatIDC, Size(getSourceWidth(), getSourceHeight()), getMaxCUWidth());
m_cReshaper = new EncReshape[m_numCuEncStacks];
#endif
if (m_lmcsEnabled)
for (int jId = 0; jId < m_numCuEncStacks; jId++)
{
m_cReshaper[jId].createEnc(getSourceWidth(), getSourceHeight(), m_maxCUWidth, m_maxCUHeight, m_bitDepth[COMPONENT_Y]);
}
#else
m_cReshaper.createEnc( getSourceWidth(), getSourceHeight(), m_maxCUWidth, m_maxCUHeight, m_bitDepth[COMPONENT_Y]);

Karsten Suehring
committed
if ( m_RCEnableRateControl )
{
#if JVET_AA0146_WRAP_AROUND_FIX
m_cRateCtrl.init(m_framesToBeEncoded, m_RCTargetBitrate, (int)((double)m_iFrameRate / m_temporalSubsampleRatio + 0.5), m_iGOPSize, m_sourceWidth, m_sourceHeight,
m_maxCUWidth, m_maxCUHeight, getBitDepth(CHANNEL_TYPE_LUMA), m_RCKeepHierarchicalBit, m_RCUseLCUSeparateModel, m_GOPList);
#else
m_cRateCtrl.init(m_framesToBeEncoded, m_RCTargetBitrate, (int)((double)m_iFrameRate / m_temporalSubsampleRatio + 0.5), m_iGOPSize, m_iSourceWidth, m_iSourceHeight,
m_maxCUWidth, m_maxCUHeight, getBitDepth(CHANNEL_TYPE_LUMA), m_RCKeepHierarchicalBit, m_RCUseLCUSeparateModel, m_GOPList);

Karsten Suehring
committed
}
#if JVET_AA0146_WRAP_AROUND_FIX
m_cEncALF.create(this, m_sourceWidth, m_sourceHeight, m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize, m_bitDepth, m_inputBitDepth);
#else
m_cEncALF.create(this, m_iSourceWidth, m_iSourceHeight, m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize, m_bitDepth, m_inputBitDepth);
#if JVET_X0071_CHROMA_BILATERAL_FILTER
if (m_bUseSAO || m_BIF || m_CCSAO || m_chromaBIF)
#endif
#else
#if JVET_X0071_CHROMA_BILATERAL_FILTER
if (m_bUseSAO || m_BIF || m_chromaBIF)
#if JVET_X0071_CHROMA_BILATERAL_FILTER
if (m_bUseSAO || m_CCSAO || m_chromaBIF)
#else
#if JVET_X0071_CHROMA_BILATERAL_FILTER
if (m_bUseSAO || m_chromaBIF)
#if JVET_AA0146_WRAP_AROUND_FIX
const uint32_t widthInCtus = (m_sourceWidth + m_maxCUWidth - 1) / m_maxCUWidth;
const uint32_t heightInCtus = (m_sourceHeight + m_maxCUHeight - 1) / m_maxCUHeight;
const uint32_t numCtuInFrame = widthInCtus * heightInCtus;
m_cEncSAO.create(m_sourceWidth, m_sourceHeight, m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize, (uint32_t)std::max(0, m_bitDepth[CHANNEL_TYPE_LUMA] - MAX_SAO_TRUNCATED_BITDEPTH), (uint32_t)std::max(0, m_bitDepth[CHANNEL_TYPE_CHROMA] - MAX_SAO_TRUNCATED_BITDEPTH));
#else
const uint32_t widthInCtus = (m_iSourceWidth + m_maxCUWidth - 1) / m_maxCUWidth;
const uint32_t heightInCtus = (m_iSourceHeight + m_maxCUHeight - 1) / m_maxCUHeight;
const uint32_t numCtuInFrame = widthInCtus * heightInCtus;
m_cEncSAO.create(m_iSourceWidth, m_iSourceHeight, m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize, (uint32_t)std::max(0, m_bitDepth[CHANNEL_TYPE_LUMA] - MAX_SAO_TRUNCATED_BITDEPTH), (uint32_t)std::max(0, m_bitDepth[CHANNEL_TYPE_CHROMA] - MAX_SAO_TRUNCATED_BITDEPTH));
m_cEncSAO.createEncData(m_saoCtuBoundary, numCtuInFrame);
}

Karsten Suehring
committed
}
void EncLib::destroy ()
{
// destroy processing unit classes
m_cGOPEncoder. destroy();
m_cSliceEncoder. destroy();

Karsten Suehring
committed
for( int jId = 0; jId < m_numCuEncStacks; jId++ )
{
m_cCuEncoder[jId].destroy();
}
#else
m_cCuEncoder. destroy();
#endif
if( m_alf )
{
m_cEncALF.destroy();
}
m_cEncSAO. destroy();
m_cLoopFilter. destroy();
m_cRateCtrl. destroy();
for (int jId = 0; jId < m_numCuEncStacks; jId++)
{
m_cReshaper[jId]. destroy();
}
#else

Karsten Suehring
committed
for( int jId = 0; jId < m_numCuEncStacks; jId++ )
{
m_cInterSearch[jId]. destroy();
m_cIntraSearch[jId]. destroy();
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
}
#else
m_cInterSearch. destroy();
m_cIntraSearch. destroy();
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
#endif

Karsten Suehring
committed
delete[] m_cCuEncoder;
delete[] m_cInterSearch;
delete[] m_cIntraSearch;
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
delete[] m_cTrQuant;
delete[] m_CABACEncoder;
delete[] m_cRdCost;

Karsten Suehring
committed
#endif
return;
}
void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
{
m_AUWriterIf = auWriterIf;
Vadim Seregin
committed
SPS &sps0 = *(m_spsMap.allocatePS( m_vps->getGeneralLayerIdx( m_layerId ) )); // NOTE: implementations that use more than 1 SPS need to be aware of activation issues.
PPS &pps0 = *( m_ppsMap.allocatePS( m_vps->getGeneralLayerIdx( m_layerId ) ) );
APS &aps0 = *( m_apsMap.allocatePS( SCALING_LIST_APS ) );
aps0.setAPSId( 0 );
aps0.setAPSType( SCALING_LIST_APS );

Karsten Suehring
committed
if (getAvoidIntraInDepLayer() && getNumRefLayers(m_vps->getGeneralLayerIdx( getLayerId())) > 0)
{
setIDRRefParamListPresent(true);
}

Karsten Suehring
committed
// initialize SPS
xInitSPS( sps0 );
xInitVPS( sps0 );

Karsten Suehring
committed

Karsten Suehring
committed
#if ENABLE_SPLIT_PARALLELISM
if( omp_get_dynamic() )
{
omp_set_dynamic( false );
}
omp_set_nested( true );
#endif
if (getUseCompositeRef() || getDependentRAPIndicationSEIEnabled())
{
sps0.setLongTermRefsPresent(true);
}

Karsten Suehring
committed
#if U0132_TARGET_BITS_SATURATION
if (m_RCCpbSaturationEnabled)
{
m_cRateCtrl.initHrdParam(sps0.getGeneralHrdParameters(), sps0.getOlsHrdParameters(), m_iFrameRate, m_RCInitialCpbFullness);

Karsten Suehring
committed
}
#endif

Karsten Suehring
committed
for( int jId = 0; jId < m_numCuEncStacks; jId++ )
{
m_cRdCost[jId].setCostMode ( m_costMode );
}
#else
m_cRdCost.setCostMode ( m_costMode );
#endif
// initialize PPS
#if JVET_AA0146_WRAP_AROUND_FIX
pps0.setPicWidthInLumaSamples( m_sourceWidth );
pps0.setPicHeightInLumaSamples( m_sourceHeight );
#else
pps0.setPicWidthInLumaSamples( m_iSourceWidth );
pps0.setPicHeightInLumaSamples( m_iSourceHeight );
#if JVET_R0068_ASPECT6_ENC_RESTRICTION
if (pps0.getPicWidthInLumaSamples() == sps0.getMaxPicWidthInLumaSamples() && pps0.getPicHeightInLumaSamples() == sps0.getMaxPicHeightInLumaSamples())
{
pps0.setConformanceWindow( sps0.getConformanceWindow() );
pps0.setConformanceWindowFlag( false );
}
else
{
pps0.setConformanceWindow( m_conformanceWindow );
pps0.setConformanceWindowFlag( m_conformanceWindow.getWindowEnabledFlag() );
}
#else
pps0.setConformanceWindow( m_conformanceWindow );

Karsten Suehring
committed
xInitPPS(pps0, sps0);
#if JVET_AA0093_DIVERSITY_CRITERION_FOR_ARMC
if (sps0.getUseAML())
{
sps0.setNumLambda(m_numQPOffset);
int maxBits = 0;
for (int idx = 0; idx < m_numQPOffset; idx++)
{
sps0.setQPOffsets(idx, m_qpOffsetList[idx]);
const uint32_t lambda = (uint32_t)LAMBDA_DEC_SIDE[min(max(26 + pps0.getPicInitQPMinus26() + m_qpOffsetList[idx] - 4 * ((int)m_isRA), 0), MAX_QP)];
sps0.setLambdaVal(idx, lambda);
for (int shift = 0; shift < 16; shift++)
if (lambda >> shift == 0)
{
if (shift > maxBits)
{
maxBits = shift;
}
break;
}
}
sps0.setMaxbitsLambdaVal(maxBits);
}
#endif

Karsten Suehring
committed
if (m_resChangeInClvsEnabled)
PPS &pps = *( m_ppsMap.allocatePS( ENC_PPS_ID_RPR ) );
Window& inputScalingWindow = pps0.getScalingWindow();
int scaledWidth = int( ( pps0.getPicWidthInLumaSamples() - SPS::getWinUnitX( sps0.getChromaFormatIdc() ) * ( inputScalingWindow.getWindowLeftOffset() + inputScalingWindow.getWindowRightOffset() ) ) / m_scalingRatioHor );
int minSizeUnit = std::max(8, 1 << sps0.getLog2MinCodingBlockSize());
int temp = scaledWidth / minSizeUnit;
int width = ( scaledWidth - ( temp * minSizeUnit) > 0 ? temp + 1 : temp ) * minSizeUnit;
int scaledHeight = int( ( pps0.getPicHeightInLumaSamples() - SPS::getWinUnitY( sps0.getChromaFormatIdc() ) * ( inputScalingWindow.getWindowTopOffset() + inputScalingWindow.getWindowBottomOffset() ) ) / m_scalingRatioVer );
temp = scaledHeight / minSizeUnit;
int height = ( scaledHeight - ( temp * minSizeUnit) > 0 ? temp + 1 : temp ) * minSizeUnit;
pps.setPicWidthInLumaSamples( width );
pps.setPicHeightInLumaSamples( height );
#if JVET_AC0096
pps.setSliceChromaQpFlag(true);
#endif
Window conformanceWindow;
conformanceWindow.setWindow( 0, ( width - scaledWidth ) / SPS::getWinUnitX( sps0.getChromaFormatIdc() ), 0, ( height - scaledHeight ) / SPS::getWinUnitY( sps0.getChromaFormatIdc() ) );
#if JVET_R0068_ASPECT6_ENC_RESTRICTION
if (pps.getPicWidthInLumaSamples() == sps0.getMaxPicWidthInLumaSamples() && pps.getPicHeightInLumaSamples() == sps0.getMaxPicHeightInLumaSamples())
{
pps.setConformanceWindow( sps0.getConformanceWindow() );
pps.setConformanceWindowFlag( false );
}
else
{
pps.setConformanceWindow( conformanceWindow );
pps.setConformanceWindowFlag( pps.getConformanceWindow().getWindowEnabledFlag() );
}
#else
pps.setConformanceWindow( conformanceWindow );
Window scalingWindow;
scalingWindow.setWindow( 0, ( width - scaledWidth ) / SPS::getWinUnitX( sps0.getChromaFormatIdc() ), 0, ( height - scaledHeight ) / SPS::getWinUnitY( sps0.getChromaFormatIdc() ) );
pps.setScalingWindow( scalingWindow );
Peter Chuang
committed
//register the width/height of the current pic into reference SPS
if (!sps0.getPPSValidFlag(pps.getPPSId()))
{
sps0.setPPSValidFlag(pps.getPPSId(), true);
sps0.setScalingWindowSizeInPPS(pps.getPPSId(), scaledWidth, scaledHeight);
}
int curSeqMaxPicWidthY = sps0.getMaxPicWidthInLumaSamples(); // pic_width_max_in_luma_samples
int curSeqMaxPicHeightY = sps0.getMaxPicHeightInLumaSamples(); // pic_height_max_in_luma_samples
int curPicWidthY = width; // pic_width_in_luma_samples
int curPicHeightY = height; // pic_height_in_luma_samples
Peter Chuang
committed
int max8MinCbSizeY = std::max((int)8, (1 << sps0.getLog2MinCodingBlockSize())); // Max(8, MinCbSizeY)
Peter Chuang
committed
//Warning message of potential scaling window size violation
Peter Chuang
committed
for (int i = 0; i < 64; i++)
{
if (sps0.getPPSValidFlag(i))
{
if ((scaledWidth * curSeqMaxPicWidthY) < sps0.getScalingWindowSizeInPPS(i).width * (curPicWidthY - max8MinCbSizeY))
printf("Potential violation: (curScaledWIdth * curSeqMaxPicWidthY) should be greater than or equal to refScaledWidth * (curPicWidthY - max(8, MinCbSizeY)\n");
if ((scaledHeight * curSeqMaxPicHeightY) < sps0.getScalingWindowSizeInPPS(i).height * (curPicHeightY - max8MinCbSizeY))
printf("Potential violation: (curScaledHeight * curSeqMaxPicHeightY) should be greater than or equal to refScaledHeight * (curPicHeightY - max(8, MinCbSizeY)\n");
}
}
// disable picture partitioning for scaled RPR pictures (slice/tile config only provided for the original resolution)
m_noPicPartitionFlag = true;
xInitPPS( pps, sps0 ); // will allocate memory for and initialize pps.pcv inside
if( pps.getWrapAroundEnabledFlag() )
{
int minCbSizeY = (1 << sps0.getLog2MinCodingBlockSize());
pps.setPicWidthMinusWrapAroundOffset ((pps.getPicWidthInLumaSamples()/minCbSizeY) - (m_wrapAroundOffset * pps.getPicWidthInLumaSamples() / pps0.getPicWidthInLumaSamples() / minCbSizeY) );
pps.setWrapAroundOffset (minCbSizeY * (pps.getPicWidthInLumaSamples() / minCbSizeY - pps.getPicWidthMinusWrapAroundOffset()));
pps.setPicWidthMinusWrapAroundOffset (0);
#if JVET_AG0116
if (m_resChangeInClvsEnabled && (m_rprFunctionalityTestingEnabledFlag || m_gopBasedRPREnabledFlag))
#else
if (m_resChangeInClvsEnabled && m_rprFunctionalityTestingEnabledFlag)
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
{
// allocate PPS that can be used
double scalingRatioHor = m_scalingRatioHor2;
double scalingRatioVer = m_scalingRatioVer2;
PPS& pps = *(m_ppsMap.allocatePS(ENC_PPS_ID_RPR2));
Window& inputScalingWindow = pps0.getScalingWindow();
int scaledWidth = int((pps0.getPicWidthInLumaSamples() - SPS::getWinUnitX(sps0.getChromaFormatIdc()) * (inputScalingWindow.getWindowLeftOffset() + inputScalingWindow.getWindowRightOffset())) / scalingRatioHor);
int minSizeUnit = std::max(8, 1 << sps0.getLog2MinCodingBlockSize());
int temp = scaledWidth / minSizeUnit;
int width = (scaledWidth - (temp * minSizeUnit) > 0 ? temp + 1 : temp) * minSizeUnit;
int scaledHeight = int((pps0.getPicHeightInLumaSamples() - SPS::getWinUnitY(sps0.getChromaFormatIdc()) * (inputScalingWindow.getWindowTopOffset() + inputScalingWindow.getWindowBottomOffset())) / scalingRatioVer);
temp = scaledHeight / minSizeUnit;
int height = (scaledHeight - (temp * minSizeUnit) > 0 ? temp + 1 : temp) * minSizeUnit;
pps.setPicWidthInLumaSamples(width);
pps.setPicHeightInLumaSamples(height);
pps.setSliceChromaQpFlag(true);
Window conformanceWindow;
conformanceWindow.setWindow(0, (width - scaledWidth) / SPS::getWinUnitX(sps0.getChromaFormatIdc()), 0, (height - scaledHeight) / SPS::getWinUnitY(sps0.getChromaFormatIdc()));
#if JVET_R0068_ASPECT6_ENC_RESTRICTION
if (pps.getPicWidthInLumaSamples() == sps0.getMaxPicWidthInLumaSamples() && pps.getPicHeightInLumaSamples() == sps0.getMaxPicHeightInLumaSamples())
{
pps.setConformanceWindow(sps0.getConformanceWindow());
pps.setConformanceWindowFlag(false);
}
else
{
pps.setConformanceWindow(conformanceWindow);
pps.setConformanceWindowFlag(pps.getConformanceWindow().getWindowEnabledFlag());
}
#else
pps.setConformanceWindow(conformanceWindow);
#endif
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
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
Window scalingWindow;
scalingWindow.setWindow(0, (width - scaledWidth) / SPS::getWinUnitX(sps0.getChromaFormatIdc()), 0, (height - scaledHeight) / SPS::getWinUnitY(sps0.getChromaFormatIdc()));
pps.setScalingWindow(scalingWindow);
//register the width/height of the current pic into reference SPS
if (!sps0.getPPSValidFlag(pps.getPPSId()))
{
sps0.setPPSValidFlag(pps.getPPSId(), true);
sps0.setScalingWindowSizeInPPS(pps.getPPSId(), scaledWidth, scaledHeight);
}
int curSeqMaxPicWidthY = sps0.getMaxPicWidthInLumaSamples(); // pic_width_max_in_luma_samples
int curSeqMaxPicHeightY = sps0.getMaxPicHeightInLumaSamples(); // pic_height_max_in_luma_samples
int curPicWidthY = width; // pic_width_in_luma_samples
int curPicHeightY = height; // pic_height_in_luma_samples
int max8MinCbSizeY = std::max((int)8, (1 << sps0.getLog2MinCodingBlockSize())); // Max(8, MinCbSizeY)
//Warning message of potential scaling window size violation
for (int i = 0; i < 64; i++)
{
if (sps0.getPPSValidFlag(i))
{
if ((scaledWidth * curSeqMaxPicWidthY) < sps0.getScalingWindowSizeInPPS(i).width * (curPicWidthY - max8MinCbSizeY))
{
printf("Potential violation: (curScaledWIdth * curSeqMaxPicWidthY) should be greater than or equal to refScaledWidth * (curPicWidthY - max(8, MinCbSizeY)\n");
}
if ((scaledHeight * curSeqMaxPicHeightY) < sps0.getScalingWindowSizeInPPS(i).height * (curPicHeightY - max8MinCbSizeY))
{
printf("Potential violation: (curScaledHeight * curSeqMaxPicHeightY) should be greater than or equal to refScaledHeight * (curPicHeightY - max(8, MinCbSizeY)\n");
}
}
}
// disable picture partitioning for scaled RPR pictures (slice/tile config only provided for the original resolution)
m_noPicPartitionFlag = true;
xInitPPS(pps, sps0); // will allocate memory for and initialize pps.pcv inside
if (pps.getWrapAroundEnabledFlag())
{
int minCbSizeY = (1 << sps0.getLog2MinCodingBlockSize());
pps.setPicWidthMinusWrapAroundOffset((pps.getPicWidthInLumaSamples() / minCbSizeY) - (m_wrapAroundOffset * pps.getPicWidthInLumaSamples() / pps0.getPicWidthInLumaSamples() / minCbSizeY));
pps.setWrapAroundOffset(minCbSizeY * (pps.getPicWidthInLumaSamples() / minCbSizeY - pps.getPicWidthMinusWrapAroundOffset()));
}
else
{
pps.setPicWidthMinusWrapAroundOffset(0);
pps.setWrapAroundOffset(0);
}
}
#if JVET_AG0116
if (m_resChangeInClvsEnabled && (m_rprFunctionalityTestingEnabledFlag || m_gopBasedRPREnabledFlag))
#else
if (m_resChangeInClvsEnabled && m_rprFunctionalityTestingEnabledFlag)
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
582
583
584
585
586
587
588
589
590
591
592
593
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
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
{
// allocate PPS that can be used
double scalingRatioHor = m_scalingRatioHor3;
double scalingRatioVer = m_scalingRatioVer3;
PPS& pps = *(m_ppsMap.allocatePS(ENC_PPS_ID_RPR3));
Window& inputScalingWindow = pps0.getScalingWindow();
int scaledWidth = int((pps0.getPicWidthInLumaSamples() - SPS::getWinUnitX(sps0.getChromaFormatIdc()) * (inputScalingWindow.getWindowLeftOffset() + inputScalingWindow.getWindowRightOffset())) / scalingRatioHor);
int minSizeUnit = std::max(8, 1 << sps0.getLog2MinCodingBlockSize());
int temp = scaledWidth / minSizeUnit;
int width = (scaledWidth - (temp * minSizeUnit) > 0 ? temp + 1 : temp) * minSizeUnit;
int scaledHeight = int((pps0.getPicHeightInLumaSamples() - SPS::getWinUnitY(sps0.getChromaFormatIdc()) * (inputScalingWindow.getWindowTopOffset() + inputScalingWindow.getWindowBottomOffset())) / scalingRatioVer);
temp = scaledHeight / minSizeUnit;
int height = (scaledHeight - (temp * minSizeUnit) > 0 ? temp + 1 : temp) * minSizeUnit;
pps.setPicWidthInLumaSamples(width);
pps.setPicHeightInLumaSamples(height);
pps.setSliceChromaQpFlag(true);
Window conformanceWindow;
conformanceWindow.setWindow(0, (width - scaledWidth) / SPS::getWinUnitX(sps0.getChromaFormatIdc()), 0, (height - scaledHeight) / SPS::getWinUnitY(sps0.getChromaFormatIdc()));
#if JVET_R0068_ASPECT6_ENC_RESTRICTION
if (pps.getPicWidthInLumaSamples() == sps0.getMaxPicWidthInLumaSamples() && pps.getPicHeightInLumaSamples() == sps0.getMaxPicHeightInLumaSamples())
{
pps.setConformanceWindow(sps0.getConformanceWindow());
pps.setConformanceWindowFlag(false);
}
else
{
pps.setConformanceWindow(conformanceWindow);
pps.setConformanceWindowFlag(pps.getConformanceWindow().getWindowEnabledFlag());
}
#else
pps.setConformanceWindow(conformanceWindow);
#endif
Window scalingWindow;
scalingWindow.setWindow(0, (width - scaledWidth) / SPS::getWinUnitX(sps0.getChromaFormatIdc()), 0, (height - scaledHeight) / SPS::getWinUnitY(sps0.getChromaFormatIdc()));
pps.setScalingWindow(scalingWindow);
//register the width/height of the current pic into reference SPS
if (!sps0.getPPSValidFlag(pps.getPPSId()))
{
sps0.setPPSValidFlag(pps.getPPSId(), true);
sps0.setScalingWindowSizeInPPS(pps.getPPSId(), scaledWidth, scaledHeight);
}
int curSeqMaxPicWidthY = sps0.getMaxPicWidthInLumaSamples(); // pic_width_max_in_luma_samples
int curSeqMaxPicHeightY = sps0.getMaxPicHeightInLumaSamples(); // pic_height_max_in_luma_samples
int curPicWidthY = width; // pic_width_in_luma_samples
int curPicHeightY = height; // pic_height_in_luma_samples
int max8MinCbSizeY = std::max((int)8, (1 << sps0.getLog2MinCodingBlockSize())); // Max(8, MinCbSizeY)
//Warning message of potential scaling window size violation
for (int i = 0; i < 64; i++)
{
if (sps0.getPPSValidFlag(i))
{
if ((scaledWidth * curSeqMaxPicWidthY) < sps0.getScalingWindowSizeInPPS(i).width * (curPicWidthY - max8MinCbSizeY))
{
printf("Potential violation: (curScaledWIdth * curSeqMaxPicWidthY) should be greater than or equal to refScaledWidth * (curPicWidthY - max(8, MinCbSizeY)\n");
}
if ((scaledHeight * curSeqMaxPicHeightY) < sps0.getScalingWindowSizeInPPS(i).height * (curPicHeightY - max8MinCbSizeY))
{
printf("Potential violation: (curScaledHeight * curSeqMaxPicHeightY) should be greater than or equal to refScaledHeight * (curPicHeightY - max(8, MinCbSizeY)\n");
}
}
}
// disable picture partitioning for scaled RPR pictures (slice/tile config only provided for the original resolution)
m_noPicPartitionFlag = true;
xInitPPS(pps, sps0); // will allocate memory for and initialize pps.pcv inside
if (pps.getWrapAroundEnabledFlag())
{
int minCbSizeY = (1 << sps0.getLog2MinCodingBlockSize());
pps.setPicWidthMinusWrapAroundOffset((pps.getPicWidthInLumaSamples() / minCbSizeY) - (m_wrapAroundOffset * pps.getPicWidthInLumaSamples() / pps0.getPicWidthInLumaSamples() / minCbSizeY));
pps.setWrapAroundOffset(minCbSizeY * (pps.getPicWidthInLumaSamples() / minCbSizeY - pps.getPicWidthMinusWrapAroundOffset()));
}
else
{
pps.setPicWidthMinusWrapAroundOffset(0);
pps.setWrapAroundOffset(0);
}
}
#endif

Karsten Suehring
committed
#if ER_CHROMA_QP_WCG_PPS
if (m_wcgChromaQpControl.isEnabled())
{
PPS &pps1=*(m_ppsMap.allocatePS(1));
xInitPPS(pps1, sps0);
}
#endif
if (getUseCompositeRef())
{
PPS &pps2 = *(m_ppsMap.allocatePS(2));
xInitPPS(pps2, sps0);
xInitPPSforLT(pps2);
}

Karsten Suehring
committed
// initialize processing unit classes
m_cGOPEncoder. init( this );
m_cSliceEncoder.init( this, sps0 );

Karsten Suehring
committed
for( int jId = 0; jId < m_numCuEncStacks; jId++ )
{
// precache a few objects
for( int i = 0; i < 10; i++ )
{
auto x = m_ctxCache[jId].get();
m_ctxCache[jId].cache( x );

Karsten Suehring
committed
}
m_cCuEncoder[jId].init( this, sps0, jId );
// initialize transform & quantization class
m_cTrQuant[jId].init( jId == 0 ? nullptr : m_cTrQuant[0].getQuant(),
1 << m_log2MaxTbSize,

Karsten Suehring
committed
m_useRDOQ,
m_useRDOQTS,
#if T0196_SELECTIVE_RDOQ
m_useSelectiveRDOQ,
#endif

Karsten Suehring
committed
);
// initialize encoder search class
CABACWriter* cabacEstimator = m_CABACEncoder[jId].getCABACEstimator( &sps0 );
m_cIntraSearch[jId].init( this,
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
&m_cTrQuant[jId],
&m_cRdCost[jId],
cabacEstimator,
getCtxCache( jId ), m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize
, sps0.getBitDepth(CHANNEL_TYPE_LUMA)

Karsten Suehring
committed
m_cInterSearch[jId].init( this,
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
&m_cTrQuant[jId],
m_iSearchRange,
m_bipredSearchRange,
m_motionEstimationSearchMethod,
m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize, &m_cRdCost[jId], cabacEstimator, getCtxCache( jId )

Karsten Suehring
committed
// link temporary buffets from intra search with inter search to avoid unnecessary memory overhead
m_cInterSearch[jId].setTempBuffers( m_cIntraSearch[jId].getSplitCSBuf(), m_cIntraSearch[jId].getFullCSBuf(), m_cIntraSearch[jId].getSaveCSBuf() );
}
#else // ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM

Karsten Suehring
committed
// initialize transform & quantization class
m_cTrQuant.init( nullptr,

Karsten Suehring
committed
m_useRDOQ,
m_useRDOQTS,
#if T0196_SELECTIVE_RDOQ
m_useSelectiveRDOQ,
#endif

Karsten Suehring
committed
);
// initialize encoder search class
CABACWriter* cabacEstimator = m_CABACEncoder.getCABACEstimator(&sps0);
m_cIntraSearch.init( this,
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
&m_cTrQuant,
&m_cRdCost,
cabacEstimator,
getCtxCache(), m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize
, sps0.getBitDepth(CHANNEL_TYPE_LUMA)

Karsten Suehring
committed
m_cInterSearch.init( this,
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
&m_cTrQuant,
m_iSearchRange,
m_bipredSearchRange,
m_motionEstimationSearchMethod,
m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize, &m_cRdCost, cabacEstimator, getCtxCache()
#if JVET_Z0153_IBC_EXT_REF
, pps0.getPicWidthInLumaSamples()
#endif

Karsten Suehring
committed
// link temporary buffets from intra search with inter search to avoid unneccessary memory overhead
m_cInterSearch.setTempBuffers( m_cIntraSearch.getSplitCSBuf(), m_cIntraSearch.getFullCSBuf(), m_cIntraSearch.getSaveCSBuf() );
#endif // ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM
#if JVET_AE0159_FIBC || JVET_AE0059_INTER_CCCM || JVET_AE0078_IBC_LIC_EXTENSION || JVET_AF0073_INTER_CCP_MERGE
m_cInterSearch.setIntraPrediction(&m_cIntraSearch);
Wei Chen
committed
#endif
#if JVET_AH0200_INTRA_TMP_BV_REORDER
m_cIntraSearch.setInterPrediction(&m_cInterSearch);
Pekka Astola
committed
#endif

Karsten Suehring
committed
m_iMaxRefPicNum = 0;
#if ER_CHROMA_QP_WCG_PPS
if( m_wcgChromaQpControl.isEnabled() )
{
xInitScalingLists( sps0, *m_apsMap.getPS( 1 ) );
xInitScalingLists( sps0, aps0 );

Karsten Suehring
committed
}
else
#endif
{
xInitScalingLists( sps0, aps0 );

Karsten Suehring
committed
}
if (m_resChangeInClvsEnabled)
xInitScalingLists( sps0, *m_apsMap.getPS( ENC_PPS_ID_RPR ) );
if (getUseCompositeRef())
{
Picture *picBg = new Picture;
picBg->create(
Fabrice Le Léannec
committed
sps0.getRprEnabledFlag(),
sps0.getGDREnabledFlag(),
sps0.getWrapAroundEnabledFlag(), sps0.getChromaFormatIdc(),
Size(pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples()), sps0.getMaxCUWidth(),
sps0.getMaxCUWidth() + EXT_PICTURE_SIZE, false, m_layerId, getGopBasedTemporalFilterEnabled());
picBg->getRecoBuf().fill(0);
picBg->finalInit( m_vps, sps0, pps0, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
picBg->allocateNewSlice();
picBg->createSpliceIdx(pps0.pcv->sizeInCtus);
m_cGOPEncoder.setPicBg(picBg);
Picture *picOrig = new Picture;
picOrig->create(
Fabrice Le Léannec
committed
sps0.getRprEnabledFlag(),
sps0.getGDREnabledFlag(),
sps0.getWrapAroundEnabledFlag(), sps0.getChromaFormatIdc(),
Size(pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples()), sps0.getMaxCUWidth(),
sps0.getMaxCUWidth() + EXT_PICTURE_SIZE, false, m_layerId, getGopBasedTemporalFilterEnabled());
picOrig->getOrigBuf().fill(0);
m_cGOPEncoder.setPicOrig(picOrig);
}

Karsten Suehring
committed
}
void EncLib::xInitScalingLists( SPS &sps, APS &aps )

Karsten Suehring
committed
{
// Initialise scaling lists
// The encoder will only use the SPS scaling lists. The PPS will never be marked present.
const int maxLog2TrDynamicRange[MAX_NUM_CHANNEL_TYPE] =
{
sps.getMaxLog2TrDynamicRange(CHANNEL_TYPE_LUMA),
sps.getMaxLog2TrDynamicRange(CHANNEL_TYPE_CHROMA)

Karsten Suehring
committed
};
Quant* quant = getTrQuant()->getQuant();
if(getUseScalingListId() == SCALING_LIST_OFF)
{
quant->setFlatScalingList(maxLog2TrDynamicRange, sps.getBitDepths());
quant->setUseScalingList(false);

Karsten Suehring
committed
for( int jId = 1; jId < m_numCuEncStacks; jId++ )
{
getTrQuant( jId )->getQuant()->setFlatScalingList( maxLog2TrDynamicRange, sps.getBitDepths() );
getTrQuant( jId )->getQuant()->setUseScalingList( false );
}
#endif

Karsten Suehring
committed
}
else if(getUseScalingListId() == SCALING_LIST_DEFAULT)
{
aps.getScalingList().setDefaultScalingList ();
quant->setScalingList( &( aps.getScalingList() ), maxLog2TrDynamicRange, sps.getBitDepths() );

Karsten Suehring
committed
quant->setUseScalingList(true);

Karsten Suehring
committed
for( int jId = 1; jId < m_numCuEncStacks; jId++ )
{
getTrQuant( jId )->getQuant()->setUseScalingList( true );
}
sps.setDisableScalingMatrixForLfnstBlks(getDisableScalingMatrixForLfnstBlks());

Karsten Suehring
committed
#endif
}
else if(getUseScalingListId() == SCALING_LIST_FILE_READ)
{
aps.getScalingList().setDefaultScalingList();
CHECK( aps.getScalingList().xParseScalingList( getScalingListFileName() ), "Error Parsing Scaling List Input File" );
aps.getScalingList().checkDcOfMatrix();
if( aps.getScalingList().isNotDefaultScalingList() == false )
{
setUseScalingListId( SCALING_LIST_DEFAULT );
}
aps.getScalingList().setChromaScalingListPresentFlag((sps.getChromaFormatIdc()!=CHROMA_400));
quant->setScalingList( &( aps.getScalingList() ), maxLog2TrDynamicRange, sps.getBitDepths() );

Karsten Suehring
committed
quant->setUseScalingList(true);

Karsten Suehring
committed
for( int jId = 1; jId < m_numCuEncStacks; jId++ )
{
getTrQuant( jId )->getQuant()->setUseScalingList( true );
}
Adarsh Krishnan Ramasubramonian
committed
#endif
sps.setDisableScalingMatrixForLfnstBlks(getDisableScalingMatrixForLfnstBlks());

Karsten Suehring
committed
}
else
{
THROW("error : ScalingList == " << getUseScalingListId() << " not supported\n");
}
if( getUseScalingListId() == SCALING_LIST_FILE_READ )

Karsten Suehring
committed
{
// Prepare delta's:
Chen-Yen Lai
committed
for (uint32_t scalingListId = 0; scalingListId < 28; scalingListId++)
{
Hongbin Zhang
committed
if (aps.getScalingList().getChromaScalingListPresentFlag()||aps.getScalingList().isLumaScalingList(scalingListId))
Chen-Yen Lai
committed
aps.getScalingList().checkPredMode(scalingListId);
Chen-Yen Lai
committed
}

Karsten Suehring
committed
}
}
void EncLib::xInitPPSforLT(PPS& pps)
{
pps.setOutputFlagPresentFlag(true);
pps.setDeblockingFilterControlPresentFlag(true);
pps.setPPSDeblockingFilterDisabledFlag(true);
}

Karsten Suehring
committed
// ====================================================================================================================
// Public member functions
// ====================================================================================================================
void EncLib::deletePicBuffer()
{
PicList::iterator iterPic = m_cListPic.begin();
int iSize = int( m_cListPic.size() );
for ( int i = 0; i < iSize; i++ )
{
Picture* pcPic = *(iterPic++);
pcPic->destroy();
// get rid of the qpadaption layer
while( pcPic->aqlayer.size() )
{
delete pcPic->aqlayer.back(); pcPic->aqlayer.pop_back();
}
delete pcPic;
pcPic = NULL;
}

Karsten Suehring
committed
}
bool EncLib::encodePrep(bool flush, PelStorage* pcPicYuvOrg, const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut, int& iNumEncoded
#if JVET_AG0116
, PelStorage** ppcPicYuvRPR
#endif
)
{
if( m_compositeRefEnabled && m_cGOPEncoder.getPicBg()->getSpliceFull() && m_iPOCLast >= 10 && m_iNumPicRcvd == 0 && m_cGOPEncoder.getEncodedLTRef() == false )
{
Picture* picCurr = NULL;
xGetNewPicBuffer( rcListPicYuvRecOut, picCurr, 2 );
const PPS *pps = m_ppsMap.getPS( 2 );
const SPS *sps = m_spsMap.getPS( pps->getSPSId() );
picCurr->M_BUFS( 0, PIC_ORIGINAL ).copyFrom( m_cGOPEncoder.getPicBg()->getRecoBuf() );
picCurr->finalInit( m_vps, *sps, *pps, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
picCurr->poc = m_iPOCLast - 1;
m_iPOCLast -= 2;
if( getUseAdaptiveQP() )
{
AQpPreanalyzer::preanalyze( picCurr );
}
if( m_RCEnableRateControl )
{
m_cRateCtrl.initRCGOP( m_iNumPicRcvd );
}
m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, false, false, snrCSC,
m_printFrameMSE,
#if MSSIM_UNIFORM_METRICS_LOG
m_printMSSSIM,
#endif
true, 0);
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
#if JVET_O0756_CALCULATE_HDRMETRICS
m_metricTime = m_cGOPEncoder.getMetricTime();
#endif
m_cGOPEncoder.setEncodedLTRef( true );
if( m_RCEnableRateControl )
{
m_cRateCtrl.destroyRCGOP();
}
iNumEncoded = 0;
m_iNumPicRcvd = 0;
}
//PROF_ACCUM_AND_START_NEW_SET( getProfilerPic(), P_GOP_LEVEL );
if( pcPicYuvOrg != NULL )
{
// get original YUV
Picture* pcPicCurr = NULL;
int ppsID = -1; // Use default PPS ID
#if ER_CHROMA_QP_WCG_PPS
if( getWCGChromaQPControl().isEnabled() )
{
ppsID = getdQPs()[m_iPOCLast / ( m_compositeRefEnabled ? 2 : 1 ) + 1];
ppsID += ( getSwitchPOC() != -1 && ( m_iPOCLast + 1 >= getSwitchPOC() ) ? 1 : 0 );
}
#endif
if( m_resChangeInClvsEnabled && m_intraPeriod == -1 )
{
const int poc = m_iPOCLast + ( m_compositeRefEnabled ? 2 : 1 );
#if JVET_AC0096
if (!(m_resChangeInClvsEnabled && m_rprFunctionalityTestingEnabledFlag))
{
ppsID = 0;
}
#else
#if JVET_AC0096
if (m_resChangeInClvsEnabled && m_rprFunctionalityTestingEnabledFlag)
{
if (poc % m_rprSwitchingSegmentSize == 0)
{
int currPoc = poc + m_FrameSkip;
int rprSegment = getRprSwitchingSegment(currPoc);
ppsID = getRprSwitchingPPSID(rprSegment);
m_gopRprPpsId = ppsID;
}
else
{
ppsID = m_gopRprPpsId;
}
}
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
#if JVET_AG0116
else if (m_resChangeInClvsEnabled && m_gopBasedRPREnabledFlag && (m_iQP >= getGOPBasedRPRQPThreshold()))
{
double upscaledPSNR = 0.0;
if (poc % getGOPSize() == 0)
{
int xScale = 32768;
int yScale = 32768;
std::pair<int, int> downScalingRatio = std::pair<int, int>(xScale, yScale);
xScale = 8192;
yScale = 8192;
std::pair<int, int> upScalingRatio = std::pair<int, int>(xScale, yScale);
const PPS* orgPPS = m_ppsMap.getPS(0);
const SPS* orgSPS = m_spsMap.getPS(orgPPS->getSPSId());
const ChromaFormat chFormatIdc = orgSPS->getChromaFormatIdc();
const PPS* pTempPPS = m_ppsMap.getPS(ENC_PPS_ID_RPR);
Picture::rescalePicture(downScalingRatio, *pcPicYuvOrg, orgPPS->getScalingWindow(), *ppcPicYuvRPR[1], pTempPPS->getScalingWindow(), chFormatIdc, orgSPS->getBitDepths(), true, true,
orgSPS->getHorCollocatedChromaFlag(), orgSPS->getVerCollocatedChromaFlag());
Picture::rescalePicture(upScalingRatio, *ppcPicYuvRPR[1], orgPPS->getScalingWindow(), *ppcPicYuvRPR[0], pTempPPS->getScalingWindow(), chFormatIdc, orgSPS->getBitDepths(), true, false,
orgSPS->getHorCollocatedChromaFlag(), orgSPS->getVerCollocatedChromaFlag());
// Calculate PSNR
const Pel* pSrc0 = pcPicYuvOrg->get(COMPONENT_Y).bufAt(0, 0);
const Pel* pSrc1 = ppcPicYuvRPR[0]->get(COMPONENT_Y).bufAt(0, 0);
uint64_t totalDiff = 0;
for (int y = 0; y < pcPicYuvOrg->get(COMPONENT_Y).height; y++)
{
for (int x = 0; x < pcPicYuvOrg->get(COMPONENT_Y).width; x++)
{
int diff = pSrc0[x] - pSrc1[x];
totalDiff += uint64_t(diff) * uint64_t(diff);
}
pSrc0 += pcPicYuvOrg->get(COMPONENT_Y).stride;
pSrc1 += ppcPicYuvRPR[0]->get(COMPONENT_Y).stride;
}
const uint32_t maxval = 255 << (orgSPS->getBitDepth(CHANNEL_TYPE_LUMA) - 8);
upscaledPSNR = totalDiff ? 10.0 * log10((double)maxval * maxval * orgPPS->getPicWidthInLumaSamples() * orgPPS->getPicHeightInLumaSamples() / (double)totalDiff) : 999.99;
}
if (poc % getGOPSize() == 0)
{
const int qpBias = 37;
if ((m_psnrThresholdRPR - (m_iQP - qpBias) * 0.5) < upscaledPSNR)
{
ppsID = ENC_PPS_ID_RPR;
}
else
{
if ((m_psnrThresholdRPR2 - (m_iQP - qpBias) * 0.5) < upscaledPSNR)
{
ppsID = ENC_PPS_ID_RPR2;
}
else
{
if ((m_psnrThresholdRPR3 - (m_iQP - qpBias) * 0.5) < upscaledPSNR)
{
ppsID = ENC_PPS_ID_RPR3;
}
else
{
ppsID = 0;
}
}
}
m_gopRprPpsId = ppsID;
}
else
{
ppsID = m_gopRprPpsId;
}
}
#endif
else
{
bApplyRpr |= (m_switchPocPeriod < 0); // RPR applied for all pictures
bApplyRpr |= (m_switchPocPeriod > 0) && (poc / m_switchPocPeriod % 2); // RPR applied for periods RA or LDB
}
#else
bApplyRpr |= (m_switchPocPeriod < 0); // RPR applied for all pictures
bApplyRpr |= (m_switchPocPeriod > 0) && (poc / m_switchPocPeriod % 2); // RPR applied for periods RA or LDB
if( poc / m_switchPocPeriod % 2 )
{
ppsID = ENC_PPS_ID_RPR;
}
else
{
#if JVET_AG0116
if (!(m_resChangeInClvsEnabled && (m_rprFunctionalityTestingEnabledFlag || (m_gopBasedRPREnabledFlag && (m_iQP >= getGOPBasedRPRQPThreshold())))))
#else
if (!(m_resChangeInClvsEnabled && m_rprFunctionalityTestingEnabledFlag))
{
ppsID = 0;
}
#else
if( m_vps->getMaxLayers() > 1 )
Vadim Seregin
committed
ppsID = m_vps->getGeneralLayerIdx( m_layerId );
}
xGetNewPicBuffer( rcListPicYuvRecOut, pcPicCurr, ppsID );
const PPS *pPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID );
const SPS *pSPS = m_spsMap.getPS( pPPS->getSPSId() );
if (m_resChangeInClvsEnabled)
{
pcPicCurr->M_BUFS( 0, PIC_ORIGINAL_INPUT ).getBuf( COMPONENT_Y ).copyFrom( pcPicYuvOrg->getBuf( COMPONENT_Y ) );
pcPicCurr->M_BUFS( 0, PIC_ORIGINAL_INPUT ).getBuf( COMPONENT_Cb ).copyFrom( pcPicYuvOrg->getBuf( COMPONENT_Cb ) );
pcPicCurr->M_BUFS( 0, PIC_ORIGINAL_INPUT ).getBuf( COMPONENT_Cr ).copyFrom( pcPicYuvOrg->getBuf( COMPONENT_Cr ) );
const ChromaFormat chromaFormatIDC = pSPS->getChromaFormatIdc();
const PPS *refPPS = m_ppsMap.getPS( 0 );
Vadim Seregin
committed
const Window& curScalingWindow = pPPS->getScalingWindow();
int curPicWidth = pPPS->getPicWidthInLumaSamples() - SPS::getWinUnitX( pSPS->getChromaFormatIdc() ) * ( curScalingWindow.getWindowLeftOffset() + curScalingWindow.getWindowRightOffset() );
int curPicHeight = pPPS->getPicHeightInLumaSamples() - SPS::getWinUnitY( pSPS->getChromaFormatIdc() ) * ( curScalingWindow.getWindowTopOffset() + curScalingWindow.getWindowBottomOffset() );
Vadim Seregin
committed
const Window& refScalingWindow = refPPS->getScalingWindow();
int refPicWidth = refPPS->getPicWidthInLumaSamples() - SPS::getWinUnitX( pSPS->getChromaFormatIdc() ) * ( refScalingWindow.getWindowLeftOffset() + refScalingWindow.getWindowRightOffset() );
int refPicHeight = refPPS->getPicHeightInLumaSamples() - SPS::getWinUnitY( pSPS->getChromaFormatIdc() ) * ( refScalingWindow.getWindowTopOffset() + refScalingWindow.getWindowBottomOffset() );
Vadim Seregin
committed
int xScale = ( ( refPicWidth << SCALE_RATIO_BITS ) + ( curPicWidth >> 1 ) ) / curPicWidth;
int yScale = ( ( refPicHeight << SCALE_RATIO_BITS ) + ( curPicHeight >> 1 ) ) / curPicHeight;
std::pair<int, int> scalingRatio = std::pair<int, int>( xScale, yScale );
Picture::rescalePicture( scalingRatio, *pcPicYuvOrg, refPPS->getScalingWindow(), pcPicCurr->getOrigBuf(), pPPS->getScalingWindow(), chromaFormatIDC, pSPS->getBitDepths(), true, true,
pSPS->getHorCollocatedChromaFlag(), pSPS->getVerCollocatedChromaFlag() );
}
else
{
pcPicCurr->M_BUFS( 0, PIC_ORIGINAL ).swap( *pcPicYuvOrg );
}
pcPicCurr->finalInit( m_vps, *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
pcPicCurr->poc = m_iPOCLast;
// compute image characteristics
if( getUseAdaptiveQP() )
{
AQpPreanalyzer::preanalyze( pcPicCurr );
}
}
if( ( m_iNumPicRcvd == 0 ) || ( !flush && ( m_iPOCLast != 0 ) && ( m_iNumPicRcvd != m_iGOPSize ) && ( m_iGOPSize != 0 ) ) )
{
iNumEncoded = 0;
return true;
}
if( m_RCEnableRateControl )
{
m_cRateCtrl.initRCGOP( m_iNumPicRcvd );
}
m_picIdInGOP = 0;
return false;

Karsten Suehring
committed
}
/**
- Application has picture buffer list with size of GOP + 1
- Picture buffer list acts like as ring buffer
- End of the list has the latest picture
.
\param flush cause encoder to encode a partial GOP
\param pcPicYuvOrg original YUV picture
\param pcPicYuvTrueOrg
\param snrCSC
\retval rcListPicYuvRecOut list of reconstruction YUV pictures
\retval accessUnitsOut list of output access units
\retval iNumEncoded number of encoded pictures
*/
bool EncLib::encode( const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut, int& iNumEncoded )
m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, false, false, snrCSC,
m_printFrameMSE,
#if MSSIM_UNIFORM_METRICS_LOG
m_printMSSSIM,
#endif
false, m_picIdInGOP);
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
m_picIdInGOP++;
// go over all pictures in a GOP excluding the first IRAP
if( m_picIdInGOP != m_iGOPSize && m_iPOCLast )
{
return true;
}
#if JVET_O0756_CALCULATE_HDRMETRICS
m_metricTime = m_cGOPEncoder.getMetricTime();
#endif
if( m_RCEnableRateControl )
{
m_cRateCtrl.destroyRCGOP();
}
iNumEncoded = m_iNumPicRcvd;
m_iNumPicRcvd = 0;
m_uiNumAllPicCoded += iNumEncoded;
return false;
}

Karsten Suehring
committed
#if JVET_AA0093_DIVERSITY_CRITERION_FOR_ARMC
void EncLib::setQPOffsetList(const int QPOffset[MAX_GOP])
{
std::memcpy(m_qpOffsetList, QPOffset,(MAX_GOP) * sizeof(int));
}
#endif

Karsten Suehring
committed
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
/**------------------------------------------------
Separate interlaced frame into two fields
-------------------------------------------------**/
void separateFields(Pel* org, Pel* dstField, uint32_t stride, uint32_t width, uint32_t height, bool isTop)
{
if (!isTop)
{
org += stride;
}
for (int y = 0; y < height>>1; y++)
{
for (int x = 0; x < width; x++)
{
dstField[x] = org[x];
}
dstField += stride;
org += stride*2;
}
}
Tangi Poirier
committed
bool EncLib::encodePrep(bool flush, PelStorage* pcPicYuvOrg, const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut,
int& iNumEncoded, bool isTff)
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
{
iNumEncoded = 0;
bool keepDoing = true;
for( int fieldNum = 0; fieldNum < 2; fieldNum++ )
{
if( pcPicYuvOrg )
{
/* -- field initialization -- */
const bool isTopField = isTff == ( fieldNum == 0 );
Picture *pcField;
xGetNewPicBuffer( rcListPicYuvRecOut, pcField, -1 );
for( uint32_t comp = 0; comp < ::getNumberValidComponents( pcPicYuvOrg->chromaFormat ); comp++ )
{
const ComponentID compID = ComponentID( comp );
{
PelBuf compBuf = pcPicYuvOrg->get( compID );
separateFields( compBuf.buf,
pcField->getOrigBuf().get( compID ).buf,
compBuf.stride,
compBuf.width,
compBuf.height,
isTopField );
}
}
int ppsID = -1; // Use default PPS ID
const PPS *pPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID );
const SPS *pSPS = m_spsMap.getPS( pPPS->getSPSId() );
pcField->finalInit( m_vps, *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
pcField->poc = m_iPOCLast;
pcField->reconstructed = false;
pcField->setBorderExtension( false );// where is this normally?
pcField->topField = isTopField; // interlaced requirement
// compute image characteristics
if( getUseAdaptiveQP() )
{
AQpPreanalyzer::preanalyze( pcField );
}
}
}
if( m_iNumPicRcvd && ( flush || m_iPOCLast == 1 || m_iNumPicRcvd == m_iGOPSize ) )
{
m_picIdInGOP = 0;
keepDoing = false;
}
return keepDoing;
}
bool EncLib::encode( const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut, int& iNumEncoded, bool isTff )
{
iNumEncoded = 0;
for( int fieldNum = 0; fieldNum < 2; fieldNum++ )
{

Haiwei Sun
committed
m_iPOCLast = m_iPOCLast < 2 ? fieldNum : m_iPOCLast;
m_cGOPEncoder.compressGOP(m_iPOCLast, m_iPOCLast < 2 ? m_iPOCLast + 1 : m_iNumPicRcvd, m_cListPic,
rcListPicYuvRecOut, true, isTff, snrCSC, m_printFrameMSE,
#if MSSIM_UNIFORM_METRICS_LOG
m_printMSSSIM,
#endif
false, m_picIdInGOP);
#if JVET_O0756_CALCULATE_HDRMETRICS
m_metricTime = m_cGOPEncoder.getMetricTime();
#endif
m_picIdInGOP++;
}
// go over all pictures in a GOP excluding first top field and first bottom field
if( m_picIdInGOP != m_iGOPSize && m_iPOCLast > 1 )
{
return true;
}
iNumEncoded += m_iNumPicRcvd;
m_uiNumAllPicCoded += m_iNumPicRcvd;
m_iNumPicRcvd = 0;

Karsten Suehring
committed
// ====================================================================================================================
// Protected member functions
// ====================================================================================================================
/**
- Application has picture buffer list with size of GOP + 1
- Picture buffer list acts like as ring buffer
- End of the list has the latest picture
.
\retval rpcPic obtained picture buffer
*/
void EncLib::xGetNewPicBuffer ( std::list<PelUnitBuf*>& rcListPicYuvRecOut, Picture*& rpcPic, int ppsId )
{

Karsten Suehring
committed
rcListPicYuvRecOut.push_back( rcListPicYuvRecOut.front() ); rcListPicYuvRecOut.pop_front();
rpcPic=0;
// At this point, the SPS and PPS can be considered activated - they are copied to the new Pic.
const PPS *pPPS=(ppsId<0) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS(ppsId);
CHECK(!(pPPS!=0), "Unspecified error");
const PPS &pps=*pPPS;
const SPS *pSPS=m_spsMap.getPS(pps.getSPSId());
CHECK(!(pSPS!=0), "Unspecified error");
const SPS &sps=*pSPS;
Slice::sortPicList(m_cListPic);
// use an entry in the buffered list if the maximum number that need buffering has been reached:
int maxDecPicBuffering = ( m_vps == nullptr || m_vps->m_numLayersInOls[m_vps->m_targetOlsIdx] == 1 ) ? sps.getMaxDecPicBuffering( MAX_TLAYER - 1 ) : m_vps->getMaxDecPicBuffering( MAX_TLAYER - 1 );
if( m_cListPic.size() >= (uint32_t)( m_iGOPSize + maxDecPicBuffering + 2 ) )

Karsten Suehring
committed
{
PicList::iterator iterPic = m_cListPic.begin();

Karsten Suehring
committed
int iSize = int( m_cListPic.size() );

Karsten Suehring
committed
{
rpcPic = *iterPic;
if( !rpcPic->referenced && rpcPic->layerId == m_layerId )

Karsten Suehring
committed
{
break;
}
else
{
rpcPic = nullptr;
}

Karsten Suehring
committed
iterPic++;
}
// If PPS ID is the same, we will assume that it has not changed since it was last used
// and return the old object.
if( rpcPic && pps.getPPSId() != rpcPic->cs->pps->getPPSId() )

Karsten Suehring
committed
{
// the IDs differ - free up an entry in the list, and then create a new one, as with the case where the max buffering state has not been reached.
rpcPic->destroy();
delete rpcPic;
m_cListPic.erase(iterPic);
rpcPic=0;
}
}
if (rpcPic==0)
{
rpcPic = new Picture;
rpcPic->create(
Fabrice Le Léannec
committed
isRprEnabled(),
getGdrEnabled(),
sps.getWrapAroundEnabledFlag(), sps.getChromaFormatIdc(),
Size(pps.getPicWidthInLumaSamples(), pps.getPicHeightInLumaSamples()), sps.getMaxCUWidth(),
sps.getMaxCUWidth() + EXT_PICTURE_SIZE, false, m_layerId, getGopBasedTemporalFilterEnabled());
if (m_resChangeInClvsEnabled)
const PPS &pps0 = *m_ppsMap.getPS(0);
rpcPic->M_BUFS(0, PIC_ORIGINAL_INPUT).create(sps.getChromaFormatIdc(), Area(Position(), Size(pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples())));

Karsten Suehring
committed
if ( getUseAdaptiveQP() )
{
const uint32_t iMaxDQPLayer = m_picHeader.getCuQpDeltaSubdivIntra()/2+1;

Karsten Suehring
committed
rpcPic->aqlayer.resize( iMaxDQPLayer );
for (uint32_t d = 0; d < iMaxDQPLayer; d++)
{
rpcPic->aqlayer[d] = new AQpLayer( pps.getPicWidthInLumaSamples(), pps.getPicHeightInLumaSamples(), sps.getMaxCUWidth() >> d, sps.getMaxCUHeight() >> d );

Karsten Suehring
committed
}
}
m_cListPic.push_back( rpcPic );
}
rpcPic->setBorderExtension( false );
rpcPic->reconstructed = false;
rpcPic->referenced = true;

Karsten Suehring
committed
m_iPOCLast += (m_compositeRefEnabled ? 2 : 1);

Karsten Suehring
committed
m_iNumPicRcvd++;
}
void EncLib::xInitVPS( const SPS& sps )
{
// The SPS must have already been set up.
// set the VPS profile information.
m_vps->m_olsHrdParams.clear();
m_vps->m_olsHrdParams.resize(m_vps->getNumOlsHrdParamsMinus1(), std::vector<OlsHrdParams>(m_vps->getMaxSubLayers()));
ProfileLevelTierFeatures profileLevelTierFeatures;
profileLevelTierFeatures.extractPTLInformation( sps );
m_vps->deriveOutputLayerSets();
m_vps->deriveTargetOutputLayerSet( m_vps->m_targetOlsIdx );
// number of the DPB parameters is set equal to the number of OLS containing multi layers
if( !m_vps->getEachLayerIsAnOlsFlag() )
m_vps->m_numDpbParams = m_vps->getNumMultiLayeredOlss();
}
if( m_vps->m_dpbParameters.size() != m_vps->m_numDpbParams )
{
m_vps->m_dpbParameters.resize( m_vps->m_numDpbParams );
}
if( m_vps->m_dpbMaxTemporalId.size() != m_vps->m_numDpbParams )
{
m_vps->m_dpbMaxTemporalId.resize( m_vps->m_numDpbParams );
}
Hendry
committed
for( int olsIdx = 0, dpbIdx = 0; olsIdx < m_vps->m_numOutputLayersInOls.size(); olsIdx++ )
if ( m_vps->getNumLayersInOls(olsIdx) > 1 )
{
Hendry
committed
if( std::find( m_vps->m_layerIdInOls[olsIdx].begin(), m_vps->m_layerIdInOls[olsIdx].end(), m_layerId ) != m_vps->m_layerIdInOls[olsIdx].end() )
{
m_vps->setOlsDpbPicWidth( olsIdx, std::max<int>( sps.getMaxPicWidthInLumaSamples(), m_vps->getOlsDpbPicSize( olsIdx ).width ) );
m_vps->setOlsDpbPicHeight( olsIdx, std::max<int>( sps.getMaxPicHeightInLumaSamples(), m_vps->getOlsDpbPicSize( olsIdx ).height ) );
m_vps->setOlsDpbChromaFormatIdc( olsIdx, std::max<int>(sps.getChromaFormatIdc(), m_vps->getOlsDpbChromaFormatIdc( olsIdx )));
m_vps->setOlsDpbBitDepthMinus8( olsIdx, std::max<int>(sps.getBitDepth(CHANNEL_TYPE_LUMA) - 8, m_vps->getOlsDpbBitDepthMinus8( olsIdx )));
Hendry
committed
}
Hendry
committed
m_vps->setOlsDpbParamsIdx( olsIdx, dpbIdx );
dpbIdx++;
}
Hendry
committed
//for( int i = 0; i < m_vps->m_numDpbParams; i++ )
for( int i = 0; i < m_vps->m_numOutputLayersInOls.size(); i++ )
if ( m_vps->getNumLayersInOls(i) > 1 )
{
Hendry
committed
int dpbIdx = m_vps->getOlsDpbParamsIdx( i );
Hendry
committed
if( m_vps->getMaxSubLayers() == 1 )
Hendry
committed
// When vps_max_sublayers_minus1 is equal to 0, the value of dpb_max_temporal_id[ dpbIdx ] is inferred to be equal to 0.
m_vps->m_dpbMaxTemporalId[dpbIdx] = 0;
Hendry
committed
if( m_vps->getAllLayersSameNumSublayersFlag() )
{
// When vps_max_sublayers_minus1 is greater than 0 and vps_all_layers_same_num_sublayers_flag is equal to 1, the value of dpb_max_temporal_id[ dpbIdx ] is inferred to be equal to vps_max_sublayers_minus1.
m_vps->m_dpbMaxTemporalId[dpbIdx] = m_vps->getMaxSubLayers() - 1;
}
else
{

Karsten Suehring
committed
#if JVET_S0100_ASPECT3
m_vps->m_dpbMaxTemporalId[dpbIdx] = m_vps->getMaxSubLayers() - 1;
#else
Hendry
committed
m_vps->m_dpbMaxTemporalId[dpbIdx] = m_maxTempLayer;

Karsten Suehring
committed
#endif
Hendry
committed
}
}
for( int j = ( m_vps->m_sublayerDpbParamsPresentFlag ? 0 : m_vps->m_dpbMaxTemporalId[dpbIdx] ); j <= m_vps->m_dpbMaxTemporalId[dpbIdx]; j++ )
{
m_vps->m_dpbParameters[dpbIdx].m_maxDecPicBuffering[j] = profileLevelTierFeatures.getMaxDpbSize( m_vps->getOlsDpbPicSize( i ).width * m_vps->getOlsDpbPicSize( i ).height );
m_vps->m_dpbParameters[dpbIdx].m_numReorderPics[j] = m_vps->m_dpbParameters[dpbIdx].m_maxDecPicBuffering[j];
m_vps->m_dpbParameters[dpbIdx].m_maxLatencyIncreasePlus1[j] = 0;
Hendry
committed
for( int j = ( m_vps->m_sublayerDpbParamsPresentFlag ? m_vps->m_dpbMaxTemporalId[dpbIdx] : 0 ); j < m_vps->m_dpbMaxTemporalId[dpbIdx]; j++ )
{
// When max_dec_pic_buffering_minus1[ dpbIdx ] is not present for dpbIdx in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_dec_pic_buffering_minus1[ maxSubLayersMinus1 ].
m_vps->m_dpbParameters[dpbIdx].m_maxDecPicBuffering[j] = m_vps->m_dpbParameters[dpbIdx].m_maxDecPicBuffering[m_vps->m_dpbMaxTemporalId[dpbIdx]];
Hendry
committed
// When max_num_reorder_pics[ dpbIdx ] is not present for dpbIdx in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_num_reorder_pics[ maxSubLayersMinus1 ].
m_vps->m_dpbParameters[dpbIdx].m_numReorderPics[j] = m_vps->m_dpbParameters[dpbIdx].m_numReorderPics[m_vps->m_dpbMaxTemporalId[dpbIdx]];
Hendry
committed
// When max_latency_increase_plus1[ dpbIdx ] is not present for dpbIdx in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_latency_increase_plus1[ maxSubLayersMinus1 ].
m_vps->m_dpbParameters[dpbIdx].m_maxLatencyIncreasePlus1[j] = m_vps->m_dpbParameters[dpbIdx].m_maxLatencyIncreasePlus1[m_vps->m_dpbMaxTemporalId[dpbIdx]];
}

Karsten Suehring
committed
#if JVET_S0100_ASPECT3
for (int i = 0; i < m_vps->getNumOutputLayerSets(); i++)
{
m_vps->setHrdMaxTid(i, m_vps->getMaxSubLayers() - 1);
}
#endif

Karsten Suehring
committed
if (m_cfgVPSParameters.m_maxTidILRefPicsPlus1 >= 0)
{
for (int i = 0; i < m_vps->getMaxLayers(); i++)
{
m_vps->setMaxTidIlRefPicsPlus1(i, m_cfgVPSParameters.m_maxTidILRefPicsPlus1);
}
}

Karsten Suehring
committed
#if JVET_S0100_ASPECT3
m_vps->checkVPS();
#endif

Karsten Suehring
committed
void EncLib::xInitDCI(DCI& dci, const SPS& sps)
{
dci.setMaxSubLayersMinus1(sps.getMaxTLayers() - 1);
std::vector<ProfileTierLevel> ptls;
ptls.resize(1);
ptls[0] = *sps.getProfileTierLevel();
dci.setProfileTierLevel(ptls);
}
void EncLib::xInitSPS( SPS& sps )

Karsten Suehring
committed
{
ProfileTierLevel* profileTierLevel = sps.getProfileTierLevel();
ConstraintInfo* cinfo = profileTierLevel->getConstraintInfo();
#if JVET_S0179_CONDITIONAL_SIGNAL_GCI
cinfo->setGciPresentFlag(m_gciPresentFlag);
#endif
cinfo->setNonPackedConstraintFlag (m_nonPackedConstraintFlag);
cinfo->setNonProjectedConstraintFlag(m_nonProjectedConstraintFlag);
Zhipin Deng
committed
#endif
#if JVET_Q0114_ASPECT5_GCI_FLAG
cinfo->setNoRprConstraintFlag(m_noRprConstraintFlag);
cinfo->setNoResChangeInClvsConstraintFlag(m_noResChangeInClvsConstraintFlag);
cinfo->setOneTilePerPicConstraintFlag(m_oneTilePerPicConstraintFlag);
cinfo->setPicHeaderInSliceHeaderConstraintFlag(m_picHeaderInSliceHeaderConstraintFlag);
cinfo->setOneSlicePerPicConstraintFlag(m_oneSlicePerPicConstraintFlag);
#if JVET_S0113_S0195_GCI
cinfo->setNoIdrRplConstraintFlag(m_noIdrRplConstraintFlag);
cinfo->setNoRectSliceConstraintFlag(m_noRectSliceConstraintFlag);
cinfo->setOneSlicePerSubpicConstraintFlag(m_oneSlicePerSubpicConstraintFlag);
cinfo->setNoSubpicInfoConstraintFlag(m_noSubpicInfoConstraintFlag);
#else
cinfo->setOneSubpicPerPicConstraintFlag(m_oneSubpicPerPicConstraintFlag);
#if !JVET_S0138_GCI_PTL
cinfo->setFrameOnlyConstraintFlag (m_frameOnlyConstraintFlag);
#endif
cinfo->setOnePictureOnlyConstraintFlag(m_onePictureOnlyConstraintFlag);
cinfo->setIntraOnlyConstraintFlag (m_intraOnlyConstraintFlag);
cinfo->setMaxBitDepthConstraintIdc (m_maxBitDepthConstraintIdc);
cinfo->setMaxChromaFormatConstraintIdc((int)m_maxChromaFormatConstraintIdc);
#if !JVET_S0138_GCI_PTL
cinfo->setSingleLayerConstraintFlag (m_singleLayerConstraintFlag);
#endif
cinfo->setAllLayersIndependentConstraintFlag (m_allLayersIndependentConstraintFlag);
cinfo->setNoMrlConstraintFlag (m_noMrlConstraintFlag);
cinfo->setNoIspConstraintFlag (m_noIspConstraintFlag);
cinfo->setNoMipConstraintFlag (m_noMipConstraintFlag);
cinfo->setNoLfnstConstraintFlag (m_noLfnstConstraintFlag);
cinfo->setNoMmvdConstraintFlag (m_noMmvdConstraintFlag);
cinfo->setNoSmvdConstraintFlag (m_noSmvdConstraintFlag);
cinfo->setNoProfConstraintFlag (m_noProfConstraintFlag);
cinfo->setNoPaletteConstraintFlag (m_noPaletteConstraintFlag);
cinfo->setNoActConstraintFlag (m_noActConstraintFlag);
cinfo->setNoLmcsConstraintFlag (m_noLmcsConstraintFlag);
#if JVET_S0050_GCI
cinfo->setNoExplicitScaleListConstraintFlag(m_noExplicitScaleListConstraintFlag);
cinfo->setNoVirtualBoundaryConstraintFlag(m_noVirtualBoundaryConstraintFlag);
#endif
#if JVET_S0058_GCI
cinfo->setNoMttConstraintFlag(m_noMttConstraintFlag);
#endif
#if JVET_R0341_GCI
cinfo->setNoChromaQpOffsetConstraintFlag(m_noChromaQpOffsetConstraintFlag);
cinfo->setNoQtbttDualTreeIntraConstraintFlag(m_noQtbttDualTreeIntraConstraintFlag);
cinfo->setNoPartitionConstraintsOverrideConstraintFlag(m_noPartitionConstraintsOverrideConstraintFlag);
cinfo->setNoSaoConstraintFlag(m_noSaoConstraintFlag);
#if JVET_W0066_CCSAO
cinfo->setNoCCSaoConstraintFlag(m_noCCSaoConstraintFlag);
#endif
cinfo->setNoAlfConstraintFlag(m_noAlfConstraintFlag);
cinfo->setNoCCAlfConstraintFlag(m_noCCAlfConstraintFlag);
cinfo->setNoWeightedPredictionConstraintFlag(m_noWeightedPredictionConstraintFlag);
cinfo->setNoRefWraparoundConstraintFlag(m_noRefWraparoundConstraintFlag);
cinfo->setNoTemporalMvpConstraintFlag(m_noTemporalMvpConstraintFlag);
cinfo->setNoSbtmvpConstraintFlag(m_noSbtmvpConstraintFlag);
cinfo->setNoAmvrConstraintFlag(m_noAmvrConstraintFlag);
cinfo->setNoBdofConstraintFlag(m_noBdofConstraintFlag);
cinfo->setNoDmvrConstraintFlag(m_noDmvrConstraintFlag);
cinfo->setNoCclmConstraintFlag(m_noCclmConstraintFlag);
cinfo->setNoMtsConstraintFlag(m_noMtsConstraintFlag);
cinfo->setNoSbtConstraintFlag(m_noSbtConstraintFlag);
cinfo->setNoAffineMotionConstraintFlag(m_noAffineMotionConstraintFlag);
cinfo->setNoBcwConstraintFlag(m_noBcwConstraintFlag);
cinfo->setNoIbcConstraintFlag(m_noIbcConstraintFlag);
#if ENABLE_DIMD
cinfo->setNoDimdConstraintFlag(m_noDimdConstraintFlag);
#endif
#if JVET_W0123_TIMD_FUSION
cinfo->setNoTimdConstraintFlag(m_noTimdConstraintFlag);
#endif
#if JVET_AB0155_SGPM
cinfo->setNoSgpmConstraintFlag(m_noSgpmConstraintFlag);
#endif
#if JVET_AD0082_TMRL_CONFIG
cinfo->setNoTmrlConstraintFlag(m_noTmrlConstraintFlag);
#endif
#if JVET_AG0058_EIP
cinfo->setNoEipConstraintFlag(m_noEipConstraintFlag);
#endif
#if ENABLE_OBMC
cinfo->setNoObmcConstraintFlag(m_noObmcConstraintFlag);
#endif
cinfo->setNoCiipConstraintFlag(m_noCiipConstraintFlag);
cinfo->setNoGeoConstraintFlag(m_noGeoConstraintFlag);
cinfo->setNoLadfConstraintFlag(m_noLadfConstraintFlag);
cinfo->setNoTransformSkipConstraintFlag(m_noTransformSkipConstraintFlag);
cinfo->setNoBDPCMConstraintFlag(m_noBDPCMConstraintFlag);
cinfo->setNoJointCbCrConstraintFlag(m_noJointCbCrConstraintFlag);
cinfo->setNoQpDeltaConstraintFlag(m_noQpDeltaConstraintFlag);
cinfo->setNoDepQuantConstraintFlag(m_noDepQuantConstraintFlag);
cinfo->setNoSignDataHidingConstraintFlag(m_noSignDataHidingConstraintFlag);
Martin Pettersson
committed
cinfo->setNoTrailConstraintFlag(m_noTrailConstraintFlag);
cinfo->setNoStsaConstraintFlag(m_noStsaConstraintFlag);
cinfo->setNoRaslConstraintFlag(m_noRaslConstraintFlag);
cinfo->setNoRadlConstraintFlag(m_noRadlConstraintFlag);
cinfo->setNoIdrConstraintFlag(m_noIdrConstraintFlag);
cinfo->setNoCraConstraintFlag(m_noCraConstraintFlag);
cinfo->setNoGdrConstraintFlag(m_noGdrConstraintFlag);
cinfo->setNoApsConstraintFlag(m_noApsConstraintFlag);

Karsten Suehring
committed
profileTierLevel->setLevelIdc (m_level);
profileTierLevel->setTierFlag (m_levelTier);
profileTierLevel->setProfileIdc (m_profile);
#if JVET_S0138_GCI_PTL
profileTierLevel->setFrameOnlyConstraintFlag (m_frameOnlyConstraintFlag);
profileTierLevel->setMultiLayerEnabledFlag (m_multiLayerEnabledFlag);
#endif
profileTierLevel->setNumSubProfile(m_numSubProfile);
for (int k = 0; k < m_numSubProfile; k++)
{
profileTierLevel->setSubProfileIdc(k, m_subProfile[k]);
}

Karsten Suehring
committed
/* XXX: should Main be marked as compatible with still picture? */
/* XXX: may be a good idea to refactor the above into a function
* that chooses the actual compatibility based upon options */
sps.setVPSId( m_vps->getVPSId() );
{
sps.setGDREnabledFlag(true);
}
else
{
sps.setGDREnabledFlag(false);
}
#else
sps.setGDREnabledFlag(false);
#endif
#if JVET_AA0146_WRAP_AROUND_FIX
sps.setMaxPicWidthInLumaSamples( m_sourceWidth );
sps.setMaxPicHeightInLumaSamples( m_sourceHeight );
#else
sps.setMaxPicWidthInLumaSamples( m_iSourceWidth );
sps.setMaxPicHeightInLumaSamples( m_iSourceHeight );
#if JVET_AI0136_ADAPTIVE_DUAL_TREE
sps.setUseInterSliceSeparateTree ( m_interSliceSeparateTreeEnabled );
if (getFrameRate() < 50 && (m_sourceWidth * m_sourceHeight) <= (832 * 480))
{
sps.setUseInterSliceSeparateTree ( false );
}
if(m_iQP < 27 || m_iQP>32)
{
sps.setUseInterSliceSeparateTree ( false );
}
#endif
if (m_resChangeInClvsEnabled)
#if JVET_AA0146_WRAP_AROUND_FIX
int maxPicWidth = std::max(m_sourceWidth, (int)((double)m_sourceWidth / m_scalingRatioHor + 0.5));
int maxPicHeight = std::max(m_sourceHeight, (int)((double)m_sourceHeight / m_scalingRatioVer + 0.5));
#else
int maxPicWidth = std::max(m_iSourceWidth, (int)((double)m_iSourceWidth / m_scalingRatioHor + 0.5));
int maxPicHeight = std::max(m_iSourceHeight, (int)((double)m_iSourceHeight / m_scalingRatioVer + 0.5));
#if JVET_AG0116
if (m_rprFunctionalityTestingEnabledFlag || m_gopBasedRPREnabledFlag)
#else
if (m_rprFunctionalityTestingEnabledFlag)
{
maxPicWidth = std::max(maxPicWidth, (int)((double)m_sourceWidth / m_scalingRatioHor2 + 0.5));
maxPicHeight = std::max(maxPicHeight, (int)((double)m_sourceHeight / m_scalingRatioVer2 + 0.5));
maxPicWidth = std::max(maxPicWidth, (int)((double)m_sourceWidth / m_scalingRatioHor3 + 0.5));
maxPicHeight = std::max(maxPicHeight, (int)((double)m_sourceHeight / m_scalingRatioVer3 + 0.5));
}
const int minCuSize = std::max(8, 1 << m_log2MinCUSize);
if (maxPicWidth % minCuSize)
maxPicWidth += ((maxPicWidth / minCuSize) + 1) * minCuSize - maxPicWidth;
maxPicHeight += ((maxPicHeight / minCuSize) + 1) * minCuSize - maxPicHeight;
sps.setMaxPicWidthInLumaSamples( maxPicWidth );
sps.setMaxPicHeightInLumaSamples( maxPicHeight );
}
Jonatan Samuelsson-Allendes
committed
sps.setConformanceWindow( m_conformanceWindow );

Karsten Suehring
committed
sps.setMaxCUWidth ( m_maxCUWidth );
sps.setMaxCUHeight ( m_maxCUHeight );
sps.setLog2MinCodingBlockSize ( m_log2MinCUSize );

Karsten Suehring
committed
sps.setChromaFormatIdc ( m_chromaFormatIDC );
sps.setCTUSize ( m_CTUSize );
sps.setSplitConsOverrideEnabledFlag ( m_useSplitConsOverride );
// convert the Intra Chroma minQT setting from chroma unit to luma unit
m_uiMinQT[2] <<= getChannelTypeScaleX(CHANNEL_TYPE_CHROMA, m_chromaFormatIDC);
sps.setMinQTSizes ( m_uiMinQT );
sps.setMaxMTTHierarchyDepth ( m_uiMaxMTTHierarchyDepth, m_uiMaxMTTHierarchyDepthI, m_uiMaxMTTHierarchyDepthIChroma );
sps.setMaxBTSize( m_uiMaxBT[1], m_uiMaxBT[0], m_uiMaxBT[2] );
sps.setMaxTTSize( m_uiMaxTT[1], m_uiMaxTT[0], m_uiMaxTT[2] );
sps.setIDRRefParamListPresent ( m_idrRefParamList );
sps.setUseDualITree ( m_dualITree );
sps.setNumPredSigns ( m_numPredSign );
#if JVET_Y0141_SIGN_PRED_IMPROVE
sps.setLog2SignPredArea (m_log2SignPredArea);
#endif
#if JVET_AH0103_LOW_DELAY_LFNST_NSPT
sps.setUseIntraLFNSTISlice ( m_intraLFNSTISlice );
sps.setUseIntraLFNSTPBSlice ( m_intraLFNSTPBSlice );
sps.setUseInterLFNST ( m_interLFNST );
#else
sps.setUseLFNST ( m_LFNST );
sps.setSbTMVPEnabledFlag(m_sbTmvpEnableFlag);
sps.setAMVREnabledFlag ( m_ImvMode != IMV_OFF );
sps.setBDOFEnabledFlag ( m_BIO );
sps.setUseAML ( m_AML );
#if JVET_AG0276_NLIC
sps.setUseAltLM ( m_altLM );
sps.setUseAffAltLM ( m_affAltLM );
#endif
#endif
#if JVET_AG0276_LIC_FLAG_SIGNALING
sps.setUseMergeOppositeLic ( m_mergeOppositeLic );
sps.setUseTMMergeOppositeLic ( m_mergeTMOppositeLic );
sps.setUseAffMergeOppositeLic ( m_mergeAffOppositeLic );
#endif
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
sps.setUseFastSubTmvp ((m_sourceWidth * m_sourceHeight) > (m_intraPeriod == -1 ? 0 : 832 * 480));
#endif
#if JVET_AA0093_REFINED_MOTION_FOR_ARMC
sps.setUseArmcRefinedMotion ( m_armcRefinedMotion );
#endif
#if JVET_AG0276_LIC_FLAG_SIGNALING
sps.setMaxNumOppositeLicMergeCand( getMaxNumOppositeLicMergeCand() );
#endif
#if JVET_X0049_ADAPT_DMVR
sps.setMaxNumBMMergeCand(getMaxNumBMMergeCand());
#endif
sps.setMaxNumAffineMergeCand(getMaxNumAffineMergeCand());
#if JVET_AG0276_LIC_FLAG_SIGNALING
sps.setMaxNumAffineOppositeLicMergeCand( getMaxNumAffineOppositeLicMergeCand() );
if (getIntraPeriod() < 0 && getBaseQP() > 32 )
{
sps.setUseMergeOppositeLic(false);
sps.setUseTMMergeOppositeLic(false);
sps.setUseAffMergeOppositeLic(false);
}
#endif
sps.setMaxNumIBCMergeCand(getMaxNumIBCMergeCand());
sps.setMaxNumGeoCand(getMaxNumGeoCand());
#if JVET_AG0164_AFFINE_GPM
sps.setMaxNumGpmAffCand (((m_sourceWidth * m_sourceHeight) > (m_intraPeriod == -1 ? 1280 * 720 : 0)) ? getMaxNumGpmAffCand() : 0);
#endif
#if JVET_Z0127_SPS_MHP_MAX_MRG_CAND
sps.setMaxNumMHPCand(getMaxNumMHPCand());
#endif
sps.setUseAffine ( m_Affine );
sps.setUseAffineType ( m_AffineType );
#if JVET_AF0163_TM_SUBBLOCK_REFINEMENT
sps.setUseAffineTM ( m_useAffineTM );
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
#if JVET_AG0276_NLIC
sps.setUseAffAltLMTM ( m_useAffAltLMTM );
if (getIntraPeriod() > 0)
{
if ((getSourceWidth() * getSourceHeight()) > (832 * 480) && ((getSourceWidth() * getSourceHeight()) < (3840 * 2160)))
{
sps.setUseAffAltLMTM(false);
}
if (getBaseQP() > 32)
{
sps.setUseAltLM(false);
sps.setUseAffAltLM(false);
sps.setUseAffAltLMTM(false);
}
else if (getBaseQP() < 27)
{
sps.setUseAltLM(false);
sps.setUseAffAltLM(true);
sps.setUseAffAltLMTM(true);
}
}
else
{
sps.setUseAffAltLM(false);
sps.setUseAffAltLMTM(false);
if (getBaseQP() < 27)
{
sps.setUseAltLM(false);
}
}
#endif
#if JVET_AH0119_SUBBLOCK_TM
sps.setUseSbTmvpTM(m_useSbTmvpTM);
if (getBaseQP() < 27)
{
sps.setUseSbTmvpTM(false);
sps.setUseAffineTM(false);
}
#endif
#if JVET_AG0135_AFFINE_CIIP
sps.setUseCiipAffine (((m_sourceWidth * m_sourceHeight) > (m_intraPeriod == -1 ? 832 * 480 : 0)) ? m_useCiipAffine : false);
#endif
#if AFFINE_MMVD
sps.setUseAffineMmvdMode ( m_AffineMmvdMode );
#endif
#if TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM || MULTI_PASS_DMVR
#endif
Chun-Chi Chen
committed
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
#if JVET_AA0132_CONFIGURABLE_TM_TOOLS
sps.setTMToolsEnableFlag ( m_tmToolsEnableFlag );
#if TM_AMVP
sps.setUseTMAmvpMode ( m_tmAmvpMode );
#endif
#if TM_MRG
sps.setUseTMMrgMode ( m_tmMrgMode );
#endif
#if JVET_W0097_GPM_MMVD_TM && TM_MRG
sps.setUseGPMTMMode ( m_tmGPMMode );
#endif
#if JVET_Z0061_TM_OBMC && ENABLE_OBMC
sps.setUseOBMCTMMode ( m_tmOBMCMode );
#endif
#if JVET_Y0134_TMVP_NAMVP_CAND_REORDERING && JVET_W0090_ARMC_TM
sps.setUseTmvpNmvpReordering ( m_useTmvpNmvpReorder );
#endif
#if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED
sps.setUseTMMMVD ( m_useTMMMVD );
#endif
#endif
#if JVET_Z0056_GPM_SPLIT_MODE_REORDERING
sps.setUseAltGPMSplitModeCode( m_altGPMSplitModeCode );
sps.setUsePROF ( m_PROF );
sps.setUseLMChroma ( m_LMChroma ? true : false );
sps.setHorCollocatedChromaFlag( m_horCollocatedChromaFlag );
sps.setVerCollocatedChromaFlag( m_verCollocatedChromaFlag );
sps.setUseMTS ( m_IntraMTS || m_InterMTS || m_ImplicitMTS );
sps.setUseIntraMTS ( m_IntraMTS );
sps.setUseInterMTS ( m_InterMTS );
Yin Zhao
committed
sps.setUseSBT ( m_SBT );
sps.setUseBcw ( m_bcw );
#if JVET_AG0276_LIC_SLOPE_ADJUST
sps.setLicSlopeAdjustEnabledFlag( m_licSlopeAdjust );
#endif
Shunsuke Iwamura
committed
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
sps.setLadfEnabled ( m_LadfEnabled );
Shunsuke Iwamura
committed
if ( m_LadfEnabled )
{
sps.setLadfNumIntervals ( m_LadfNumIntervals );
Shunsuke Iwamura
committed
for ( int k = 0; k < m_LadfNumIntervals; k++ )
{
sps.setLadfQpOffset( m_LadfQpOffset[k], k );
sps.setLadfIntervalLowerBound( m_LadfIntervalLowerBound[k], k );
Shunsuke Iwamura
committed
}
CHECK( m_LadfIntervalLowerBound[0] != 0, "abnormal value set to LadfIntervalLowerBound[0]" );
}
#endif
#if JVET_AA0133_INTER_MTS_OPT
sps.setInterMTSMaxSize(m_interMTSMaxSize);
#endif
#if ENABLE_DIMD
sps.setUseDimd ( m_dimd );
#endif
#if JVET_W0123_TIMD_FUSION
sps.setUseTimd ( m_timd );
#endif
#if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION
sps.setUseCiipTimd ( m_ciipTimd );
#endif
#if JVET_AB0155_SGPM
sps.setUseSgpm ( m_sgpm );
#endif
#if JVET_AD0082_TMRL_CONFIG
sps.setUseTmrl ( m_tmrl );
#endif
#if JVET_AE0174_NONINTER_TM_TOOLS_CONTROL
sps.setTMnoninterToolsEnableFlag ( m_tmNoninterToolsEnableFlag );
#endif
#if JVET_AG0058_EIP
sps.setUseEip ( m_eip );
#endif
#if JVET_AD0085_MPM_SORTING
sps.setUseMpmSorting ( m_mpmSorting );
#endif
#if JVET_AH0136_CHROMA_REORDERING
sps.setUseChromaReordering (m_chromaReordering);
#endif
#if JVET_AC0147_CCCM_NO_SUBSAMPLING
sps.setUseCccm ( m_cccm );
#endif
Chia-Ming Tsai
committed
#if JVET_AD0188_CCP_MERGE
sps.setUseCcpMerge ( m_ccpMerge );
#endif
#if JVET_AG0154_DECODER_DERIVED_CCP_FUSION
sps.setUseDdCcpFusion ( m_ddCcpFusion );
#endif
#if ENABLE_OBMC
sps.setUseOBMC ( m_OBMC );
#endif
sps.setUseCiip ( m_ciip );
#if JVET_X0141_CIIP_TIMD_TM && TM_MRG
if(sps.getUseCiip())
{
Chun-Chi Chen
committed
#if JVET_AA0132_CONFIGURABLE_TM_TOOLS
if(m_tmCIIPMode == 2)
{
#endif
if(getIntraPeriod() < 0)
{
sps.setUseCiipTmMrg (false);
}
else
{
sps.setUseCiipTmMrg (true);
}
Chun-Chi Chen
committed
#if JVET_AA0132_CONFIGURABLE_TM_TOOLS
}
else
{
sps.setUseCiipTmMrg (m_tmCIIPMode == 1);
}
#endif
sps.setUseGeo ( m_Geo );
#if JVET_AG0112_REGRESSION_BASED_GPM_BLENDING
sps.setUseGeoBlend ( true );
#endif
sps.setFpelMmvdEnabledFlag (( m_MMVD ) ? m_allowDisFracMMVD : false);
#if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED || JVET_AD0140_MVD_PREDICTION
sps.setUseMvdPred (m_mvdPred);
#if JVET_AC0104_IBC_BVD_PREDICTION
sps.setUseBvdPred (m_bvdPred);
#endif
#if JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
sps.setUseBvpCluster (m_bvpCluster);
#endif
#if JVET_Z0054_BLK_REF_PIC_REORDER
sps.setUseARL (m_useARL);
Mehdi Salehifar
committed
#endif

Xuewei Meng
committed
sps.setBdofControlPresentFlag(m_BIO);
sps.setDmvrControlPresentFlag(m_DMVR);
sps.setProfControlPresentFlag(m_PROF);
sps.setAffineAmvrEnabledFlag ( m_AffineAmvr );
#if JVET_AD0182_AFFINE_DMVR_PLUS_EXTENSIONS
sps.setUseAffineParaRefinement (m_affineParaRefinement);
#endif
sps.setUseColorTrans(m_useColorTrans);
sps.setPLTMode ( m_PLTMode);
#if !JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
#else
sps.setIBCFlag ( m_IBCMode & 0x01);
sps.setIBCFlagInterSlice ( m_IBCMode & 0x02);
sps.setUseRRIbc ( m_rribc );
sps.setUseTMIbc ( m_tmibc );
sps.setUseIbcMerge ( m_ibcMerge );
sps.setIBCFracFlag ( m_IBCFracMode);
#endif
#if JVET_AA0061_IBC_MBVD
sps.setUseIbcMbvd ( m_ibcMbvd );
#if JVET_AE0169_IBC_MBVD_LIST_DERIVATION
sps.setUseIbcMbvdAdSearch ( m_ibcMbvdAdSearch );
#endif
#endif
#if JVET_AC0112_IBC_CIIP
sps.setUseIbcCiip ( m_ibcCiip );
#endif
#if JVET_AC0112_IBC_GPM
sps.setUseIbcGpm ( m_ibcGpm );
#endif
#if JVET_AC0112_IBC_LIC
sps.setUseIbcLic ( m_ibcLic );
#if JVET_AE0159_FIBC
sps.setUseIbcFilter ( m_ibcFilter );
#endif
#if JVET_AE0094_IBC_NONADJACENT_SPATIAL_CANDIDATES
sps.setUseIbcNonAdjCand ( m_ibcNonAdjCand );
#endif
#if JVET_AG0136_INTRA_TMP_LIC
sps.setItmpLicExtension ( m_itmpLicExtension );
sps.setItmpLicMode ( m_itmpLicMode );
sps.setWrapAroundEnabledFlag ( m_wrapAround );
#if JVET_AH0135_TEMPORAL_PARTITIONING
sps.setEnableMaxMttIncrease ( m_enableMaxMttIncrease );
#endif
#if MULTI_HYP_PRED
sps.setMaxNumAddHyps(m_maxNumAddHyps);
sps.setNumAddHypWeights(m_numAddHypWeights);
sps.setMaxNumAddHypRefFrames(m_maxNumAddHypRefFrames);
#if JVET_V0130_INTRA_TMP
sps.setUseIntraTMP(m_intraTMP);
sps.setIntraTMPMaxSize(m_intraTmpMaxSize);
#if JVET_AE0100_BVGCCCM
sps.setUseBvgCccm(m_bvgCccm);
#endif
#if JVET_AC0071_DBV
sps.setUseIntraDBV(m_intraDBV);
Pekka Astola
committed
#endif
#if JVET_AE0059_INTER_CCCM
sps.setUseInterCccm(m_interCccm);
#endif
#if JVET_AF0073_INTER_CCP_MERGE
sps.setUseInterCcpMerge(m_interCcpMerge);
#if JVET_AH0066_JVET_AH0202_CCP_MERGE_LUMACBF0
sps.setUseInterCcpMergeZeroLumaCbf(m_interCcpMergeZeroLumaCbf);
#endif
Bappaditya Ray
committed
#endif
#if JVET_AH0209_PDP
sps.setUsePDP( m_pdp );

Karsten Suehring
committed
// ADD_NEW_TOOL : (encoder lib) set tool enabling flags and associated parameters here
sps.setUseISP ( m_ISP );
sps.setUseLmcs ( m_lmcsEnabled );
sps.setUseMIP ( m_MIP );
CHECK(m_log2MinCUSize > std::min(6, floorLog2(sps.getMaxCUWidth())), "log2_min_luma_coding_block_size_minus2 shall be in the range of 0 to min (4, log2_ctu_size - 2)");
CHECK(m_uiMaxMTTHierarchyDepth > 2 * (floorLog2(sps.getCTUSize()) - sps.getLog2MinCodingBlockSize()), "sps_max_mtt_hierarchy_depth_inter_slice shall be in the range 0 to 2*(ctbLog2SizeY - log2MinCUSize)");
CHECK(m_uiMaxMTTHierarchyDepthI > 2 * (floorLog2(sps.getCTUSize()) - sps.getLog2MinCodingBlockSize()), "sps_max_mtt_hierarchy_depth_intra_slice_luma shall be in the range 0 to 2*(ctbLog2SizeY - log2MinCUSize)");
CHECK(m_uiMaxMTTHierarchyDepthIChroma > 2 * (floorLog2(sps.getCTUSize()) - sps.getLog2MinCodingBlockSize()), "sps_max_mtt_hierarchy_depth_intra_slice_chroma shall be in the range 0 to 2*(ctbLog2SizeY - log2MinCUSize)");

Karsten Suehring
committed
sps.setTransformSkipEnabledFlag(m_useTransformSkip);
Shih-Ta Hsiang
committed
sps.setLog2MaxTransformSkipBlockSize(m_log2MaxTransformSkipBlockSize);
Alican Nalci
committed
sps.setBDPCMEnabledFlag(m_useBDPCM);

Karsten Suehring
committed
sps.setSPSTemporalMVPEnabledFlag((getTMVPModeId() == 2 || getTMVPModeId() == 1));
sps.setLog2MaxTbSize ( m_log2MaxTbSize );

Karsten Suehring
committed
for (uint32_t channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
{
sps.setBitDepth (ChannelType(channelType), m_bitDepth[channelType] );
sps.setQpBDOffset (ChannelType(channelType), (6 * (m_bitDepth[channelType] - 8)));
sps.setInternalMinusInputBitDepth(ChannelType(channelType), max(0, (m_bitDepth[channelType] - m_inputBitDepth[channelType])));

Karsten Suehring
committed
}
sps.setEntropyCodingSyncEnabledFlag( m_entropyCodingSyncEnabledFlag );
sps.setEntryPointsPresentFlag( m_entryPointPresentFlag );
sps.setUseWP( m_useWeightedPred );
sps.setUseWPBiPred( m_useWeightedBiPred );
sps.setSAOEnabledFlag( m_bUseSAO );
#if JVET_W0066_CCSAO
sps.setCCSAOEnabledFlag( m_CCSAO );
#endif
#if JVET_AG0158_ALF_LUMA_COEFF_PRECISION
sps.setAlfPrecisionFlag( m_alfPrecision );
#endif
#if JVET_AH0057_CCALF_COEFF_PRECISION
sps.setCCALFPrecisionFlag( m_ccalfPrecision );
sps.setJointCbCrEnabledFlag( m_JointCbCrMode );

Karsten Suehring
committed
sps.setMaxTLayers( m_maxTempLayer );
sps.setTemporalIdNestingFlag( ( m_maxTempLayer == 1 ) ? true : false );
for (int i = 0; i < std::min(sps.getMaxTLayers(), (uint32_t) MAX_TLAYER); i++ )

Karsten Suehring
committed
{
sps.setMaxDecPicBuffering(m_maxDecPicBuffering[i], i);
sps.setNumReorderPics(m_numReorderPics[i], i);
}
sps.setScalingListFlag ( (m_useScalingListId == SCALING_LIST_OFF) ? 0 : 1 );
if (sps.getUseColorTrans() && sps.getScalingListFlag())
{
sps.setScalingMatrixForAlternativeColourSpaceDisabledFlag( m_disableScalingMatrixForAlternativeColourSpace );
Loading
Loading full blame...