Commit 633ea8b1 authored by Karsten Suehring's avatar Karsten Suehring
Browse files

Merge branch 'fgs_rdd5' into 'master'

JCTVC-AM0023: Illustration of the film grain characteristics SEI message in HEVC

See merge request !35
parents 0046fe97 19cc9bd9
#======== Film grain characteristics SEI message =====================
SEIFGCEnabled : 1
SEIFGCCancelFlag : 0
SEIFGCPersistenceFlag : 1
SEIFGCModelID : 0 # 0: frequency filtering; 1: auto-regression; 2-3 are reserved
SEIFGCSepColourDescPresentFlag : 0 # if not 0, need to specify separate colour description (not implemented in current encoder cmd line)
SEIFGCBlendingModeID : 0 # 0: additive; 1: multipliciative
SEIFGCLog2ScaleFactor : 0
SEIFGCCompModelPresentComp0 : 0 # if not 0, need to specify model for comp 0 (not implemented in current encoder cmd line)
SEIFGCCompModelPresentComp1 : 0 # if not 0, need to specify model for comp 1 (not implemented in current encoder cmd line)
SEIFGCCompModelPresentComp2 : 0 # if not 0, need to specify model for comp 2 (not implemented in current encoder cmd line)
SEIFGCCancelFlag : 0 # for SMPTE-RDD5: the value must be 0
SEIFGCPersistenceFlag : 0 # for SMPTE-RDD5: the value must be 0
SEIFGCModelID : 0 # for SMPTE-RDD5: the value must be 0 (0: frequency filtering; 1: auto-regression; 2-3 are reserved)
SEIFGCSepColourDescPresentFlag : 0 # for SMPTE-RDD5: the value must be 0 (if not 0, need to specify separate colour description (not implemented in current encoder cmd line))
SEIFGCBlendingModeID : 0 # for SMPTE-RDD5: the value must be 0 (0: additive; 1: multipliciative)
SEIFGCLog2ScaleFactor : 6
SEIFGCCompModelPresentComp0 : 1 # if not 0, need to specify model for comp 0
SEIFGCCompModelPresentComp1 : 1 # if not 0, need to specify model for comp 1
SEIFGCCompModelPresentComp2 : 1 # if not 0, need to specify model for comp 2
SEIFGCNumIntensityIntervalMinus1Comp0 : 1 # Number of intensity intervals minus 1 for comp 0
SEIFGCNumIntensityIntervalMinus1Comp1 : 2 # Number of intensity intervals minus 1 for comp 1
SEIFGCNumIntensityIntervalMinus1Comp2 : 3 # Number of intensity intervals minus 1 for comp 2
SEIFGCNumModelValuesMinus1Comp0 : 0 # Number of model values minus 1 for comp 0
SEIFGCNumModelValuesMinus1Comp1 : 2 # Number of model values minus 1 for comp 1
SEIFGCNumModelValuesMinus1Comp2 : 2 # Number of model values minus 1 for comp 2
SEIFGCIntensityIntervalLowerBoundComp0 : 10 110 # Lower bound of intensity interval for comp 0 (for SMPTE-RDD5, non-overlapping interval)
SEIFGCIntensityIntervalLowerBoundComp1 : 10 110 210 # Lower bound of intensity interval for comp 1 (for SMPTE-RDD5, non-overlapping interval)
SEIFGCIntensityIntervalLowerBoundComp2 : 10 60 110 210 # Lower bound of intensity interval for comp 2 (for SMPTE-RDD5, non-overlapping interval)
SEIFGCIntensityIntervalUpperBoundComp0 : 100 250 # Upper bound of intensity interval for comp 0 (for SMPTE-RDD5, non-overlapping interval)
SEIFGCIntensityIntervalUpperBoundComp1 : 100 200 250 # Upper bound of intensity interval for comp 1 (for SMPTE-RDD5, non-overlapping interval)
SEIFGCIntensityIntervalUpperBoundComp2 : 50 100 200 250 # Upper bound of intensity interval for comp 2 (for SMPTE-RDD5, non-overlapping interval)
SEIFGCCompModelValuesComp0 : 100 150 # model values for each intensity interval for comp 0 (sigma, h, v (h,v might be inferred based on number of model value))
SEIFGCCompModelValuesComp1 : 100 2 2 120 12 12 140 14 14 # model values for each intensity interval for comp 1 (sigma, h, v (h,v might be inferred based on number of model value))
SEIFGCCompModelValuesComp2 : 160 4 4 200 6 6 240 11 11 250 13 13 # model values for each intensity interval for comp 2 (sigma, h, v (h,v might be inferred based on number of model value))
\ No newline at end of file
......@@ -2439,15 +2439,15 @@ Enables or disables the insertion of the film grain characteristics SEI message.
\\
\Option{SEIFGCCancelFlag} &
\Default{0} &
Specifies the persistence of any previous film grain characteristics SEI message in output order.
Specifies the persistence of any previous film grain characteristics SEI message in output order. For SMPTE-RDD5, the value must be 0.
\\
\Option{SEIFGCPersistenceFlag} &
\Default{1} &
Specifies the persistence of the film grain characteristics SEI message for the current layer.
\Default{0} &
Specifies the persistence of the film grain characteristics SEI message for the current layer. For SMPTE-RDD5, the value must be 0.
\\
\Option{SEIFGCModelID} &
\Default{0} &
Specifies the film grain simulation model.
Specifies the film grain simulation model. For SMPTE-RDD5, the value must be 0.
\par
\begin{tabular}{cp{0.35\textwidth}}
0 & frequency filtering \\
......@@ -2456,11 +2456,11 @@ Specifies the film grain simulation model.
\\
\Option{SEIFGCSepColourDescPresentFlag} &
\Default{0} &
Specifies the presence of a distinct colour space description for the film grain characteristics specified in the SEI message.
Specifies the presence of a distinct colour space description for the film grain characteristics specified in the SEI message. For SMPTE-RDD5, the value must be 0.
\\
\Option{SEIFGCBlendingModeID} &
\Default{0} &
Specifies the blending mode used to blend the simulated film grain with the decoded images.
Specifies the blending mode used to blend the simulated film grain with the decoded images. For SMPTE-RDD5, the value must be 0.
\par
\begin{tabular}{cp{0.35\textwidth}}
0 & additive \\
......@@ -2468,21 +2468,81 @@ Specifies the blending mode used to blend the simulated film grain with the deco
\end{tabular}
\\
\Option{SEIFGCLog2ScaleFactor} &
\Default{0} &
\Default{6} &
Specifies a scale factor used in the film grain characterization equations.
\\
\Option{SEIFGCCompModelPresentComp0} &
\Default{0} &
\Default{1} &
Specifies the presence of film grain modelling on colour component 0.
\\
\Option{SEIFGCCompModelPresentComp1} &
\Default{0} &
\Default{1} &
Specifies the presence of film grain modelling on colour component 1.
\\
\Option{SEIFGCCompModelPresentComp2} &
\Default{0} &
\Default{1} &
Specifies the presence of film grain modelling on colour component 2.
\\
\Option{SEIFGCNumIntensityIntervalMinus1Comp0} &
\Default{1} &
Specifies the number of intensity intervals minus 1 for comp 0
\\
\Option{SEIFGCNumIntensityIntervalMinus1Comp1} &
\Default{2} &
Specifies the number of intensity intervals minus 1 for comp 1
\\
\Option{SEIFGCNumIntensityIntervalMinus1Comp2} &
\Default{3} &
Specifies the number of intensity intervals minus 1 for comp 2
\\
\Option{SEIFGCNumModelValuesMinus1Comp0} &
\Default{0} &
Specifies the number of model values minus 1 for comp 0
\\
\Option{SEIFGCNumModelValuesMinus1Comp1} &
\Default{2} &
Specifies the number of model values minus 1 for comp 1
\\
\Option{SEIFGCNumModelValuesMinus1Comp2} &
\Default{2} &
Specifies the number of model values minus 1 for comp 2
\\
\Option{SEIFGCIntensityIntervalLowerBoundComp0} &
\Default{10 110} &
Specifies the lower bound of intensity interval for comp 0 (for SMPTE-RDD5, non-overlapping interval)
\\
\Option{SEIFGCIntensityIntervalLowerBoundComp1} &
\Default{10 110 210} &
Specifies the lower bound of intensity interval for comp 1 (for SMPTE-RDD5, non-overlapping interval)
\\
\Option{SEIFGCIntensityIntervalLowerBoundComp2} &
\Default{10 60 110 210} &
Specifies the lower bound of intensity interval for comp 2 (for SMPTE-RDD5, non-overlapping interval)
\\
\Option{SEIFGCIntensityIntervalUpperBoundComp0} &
\Default{100 250} &
Specifies the upper bound of intensity interval for comp 0 (for SMPTE-RDD5, non-overlapping interval)
\\
\Option{SEIFGCIntensityIntervalUpperBoundComp1} &
\Default{100 200 250} &
Specifies the upper bound of intensity interval for comp 1 (for SMPTE-RDD5, non-overlapping interval)
\\
\Option{SEIFGCIntensityIntervalUpperBoundComp2} &
\Default{50 100 200 250} &
Specifies the upper bound of intensity interval for comp 2 (for SMPTE-RDD5, non-overlapping interval)
\\
\Option{SEIFGCCompModelValuesComp0} &
\Default{100 150} &
Specifies the model values for each intensity interval for comp 0 (sigma, h, v (h,v might be inferred based on number of model value))
\\
\Option{SEIFGCCompModelValuesComp1} &
\Default{100 2 2 120 12 12 140 14 14} &
Specifies the model values for each intensity interval for comp 1 (sigma, h, v (h,v might be inferred based on number of model value))
\\
\Option{SEIFGCCompModelValuesComp2} &
\Default{160 4 4 200 6 6 240 11 11 250 13 13} &
Specifies the model values for each intensity interval for comp 2 (sigma, h, v (h,v might be inferred based on number of model value))
\\
\end{OptionTableNoShorthand}
......
......@@ -86,6 +86,9 @@ Bool TAppDecCfg::parseCfg( Int argc, TChar* argv[] )
("TarDecLayerIdSetFile,l", cfg_TargetDecLayerIdSetFile, string(""), "targetDecLayerIdSet file name. The file should include white space separated LayerId values to be decoded. Omitting the option or a value of -1 in the file decodes all layers.")
("RespectDefDispWindow,w", m_respectDefDispWindow, 0, "Only output content inside the default display window\n")
("SEIColourRemappingInfoFilename", m_colourRemapSEIFileName, string(""), "Colour Remapping YUV output file name. If empty, no remapping is applied (ignore SEI message)\n")
#if FGS_RDD5_ENABLE
("SEIFGSFilename", m_SEIFGSFileName, string(""), "FGS YUV output file name. If empty, no film grain is applied (ignore SEI message)\n")
#endif
("SEIAnnotatedRegionsInfoFilename", m_annotatedRegionsSEIFileName, string(""), "Annotated regions output file name. If empty, no object information will be saved (ignore SEI message)\n")
#if O0043_BEST_EFFORT_DECODING
("ForceDecodeBitDepth", m_forceDecodeBitDepth, 0U, "Force the decoder to operate at a particular bit-depth (best effort decoding)")
......
......@@ -66,6 +66,9 @@ protected:
Int m_decodedPictureHashSEIEnabled; ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message
Bool m_decodedNoDisplaySEIEnabled; ///< Enable(true)/disable(false) writing only pictures that get displayed based on the no display SEI message
std::string m_colourRemapSEIFileName; ///< output Colour Remapping file name
#if FGS_RDD5_ENABLE
std::string m_SEIFGSFileName; ///< output reconstruction file name
#endif
std::string m_annotatedRegionsSEIFileName; ///< annotated regions file name
std::vector<Int> m_targetDecLayerIdSet; ///< set of LayerIds to be included in the sub-bitstream extraction process.
Int m_respectDefDispWindow; ///< Only output content inside the default display window
......@@ -89,6 +92,9 @@ public:
, m_decodedPictureHashSEIEnabled(0)
, m_decodedNoDisplaySEIEnabled(false)
, m_colourRemapSEIFileName()
#if FGS_RDD5_ENABLE
, m_SEIFGSFileName()
#endif
, m_annotatedRegionsSEIFileName()
, m_targetDecLayerIdSet()
, m_respectDefDispWindow(0)
......
......@@ -69,6 +69,9 @@ Void TAppDecTop::destroy()
{
m_bitstreamFileName.clear();
m_reconFileName.clear();
#if FGS_RDD5_ENABLE
m_SEIFGSFileName.clear();
#endif
}
// ====================================================================================================================
......@@ -136,6 +139,9 @@ Void TAppDecTop::decode()
// main decoder loop
Bool openedReconFile = false; // reconstruction file not yet opened. (must be performed after SPS is seen)
#if FGS_RDD5_ENABLE
Bool openedSEIFGSFile = false; // reconstruction file (with FGS) not yet opened. (must be performed after SPS is seen)
#endif
Bool loopFiltered = false;
while (!!bitstreamFile)
......@@ -230,6 +236,23 @@ Void TAppDecTop::decode()
m_cTVideoIOYuvReconFile.open( m_reconFileName, true, m_outputBitDepth, m_outputBitDepth, bitDepths.recon ); // write mode
openedReconFile = true;
}
#if FGS_RDD5_ENABLE
// Initialize file handle to write output with film grain
if ((!m_SEIFGSFileName.empty()) && (!openedSEIFGSFile))
{
const BitDepths &bitDepths = pcListPic->front()->getPicSym()->getSPS().getBitDepths(); // use bit depths of first reconstructed picture.
for (UInt channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
{
if (m_outputBitDepth[channelType] == 0)
{
m_outputBitDepth[channelType] = bitDepths.recon[channelType];
}
}
m_cTVideoIOYuvSEIFGSFile.open(m_SEIFGSFileName, true, m_outputBitDepth, m_outputBitDepth, bitDepths.recon); // write mode
openedSEIFGSFile = true;
}
#endif
// write reconstruction to file
if( bNewPicture )
{
......@@ -286,6 +309,12 @@ Void TAppDecTop::xDestroyDecLib()
{
m_cTVideoIOYuvReconFile.close();
}
#if FGS_RDD5_ENABLE
if (!m_SEIFGSFileName.empty())
{
m_cTVideoIOYuvSEIFGSFile.close();
}
#endif
// destroy decoder class
m_cTDecTop.destroy();
......@@ -477,6 +506,21 @@ Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range );
}
#if FGS_RDD5_ENABLE
// Perform FGS on decoded frame and write to output FGS file
if (!m_SEIFGSFileName.empty())
{
const Window &conf = pcPic->getConformanceWindow();
const Window defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
m_cTVideoIOYuvSEIFGSFile.write(pcPic->getPicYuvDisp(),
m_outputColourSpaceConvert,
conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(),
NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range);
}
#endif
if (!m_annotatedRegionsSEIFileName.empty())
{
xOutputAnnotatedRegions(pcPic);
......@@ -605,7 +649,22 @@ Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range );
}
if (!m_colourRemapSEIFileName.empty())
#if FGS_RDD5_ENABLE
// Perform FGS on decoded frame and write to output FGS file
if (!m_SEIFGSFileName.empty())
{
const Window &conf = pcPic->getConformanceWindow();
const Window defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
m_cTVideoIOYuvSEIFGSFile.write(pcPic->getPicYuvDisp(),
m_outputColourSpaceConvert,
conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(),
NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range);
}
#endif
if (!m_colourRemapSEIFileName.empty())
{
xOutputColourRemapPic(pcPic);
}
......
......@@ -62,7 +62,9 @@ private:
// class interface
TDecTop m_cTDecTop; ///< decoder class
TVideoIOYuv m_cTVideoIOYuvReconFile; ///< reconstruction YUV class
#if FGS_RDD5_ENABLE
TVideoIOYuv m_cTVideoIOYuvSEIFGSFile; ///< reconstruction YUV class
#endif
// for output control
Int m_iPOCLastDisplay; ///< last POC in display order
std::ofstream m_seiMessageFileStream; ///< Used for outputing SEI messages.
......
......@@ -727,6 +727,12 @@ Bool TAppEncCfg::parseCfg( Int argc, TChar* argv[] )
SMultiValueInput<Bool> cfg_timeCodeSeiHoursFlag (0, 1, 0, MAX_TIMECODE_SEI_SETS);
SMultiValueInput<Int> cfg_timeCodeSeiTimeOffsetLength (0, 31, 0, MAX_TIMECODE_SEI_SETS);
SMultiValueInput<Int> cfg_timeCodeSeiTimeOffsetValue (std::numeric_limits<Int>::min(), std::numeric_limits<Int>::max(), 0, MAX_TIMECODE_SEI_SETS);
#if FGS_RDD5_ENABLE
// default values used for FGC SEI parameter parsing
SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalLowerBoundComp[3]={SMultiValueInput<UInt> (0, 255, 0, 256), SMultiValueInput<UInt> (0, 255, 0, 256), SMultiValueInput<UInt> (0, 255, 0, 256)};
SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalUpperBoundComp[3]={SMultiValueInput<UInt> (0, 255, 0, 256), SMultiValueInput<UInt> (0, 255, 0, 256), SMultiValueInput<UInt> (0, 255, 0, 256)};
SMultiValueInput<UInt> cfg_FgcSEICompModelValueComp[3]={SMultiValueInput<UInt> (0, 65535, 0, 256 * 6), SMultiValueInput<UInt> (0, 65535, 0, 256 * 6), SMultiValueInput<UInt> (0, 65535, 0, 256 * 6)};
#endif
SMultiValueInput<Int> cfg_omniViewportSEIAzimuthCentre (-11796480, 11796479, 0, 15);
SMultiValueInput<Int> cfg_omniViewportSEIElevationCentre ( -5898240, 5898240, 0, 15);
SMultiValueInput<Int> cfg_omniViewportSEITiltCentre (-11796480, 11796479, 0, 15);
......@@ -1215,6 +1221,23 @@ Bool TAppEncCfg::parseCfg( Int argc, TChar* argv[] )
("SEIFGCCompModelPresentComp0", m_fgcSEICompModelPresent[0], false, "Specifies the presense of film grain modelling on colour component 0.")
("SEIFGCCompModelPresentComp1", m_fgcSEICompModelPresent[1], false, "Specifies the presense of film grain modelling on colour component 1.")
("SEIFGCCompModelPresentComp2", m_fgcSEICompModelPresent[2], false, "Specifies the presense of film grain modelling on colour component 2.")
#if FGS_RDD5_ENABLE
("SEIFGCNumIntensityIntervalMinus1Comp0", m_fgcSEINumIntensityIntervalMinus1[0], 0u, "Specifies the number of intensity intervals minus1 on colour component 0.")
("SEIFGCNumIntensityIntervalMinus1Comp1", m_fgcSEINumIntensityIntervalMinus1[1], 0u, "Specifies the number of intensity intervals minus1 on colour component 1.")
("SEIFGCNumIntensityIntervalMinus1Comp2", m_fgcSEINumIntensityIntervalMinus1[2], 0u, "Specifies the number of intensity intervals minus1 on colour component 2.")
("SEIFGCNumModelValuesMinus1Comp0", m_fgcSEINumModelValuesMinus1[0], 0u, "Specifies the number of component model values minus1 on colour component 0.")
("SEIFGCNumModelValuesMinus1Comp1", m_fgcSEINumModelValuesMinus1[1], 0u, "Specifies the number of component model values minus1 on colour component 1.")
("SEIFGCNumModelValuesMinus1Comp2", m_fgcSEINumModelValuesMinus1[2], 0u, "Specifies the number of component model values minus1 on colour component 2.")
("SEIFGCIntensityIntervalLowerBoundComp0", cfg_FgcSEIIntensityIntervalLowerBoundComp[0], cfg_FgcSEIIntensityIntervalLowerBoundComp[0], "Specifies the lower bound for the intensity intervals on colour component 0.")
("SEIFGCIntensityIntervalLowerBoundComp1", cfg_FgcSEIIntensityIntervalLowerBoundComp[1], cfg_FgcSEIIntensityIntervalLowerBoundComp[1], "Specifies the lower bound for the intensity intervals on colour component 1.")
("SEIFGCIntensityIntervalLowerBoundComp2", cfg_FgcSEIIntensityIntervalLowerBoundComp[2], cfg_FgcSEIIntensityIntervalLowerBoundComp[2], "Specifies the lower bound for the intensity intervals on colour component 2.")
("SEIFGCIntensityIntervalUpperBoundComp0", cfg_FgcSEIIntensityIntervalUpperBoundComp[0], cfg_FgcSEIIntensityIntervalUpperBoundComp[0], "Specifies the upper bound for the intensity intervals on colour component 0.")
("SEIFGCIntensityIntervalUpperBoundComp1", cfg_FgcSEIIntensityIntervalUpperBoundComp[1], cfg_FgcSEIIntensityIntervalUpperBoundComp[1], "Specifies the upper bound for the intensity intervals on colour component 1.")
("SEIFGCIntensityIntervalUpperBoundComp2", cfg_FgcSEIIntensityIntervalUpperBoundComp[2], cfg_FgcSEIIntensityIntervalUpperBoundComp[2], "Specifies the upper bound for the intensity intervals on colour component 2.")
("SEIFGCCompModelValuesComp0", cfg_FgcSEICompModelValueComp[0], cfg_FgcSEICompModelValueComp[0], "Specifies the component model values on colour component 0.")
("SEIFGCCompModelValuesComp1", cfg_FgcSEICompModelValueComp[1], cfg_FgcSEICompModelValueComp[1], "Specifies the component model values on colour component 1.")
("SEIFGCCompModelValuesComp2", cfg_FgcSEICompModelValueComp[2], cfg_FgcSEICompModelValueComp[2], "Specifies the component model values on colour component 2.")
#endif
// content light level SEI
("SEICLLEnabled", m_cllSEIEnabled, false, "Control generation of the content light level SEI message")
("SEICLLMaxContentLightLevel", m_cllSEIMaxContentLevel, 0u, "When not equal to 0, specifies an upper bound on the maximum light level among all individual samples in a 4:4:4 representation "
......@@ -2045,7 +2068,30 @@ Bool TAppEncCfg::parseCfg( Int argc, TChar* argv[] )
m_timeSetArray[i].timeOffsetValue = cfg_timeCodeSeiTimeOffsetValue .values.size()>i ? cfg_timeCodeSeiTimeOffsetValue .values [i] : 0;
}
}
#if FGS_RDD5_ENABLE
// Assigning the FGC SEI params from App to Lib
if (m_fgcSEIEnabled)
{
UInt numModelCtr;
for (UInt c = 0; c <= 2; c++ )
{
if (m_fgcSEICompModelPresent[c])
{
numModelCtr = 0;
for (UInt i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[c]; i++)
{
m_fgcSEIIntensityIntervalLowerBound[c][i] = UChar((cfg_FgcSEIIntensityIntervalLowerBoundComp[c].values.size() > i) ? cfg_FgcSEIIntensityIntervalLowerBoundComp[c].values[i] : 0);
m_fgcSEIIntensityIntervalUpperBound[c][i] = UChar((cfg_FgcSEIIntensityIntervalUpperBoundComp[c].values.size() > i) ? cfg_FgcSEIIntensityIntervalUpperBoundComp[c].values[i] : 0);
for (UInt j = 0; j <= m_fgcSEINumModelValuesMinus1[c]; j++)
{
m_fgcSEICompModelValue[c][i][j] = UInt((cfg_FgcSEICompModelValueComp[c].values.size() > numModelCtr) ? cfg_FgcSEICompModelValueComp[c].values[numModelCtr] : 0);
numModelCtr++;
}
}
}
}
}
#endif
// check validity of input parameters
xCheckParameter();
......
......@@ -496,6 +496,13 @@ protected:
UInt m_fgcSEIBlendingModeID;
UInt m_fgcSEILog2ScaleFactor;
Bool m_fgcSEICompModelPresent[MAX_NUM_COMPONENT];
#if FGS_RDD5_ENABLE
UInt m_fgcSEINumIntensityIntervalMinus1[MAX_NUM_COMPONENT];
UInt m_fgcSEINumModelValuesMinus1[MAX_NUM_COMPONENT];
UInt m_fgcSEIIntensityIntervalLowerBound[MAX_NUM_COMPONENT][MAX_NUM_INTENSITIES];
UInt m_fgcSEIIntensityIntervalUpperBound[MAX_NUM_COMPONENT][MAX_NUM_INTENSITIES];
UInt m_fgcSEICompModelValue[MAX_NUM_COMPONENT][MAX_NUM_INTENSITIES][MAX_NUM_MODEL_VALUES];
#endif
// content light level SEI
Bool m_cllSEIEnabled;
UInt m_cllSEIMaxContentLevel;
......
......@@ -433,6 +433,19 @@ Void TAppEncTop::xInitLibCfg()
m_cTEncTop.setFilmGrainCharactersticsSEILog2ScaleFactor ((UChar)m_fgcSEILog2ScaleFactor);
for (Int i = 0; i < MAX_NUM_COMPONENT; i++) {
m_cTEncTop.setFGCSEICompModelPresent (m_fgcSEICompModelPresent[i], i);
#if FGS_RDD5_ENABLE
if (m_fgcSEICompModelPresent[i]) {
m_cTEncTop.setFGCSEINumIntensityIntervalMinus1((UChar)m_fgcSEINumIntensityIntervalMinus1[i], i);
m_cTEncTop.setFGCSEINumModelValuesMinus1((UChar)m_fgcSEINumModelValuesMinus1[i], i);
for (UInt j = 0; j <= m_fgcSEINumIntensityIntervalMinus1[i]; j++) {
m_cTEncTop.setFGCSEIIntensityIntervalLowerBound((UChar)m_fgcSEIIntensityIntervalLowerBound[i][j], i, j);
m_cTEncTop.setFGCSEIIntensityIntervalUpperBound((UChar)m_fgcSEIIntensityIntervalUpperBound[i][j], i, j);
for (UInt k = 0; k <= m_fgcSEINumModelValuesMinus1[i]; k++) {
m_cTEncTop.setFGCSEICompModelValue(m_fgcSEICompModelValue[i][j][k], i, j, k);
}
}
}
#endif
}
// content light level
m_cTEncTop.setCLLSEIEnabled (m_cllSEIEnabled);
......
......@@ -246,6 +246,10 @@ static const Int MAX_ENCODER_DEBLOCKING_QUALITY_LAYERS = 8 ;
static const UInt LUMA_LEVEL_TO_DQP_LUT_MAXSIZE = 1024; ///< max LUT size for QP offset based on luma
#if FGS_RDD5_ENABLE
static const Int MAX_NUM_INTENSITIES = 256; // Maximum nuber of intensity intervals supported in FGC SEI
static const Int MAX_NUM_MODEL_VALUES = 6; // Maximum nuber of model values supported in FGC SEI
#endif
// ====================================================================================================================
// Macro functions
// ====================================================================================================================
......
This diff is collapsed.
/* The copyright in this software is being made available under the BSD
* License, included below. This software may be subject to other third party
* and contributor rights, including patent rights, and no such rights are
* granted under this license.
*
* Copyright (c) 2010-2020, ITU/ISO/IEC
* 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 SEIFilmGrainSynthesizer.h
\brief SMPTE RDD5 based film grain synthesis functionality from SEI messages
*/
#ifndef __SEIFILMGRAINSYNTHESIZER__
#define __SEIFILMGRAINSYNTHESIZER__
#include "SEI.h"
#include "TComPicYuv.h"
//#if _MSC_VER > 1000
//#pragma once
//#endif // _MSC_VER > 1000
//! \ingroup CommonLib
//! \{
#define MAX_ALLOWED_MODEL_VALUES 3
#define MIN_LOG2SCALE_VALUE 2
#define MAX_LOG2SCALE_VALUE 7
#define FILM_GRAIN_MODEL_ID_VALUE 0
#define BLENDING_MODE_VALUE 0
#define MAX_STANDARD_DEVIATION 255
#define MIN_CUT_OFF_FREQUENCY 2
#define MAX_CUT_OFF_FREQUENCY 14
#define DEFAULT_HORZ_CUT_OFF_FREQUENCY 8
#define MAX_ALLOWED_COMP_MODEL_PAIRS 10
#define SCALE_DOWN_422 181 /* in Q-format of 8 : 1/sqrt(2) */
#define Q_FORMAT_SCALING 8
#define GRAIN_SCALE 6
#define MIN_CHROMA_FORMAT_IDC 0
#define MAX_CHROMA_FORMAT_IDC 3
#define MIN_BIT_DEPTH 8
#define MAX_BIT_DEPTH 16
#define BIT_DEPTH_8 8
#define NUM_8x8_BLKS_16x16 4
#define BLK_8 8
#define BLK_16 16
#define INTENSITY_INTERVAL_MATCH_FAIL -1
#define COLOUR_OFFSET_LUMA 0
#define COLOUR_OFFSET_CR 85
#define COLOUR_OFFSET_CB 170
#define NUM_CUT_OFF_FREQ 13
#define DATA_BASE_SIZE 64
#define MIN_WIDTH 128
#define MAX_WIDTH 7680
#define MIN_HEIGHT 128
#define MAX_HEIGHT 4320
#define MIN_CHROMA_FORMAT_IDC 0
#define MAX_CHROMA_FORMAT_IDC 3
#define MIN_BIT_DEPTH 8
#define MAX_BIT_DEPTH 16
#define BIT_DEPTH_8 8
#define NUM_8x8_BLKS_16x16 4
#define BLK_8 8
#define BLK_16 16
#define INTENSITY_INTERVAL_MATCH_FAIL -1
#define COLOUR_OFFSET_LUMA 0
#define COLOUR_OFFSET_CR 85
#define COLOUR_OFFSET_CB 170
#define CLIP3(min, max, x) (((x) > (max)) ? (max) :(((x) < (min))? (min):(x)))
#define MIN(x,y) (((x) > (y)) ? (y) : (x))
#define MSB16(x) ((x&0xFFFF0000)>>16)
#define LSB16(x) (x&0x0000FFFF)
#define BIT0(x) (x&0x1)
#define POS_30 (1<<30)
#define POS_2 (1<<2)
/* Error start codes for various classes of errors */
#define FGS_FILE_IO_ERROR 0x0010
#define FGS_PARAM_ERROR 0x0020
/* Error codes for various errors in SMPTE-RDD5 standalone grain synthesizer */
typedef enum
{
/* No error */
FGS_SUCCESS = 0,
/* Invalid input width */
FGS_INVALID_WIDTH = FGS_FILE_IO_ERROR + 0x01,
/* Invalid input height */
FGS_INVALID_HEIGHT = FGS_FILE_IO_ERROR + 0x02,
/* Invalid Chroma format idc */
FGS_INVALID_CHROMA_FORMAT = FGS_FILE_IO_ERROR + 0x03,
/* Invalid bit depth */
FGS_INVALID_BIT_DEPTH = FGS_FILE_IO_ERROR + 0x04,
/* Invalid Film grain characteristic cancel flag */
FGS_INVALID_FGC_CANCEL_FLAG = FGS_PARAM_ERROR + 0x01,
/* Invalid film grain model id */
FGS_INVALID_GRAIN_MODEL_ID = FGS_PARAM_ERROR + 0x02,
/* Invalid separate color description present flag */
FGS_INVALID_SEP_COL_DES_FLAG = FGS_PARAM_ERROR + 0x03,
/* Invalid blending mode */
FGS_INVALID_BLEND_MODE = FGS_PARAM_ERROR + 0x04,
/* Invalid log_2_scale_factor value */
FGS_INVALID_LOG2_SCALE_FACTOR = FGS_PARAM_ERROR + 0x05,
/* Invalid component model present flag */
FGS_INVALID_COMP_MODEL_PRESENT_FLAG = FGS_PARAM_ERROR + 0x06,
/* Invalid number of model values */
FGS_INVALID_NUM_MODEL_VALUES = FGS_PARAM_ERROR + 0x07,
/* Invalid bound values, overlapping boundaries */
FGS_INVALID_INTENSITY_BOUNDARY_VALUES = FGS_PARAM_ERROR + 0x08,
/* Invalid standard deviation */
FGS_INVALID_STANDARD_DEVIATION = FGS_PARAM_ERROR + 0x09,
/* Invalid cut off frequencies */
FGS_INVALID_CUT_OFF_FREQUENCIES = FGS_PARAM_ERROR + 0x0A,
/* Invalid number of cut off frequency pairs */
FGS_INVALID_NUM_CUT_OFF_FREQ_PAIRS = FGS_PARAM_ERROR + 0x0B,
/* Invalid film grain characteristics repetition period */
FGS_INVALID_FGC_REPETETION_PERIOD = FGS_PARAM_ERROR + 0x0C,
/* Failure error code */
FGS_FAIL = 0xFF
}FGS_ERROR_T;
/* FGC Error Codes END */
typedef struct GrainSynthesisStruct_t
{
int8_t dataBase[NUM_CUT_OFF_FREQ][NUM_CUT_OFF_FREQ][DATA_BASE_SIZE][DATA_BASE_SIZE];
int16_t intensityInterval[MAX_NUM_COMPONENT][MAX_NUM_INTENSITIES];
}GrainSynthesisStruct;
class SEIFilmGrainSynthesizer
{
private:
uint32_t m_width;
uint32_t m_height;
ChromaFormat m_chromaFormat;
uint8_t m_bitDepth;
uint32_t m_idrPicId;
uint8_t m_enableDeblocking;
GrainSynthesisStruct *m_pGrainSynt;
public:
uint32_t m_poc;
uint32_t m_errorCode;
SEIFilmGrainCharacteristics *m_pFgcParameters;
public:
SEIFilmGrainSynthesizer();
void create(uint32_t width, uint32_t height, ChromaFormat fmt, uint8_t bitDepth,
uint32_t idrPicId, uint8_t enableDeblocking);
virtual ~SEIFilmGrainSynthesizer();