Newer
Older
}
}
#endif
Yago Sanchez de la Fuente
committed
m_bpDeltasGOPStructure = false;
Yago Sanchez de la Fuente
committed
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
{
if ((m_GOPList[0].m_POC == 16 && m_GOPList[0].m_temporalId == 0 )
&& (m_GOPList[1].m_POC == 8 && m_GOPList[1].m_temporalId == 1 )
&& (m_GOPList[2].m_POC == 4 && m_GOPList[2].m_temporalId == 2 )
&& (m_GOPList[3].m_POC == 2 && m_GOPList[3].m_temporalId == 3 )
&& (m_GOPList[4].m_POC == 1 && m_GOPList[4].m_temporalId == 4 )
&& (m_GOPList[5].m_POC == 3 && m_GOPList[5].m_temporalId == 4 )
&& (m_GOPList[6].m_POC == 6 && m_GOPList[6].m_temporalId == 3 )
&& (m_GOPList[7].m_POC == 5 && m_GOPList[7].m_temporalId == 4 )
&& (m_GOPList[8].m_POC == 7 && m_GOPList[8].m_temporalId == 4 )
&& (m_GOPList[9].m_POC == 12 && m_GOPList[9].m_temporalId == 2 )
&& (m_GOPList[10].m_POC == 10 && m_GOPList[10].m_temporalId == 3 )
&& (m_GOPList[11].m_POC == 9 && m_GOPList[11].m_temporalId == 4 )
&& (m_GOPList[12].m_POC == 11 && m_GOPList[12].m_temporalId == 4 )
&& (m_GOPList[13].m_POC == 14 && m_GOPList[13].m_temporalId == 3 )
&& (m_GOPList[14].m_POC == 13 && m_GOPList[14].m_temporalId == 4 )
&& (m_GOPList[15].m_POC == 15 && m_GOPList[15].m_temporalId == 4 ))
{
m_bpDeltasGOPStructure = true;
}
}
Yago Sanchez de la Fuente
committed
{
if ((m_GOPList[0].m_POC == 8 && m_GOPList[0].m_temporalId == 0 )
&& (m_GOPList[1].m_POC == 4 && m_GOPList[1].m_temporalId == 1 )
&& (m_GOPList[2].m_POC == 2 && m_GOPList[2].m_temporalId == 2 )
&& (m_GOPList[3].m_POC == 1 && m_GOPList[3].m_temporalId == 3 )
&& (m_GOPList[4].m_POC == 3 && m_GOPList[4].m_temporalId == 3 )
&& (m_GOPList[5].m_POC == 6 && m_GOPList[5].m_temporalId == 2 )
&& (m_GOPList[6].m_POC == 5 && m_GOPList[6].m_temporalId == 3 )
&& (m_GOPList[7].m_POC == 7 && m_GOPList[7].m_temporalId == 3 ))
{
m_bpDeltasGOPStructure = true;
}
}
else
{
m_bpDeltasGOPStructure = false;
}
for (int i = 0; m_GOPList[i].m_POC != -1 && i < MAX_GOP + 1; i++)
{
m_RPLList0[i].m_POC = m_RPLList1[i].m_POC = m_GOPList[i].m_POC;
m_RPLList0[i].m_temporalId = m_RPLList1[i].m_temporalId = m_GOPList[i].m_temporalId;
m_RPLList0[i].m_refPic = m_RPLList1[i].m_refPic = m_GOPList[i].m_refPic;
m_RPLList0[i].m_sliceType = m_RPLList1[i].m_sliceType = m_GOPList[i].m_sliceType;
m_RPLList0[i].m_isEncoded = m_RPLList1[i].m_isEncoded = m_GOPList[i].m_isEncoded;
m_RPLList0[i].m_numRefPicsActive = m_GOPList[i].m_numRefPicsActive0;
m_RPLList1[i].m_numRefPicsActive = m_GOPList[i].m_numRefPicsActive1;
m_RPLList0[i].m_numRefPics = m_GOPList[i].m_numRefPics0;
m_RPLList1[i].m_numRefPics = m_GOPList[i].m_numRefPics1;
m_RPLList0[i].m_ltrpInSliceHeaderFlag = m_GOPList[i].m_ltrpInSliceHeaderFlag;
m_RPLList1[i].m_ltrpInSliceHeaderFlag = m_GOPList[i].m_ltrpInSliceHeaderFlag;
for (int j = 0; j < m_GOPList[i].m_numRefPics0; j++)
m_RPLList0[i].m_deltaRefPics[j] = m_GOPList[i].m_deltaRefPics0[j];
for (int j = 0; j < m_GOPList[i].m_numRefPics1; j++)
m_RPLList1[i].m_deltaRefPics[j] = m_GOPList[i].m_deltaRefPics1[j];
}
{
m_GOPList[i].m_POC *= 2;
m_RPLList0[i].m_POC *= 2;
m_RPLList1[i].m_POC *= 2;
for (int j = 0; j < m_RPLList0[i].m_numRefPics; j++)
{
m_RPLList0[i].m_deltaRefPics[j] *= 2;
}
for (int j = 0; j < m_RPLList1[i].m_numRefPics; j++)
{
m_RPLList1[i].m_deltaRefPics[j] *= 2;
}
}
}

Karsten Suehring
committed
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
for (list<const char*>::const_iterator it = argv_unhandled.begin(); it != argv_unhandled.end(); it++)
{
msg( ERROR, "Unhandled argument ignored: `%s'\n", *it);
}
if (argc == 1 || do_help)
{
/* argc == 1: no options have been specified */
po::doHelp(cout, opts);
return false;
}
if (err.is_errored)
{
if (!warnUnknowParameter)
{
/* error report has already been printed on stderr */
return false;
}
}
g_verbosity = MsgLevel( m_verbosity );
/*
* Set any derived parameters
*/
#if EXTENSION_360_VIDEO
Yang Wang
committed
m_inputFileWidth = m_sourceWidth;
m_inputFileHeight = m_sourceHeight;

Karsten Suehring
committed
#endif
if (!inputPathPrefix.empty() && inputPathPrefix.back() != '/' && inputPathPrefix.back() != '\\' )
{
inputPathPrefix += "/";
}
m_inputFileName = inputPathPrefix + m_inputFileName;
if (m_firstValidFrame < 0)
{
}
if (m_lastValidFrame < 0)
{
m_lastValidFrame = m_firstValidFrame + m_framesToBeEncoded - 1;
}
if( m_temporalSubsampleRatio < 1)
{
EXIT ( "Error: TemporalSubsampleRatio must be greater than 0" );
}

Karsten Suehring
committed
m_framesToBeEncoded = ( m_framesToBeEncoded + m_temporalSubsampleRatio - 1 ) / m_temporalSubsampleRatio;
m_adIntraLambdaModifier = cfg_adIntraLambdaModifier.values;
if(m_isField)
{
//Frame height
m_iSourceHeightOrg = m_sourceHeight;

Karsten Suehring
committed
//Field height
m_sourceHeight = m_sourceHeight >> 1;

Karsten Suehring
committed
//number of fields to encode
m_framesToBeEncoded *= 2;
}
Kui Fan
committed
if ( m_subPicInfoPresentFlag )
CHECK( m_numSubPics > MAX_NUM_SUB_PICS || m_numSubPics < 1, "Number of subpicture must be within 1 to 2^16" )
if (!m_subPicSameSizeFlag)
{
CHECK(cfg_subPicCtuTopLeftX.values.size() != m_numSubPics, "Number of SubPicCtuTopLeftX values must be equal to NumSubPics");
CHECK(cfg_subPicCtuTopLeftY.values.size() != m_numSubPics, "Number of SubPicCtuTopLeftY values must be equal to NumSubPics");
CHECK(cfg_subPicWidth.values.size() != m_numSubPics, "Number of SubPicWidth values must be equal to NumSubPics");
CHECK(cfg_subPicHeight.values.size() != m_numSubPics, "Number of SubPicHeight values must be equal to NumSubPics");
}
else
{
CHECK(cfg_subPicCtuTopLeftX.values.size() != 0, "Number of SubPicCtuTopLeftX values must be equal to 0");
CHECK(cfg_subPicCtuTopLeftY.values.size() != 0, "Number of SubPicCtuTopLeftY values must be equal to 0");
CHECK(cfg_subPicWidth.values.size() != 1, "Number of SubPicWidth values must be equal to 1");
CHECK(cfg_subPicHeight.values.size() != 1, "Number of SubPicHeight values must be equal to 1");
}
CHECK( cfg_subPicTreatedAsPicFlag.values.size() != m_numSubPics, "Number of SubPicTreatedAsPicFlag values must be equal to NumSubPics");
CHECK( cfg_loopFilterAcrossSubpicEnabledFlag.values.size() != m_numSubPics, "Number of LoopFilterAcrossSubpicEnabledFlag values must be equal to NumSubPics");
if (m_subPicIdMappingExplicitlySignalledFlag)
{
CHECK( cfg_subPicId.values.size() != m_numSubPics, "Number of SubPicId values must be equal to NumSubPics");
}
m_subPicCtuTopLeftX = cfg_subPicCtuTopLeftX.values;
m_subPicCtuTopLeftY = cfg_subPicCtuTopLeftY.values;
m_subPicWidth = cfg_subPicWidth.values;
m_subPicHeight = cfg_subPicHeight.values;
m_subPicTreatedAsPicFlag = cfg_subPicTreatedAsPicFlag.values;
m_loopFilterAcrossSubpicEnabledFlag = cfg_loopFilterAcrossSubpicEnabledFlag.values;
if (m_subPicIdMappingExplicitlySignalledFlag)
LI JINGYA
committed
{
for (int i=0; i < m_numSubPics; i++)
{
m_subPicId[i] = cfg_subPicId.values[i];
}
uint32_t tmpWidthVal = (m_sourceWidth + m_ctuSize - 1) / m_ctuSize;
uint32_t tmpHeightVal = (m_sourceHeight + m_ctuSize - 1) / m_ctuSize;
if (!m_subPicSameSizeFlag)
{
for (int i = 0; i < m_numSubPics; i++)
{
CHECK(m_subPicCtuTopLeftX[i] + m_subPicWidth[i] > tmpWidthVal, "Subpicture must not exceed picture boundary");
CHECK(m_subPicCtuTopLeftY[i] + m_subPicHeight[i] > tmpHeightVal, "Subpicture must not exceed picture boundary");
}
}
else
{
uint32_t numSubpicCols = tmpWidthVal / m_subPicWidth[0];
Martin Pettersson
committed
CHECK(tmpWidthVal % m_subPicWidth[0] != 0, "sps_subpic_width_minus1[0] is invalid.");
CHECK(tmpHeightVal % m_subPicHeight[0] != 0, "sps_subpic_height_minus1[0] is invalid.");
CHECK(numSubpicCols * (tmpHeightVal / m_subPicHeight[0]) != m_numSubPics, "when sps_subpic_same_size_flag is equal to, sps_num_subpics_minus1 is invalid");
}
// automatically determine subpicture ID lenght in case it is not specified
if (m_subPicIdLen == 0)
LI JINGYA
committed
{
if (m_subPicIdMappingExplicitlySignalledFlag)
{
// use the heighest specified ID
auto maxIdVal = std::max_element(m_subPicId.begin(),m_subPicId.end());
m_subPicIdLen = ceilLog2(*maxIdVal);
}
else
LI JINGYA
committed
{
// use the number of subpictures
m_subPicIdLen = ceilLog2(m_numSubPics);
CHECK( m_subPicIdLen > 16, "SubPicIdLen must not exceed 16 bits" );
CHECK(m_resChangeInClvsEnabled, "resolution change in CLVS and subpictures cannot be enabled together");
if (m_virtualBoundariesPresentFlag)
{
CHECK(m_numVerVirtualBoundaries != 0, "The number of vertical virtual boundaries shall be 0 when the picture width is less than or equal to 8");
CHECK(m_numHorVirtualBoundaries != 0, "The number of horizontal virtual boundaries shall be 0 when the picture height is less than or equal to 8");
}
if (m_cfgSubpictureLevelInfoSEI.m_enabled)
{
CHECK (m_numSubPics != m_cfgSubpictureLevelInfoSEI.m_numSubpictures, "NumSubPics must be equal to SEISubpicLevelInfoNumSubpics" );
CHECK (m_cfgSubpictureLevelInfoSEI.m_sliMaxSublayers != m_maxSublayers, "SEISubpicLevelInfoMaxSublayers must be equal to vps_max_sublayers");
if (m_cfgSubpictureLevelInfoSEI.m_sliSublayerInfoPresentFlag)
{
CHECK(cfg_sliRefLevels.values.size() < m_maxSublayers, "when sliSublayerInfoPresentFlag = 1, the number of reference levels must be greater than or equal to sublayers");
}
if (m_cfgSubpictureLevelInfoSEI.m_explicitFraction)
{
m_cfgSubpictureLevelInfoSEI.m_fractions = cfg_sliFractions.values;
m_cfgSubpictureLevelInfoSEI.m_refLevels = cfg_sliRefLevels.values;
if (m_cfgSubpictureLevelInfoSEI.m_sliSublayerInfoPresentFlag)
{
CHECK((int)cfg_sliRefLevels.values.size() / m_maxSublayers * m_cfgSubpictureLevelInfoSEI.m_numSubpictures * m_cfgSubpictureLevelInfoSEI.m_sliMaxSublayers != cfg_sliFractions.values.size(),
"when sliSublayerInfoPresentFlag = 1, the number of subpicture level fractions must be equal to the numer of subpictures times the number of reference levels times the number of sublayers");
}
else
{
CHECK((int)cfg_sliRefLevels.values.size() * m_cfgSubpictureLevelInfoSEI.m_numSubpictures != cfg_sliFractions.values.size(), "when sliSublayerInfoPresentFlag = 0, the number of subpicture level fractions must be equal to the numer of subpictures times the number of reference levels");
}
}
m_cfgSubpictureLevelInfoSEI.m_nonSubpicLayersFraction = cfg_sliNonSubpicLayersFractions.values;
if (m_cfgSubpictureLevelInfoSEI.m_sliSublayerInfoPresentFlag)
{
CHECK((int)cfg_sliNonSubpicLayersFractions.values.size() != ( cfg_sliRefLevels.values.size() * m_cfgSubpictureLevelInfoSEI.m_numSubpictures ),
"when sliSublayerInfoPresentFlag = 1, the number of non-subpicture level fractions must be equal to the numer of reference levels times the number of sublayers");
}
else
{
CHECK((int)cfg_sliNonSubpicLayersFractions.values.size() != ( cfg_sliRefLevels.values.size() ),
"when sliSublayerInfoPresentFlag = 0, the number of non-subpicture level fractions must be equal to the numer of reference levels");
}
}
if (m_costMode != COST_LOSSLESS_CODING && m_mixedLossyLossless)
m_mixedLossyLossless = 0;
msg(WARNING, "*************************************************************************\n");
msg(WARNING, "* Mixed lossy lossles coding cannot enable in lossy costMode *\n");
msg(WARNING, "* Forcely disabled m_mixedLossyLossless *\n");
msg(WARNING, "*************************************************************************\n");
if (!m_mixedLossyLossless && cfgSliceLosslessArray.values.size() > 0)
msg(WARNING, "*************************************************************************\n");
msg(WARNING, "* Mixed lossy lossles coding is not enabled *\n");
msg(WARNING, "* ignoring the value of SliceLosslessArray *\n");
msg(WARNING, "*************************************************************************\n");
}
if (m_costMode == COST_LOSSLESS_CODING && m_mixedLossyLossless)
{
m_sliceLosslessArray.resize(cfgSliceLosslessArray.values.size());
for (uint32_t i = 0; i < cfgSliceLosslessArray.values.size(); i++)
{
m_sliceLosslessArray[i] = cfgSliceLosslessArray.values[i];
}
}
if( m_picPartitionFlag )
{
// store tile column widths
m_tileColumnWidth.resize(cfgTileColumnWidth.values.size());
for(uint32_t i=0; i<cfgTileColumnWidth.values.size(); i++)
{
m_tileColumnWidth[i]=cfgTileColumnWidth.values[i];
}
// store tile row heights
m_tileRowHeight.resize(cfgTileRowHeight.values.size());
for(uint32_t i=0; i<cfgTileRowHeight.values.size(); i++)
{
m_tileRowHeight[i]=cfgTileRowHeight.values[i];
}
// store rectangular slice positions
if( !m_rasterSliceFlag )
{
m_rectSlicePos.resize(cfgRectSlicePos.values.size());
for(uint32_t i=0; i<cfgRectSlicePos.values.size(); i++)
{
m_rectSlicePos[i]=cfgRectSlicePos.values[i];
}
}
// store raster-scan slice sizes
{
m_rasterSliceSize.resize(cfgRasterSliceSize.values.size());
for(uint32_t i=0; i<cfgRasterSliceSize.values.size(); i++)
{
m_rasterSliceSize[i]=cfgRasterSliceSize.values[i];
}
}
}
{
m_tileColumnWidth.clear();
m_tileRowHeight.clear();
m_rectSlicePos.clear();
m_rasterSliceSize.clear();
m_rectSliceFixedWidth = 0;
m_rectSliceFixedHeight = 0;
}
m_numSubProfile = (uint8_t) cfg_SubProfile.values.size();
m_subProfile.resize(m_numSubProfile);
for (uint8_t i = 0; i < m_numSubProfile; ++i)
{
m_subProfile[i] = cfg_SubProfile.values[i];
}

Karsten Suehring
committed
/* rules for input, output and internal bitdepths as per help text */

Karsten Suehring
committed
{
m_msbExtendedBitDepth[CHANNEL_TYPE_LUMA] = m_inputBitDepth[CHANNEL_TYPE_LUMA];

Karsten Suehring
committed
}

Karsten Suehring
committed
{
m_msbExtendedBitDepth[CHANNEL_TYPE_CHROMA] = m_msbExtendedBitDepth[CHANNEL_TYPE_LUMA];

Karsten Suehring
committed
}
if (m_internalBitDepth [CHANNEL_TYPE_LUMA ] == 0)
{
m_internalBitDepth[CHANNEL_TYPE_LUMA] = m_msbExtendedBitDepth[CHANNEL_TYPE_LUMA];

Karsten Suehring
committed
}
m_internalBitDepth [CHANNEL_TYPE_CHROMA] = m_internalBitDepth [CHANNEL_TYPE_LUMA ];
if (m_inputBitDepth [CHANNEL_TYPE_CHROMA] == 0)
{
m_inputBitDepth [CHANNEL_TYPE_CHROMA] = m_inputBitDepth [CHANNEL_TYPE_LUMA ];
}
if (m_outputBitDepth [CHANNEL_TYPE_LUMA ] == 0)
{
m_outputBitDepth [CHANNEL_TYPE_LUMA ] = m_internalBitDepth [CHANNEL_TYPE_LUMA ];
}
if (m_outputBitDepth [CHANNEL_TYPE_CHROMA] == 0)
{
m_outputBitDepth [CHANNEL_TYPE_CHROMA] = m_outputBitDepth [CHANNEL_TYPE_LUMA ];
}
m_inputChromaFormatIDC = numberToChromaFormat(tmpInputChromaFormat);
m_chromaFormatIDC = ((tmpChromaFormat == 0) ? (m_inputChromaFormatIDC) : (numberToChromaFormat(tmpChromaFormat)));

Karsten Suehring
committed
#if EXTENSION_360_VIDEO
m_ext360.processOptions(ext360CfgContext);
#endif
if (isY4mFileExt(m_inputFileName))
{
int width = 0, height = 0, frameRate = 0, inputBitDepth = 0;
ChromaFormat chromaFormat = CHROMA_420;
VideoIOYuv inputFile;
inputFile.parseY4mFileHeader(m_inputFileName, width, height, frameRate, inputBitDepth, chromaFormat);
if (width != m_sourceWidth || height != m_sourceHeight || frameRate != m_frameRate
|| inputBitDepth != m_inputBitDepth[0] || chromaFormat != m_chromaFormatIDC)
{
msg(WARNING, "\nWarning: Y4M file info is different from input setting. Using the info from Y4M file\n");
m_sourceWidth = width;
m_sourceHeight = height;
m_inputBitDepth[0] = inputBitDepth;
m_inputBitDepth[1] = inputBitDepth;
m_chromaFormatIDC = chromaFormat;
m_msbExtendedBitDepth[0] = m_inputBitDepth[0];
m_msbExtendedBitDepth[1] = m_inputBitDepth[1];
}
}

Karsten Suehring
committed
CHECK( !( tmpWeightedPredictionMethod >= 0 && tmpWeightedPredictionMethod <= WP_PER_PICTURE_WITH_HISTOGRAM_AND_PER_COMPONENT_AND_CLIPPING_AND_EXTENSION ), "Error in cfg" );
m_weightedPredictionMethod = WeightedPredictionMethod(tmpWeightedPredictionMethod);
CHECK( tmpFastInterSearchMode<0 || tmpFastInterSearchMode>FASTINTERSEARCH_MODE3, "Error in cfg" );
m_fastInterSearchMode = FastInterSearchMode(tmpFastInterSearchMode);
CHECK( tmpMotionEstimationSearchMethod < 0 || tmpMotionEstimationSearchMethod >= MESEARCH_NUMBER_OF_METHODS, "Error in cfg" );
m_motionEstimationSearchMethod=MESearchMethod(tmpMotionEstimationSearchMethod);
if (extendedProfile == ExtendedProfileName::AUTO)
{
if (xAutoDetermineProfile())
{
EXIT( "Unable to determine profile from configured settings");
}
}

Karsten Suehring
committed
else
{
switch (extendedProfile)
{
case ExtendedProfileName::NONE: m_profile = Profile::NONE; break;
case ExtendedProfileName::MAIN_10: m_profile = Profile::MAIN_10; break;
case ExtendedProfileName::MAIN_10_444: m_profile = Profile::MAIN_10_444; break;
case ExtendedProfileName::MAIN_10_STILL_PICTURE: m_profile = Profile::MAIN_10_STILL_PICTURE; break;
case ExtendedProfileName::MAIN_10_444_STILL_PICTURE: m_profile = Profile::MAIN_10_444_STILL_PICTURE; break;
case ExtendedProfileName::MULTILAYER_MAIN_10: m_profile = Profile::MULTILAYER_MAIN_10; break;
case ExtendedProfileName::MULTILAYER_MAIN_10_444: m_profile = Profile::MULTILAYER_MAIN_10_444; break;
case ExtendedProfileName::MULTILAYER_MAIN_10_STILL_PICTURE:
m_profile = Profile::MULTILAYER_MAIN_10_STILL_PICTURE;
break;
case ExtendedProfileName::MULTILAYER_MAIN_10_444_STILL_PICTURE:
m_profile = Profile::MULTILAYER_MAIN_10_444_STILL_PICTURE;
break;
Tomohiro Ikai
committed
case ExtendedProfileName::MAIN_12:
m_profile = Profile::MAIN_12; break;
case ExtendedProfileName::MAIN_12_444:
m_profile = Profile::MAIN_12_444; break;
case ExtendedProfileName::MAIN_16_444:
m_profile = Profile::MAIN_16_444; break;
case ExtendedProfileName::MAIN_12_INTRA:
m_profile = Profile::MAIN_12_INTRA; break;
case ExtendedProfileName::MAIN_12_444_INTRA:
m_profile = Profile::MAIN_12_444_INTRA; break;
case ExtendedProfileName::MAIN_16_444_INTRA:
m_profile = Profile::MAIN_16_444_INTRA; break;
case ExtendedProfileName::MAIN_12_STILL_PICTURE:
m_profile = Profile::MAIN_12_STILL_PICTURE; break;
case ExtendedProfileName::MAIN_12_444_STILL_PICTURE:
m_profile = Profile::MAIN_12_444_STILL_PICTURE; break;
case ExtendedProfileName::MAIN_16_444_STILL_PICTURE:
m_profile = Profile::MAIN_16_444_STILL_PICTURE; break;
default: EXIT("Unable to determine profile from configured settings"); break;

Karsten Suehring
committed
}
{
m_chromaFormatConstraint = (tmpConstraintChromaFormat == 0) ? m_chromaFormatIDC : numberToChromaFormat(tmpConstraintChromaFormat);
if (m_bitDepthConstraint == 0)
{
if (m_profile != Profile::NONE)
{
const ProfileFeatures *features = ProfileFeatures::getProfileFeatures(m_profile);
CHECK(features->profile != m_profile, "Profile not found");
m_bitDepthConstraint = features->maxBitDepth;
}
else // m_profile == Profile::NONE
{
m_bitDepthConstraint = 16; // max value - unconstrained.
CHECK(m_bitDepthConstraint < m_internalBitDepth[CHANNEL_TYPE_LUMA], "MaxBitDepthConstraint setting does not allow the specified luma bit depth to be coded.");
CHECK(m_bitDepthConstraint < m_internalBitDepth[CHANNEL_TYPE_CHROMA], "MaxBitDepthConstraint setting does not allow the specified chroma bit depth to be coded.");
CHECK(m_chromaFormatConstraint < m_chromaFormatIDC, "MaxChromaFormatConstraint setting does not allow the specified chroma format to be coded.");
CHECK(m_chromaFormatConstraint >= NUM_CHROMA_FORMAT, "Bad value given for MaxChromaFormatConstraint setting.")
CHECK(m_bitDepthConstraint < 8 || m_bitDepthConstraint>16, "MaxBitDepthConstraint setting must be in the range 8 to 16 (inclusive)");

Karsten Suehring
committed
m_inputColourSpaceConvert = stringToInputColourSpaceConvert(inputColourSpaceConvert, true);
m_rgbFormat = (m_inputColourSpaceConvert == IPCOLOURSPACE_RGBtoGBR && m_chromaFormatIDC == CHROMA_444) ? true : false;
Tomohiro Ikai
committed
if (m_profile == Profile::MAIN_12 || m_profile == Profile::MAIN_12_INTRA || m_profile == Profile::MAIN_12_STILL_PICTURE ||
m_profile == Profile::MAIN_12_444 || m_profile == Profile::MAIN_12_444_INTRA || m_profile == Profile::MAIN_12_444_STILL_PICTURE ||
m_profile == Profile::MAIN_16_444 || m_profile == Profile::MAIN_16_444_INTRA || m_profile == Profile::MAIN_16_444_STILL_PICTURE)
{
m_gciPresentFlag = true;
}
if (m_profile == Profile::MAIN_12_INTRA || m_profile == Profile::MAIN_12_444_INTRA || m_profile == Profile::MAIN_16_444_INTRA)
{
CHECK(m_intraPeriod != 1, "IntraPeriod setting must be 1 for Intra profiles")
Tomohiro Ikai
committed
}
if (m_profile == Profile::MULTILAYER_MAIN_10_STILL_PICTURE || m_profile == Profile::MAIN_10_STILL_PICTURE ||
m_profile == Profile::MAIN_12_STILL_PICTURE || m_profile == Profile::MAIN_12_444_STILL_PICTURE || m_profile == Profile::MAIN_16_444_STILL_PICTURE)
{
CHECK(m_framesToBeEncoded != 1, "FramesToBeEncoded setting must be 1 for Still Picture profiles")
}

Karsten Suehring
committed
Jonatan Samuelsson-Allendes
committed
// Picture width and height must be multiples of 8 and minCuSize
const int minResolutionMultiple = std::max(8, 1 << m_log2MinCuSize);

Karsten Suehring
committed

Karsten Suehring
committed
switch (m_conformanceWindowMode)
{
case 0:
{
// no conformance or padding
m_confWinLeft = m_confWinRight = m_confWinTop = m_confWinBottom = 0;
m_sourcePadding[1] = m_sourcePadding[0] = 0;

Karsten Suehring
committed
break;
}
case 1:
{
// automatic padding to minimum CU size
if (m_sourceWidth % minResolutionMultiple)
Jonatan Samuelsson-Allendes
committed
{
m_sourcePadding[0] = m_confWinRight = ((m_sourceWidth / minResolutionMultiple) + 1) * minResolutionMultiple - m_sourceWidth;
m_sourceWidth += m_confWinRight;
Jonatan Samuelsson-Allendes
committed
}
if (m_sourceHeight % minResolutionMultiple)
Jonatan Samuelsson-Allendes
committed
{
m_sourcePadding[1] = m_confWinBottom = ((m_sourceHeight / minResolutionMultiple) + 1) * minResolutionMultiple - m_sourceHeight;
m_sourceHeight += m_confWinBottom;

Karsten Suehring
committed
if ( m_isField )
{
m_iSourceHeightOrg += m_confWinBottom << 1;
m_sourcePadding[1] = m_confWinBottom << 1;

Karsten Suehring
committed
}
}
if (m_sourcePadding[0] % SPS::getWinUnitX(m_chromaFormatIDC) != 0)

Karsten Suehring
committed
{
EXIT( "Error: picture width is not an integer multiple of the specified chroma subsampling");
}
if (m_sourcePadding[1] % SPS::getWinUnitY(m_chromaFormatIDC) != 0)

Karsten Suehring
committed
{
EXIT( "Error: picture height is not an integer multiple of the specified chroma subsampling");
}
if (m_sourcePadding[0])
{
msg( INFO, "Info: Conformance window automatically enabled. Adding %i lumal pel horizontally\n", m_sourcePadding[0]);
}
if (m_sourcePadding[1])
{
msg( INFO, "Info: Conformance window automatically enabled. Adding %i lumal pel vertically\n", m_sourcePadding[1]);
}

Karsten Suehring
committed
break;
}
case 2:
{
//padding
m_sourceWidth += m_sourcePadding[0];
m_sourceHeight += m_sourcePadding[1];
m_confWinRight = m_sourcePadding[0];
m_confWinBottom = m_sourcePadding[1];

Karsten Suehring
committed
break;
}
case 3:
{
// conformance
if ((m_confWinLeft == 0) && (m_confWinRight == 0) && (m_confWinTop == 0) && (m_confWinBottom == 0))
{
msg( ERROR, "Warning: Conformance window enabled, but all conformance window parameters set to zero\n");
}
if ((m_sourcePadding[1] != 0) || (m_sourcePadding[0]!=0))

Karsten Suehring
committed
{
msg( ERROR, "Warning: Conformance window enabled, padding parameters will be ignored\n");
}
m_sourcePadding[1] = m_sourcePadding[0] = 0;

Karsten Suehring
committed
break;
}
}

Karsten Suehring
committed
CHECK(((m_sourceWidth% minResolutionMultiple) || (m_sourceHeight % minResolutionMultiple)), "Picture width or height (after padding) is not a multiple of 8 or minCuSize, please use ConformanceWindowMode=1 for automatic adjustment or ConformanceWindowMode=2 to specify padding manually!!");

Karsten Suehring
committed
if( m_conformanceWindowMode > 0 && m_subPicInfoPresentFlag )
{
for(int i = 0; i < m_numSubPics; i++)
{
CHECK((m_subPicCtuTopLeftX[i] * m_ctuSize)
>= (m_sourceWidth - m_confWinRight * SPS::getWinUnitX(m_chromaFormatIDC)),
"No subpicture can be located completely outside of the conformance cropping window");
CHECK(((m_subPicCtuTopLeftX[i] + m_subPicWidth[i]) * m_ctuSize)
<= (m_confWinLeft * SPS::getWinUnitX(m_chromaFormatIDC)),
"No subpicture can be located completely outside of the conformance cropping window");
CHECK((m_subPicCtuTopLeftY[i] * m_ctuSize)
>= (m_sourceHeight - m_confWinBottom * SPS::getWinUnitY(m_chromaFormatIDC)),
"No subpicture can be located completely outside of the conformance cropping window");
CHECK(((m_subPicCtuTopLeftY[i] + m_subPicHeight[i]) * m_ctuSize)
<= (m_confWinTop * SPS::getWinUnitY(m_chromaFormatIDC)),
"No subpicture can be located completely outside of the conformance cropping window");
if (tmpDecodedPictureHashSEIMappedType < 0 || tmpDecodedPictureHashSEIMappedType > to_underlying(HashType::NUM))

Karsten Suehring
committed
{
EXIT( "Error: bad checksum mode");
}
// Need to map values to match those of the SEI message:
if (tmpDecodedPictureHashSEIMappedType==0)
{
m_decodedPictureHashSEIType = HashType::NONE;

Karsten Suehring
committed
}
else
{
m_decodedPictureHashSEIType = static_cast<HashType>(tmpDecodedPictureHashSEIMappedType - 1);

Karsten Suehring
committed
}

Karsten Suehring
committed
// Need to map values to match those of the SEI message:
if (tmpSubpicDecodedPictureHashMappedType==0)
{
m_subpicDecodedPictureHashType = HashType::NONE;

Karsten Suehring
committed
}
else
{
m_subpicDecodedPictureHashType = static_cast<HashType>(tmpSubpicDecodedPictureHashMappedType - 1);

Karsten Suehring
committed
}

Karsten Suehring
committed
// allocate slice-based dQP values
m_frameDeltaQps.resize(m_framesToBeEncoded + m_gopSize + 1);
std::fill(m_frameDeltaQps.begin(), m_frameDeltaQps.end(), 0);

Karsten Suehring
committed
if (m_qpIncrementAtSourceFrame.bPresent)
{
uint32_t switchingPOC = 0;

Karsten Suehring
committed
{
// if switch source frame (ssf) = 10, and frame skip (fs)=2 and temporal subsample ratio (tsr) =1, then
// for this simulation switch at POC 8 (=10-2).
// if ssf=10, fs=2, tsr=2, then for this simulation, switch at POC 4 (=(10-2)/2): POC0=Src2, POC1=Src4, POC2=Src6, POC3=Src8, POC4=Src10
switchingPOC = (m_qpIncrementAtSourceFrame.value - m_frameSkip) / m_temporalSubsampleRatio;

Karsten Suehring
committed
}
for (uint32_t i = switchingPOC; i < m_frameDeltaQps.size(); i++)

Karsten Suehring
committed
{

Karsten Suehring
committed
}
}
#if SHARP_LUMA_DELTA_QP
CHECK( lumaLevelToDeltaQPMode >= LUMALVL_TO_DQP_NUM_MODES, "Error in cfg" );
m_lumaLevelToDeltaQPMapping.mode=LumaLevelToDQPMode(lumaLevelToDeltaQPMode);
if (m_lumaLevelToDeltaQPMapping.mode)
{
CHECK( cfg_lumaLeveltoDQPMappingLuma.values.size() != cfg_lumaLeveltoDQPMappingQP.values.size(), "Error in cfg" );
m_lumaLevelToDeltaQPMapping.mapping.resize(cfg_lumaLeveltoDQPMappingLuma.values.size());
for(uint32_t i=0; i<cfg_lumaLeveltoDQPMappingLuma.values.size(); i++)
{
m_lumaLevelToDeltaQPMapping.mapping[i]=std::pair<int,int>(cfg_lumaLeveltoDQPMappingLuma.values[i], cfg_lumaLeveltoDQPMappingQP.values[i]);
}
}
#endif
Adarsh Krishnan Ramasubramonian
committed
CHECK(cfg_qpInValCb.values.size() != cfg_qpOutValCb.values.size(), "Chroma QP table for Cb is incomplete.");
CHECK(cfg_qpInValCr.values.size() != cfg_qpOutValCr.values.size(), "Chroma QP table for Cr is incomplete.");
CHECK(cfg_qpInValCbCr.values.size() != cfg_qpOutValCbCr.values.size(), "Chroma QP table for CbCr is incomplete.");

Christian Helmrich
committed
if (m_useIdentityTableForNon420Chroma && m_chromaFormatIDC != CHROMA_420)
Adarsh Krishnan Ramasubramonian
committed
{
m_chromaQpMappingTableParams.m_sameCQPTableForAllChromaFlag = true;
cfg_qpInValCb.values = { 26 };
cfg_qpInValCr.values = { 26 };
cfg_qpInValCbCr.values = { 26 };
cfg_qpOutValCb.values = { 26 };
cfg_qpOutValCr.values = { 26 };
cfg_qpOutValCbCr.values = { 26 };
Adarsh Krishnan Ramasubramonian
committed
}
// Need to have at least 2 points in the set. Add second one if only one given
if (cfg_qpInValCb.values.size() == 1)
{
cfg_qpInValCb.values.push_back(cfg_qpInValCb.values[0] + 1);
cfg_qpOutValCb.values.push_back(cfg_qpOutValCb.values[0] + 1);
}
if (cfg_qpInValCr.values.size() == 1)
{
cfg_qpInValCr.values.push_back(cfg_qpInValCr.values[0] + 1);
cfg_qpOutValCr.values.push_back(cfg_qpOutValCr.values[0] + 1);
}
if (cfg_qpInValCbCr.values.size() == 1)
{
cfg_qpInValCbCr.values.push_back(cfg_qpInValCbCr.values[0] + 1);
cfg_qpOutValCbCr.values.push_back(cfg_qpOutValCbCr.values[0] + 1);
}
int qpBdOffsetC = 6 * (m_internalBitDepth[CHANNEL_TYPE_CHROMA] - 8);
m_chromaQpMappingTableParams.m_deltaQpInValMinus1[0].resize(cfg_qpInValCb.values.size());
m_chromaQpMappingTableParams.m_deltaQpOutVal[0].resize(cfg_qpOutValCb.values.size());
m_chromaQpMappingTableParams.m_numPtsInCQPTableMinus1[0] = (int) cfg_qpOutValCb.values.size() - 2;
m_chromaQpMappingTableParams.m_qpTableStartMinus26[0] = -26 + cfg_qpInValCb.values[0];
CHECK(m_chromaQpMappingTableParams.m_qpTableStartMinus26[0] < -26 - qpBdOffsetC || m_chromaQpMappingTableParams.m_qpTableStartMinus26[0] > 36, "qpTableStartMinus26[0] is out of valid range of -26 -qpBdOffsetC to 36, inclusive.")
CHECK(cfg_qpInValCb.values[0] != cfg_qpOutValCb.values[0], "First qpInValCb value should be equal to first qpOutValCb value");
Tangi Poirier
committed
for (int i = 0; i < cfg_qpInValCb.values.size() - 1; i++)
Adarsh Krishnan Ramasubramonian
committed
{
CHECK(cfg_qpInValCb.values[i] < -qpBdOffsetC || cfg_qpInValCb.values[i] > MAX_QP, "Some entries cfg_qpInValCb are out of valid range of -qpBdOffsetC to 63, inclusive.");
CHECK(cfg_qpOutValCb.values[i] < -qpBdOffsetC || cfg_qpOutValCb.values[i] > MAX_QP, "Some entries cfg_qpOutValCb are out of valid range of -qpBdOffsetC to 63, inclusive.");
Tangi Poirier
committed
m_chromaQpMappingTableParams.m_deltaQpInValMinus1[0][i] = cfg_qpInValCb.values[i + 1] - cfg_qpInValCb.values[i] - 1;
m_chromaQpMappingTableParams.m_deltaQpOutVal[0][i] = cfg_qpOutValCb.values[i + 1] - cfg_qpOutValCb.values[i];
Adarsh Krishnan Ramasubramonian
committed
}
if (!m_chromaQpMappingTableParams.m_sameCQPTableForAllChromaFlag)
Adarsh Krishnan Ramasubramonian
committed
{
m_chromaQpMappingTableParams.m_deltaQpInValMinus1[1].resize(cfg_qpInValCr.values.size());
m_chromaQpMappingTableParams.m_deltaQpOutVal[1].resize(cfg_qpOutValCr.values.size());
m_chromaQpMappingTableParams.m_numPtsInCQPTableMinus1[1] = (int) cfg_qpOutValCr.values.size() - 2;
m_chromaQpMappingTableParams.m_qpTableStartMinus26[1] = -26 + cfg_qpInValCr.values[0];
CHECK(m_chromaQpMappingTableParams.m_qpTableStartMinus26[1] < -26 - qpBdOffsetC || m_chromaQpMappingTableParams.m_qpTableStartMinus26[1] > 36, "qpTableStartMinus26[1] is out of valid range of -26 -qpBdOffsetC to 36, inclusive.")
CHECK(cfg_qpInValCr.values[0] != cfg_qpOutValCr.values[0], "First qpInValCr value should be equal to first qpOutValCr value");
Tangi Poirier
committed
for (int i = 0; i < cfg_qpInValCr.values.size() - 1; i++)
Adarsh Krishnan Ramasubramonian
committed
{
CHECK(cfg_qpInValCr.values[i] < -qpBdOffsetC || cfg_qpInValCr.values[i] > MAX_QP, "Some entries cfg_qpInValCr are out of valid range of -qpBdOffsetC to 63, inclusive.");
CHECK(cfg_qpOutValCr.values[i] < -qpBdOffsetC || cfg_qpOutValCr.values[i] > MAX_QP, "Some entries cfg_qpOutValCr are out of valid range of -qpBdOffsetC to 63, inclusive.");
Tangi Poirier
committed
m_chromaQpMappingTableParams.m_deltaQpInValMinus1[1][i] = cfg_qpInValCr.values[i + 1] - cfg_qpInValCr.values[i] - 1;
m_chromaQpMappingTableParams.m_deltaQpOutVal[1][i] = cfg_qpOutValCr.values[i + 1] - cfg_qpOutValCr.values[i];
Adarsh Krishnan Ramasubramonian
committed
}
m_chromaQpMappingTableParams.m_deltaQpInValMinus1[2].resize(cfg_qpInValCbCr.values.size());
m_chromaQpMappingTableParams.m_deltaQpOutVal[2].resize(cfg_qpOutValCbCr.values.size());
m_chromaQpMappingTableParams.m_numPtsInCQPTableMinus1[2] = (int) cfg_qpOutValCbCr.values.size() - 2;
m_chromaQpMappingTableParams.m_qpTableStartMinus26[2] = -26 + cfg_qpInValCbCr.values[0];
CHECK(m_chromaQpMappingTableParams.m_qpTableStartMinus26[2] < -26 - qpBdOffsetC || m_chromaQpMappingTableParams.m_qpTableStartMinus26[2] > 36, "qpTableStartMinus26[2] is out of valid range of -26 -qpBdOffsetC to 36, inclusive.")
CHECK(cfg_qpInValCbCr.values[0] != cfg_qpInValCbCr.values[0], "First qpInValCbCr value should be equal to first qpOutValCbCr value");
Tangi Poirier
committed
for (int i = 0; i < cfg_qpInValCbCr.values.size() - 1; i++)
Adarsh Krishnan Ramasubramonian
committed
{
CHECK(cfg_qpInValCbCr.values[i] < -qpBdOffsetC || cfg_qpInValCbCr.values[i] > MAX_QP, "Some entries cfg_qpInValCbCr are out of valid range of -qpBdOffsetC to 63, inclusive.");
CHECK(cfg_qpOutValCbCr.values[i] < -qpBdOffsetC || cfg_qpOutValCbCr.values[i] > MAX_QP, "Some entries cfg_qpOutValCbCr are out of valid range of -qpBdOffsetC to 63, inclusive.");
Tangi Poirier
committed
m_chromaQpMappingTableParams.m_deltaQpInValMinus1[2][i] = cfg_qpInValCbCr.values[i + 1] - cfg_qpInValCbCr.values[i] - 1;
m_chromaQpMappingTableParams.m_deltaQpOutVal[2][i] = cfg_qpInValCbCr.values[i + 1] - cfg_qpInValCbCr.values[i];
Adarsh Krishnan Ramasubramonian
committed
}
}

Karsten Suehring
committed
Philippe de Lagrange
committed
/* Local chroma QP offsets configuration */
Philippe de Lagrange
committed
CHECK(m_cuChromaQpOffsetSubdiv < 0, "MaxCuChromaQpOffsetSubdiv shall be >= 0");
Philippe de Lagrange
committed
CHECK(cfg_crQpOffsetList.values.size() != cfg_cbQpOffsetList.values.size(), "Chroma QP offset lists shall be the same size");
Philippe de Lagrange
committed
CHECK(cfg_cbCrQpOffsetList.values.size() != cfg_cbQpOffsetList.values.size() && cfg_cbCrQpOffsetList.values.size() > 0, "Chroma QP offset list for joint CbCr shall be either the same size as Cb and Cr or empty");
Philippe de Lagrange
committed
if (m_cuChromaQpOffsetSubdiv > 0 && !cfg_cbQpOffsetList.values.size())
Philippe de Lagrange
committed
{
Philippe de Lagrange
committed
msg(WARNING, "MaxCuChromaQpOffsetSubdiv has no effect when chroma QP offset lists are empty\n");
Philippe de Lagrange
committed
}
m_cuChromaQpOffsetList.resize(cfg_cbQpOffsetList.values.size());
for (int i=0; i < cfg_cbQpOffsetList.values.size(); i++)
{
m_cuChromaQpOffsetList[i].u.comp.cbOffset = cfg_cbQpOffsetList.values[i];
m_cuChromaQpOffsetList[i].u.comp.crOffset = cfg_crQpOffsetList.values[i];
m_cuChromaQpOffsetList[i].u.comp.jointCbCrOffset =
cfg_cbCrQpOffsetList.values.size() ? cfg_cbCrQpOffsetList.values[i] : 0;
Philippe de Lagrange
committed
}
Shunsuke Iwamura
committed
if ( m_LadfEnabed )
{
CHECK( m_LadfNumIntervals != cfg_LadfQpOffset.values.size(), "size of LadfQpOffset must be equal to LadfNumIntervals");
CHECK( m_LadfNumIntervals - 1 != cfg_LadfIntervalLowerBound.values.size(), "size of LadfIntervalLowerBound must be equal to LadfNumIntervals - 1");
m_LadfQpOffset = cfg_LadfQpOffset.values;
m_LadfIntervalLowerBound[0] = 0;
Shunsuke Iwamura
committed
for (int k = 1; k < m_LadfNumIntervals; k++)
{
m_LadfIntervalLowerBound[k] = cfg_LadfIntervalLowerBound.values[k - 1];
}
}
if (m_chromaFormatIDC != CHROMA_420)
{
if (!m_horCollocatedChromaFlag)
{
msg(WARNING, "\nWARNING: HorCollocatedChroma is forced to 1 for chroma formats other than 4:2:0\n");
m_horCollocatedChromaFlag = true;
}
if (!m_verCollocatedChromaFlag)
{
msg(WARNING, "\nWARNING: VerCollocatedChroma is forced to 1 for chroma formats other than 4:2:0\n");
m_verCollocatedChromaFlag = true;
}
}
#if JVET_O0756_CONFIG_HDRMETRICS && !JVET_O0756_CALCULATE_HDRMETRICS
if ( m_calculateHdrMetrics == true)
{
printf ("Warning: Configuration enables HDR metric calculations. However, HDR metric support was not linked when compiling the VTM.\n");
m_calculateHdrMetrics = false;
}
#endif
if (m_gdrEnabled)
{
m_virtualBoundariesEnabledFlag = 1;
m_virtualBoundariesPresentFlag = 0;
}
else
{
m_virtualBoundariesEnabledFlag = 0;
}
m_virtualBoundariesEnabledFlag = 0;
if( m_numVerVirtualBoundaries > 0 || m_numHorVirtualBoundaries > 0 )
m_virtualBoundariesEnabledFlag = 1;
if( m_virtualBoundariesEnabledFlag )
Sheng-Yen Lin
committed
{
CHECK( m_subPicInfoPresentFlag && m_virtualBoundariesPresentFlag != 1, "When subpicture signalling is present, the signalling of virtual boundaries, if present, shall be in the SPS" );
if( m_virtualBoundariesPresentFlag )
Sheng-Yen Lin
committed
{
CHECK( m_numVerVirtualBoundaries > 3, "Number of vertical virtual boundaries must be comprised between 0 and 3 included" );
CHECK( m_numHorVirtualBoundaries > 3, "Number of horizontal virtual boundaries must be comprised between 0 and 3 included" );
CHECK( m_numVerVirtualBoundaries != cfg_virtualBoundariesPosX.values.size(), "Size of VirtualBoundariesPosX must be equal to NumVerVirtualBoundaries");
CHECK( m_numHorVirtualBoundaries != cfg_virtualBoundariesPosY.values.size(), "Size of VirtualBoundariesPosY must be equal to NumHorVirtualBoundaries");
m_virtualBoundariesPosX = cfg_virtualBoundariesPosX.values;
if (m_numVerVirtualBoundaries > 1)
Sheng-Yen Lin
committed
{
sort(m_virtualBoundariesPosX.begin(), m_virtualBoundariesPosX.end());
Sheng-Yen Lin
committed
}
for (unsigned i = 0; i < m_numVerVirtualBoundaries; i++)
Sheng-Yen Lin
committed
{
CHECK( m_virtualBoundariesPosX[i] == 0 || m_virtualBoundariesPosX[i] >= m_sourceWidth, "The vertical virtual boundary must be within the picture" );
CHECK( m_virtualBoundariesPosX[i] % 8, "The vertical virtual boundary must be a multiple of 8 luma samples" );
if (i > 0)
{
CHECK(
m_virtualBoundariesPosX[i] - m_virtualBoundariesPosX[i - 1] < m_ctuSize,
"The distance between any two vertical virtual boundaries shall be greater than or equal to the CTU size");
}
}
m_virtualBoundariesPosY = cfg_virtualBoundariesPosY.values;
if (m_numHorVirtualBoundaries > 1)
{
sort(m_virtualBoundariesPosY.begin(), m_virtualBoundariesPosY.end());
}
for (unsigned i = 0; i < m_numHorVirtualBoundaries; i++)
{
CHECK( m_virtualBoundariesPosY[i] == 0 || m_virtualBoundariesPosY[i] >= m_sourceHeight, "The horizontal virtual boundary must be within the picture" );
CHECK( m_virtualBoundariesPosY[i] % 8, "The horizontal virtual boundary must be a multiple of 8 luma samples" );
if (i > 0)
{
CHECK(m_virtualBoundariesPosY[i] - m_virtualBoundariesPosY[i - 1] < m_ctuSize,
"The distance between any two horizontal virtual boundaries shall be greater than or equal to the CTU "
"size");
Sheng-Yen Lin
committed
}
}
}
if ( m_alf )
{
CHECK( m_maxNumAlfAlternativesChroma < 1 || m_maxNumAlfAlternativesChroma > MAX_NUM_ALF_ALTERNATIVES_CHROMA, std::string("The maximum number of ALF Chroma filter alternatives must be in the range (1-") + std::to_string(MAX_NUM_ALF_ALTERNATIVES_CHROMA) + std::string (", inclusive)") );
}

Karsten Suehring
committed
// reading external dQP description from file
if ( !m_dQPFileName.empty() )
{
FILE* fpt=fopen( m_dQPFileName.c_str(), "r" );
if ( fpt )
{
int val;
int poc = 0;
m_frameDeltaQps.clear();
while (poc < m_framesToBeEncoded)

Karsten Suehring
committed
{
if (fscanf(fpt, "%d", &val) == EOF)

Karsten Suehring
committed
{
break;
}
m_frameDeltaQps.push_back(val);
poc++;

Karsten Suehring
committed
}
fclose(fpt);
}
}
if( m_masteringDisplay.colourVolumeSEIEnabled )
{
for(uint32_t idx=0; idx<6; idx++)
{
m_masteringDisplay.primaries[idx/2][idx%2] = uint16_t((cfg_DisplayPrimariesCode.values.size() > idx) ? cfg_DisplayPrimariesCode.values[idx] : 0);
}
for(uint32_t idx=0; idx<2; idx++)
{
m_masteringDisplay.whitePoint[idx] = uint16_t((cfg_DisplayWhitePointCode.values.size() > idx) ? cfg_DisplayWhitePointCode.values[idx] : 0);
}
}
// set sei film grain parameters.
CHECK(!m_fgcSEIEnabled && m_fgcSEIAnalysisEnabled, "FGC SEI must be enabled in order to perform film grain analysis!");
if (m_fgcSEIEnabled)
{
if (m_iQP < 17 && m_fgcSEIAnalysisEnabled == true)
{ // TODO: JVET_Z0047_FG_IMPROVEMENT: check this; the constraint may have gone
msg(WARNING, "*************************************************************************\n");
msg(WARNING, "* WARNING: Film Grain Estimation is disabled for Qp<17! FGC SEI will use default parameters for film grain! *\n");
msg(WARNING, "*************************************************************************\n");
m_fgcSEIAnalysisEnabled = false;
}
if (m_intraPeriod < 1)
{ // low delay configuration
msg(WARNING, "*************************************************************************\n");
msg(WARNING, "* WARNING: For low delay configuration, FGC SEI is inserted for first frame only!*\n");
msg(WARNING, "*************************************************************************\n");
m_fgcSEIPerPictureSEI = false;
m_fgcSEIPersistenceFlag = true;
}
else if (m_intraPeriod == 1)
{ // all intra configuration
msg(WARNING, "*************************************************************************\n");
msg(WARNING, "* WARNING: For Intra Period = 1, FGC SEI is inserted per frame!*\n");
msg(WARNING, "*************************************************************************\n");
m_fgcSEIPerPictureSEI = true;
m_fgcSEIPersistenceFlag = false;
}
if (!m_fgcSEIPerPictureSEI && !m_fgcSEIPersistenceFlag) {
msg(WARNING, "*************************************************************************\n");
msg(WARNING, "* WARNING: SEIPerPictureSEI is set to 0, SEIPersistenceFlag needs to be set to 1! *\n");
msg(WARNING, "*************************************************************************\n");
m_fgcSEIPersistenceFlag = true;
}
else if (m_fgcSEIPerPictureSEI && m_fgcSEIPersistenceFlag) {
msg(WARNING, "*************************************************************************\n");
msg(WARNING, "* WARNING: SEIPerPictureSEI is set to 1, SEIPersistenceFlag needs to be set to 0! *\n");
msg(WARNING, "*************************************************************************\n");
m_fgcSEIPersistenceFlag = false;
}
if (m_fgcSEIAnalysisEnabled && m_fgcSEITemporalFilterStrengths.empty())
{
// By default: in random-acces = filter RAPs, in all-intra = filter every frame, otherwise = filter every 2s
int filteredFrame = m_intraPeriod < 1 ? 2 * m_frameRate : m_intraPeriod;
m_fgcSEITemporalFilterStrengths[filteredFrame] = 1.5;
}
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
uint32_t numModelCtr;
if (m_fgcSEICompModelPresent[0])
{
numModelCtr = 0;
for (uint8_t i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[0]; i++)
{
m_fgcSEIIntensityIntervalLowerBound[0][i] = uint32_t((cfg_FgcSEIIntensityIntervalLowerBoundComp0.values.size() > i) ? cfg_FgcSEIIntensityIntervalLowerBoundComp0.values[i] : 10);
m_fgcSEIIntensityIntervalUpperBound[0][i] = uint32_t((cfg_FgcSEIIntensityIntervalUpperBoundComp0.values.size() > i) ? cfg_FgcSEIIntensityIntervalUpperBoundComp0.values[i] : 250);
for (uint8_t j = 0; j <= m_fgcSEINumModelValuesMinus1[0]; j++)
{
m_fgcSEICompModelValue[0][i][j] = uint32_t((cfg_FgcSEICompModelValueComp0.values.size() > numModelCtr) ? cfg_FgcSEICompModelValueComp0.values[numModelCtr] : 24);
numModelCtr++;
}
}
}
if (m_fgcSEICompModelPresent[1])
{
numModelCtr = 0;
for (uint8_t i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[1]; i++)
{
m_fgcSEIIntensityIntervalLowerBound[1][i] = uint32_t((cfg_FgcSEIIntensityIntervalLowerBoundComp1.values.size() > i) ? cfg_FgcSEIIntensityIntervalLowerBoundComp1.values[i] : 60);
m_fgcSEIIntensityIntervalUpperBound[1][i] = uint32_t((cfg_FgcSEIIntensityIntervalUpperBoundComp1.values.size() > i) ? cfg_FgcSEIIntensityIntervalUpperBoundComp1.values[i] : 200);
for (uint8_t j = 0; j <= m_fgcSEINumModelValuesMinus1[1]; j++)
{
m_fgcSEICompModelValue[1][i][j] = uint32_t((cfg_FgcSEICompModelValueComp1.values.size() > numModelCtr) ? cfg_FgcSEICompModelValueComp1.values[numModelCtr] : 16);
numModelCtr++;
}
}
}
if (m_fgcSEICompModelPresent[2])
{
numModelCtr = 0;
for (uint8_t i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[2]; i++)
{
m_fgcSEIIntensityIntervalLowerBound[2][i] = uint32_t((cfg_FgcSEIIntensityIntervalLowerBoundComp2.values.size() > i) ? cfg_FgcSEIIntensityIntervalLowerBoundComp2.values[i] : 60);
m_fgcSEIIntensityIntervalUpperBound[2][i] = uint32_t((cfg_FgcSEIIntensityIntervalUpperBoundComp2.values.size() > i) ? cfg_FgcSEIIntensityIntervalUpperBoundComp2.values[i] : 250);
for (uint8_t j = 0; j <= m_fgcSEINumModelValuesMinus1[2]; j++)
{
m_fgcSEICompModelValue[2][i][j] = uint32_t((cfg_FgcSEICompModelValueComp2.values.size() > numModelCtr) ? cfg_FgcSEICompModelValueComp2.values[numModelCtr] : 12);
numModelCtr++;
}
}
}
m_fgcSEILog2ScaleFactor = m_fgcSEILog2ScaleFactor ? m_fgcSEILog2ScaleFactor : 2;
}
{
CHECK(!m_ctiSEICrossComponentFlag && m_ctiSEICrossComponentInferred, "CTI CrossComponentFlag is 0, but CTI CrossComponentInferred is 1 (must be 0 for CrossComponentFlag 0)");
CHECK(!m_ctiSEICrossComponentFlag && !m_ctiSEICrossComponentInferred && !m_ctiSEINumberChromaLut, "For CTI CrossComponentFlag = 0, CTI NumberChromaLut needs to be specified (1 or 2) ");
CHECK(m_ctiSEICrossComponentFlag && !m_ctiSEICrossComponentInferred && !m_ctiSEINumberChromaLut, "For CTI CrossComponentFlag = 1 and CrossComponentInferred = 0, CTI NumberChromaLut needs to be specified (1 or 2) ");
CHECK(cfg_SEICTILut0.values.empty(), "SEI CTI (SEICTIEnabled) but no LUT0 specified");
m_ctiSEILut[0].presentFlag = true;
m_ctiSEILut[0].numLutValues = (int)cfg_SEICTILut0.values.size();
m_ctiSEILut[0].lutValues = cfg_SEICTILut0.values;
if (!m_ctiSEICrossComponentFlag || (m_ctiSEICrossComponentFlag && !m_ctiSEICrossComponentInferred))
{
CHECK(cfg_SEICTILut1.values.empty(), "SEI CTI LUT1 not specified");
m_ctiSEILut[1].presentFlag = true;
m_ctiSEILut[1].numLutValues = (int)cfg_SEICTILut1.values.size();
m_ctiSEILut[1].lutValues = cfg_SEICTILut1.values;
if (m_ctiSEINumberChromaLut == 1)
{ // Cb lut the same as Cr lut
m_ctiSEILut[2].presentFlag = true;
m_ctiSEILut[2].numLutValues = m_ctiSEILut[1].numLutValues;
m_ctiSEILut[2].lutValues = m_ctiSEILut[1].lutValues;
}
else if (m_ctiSEINumberChromaLut == 2)
{ // read from cfg
CHECK(cfg_SEICTILut2.values.empty(), "SEI CTI LUT2 not specified");
m_ctiSEILut[2].presentFlag = true;
m_ctiSEILut[2].numLutValues = (int)cfg_SEICTILut2.values.size();
m_ctiSEILut[2].lutValues = cfg_SEICTILut2.values;
}
{
CHECK(m_ctiSEINumberChromaLut < 1 && m_ctiSEINumberChromaLut > 2, "Number of chroma LUTs is missing or out of range!");
}
}
// check if lut size is power of 2
for (int idx = 0; idx < MAX_NUM_COMPONENT; idx++)