From 7a5ecba472a0a00ceaa1c66813656dbc8b7459f1 Mon Sep 17 00:00:00 2001 From: Taoran Lu <tlu@dolby.com> Date: Thu, 30 Apr 2020 10:56:38 -0700 Subject: [PATCH 1/5] SMPTE-RDD5 implementation for film grain synthesis --- cfg/sei/film_grain_characterstics.cfg | 33 +- doc/software-manual.tex | 80 +- source/App/TAppDecoder/TAppDecCfg.cpp | 3 + source/App/TAppDecoder/TAppDecCfg.h | 6 + source/App/TAppDecoder/TAppDecTop.cpp | 61 +- source/App/TAppDecoder/TAppDecTop.h | 4 +- source/App/TAppEncoder/TAppEncCfg.cpp | 79 +- source/App/TAppEncoder/TAppEncCfg.h | 7 + source/App/TAppEncoder/TAppEncTop.cpp | 13 + source/Lib/TLibCommon/CommonDef.h | 4 + .../TLibCommon/SEIFilmGrainSynthesizer.cpp | 1130 +++++++++++++++++ .../Lib/TLibCommon/SEIFilmGrainSynthesizer.h | 210 +++ source/Lib/TLibCommon/TComPic.cpp | 66 + source/Lib/TLibCommon/TComPic.h | 10 + source/Lib/TLibCommon/TypeDef.h | 1 + source/Lib/TLibDecoder/TDecTop.cpp | 11 +- source/Lib/TLibDecoder/TDecTop.h | 5 + source/Lib/TLibEncoder/SEIEncoder.cpp | 17 + source/Lib/TLibEncoder/TEncCfg.h | 19 + source/Lib/TLibEncoder/TEncGOP.cpp | 13 +- 20 files changed, 1748 insertions(+), 24 deletions(-) create mode 100644 source/Lib/TLibCommon/SEIFilmGrainSynthesizer.cpp create mode 100644 source/Lib/TLibCommon/SEIFilmGrainSynthesizer.h diff --git a/cfg/sei/film_grain_characterstics.cfg b/cfg/sei/film_grain_characterstics.cfg index d8c9c739f..514c6f673 100644 --- a/cfg/sei/film_grain_characterstics.cfg +++ b/cfg/sei/film_grain_characterstics.cfg @@ -1,11 +1,26 @@ #======== 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 diff --git a/doc/software-manual.tex b/doc/software-manual.tex index c83e25d17..bb6320535 100644 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -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} diff --git a/source/App/TAppDecoder/TAppDecCfg.cpp b/source/App/TAppDecoder/TAppDecCfg.cpp index e1466f28c..20b3e3041 100644 --- a/source/App/TAppDecoder/TAppDecCfg.cpp +++ b/source/App/TAppDecoder/TAppDecCfg.cpp @@ -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)") diff --git a/source/App/TAppDecoder/TAppDecCfg.h b/source/App/TAppDecoder/TAppDecCfg.h index 1c491c780..0802109e1 100644 --- a/source/App/TAppDecoder/TAppDecCfg.h +++ b/source/App/TAppDecoder/TAppDecCfg.h @@ -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) diff --git a/source/App/TAppDecoder/TAppDecTop.cpp b/source/App/TAppDecoder/TAppDecTop.cpp index 6c9676c72..46c8d922f 100644 --- a/source/App/TAppDecoder/TAppDecTop.cpp +++ b/source/App/TAppDecoder/TAppDecTop.cpp @@ -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); } diff --git a/source/App/TAppDecoder/TAppDecTop.h b/source/App/TAppDecoder/TAppDecTop.h index 595225c1a..d4ce6add1 100644 --- a/source/App/TAppDecoder/TAppDecTop.h +++ b/source/App/TAppDecoder/TAppDecTop.h @@ -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. diff --git a/source/App/TAppEncoder/TAppEncCfg.cpp b/source/App/TAppEncoder/TAppEncCfg.cpp index 5ae63df72..bc7cf9302 100644 --- a/source/App/TAppEncoder/TAppEncCfg.cpp +++ b/source/App/TAppEncoder/TAppEncCfg.cpp @@ -727,6 +727,18 @@ 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_FgcSEIIntensityIntervalLowerBoundComp0(0, 255, 0, 256); + SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalLowerBoundComp1(0, 255, 0, 256); + SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalLowerBoundComp2(0, 255, 0, 256); + SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalUpperBoundComp0(0, 255, 0, 256); + SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalUpperBoundComp1(0, 255, 0, 256); + SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalUpperBoundComp2(0, 255, 0, 256); + SMultiValueInput<UInt> cfg_FgcSEICompModelValueComp0(0, 65535, 0, 256 * 6); + SMultiValueInput<UInt> cfg_FgcSEICompModelValueComp1(0, 65535, 0, 256 * 6); + SMultiValueInput<UInt> cfg_FgcSEICompModelValueComp2(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 +1227,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_FgcSEIIntensityIntervalLowerBoundComp0, cfg_FgcSEIIntensityIntervalLowerBoundComp0, "Specifies the lower bound for the intensity intervals on colour component 0.") + ("SEIFGCIntensityIntervalLowerBoundComp1", cfg_FgcSEIIntensityIntervalLowerBoundComp1, cfg_FgcSEIIntensityIntervalLowerBoundComp1, "Specifies the lower bound for the intensity intervals on colour component 1.") + ("SEIFGCIntensityIntervalLowerBoundComp2", cfg_FgcSEIIntensityIntervalLowerBoundComp2, cfg_FgcSEIIntensityIntervalLowerBoundComp2, "Specifies the lower bound for the intensity intervals on colour component 2.") + ("SEIFGCIntensityIntervalUpperBoundComp0", cfg_FgcSEIIntensityIntervalUpperBoundComp0, cfg_FgcSEIIntensityIntervalUpperBoundComp0, "Specifies the upper bound for the intensity intervals on colour component 0.") + ("SEIFGCIntensityIntervalUpperBoundComp1", cfg_FgcSEIIntensityIntervalUpperBoundComp1, cfg_FgcSEIIntensityIntervalUpperBoundComp1, "Specifies the upper bound for the intensity intervals on colour component 1.") + ("SEIFGCIntensityIntervalUpperBoundComp2", cfg_FgcSEIIntensityIntervalUpperBoundComp2, cfg_FgcSEIIntensityIntervalUpperBoundComp2, "Specifies the upper bound for the intensity intervals on colour component 2.") + ("SEIFGCCompModelValuesComp0", cfg_FgcSEICompModelValueComp0, cfg_FgcSEICompModelValueComp0, "Specifies the component model values on colour component 0.") + ("SEIFGCCompModelValuesComp1", cfg_FgcSEICompModelValueComp1, cfg_FgcSEICompModelValueComp1, "Specifies the component model values on colour component 1.") + ("SEIFGCCompModelValuesComp2", cfg_FgcSEICompModelValueComp2, cfg_FgcSEICompModelValueComp2, "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 +2074,55 @@ 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; + if (m_fgcSEICompModelPresent[0]) + { + numModelCtr = 0; + for (UChar i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[0]; i++) + { + m_fgcSEIIntensityIntervalLowerBound[0][i] = UChar((cfg_FgcSEIIntensityIntervalLowerBoundComp0.values.size() > i) ? cfg_FgcSEIIntensityIntervalLowerBoundComp0.values[i] : 0); + m_fgcSEIIntensityIntervalUpperBound[0][i] = UChar((cfg_FgcSEIIntensityIntervalUpperBoundComp0.values.size() > i) ? cfg_FgcSEIIntensityIntervalUpperBoundComp0.values[i] : 0); + for (UChar j = 0; j <= m_fgcSEINumModelValuesMinus1[0]; j++) + { + m_fgcSEICompModelValue[0][i][j] = UInt((cfg_FgcSEICompModelValueComp0.values.size() > numModelCtr) ? cfg_FgcSEICompModelValueComp0.values[numModelCtr] : 0); + numModelCtr++; + } + } + } + if (m_fgcSEICompModelPresent[1]) + { + numModelCtr = 0; + for (UChar i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[1]; i++) + { + m_fgcSEIIntensityIntervalLowerBound[1][i] = UChar((cfg_FgcSEIIntensityIntervalLowerBoundComp1.values.size() > i) ? cfg_FgcSEIIntensityIntervalLowerBoundComp1.values[i] : 0); + m_fgcSEIIntensityIntervalUpperBound[1][i] = UChar((cfg_FgcSEIIntensityIntervalUpperBoundComp1.values.size() > i) ? cfg_FgcSEIIntensityIntervalUpperBoundComp1.values[i] : 0); + for (UChar j = 0; j <= m_fgcSEINumModelValuesMinus1[1]; j++) + { + m_fgcSEICompModelValue[1][i][j] = UInt((cfg_FgcSEICompModelValueComp1.values.size() > numModelCtr) ? cfg_FgcSEICompModelValueComp1.values[numModelCtr] : 0); + numModelCtr++; + } + } + } + if (m_fgcSEICompModelPresent[2]) + { + numModelCtr = 0; + for (UChar i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[2]; i++) + { + m_fgcSEIIntensityIntervalLowerBound[2][i] = UChar((cfg_FgcSEIIntensityIntervalLowerBoundComp2.values.size() > i) ? cfg_FgcSEIIntensityIntervalLowerBoundComp2.values[i] : 0); + m_fgcSEIIntensityIntervalUpperBound[2][i] = UChar((cfg_FgcSEIIntensityIntervalUpperBoundComp2.values.size() > i) ? cfg_FgcSEIIntensityIntervalUpperBoundComp2.values[i] : 0); + for (UChar j = 0; j <= m_fgcSEINumModelValuesMinus1[2]; j++) + { + m_fgcSEICompModelValue[2][i][j] = UInt((cfg_FgcSEICompModelValueComp2.values.size() > numModelCtr) ? cfg_FgcSEICompModelValueComp2.values[numModelCtr] : 0); + numModelCtr++; + } + } + } + } +#endif // check validity of input parameters xCheckParameter(); diff --git a/source/App/TAppEncoder/TAppEncCfg.h b/source/App/TAppEncoder/TAppEncCfg.h index 97bb62deb..069eb623e 100644 --- a/source/App/TAppEncoder/TAppEncCfg.h +++ b/source/App/TAppEncoder/TAppEncCfg.h @@ -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; diff --git a/source/App/TAppEncoder/TAppEncTop.cpp b/source/App/TAppEncoder/TAppEncTop.cpp index 574b8a5dd..cc9e3a9da 100644 --- a/source/App/TAppEncoder/TAppEncTop.cpp +++ b/source/App/TAppEncoder/TAppEncTop.cpp @@ -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 (int 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 (int 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); diff --git a/source/Lib/TLibCommon/CommonDef.h b/source/Lib/TLibCommon/CommonDef.h index 8494b062b..9c74f8660 100644 --- a/source/Lib/TLibCommon/CommonDef.h +++ b/source/Lib/TLibCommon/CommonDef.h @@ -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 // ==================================================================================================================== diff --git a/source/Lib/TLibCommon/SEIFilmGrainSynthesizer.cpp b/source/Lib/TLibCommon/SEIFilmGrainSynthesizer.cpp new file mode 100644 index 000000000..35608b970 --- /dev/null +++ b/source/Lib/TLibCommon/SEIFilmGrainSynthesizer.cpp @@ -0,0 +1,1130 @@ +/* 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.cpp + \brief SMPTE RDD5 based film grain synthesis functionality from SEI messages +*/ + +#include "SEIFilmGrainSynthesizer.h" + +#include <stdio.h> + +#if FGS_RDD5_ENABLE + +/* static look up table definitions */ +static const int8_t gaussianLUT[2048] = +{ +-11, 12, 103, -11, 42, -35, 12, 59, 77, 98, -87, 3, 65, -78, 45, 56, +-51, 21, 13, -11, -20, -19, 33, -127, 17, -6, -105, 18, 19, 71, 48, -10, +-38, 42, -2, 75, -67, 52, -90, 33, -47, 21, -3, -56, 49, 1, -57, -42, +-1, 120, -127, -108, -49, 9, 14, 127, 122, 109, 52, 127, 2, 7, 114, 19, +30, 12, 77, 112, 82, -61, -127, 111, -52, -29, 2, -49, -24, 58, -29, -73, +12, 112, 67, 79, -3, -114, -87, -6, -5, 40, 58, -81, 49, -27, -31, -34, +-105, 50, 16, -24, -35, -14, -15, -127, -55, -22, -55, -127, -112, 5, -26, -72, +127, 127, -2, 41, 87, -65, -16, 55, 19, 91, -81, -65, -64, 35, -7, -54, +99, -7, 88, 125, -26, 91, 0, 63, 60, -14, -23, 113, -33, 116, 14, 26, +51, -16, 107, -8, 53, 38, -34, 17, -7, 4, -91, 6, 63, 63, -15, 39, +-36, 19, 55, 17, -51, 40, 33, -37, 126, -39, -118, 17, -30, 0, 19, 98, +60, 101, -12, -73, -17, -52, 98, 3, 3, 60, 33, -3, -2, 10, -42, -106, +-38, 14, 127, 16, -127, -31, -86, -39, -56, 46, -41, 75, 23, -19, -22, -70, +74, -54, -2, 32, -45, 17, -92, 59, -64, -67, 56, -102, -29, -87, -34, -92, +68, 5, -74, -61, 93, -43, 14, -26, -38, -126, -17, 16, -127, 64, 34, 31, +93, 17, -51, -59, 71, 77, 81, 127, 127, 61, 33, -106, -93, 0, 0, 75, +-69, 71, 127, -19, -111, 30, 23, 15, 2, 39, 92, 5, 42, 2, -6, 38, +15, 114, -30, -37, 50, 44, 106, 27, 119, 7, -80, 25, -68, -21, 92, -11, +-1, 18, 41, -50, 79, -127, -43, 127, 18, 11, -21, 32, -52, 27, -88, -90, +-39, -19, -10, 24, -118, 72, -24, -44, 2, 12, 86, -107, 39, -33, -127, 47, +51, -24, -22, 46, 0, 15, -35, -69, -2, -74, 24, -6, 0, 29, -3, 45, +32, -32, 117, -45, 79, -24, -17, -109, -10, -70, 88, -48, 24, -91, 120, -37, +50, -127, 58, 32, -82, -10, -17, -7, 46, -127, -15, 89, 127, 17, 98, -39, +-33, 37, 42, -40, -32, -21, 105, -19, 19, 19, -59, -9, 30, 0, -127, 34, +127, -84, 75, 24, -40, -49, -127, -107, -14, 45, -75, 1, 30, -20, 41, -68, +-40, 12, 127, -3, 5, 20, -73, -59, -127, -3, -3, -53, -6, -119, 93, 120, +-80, -50, 0, 20, -46, 67, 78, -12, -22, -127, 36, -41, 56, 119, -5, -116, +-22, 68, -14, -90, 24, -82, -44, -127, 107, -25, -37, 40, -7, -7, -82, 5, +-87, 44, -34, 9, -127, 39, 70, 49, -63, 74, -49, 109, -27, -89, -47, -39, +44, 49, -4, 60, -42, 80, 9, -127, -9, -56, -49, 125, -66, 47, 36, 117, +15, -11, -96, 109, 94, -17, -56, 70, 8, -14, -5, 50, 37, -45, 120, -30, +-76, 40, -46, 6, 3, 69, 17, -78, 1, -79, 6, 127, 43, 26, 127, -127, +28, -55, -26, 55, 112, 48, 107, -1, -77, -1, 53, -9, -22, -43, 123, 108, +127, 102, 68, 46, 5, 1, 123, -13, -55, -34, -49, 89, 65, -105, -5, 94, +-53, 62, 45, 30, 46, 18, -35, 15, 41, 47, -98, -24, 94, -75, 127, -114, +127, -68, 1, -17, 51, -95, 47, 12, 34, -45, -75, 89, -107, -9, -58, -29, +-109, -24, 127, -61, -13, 77, -45, 17, 19, 83, -24, 9, 127, -66, 54, 4, +26, 13, 111, 43, -113, -22, 10, -24, 83, 67, -14, 75, -123, 59, 127, -12, +99, -19, 64, -38, 54, 9, 7, 61, -56, 3, -57, 113, -104, -59, 3, -9, +-47, 74, 85, -55, -34, 12, 118, 28, 93, -72, 13, -99, -72, -20, 30, 72, +-94, 19, -54, 64, -12, -63, -25, 65, 72, -10, 127, 0, -127, 103, -20, -73, +-112, -103, -6, 28, -42, -21, -59, -29, -26, 19, -4, -51, 94, -58, -95, -37, +35, 20, -69, 127, -19, -127, -22, -120, -53, 37, 74, -127, -1, -12, -119, -53, +-28, 38, 69, 17, 16, -114, 89, 62, 24, 37, -23, 49, -101, -32, -9, -95, +-53, 5, 93, -23, -49, -8, 51, 3, -75, -90, -10, -39, 127, -86, -22, 20, +20, 113, 75, 52, -31, 92, -63, 7, -12, 46, 36, 101, -43, -17, -53, -7, +-38, -76, -31, -21, 62, 31, 62, 20, -127, 31, 64, 36, 102, -85, -10, 77, +80, 58, -79, -8, 35, 8, 80, -24, -9, 3, -17, 72, 127, 83, -87, 55, +18, -119, -123, 36, 10, 127, 56, -55, 113, 13, 26, 32, -13, -48, 22, -13, +5, 58, 27, 24, 26, -11, -36, 37, -92, 78, 81, 9, 51, 14, 67, -13, +0, 32, 45, -76, 32, -39, -22, -49, -127, -27, 31, -9, 36, 14, 71, 13, +57, 12, -53, -86, 53, -44, -35, 2, 127, 12, -66, -44, 46, -115, 3, 10, +56, -35, 119, -19, -61, 52, -59, -127, -49, -23, 4, -5, 17, -82, -6, 127, +25, 79, 67, 64, -25, 14, -64, -37, -127, -28, 21, -63, 66, -53, -41, 109, +-62, 15, -22, 13, 29, -63, 20, 27, 95, -44, -59, -116, -10, 79, -49, 22, +-43, -16, 46, -47, -120, -36, -29, -52, -44, 29, 127, -13, 49, -9, -127, 75, +-28, -23, 88, 59, 11, -95, 81, -59, 58, 60, -26, 40, -92, -3, -22, -58, +-45, -59, -22, -53, 71, -29, 66, -32, -23, 14, -17, -66, -24, -28, -62, 47, +38, 17, 16, -37, -24, -11, 8, -27, -19, 59, 45, -49, -47, -4, -22, -81, +30, -67, -127, 74, 102, 5, -18, 98, 34, -66, 42, -52, 7, -59, 24, -58, +-19, -24, -118, -73, 91, 15, -16, 79, -32, -79, -127, -36, 41, 77, -83, 2, +56, 22, -75, 127, -16, -21, 12, 31, 56, -113, -127, 90, 55, 61, 12, 55, +-14, -113, -14, 32, 49, -67, -17, 91, -10, 1, 21, 69, -70, 99, -19, -112, +66, -90, -10, -9, -71, 127, 50, -81, -49, 24, 61, -61, -111, 7, -41, 127, +88, -66, 108, -127, -6, 36, -14, 41, -50, 14, 14, 73, -101, -28, 77, 127, +-8, -100, 88, 38, 121, 88, -125, -60, 13, -94, -115, 20, -67, -87, -94, -119, +44, -28, -30, 18, 5, -53, -61, 20, -43, 11, -77, -60, 13, 29, 3, 6, +-72, 38, -60, -11, 108, -53, 41, 66, -12, -127, -127, -49, 24, 29, 46, 36, +91, 34, -33, 116, -51, -34, -52, 91, 7, -83, 73, -26, -103, 24, -10, 76, +84, 5, 68, -80, -13, -17, -32, -48, 20, 50, 26, 10, 63, -104, -14, 37, +127, 114, 97, 35, 1, -33, -55, 127, -124, -33, 61, -7, 119, -32, -127, -53, +-42, 63, 3, -5, -26, 70, -58, -33, -44, -43, 34, -56, -127, 127, 25, -35, +-11, 16, -81, 29, -58, 40, -127, -127, 20, -47, -11, -36, -63, -52, -32, -82, +78, -76, -73, 8, 27, -72, -9, -74, -85, -86, -57, 25, 78, -10, -97, 35, +-65, 8, -59, 14, 1, -42, 32, -88, -44, 17, -3, -9, 59, 40, 12, -108, +-40, 24, 34, 18, -28, 2, 51, -110, -4, 100, 1, 65, 22, 0, 127, 61, +45, 25, -31, 6, 9, -7, -48, 99, 16, 44, -2, -40, 32, -39, -52, 10, +-110, -19, 56, -127, 69, 26, 51, 92, 40, 61, -52, 45, -38, 13, 85, 122, +27, 66, 45, -111, -83, -3, 31, 37, 19, -36, 58, 71, 39, -78, -47, 58, +-78, 8, -62, -36, -14, 61, 42, -127, 71, -4, 24, -54, 52, -127, 67, -4, +-42, 30, -63, 59, -3, -1, -18, -46, -92, -81, -96, -14, -53, -10, -11, -77, +13, 1, 8, -67, -127, 127, -28, 26, -14, 18, -13, -26, 2, 10, -46, -32, +-15, 27, -31, -59, 59, 77, -121, 28, 40, -54, -62, -31, -21, -37, -32, -6, +-127, -25, -60, 70, -127, 112, -127, 127, 88, -7, 116, 110, 53, 87, -127, 3, +16, 23, 74, -106, -51, 3, 74, -82, -112, -74, 65, 81, 25, 53, 127, -45, +-50, -103, -41, -65, -29, 79, -67, 64, -33, -30, -8, 127, 0, -13, -51, 67, +-14, 5, -92, 29, -35, -8, -90, -57, -3, 36, 43, 44, -31, -69, -7, 36, +39, -51, 43, -81, 58, 6, 127, 12, 57, 66, 46, 59, -43, -42, 41, -15, +-120, 24, 3, -11, 19, -13, 51, 28, 3, 55, -48, -12, -1, 2, 97, -19, +29, 42, 13, 43, 78, -44, 56, -108, -43, -19, 127, 15, -11, -18, -81, 83, +-37, 77, -109, 15, 65, -50, 43, 12, 13, 27, 28, 61, 57, 30, 26, 106, +-18, 56, 13, 97, 4, -8, -62, -103, 94, 108, -44, 52, 27, -47, -9, 105, +-53, 46, 89, 103, -33, 38, -34, 55, 51, 70, -94, -35, -87, -107, -19, -31, +9, -19, 79, -14, 77, 5, -19, -107, 85, 21, -45, -39, -42, 9, -29, 74, +47, -75, 60, -127, 120, -112, -57, -32, 41, 7, 79, 76, 66, 57, 41, -25, +31, 37, -47, -36, 43, -73, -37, 63, 127, -69, -52, 90, -33, -61, 60, -55, +44, 15, 4, -67, 13, -92, 64, 29, -39, -3, 83, -2, -38, -85, -86, 58, +35, -69, -61, 29, -37, -95, -78, 4, 30, -4, -32, -80, -22, -9, -77, 46, +7, -93, -71, 65, 9, -50, 127, -70, 26, -12, -39, -114, 63, -127, -100, 4, +-32, 111, 22, -60, 65, -101, 26, -42, 21, -59, -27, -74, 2, -94, 6, 126, +5, 76, -88, -9, -43, -101, 127, 1, 125, 92, -63, 52, 56, 4, 81, -127, +127, 80, 127, -29, 30, 116, -74, -17, -57, 105, 48, 45, 25, -72, 48, -38, +-108, 31, -34, 4, -11, 41, -127, 52, -104, -43, -37, 52, 2, 47, 87, -9, +77, 27, -41, -25, 90, 86, -56, 75, 10, 33, 78, 58, 127, 127, -7, -73, +49, -33, -106, -35, 38, 57, 53, -17, -4, 83, 52, -108, 54, -125, 28, 23, +56, -43, -88, -17, -6, 47, 23, -9, 0, -13, 111, 75, 27, -52, -38, -34, +39, 30, 66, 39, 38, -64, 38, 3, 21, -32, -51, -28, 54, -38, -87, 20, +52, 115, 18, -81, -70, 0, -14, -46, -46, -3, 125, 16, -14, 23, -82, -84, +-69, -20, -65, -127, 9, 81, -49, 61, 7, -36, -45, -42, 57, -26, 47, 20, +-85, 46, -13, 41, -37, -75, -60, 86, -78, -127, 12, 50, 2, -3, 13, 47, +5, 19, -78, -55, -27, 65, -71, 12, -108, 20, -16, 11, -31, 63, -55, 37, +75, -17, 127, -73, -33, -28, -120, 105, 68, 106, -103, -106, 71, 61, 2, 23, +-3, 33, -5, -15, -67, -15, -23, -54, 15, -63, 76, 58, -110, 1, 83, -27, +22, 75, -39, -17, -11, 64, -17, -127, -54, -66, 31, 96, 116, 3, -114, -7, +-108, -63, 97, 9, 50, 8, 75, -28, 72, 112, -36, -112, 95, -50, 23, -13, +-19, 55, 21, 23, 92, 91, 22, -49, 16, -75, 23, 9, -49, -97, -37, 49, +-36, 36, -127, -86, 43, 127, -24, -24, 84, 83, -35, -34, -12, 109, 102, -38, +51, -68, 34, 19, -22, 49, -32, 127, 40, 24, -93, -4, -3, 105, 3, -58, +-18, 8, 127, -18, 125, 68, 69, -62, 30, -36, 54, -57, -24, 17, 43, -36, +-27, -57, -67, -21, -10, -49, 68, 12, 65, 4, 48, 55, 127, -75, 44, 89, +-66, -13, -78, -82, -91, 22, 30, 33, -40, -87, -34, 96, -91, 39, 10, -64, +-3, -12, 127, -50, -37, -56, 23, -35, -36, -54, 90, -91, 2, 50, 77, -6, +-127, 16, 46, -5, -73, 0, -56, -18, -72, 28, 93, 60, 49, 20, 18, 111, +-111, 32, -83, 47, 47, -10, 35, -88, 43, 57, -98, 127, -17, 0, 1, -39, +-127, -2, 0, 63, 93, 0, 36, -66, -61, -19, 39, -127, 58, 50, -17, 127, +88, -43, -108, -51, -16, 7, -36, 68, 46, -14, 107, 40, 57, 7, 19, 8, +3, 88, -90, -92, -18, -21, -24, 13, 7, -4, -78, -91, -4, 8, -35, -5, +19, 2, -111, 4, -66, -81, 122, -20, -34, -37, -84, 127, 68, 46, 17, 47 +}; + +static const uint32_t seedLUT[256] = { +747538460, 1088979410, 1744950180, 1767011913, 1403382928, 521866116, 1060417601, 2110622736, +1557184770, 105289385, 585624216, 1827676546, 1191843873, 1018104344, 1123590530, 663361569, +2023850500, 76561770, 1226763489, 80325252, 1992581442, 502705249, 740409860, 516219202, +557974537, 1883843076, 720112066, 1640137737, 1820967556, 40667586, 155354121, 1820967557, +1115949072, 1631803309, 98284748, 287433856, 2119719977, 988742797, 1827432592, 579378475, +1017745956, 1309377032, 1316535465, 2074315269, 1923385360, 209722667, 1546228260, 168102420, +135274561, 355958469, 248291472, 2127839491, 146920100, 585982612, 1611702337, 696506029, +1386498192, 1258072451, 1212240548, 1043171860, 1217404993, 1090770605, 1386498193, 169093201, +541098240, 1468005469, 456510673, 1578687785, 1838217424, 2010752065, 2089828354, 1362717428, +970073673, 854129835, 714793201, 1266069081, 1047060864, 1991471829, 1098097741, 913883585, +1669598224, 1337918685, 1219264706, 1799741108, 1834116681, 683417731, 1120274457, 1073098457, +1648396544, 176642749, 31171789, 718317889, 1266977808, 1400892508, 549749008, 1808010512, +67112961, 1005669825, 903663673, 1771104465, 1277749632, 1229754427, 950632997, 1979371465, +2074373264, 305357524, 1049387408, 1171033360, 1686114305, 2147468765, 1941195985, 117709841, +809550080, 991480851, 1816248997, 1561503561, 329575568, 780651196, 1659144592, 1910793616, +604016641, 1665084765, 1530186961, 1870928913, 809550081, 2079346113, 71307521, 876663040, +1073807360, 832356664, 1573927377, 204073344, 2026918147, 1702476788, 2043881033, 57949587, +2001393952, 1197426649, 1186508931, 332056865, 950043140, 890043474, 349099312, 148914948, +236204097, 2022643605, 1441981517, 498130129, 1443421481, 924216797, 1817491777, 1913146664, +1411989632, 929068432, 495735097, 1684636033, 1284520017, 432816184, 1344884865, 210843729, +676364544, 234449232, 12112337, 1350619139, 1753272996, 2037118872, 1408560528, 533334916, +1043640385, 357326099, 201376421, 110375493, 541106497, 416159637, 242512193, 777294080, +1614872576, 1535546636, 870600145, 910810409, 1821440209, 1605432464, 1145147393, 951695441, +1758494976, 1506656568, 1557150160, 608221521, 1073840384, 217672017, 684818688, 1750138880, +16777217, 677990609, 953274371, 1770050213, 1359128393, 1797602707, 1984616737, 1865815816, +2120835200, 2051677060, 1772234061, 1579794881, 1652821009, 1742099468, 1887260865, 46468113, +1011925248, 1134107920, 881643832, 1354774993, 472508800, 1892499769, 1752793472, 1962502272, +687898625, 883538000, 1354355153, 1761673473, 944820481, 2020102353, 22020353, 961597696, +1342242816, 964808962, 1355809701, 17016649, 1386540177, 647682692, 1849012289, 751668241, +1557184768, 127374604, 1927564752, 1045744913, 1614921984, 43588881, 1016185088, 1544617984, +1090519041, 136122424, 215038417, 1563027841, 2026918145, 1688778833, 701530369, 1372639488, +1342242817, 2036945104, 953274369, 1750192384, 16842753, 964808960, 1359020032, 1358954497 +}; +static const int8_t R64_IDCT[64][64] = +{ +{ /* Row 0 */ +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}, +{ /* Row 1 */ +45, 45, 45, 45, 44, 44, 43, 42, 41, 40, 39, 38, 37, 36, 34, 33, +31, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 3, 1, +-1, -3, -6, -8, -10, -12, -14, -16, -18, -20, -22, -24, -26, -28, -30, -31, +-33, -34, -36, -37, -38, -39, -40, -41, -42, -43, -44, -44, -45, -45, -45, -45}, +{ /* Row 2 */ +45, 45, 44, 43, 41, 39, 36, 34, 30, 27, 23, 19, 15, 11, 7, 2, +-2, -7, -11, -15, -19, -23, -27, -30, -34, -36, -39, -41, -43, -44, -45, -45, +-45, -45, -44, -43, -41, -39, -36, -34, -30, -27, -23, -19, -15, -11, -7, -2, +2, 7, 11, 15, 19, 23, 27, 30, 34, 36, 39, 41, 43, 44, 45, 45}, +{ /* Row 3 */ +45, 44, 42, 39, 36, 31, 26, 20, 14, 8, 1, -6, -12, -18, -24, -30, +-34, -38, -41, -44, -45, -45, -45, -43, -40, -37, -33, -28, -22, -16, -10, -3, +3, 10, 16, 22, 28, 33, 37, 40, 43, 45, 45, 45, 44, 41, 38, 34, +30, 24, 18, 12, 6, -1, -8, -14, -20, -26, -31, -36, -39, -42, -44, -45}, +{ /* Row 4 */ +45, 43, 40, 35, 29, 21, 13, 4, -4, -13, -21, -29, -35, -40, -43, -45, +-45, -43, -40, -35, -29, -21, -13, -4, 4, 13, 21, 29, 35, 40, 43, 45, +45, 43, 40, 35, 29, 21, 13, 4, -4, -13, -21, -29, -35, -40, -43, -45, +-45, -43, -40, -35, -29, -21, -13, -4, 4, 13, 21, 29, 35, 40, 43, 45}, +{ /* Row 5 */ +45, 42, 37, 30, 20, 10, -1, -12, -22, -31, -38, -43, -45, -45, -41, -36, +-28, -18, -8, 3, 14, 24, 33, 39, 44, 45, 44, 40, 34, 26, 16, 6, +-6, -16, -26, -34, -40, -44, -45, -44, -39, -33, -24, -14, -3, 8, 18, 28, +36, 41, 45, 45, 43, 38, 31, 22, 12, 1, -10, -20, -30, -37, -42, -45}, +{ /* Row 6 */ +45, 41, 34, 23, 11, -2, -15, -27, -36, -43, -45, -44, -39, -30, -19, -7, +7, 19, 30, 39, 44, 45, 43, 36, 27, 15, 2, -11, -23, -34, -41, -45, +-45, -41, -34, -23, -11, 2, 15, 27, 36, 43, 45, 44, 39, 30, 19, 7, +-7, -19, -30, -39, -44, -45, -43, -36, -27, -15, -2, 11, 23, 34, 41, 45}, +{ /* Row 7 */ +45, 39, 30, 16, 1, -14, -28, -38, -44, -45, -40, -31, -18, -3, 12, 26, +37, 44, 45, 41, 33, 20, 6, -10, -24, -36, -43, -45, -42, -34, -22, -8, +8, 22, 34, 42, 45, 43, 36, 24, 10, -6, -20, -33, -41, -45, -44, -37, +-26, -12, 3, 18, 31, 40, 45, 44, 38, 28, 14, -1, -16, -30, -39, -45}, +{ /* Row 8 */ +44, 38, 25, 9, -9, -25, -38, -44, -44, -38, -25, -9, 9, 25, 38, 44, +44, 38, 25, 9, -9, -25, -38, -44, -44, -38, -25, -9, 9, 25, 38, 44, +44, 38, 25, 9, -9, -25, -38, -44, -44, -38, -25, -9, 9, 25, 38, 44, +44, 38, 25, 9, -9, -25, -38, -44, -44, -38, -25, -9, 9, 25, 38, 44}, +{ /* Row 9 */ +44, 36, 20, 1, -18, -34, -44, -45, -37, -22, -3, 16, 33, 43, 45, 38, +24, 6, -14, -31, -42, -45, -39, -26, -8, 12, 30, 41, 45, 40, 28, 10, +-10, -28, -40, -45, -41, -30, -12, 8, 26, 39, 45, 42, 31, 14, -6, -24, +-38, -45, -43, -33, -16, 3, 22, 37, 45, 44, 34, 18, -1, -20, -36, -44}, +{ /* Row 10 */ +44, 34, 15, -7, -27, -41, -45, -39, -23, -2, 19, 36, 45, 43, 30, 11, +-11, -30, -43, -45, -36, -19, 2, 23, 39, 45, 41, 27, 7, -15, -34, -44, +-44, -34, -15, 7, 27, 41, 45, 39, 23, 2, -19, -36, -45, -43, -30, -11, +11, 30, 43, 45, 36, 19, -2, -23, -39, -45, -41, -27, -7, 15, 34, 44}, +{ /* Row 11 */ +44, 31, 10, -14, -34, -45, -42, -28, -6, 18, 37, 45, 40, 24, 1, -22, +-39, -45, -38, -20, 3, 26, 41, 45, 36, 16, -8, -30, -43, -44, -33, -12, +12, 33, 44, 43, 30, 8, -16, -36, -45, -41, -26, -3, 20, 38, 45, 39, +22, -1, -24, -40, -45, -37, -18, 6, 28, 42, 45, 34, 14, -10, -31, -44}, +{ /* Row 12 */ +43, 29, 4, -21, -40, -45, -35, -13, 13, 35, 45, 40, 21, -4, -29, -43, +-43, -29, -4, 21, 40, 45, 35, 13, -13, -35, -45, -40, -21, 4, 29, 43, +43, 29, 4, -21, -40, -45, -35, -13, 13, 35, 45, 40, 21, -4, -29, -43, +-43, -29, -4, 21, 40, 45, 35, 13, -13, -35, -45, -40, -21, 4, 29, 43}, +{ /* Row 13 */ +43, 26, -1, -28, -44, -42, -24, 3, 30, 44, 41, 22, -6, -31, -45, -40, +-20, 8, 33, 45, 39, 18, -10, -34, -45, -38, -16, 12, 36, 45, 37, 14, +-14, -37, -45, -36, -12, 16, 38, 45, 34, 10, -18, -39, -45, -33, -8, 20, +40, 45, 31, 6, -22, -41, -44, -30, -3, 24, 42, 44, 28, 1, -26, -43}, +{ /* Row 14 */ +43, 23, -7, -34, -45, -36, -11, 19, 41, 44, 27, -2, -30, -45, -39, -15, +15, 39, 45, 30, 2, -27, -44, -41, -19, 11, 36, 45, 34, 7, -23, -43, +-43, -23, 7, 34, 45, 36, 11, -19, -41, -44, -27, 2, 30, 45, 39, 15, +-15, -39, -45, -30, -2, 27, 44, 41, 19, -11, -36, -45, -34, -7, 23, 43}, +{ /* Row 15 */ +42, 20, -12, -38, -45, -28, 3, 33, 45, 34, 6, -26, -44, -39, -14, 18, +41, 43, 22, -10, -37, -45, -30, 1, 31, 45, 36, 8, -24, -44, -40, -16, +16, 40, 44, 24, -8, -36, -45, -31, -1, 30, 45, 37, 10, -22, -43, -41, +-18, 14, 39, 44, 26, -6, -34, -45, -33, -3, 28, 45, 38, 12, -20, -42}, +{ /* Row 16 */ +42, 17, -17, -42, -42, -17, 17, 42, 42, 17, -17, -42, -42, -17, 17, 42, +42, 17, -17, -42, -42, -17, 17, 42, 42, 17, -17, -42, -42, -17, 17, 42, +42, 17, -17, -42, -42, -17, 17, 42, 42, 17, -17, -42, -42, -17, 17, 42, +42, 17, -17, -42, -42, -17, 17, 42, 42, 17, -17, -42, -42, -17, 17, 42}, +{ /* Row 17 */ +41, 14, -22, -44, -37, -6, 30, 45, 31, -3, -36, -45, -24, 12, 40, 42, +16, -20, -44, -38, -8, 28, 45, 33, -1, -34, -45, -26, 10, 39, 43, 18, +-18, -43, -39, -10, 26, 45, 34, 1, -33, -45, -28, 8, 38, 44, 20, -16, +-42, -40, -12, 24, 45, 36, 3, -31, -45, -30, 6, 37, 44, 22, -14, -41}, +{ /* Row 18 */ +41, 11, -27, -45, -30, 7, 39, 43, 15, -23, -45, -34, 2, 36, 44, 19, +-19, -44, -36, -2, 34, 45, 23, -15, -43, -39, -7, 30, 45, 27, -11, -41, +-41, -11, 27, 45, 30, -7, -39, -43, -15, 23, 45, 34, -2, -36, -44, -19, +19, 44, 36, 2, -34, -45, -23, 15, 43, 39, 7, -30, -45, -27, 11, 41}, +{ /* Row 19 */ +40, 8, -31, -45, -22, 18, 44, 34, -3, -38, -42, -12, 28, 45, 26, -14, +-43, -37, -1, 36, 44, 16, -24, -45, -30, 10, 41, 39, 6, -33, -45, -20, +20, 45, 33, -6, -39, -41, -10, 30, 45, 24, -16, -44, -36, 1, 37, 43, +14, -26, -45, -28, 12, 42, 38, 3, -34, -44, -18, 22, 45, 31, -8, -40}, +{ /* Row 20 */ +40, 4, -35, -43, -13, 29, 45, 21, -21, -45, -29, 13, 43, 35, -4, -40, +-40, -4, 35, 43, 13, -29, -45, -21, 21, 45, 29, -13, -43, -35, 4, 40, +40, 4, -35, -43, -13, 29, 45, 21, -21, -45, -29, 13, 43, 35, -4, -40, +-40, -4, 35, 43, 13, -29, -45, -21, 21, 45, 29, -13, -43, -35, 4, 40}, +{ /* Row 21 */ +39, 1, -38, -40, -3, 37, 41, 6, -36, -42, -8, 34, 43, 10, -33, -44, +-12, 31, 44, 14, -30, -45, -16, 28, 45, 18, -26, -45, -20, 24, 45, 22, +-22, -45, -24, 20, 45, 26, -18, -45, -28, 16, 45, 30, -14, -44, -31, 12, +44, 33, -10, -43, -34, 8, 42, 36, -6, -41, -37, 3, 40, 38, -1, -39}, +{ /* Row 22 */ +39, -2, -41, -36, 7, 43, 34, -11, -44, -30, 15, 45, 27, -19, -45, -23, +23, 45, 19, -27, -45, -15, 30, 44, 11, -34, -43, -7, 36, 41, 2, -39, +-39, 2, 41, 36, -7, -43, -34, 11, 44, 30, -15, -45, -27, 19, 45, 23, +-23, -45, -19, 27, 45, 15, -30, -44, -11, 34, 43, 7, -36, -41, -2, 39}, +{ /* Row 23 */ +38, -6, -43, -31, 16, 45, 22, -26, -45, -12, 34, 41, 1, -40, -36, 10, +44, 28, -20, -45, -18, 30, 44, 8, -37, -39, 3, 42, 33, -14, -45, -24, +24, 45, 14, -33, -42, -3, 39, 37, -8, -44, -30, 18, 45, 20, -28, -44, +-10, 36, 40, -1, -41, -34, 12, 45, 26, -22, -45, -16, 31, 43, 6, -38}, +{ /* Row 24 */ +38, -9, -44, -25, 25, 44, 9, -38, -38, 9, 44, 25, -25, -44, -9, 38, +38, -9, -44, -25, 25, 44, 9, -38, -38, 9, 44, 25, -25, -44, -9, 38, +38, -9, -44, -25, 25, 44, 9, -38, -38, 9, 44, 25, -25, -44, -9, 38, +38, -9, -44, -25, 25, 44, 9, -38, -38, 9, 44, 25, -25, -44, -9, 38}, +{ /* Row 25 */ +37, -12, -45, -18, 33, 40, -6, -44, -24, 28, 43, 1, -42, -30, 22, 45, +8, -39, -34, 16, 45, 14, -36, -38, 10, 45, 20, -31, -41, 3, 44, 26, +-26, -44, -3, 41, 31, -20, -45, -10, 38, 36, -14, -45, -16, 34, 39, -8, +-45, -22, 30, 42, -1, -43, -28, 24, 44, 6, -40, -33, 18, 45, 12, -37}, +{ /* Row 26 */ +36, -15, -45, -11, 39, 34, -19, -45, -7, 41, 30, -23, -44, -2, 43, 27, +-27, -43, 2, 44, 23, -30, -41, 7, 45, 19, -34, -39, 11, 45, 15, -36, +-36, 15, 45, 11, -39, -34, 19, 45, 7, -41, -30, 23, 44, 2, -43, -27, +27, 43, -2, -44, -23, 30, 41, -7, -45, -19, 34, 39, -11, -45, -15, 36}, +{ /* Row 27 */ +36, -18, -45, -3, 43, 24, -31, -39, 12, 45, 10, -40, -30, 26, 42, -6, +-45, -16, 37, 34, -20, -44, -1, 44, 22, -33, -38, 14, 45, 8, -41, -28, +28, 41, -8, -45, -14, 38, 33, -22, -44, 1, 44, 20, -34, -37, 16, 45, +6, -42, -26, 30, 40, -10, -45, -12, 39, 31, -24, -43, 3, 45, 18, -36}, +{ /* Row 28 */ +35, -21, -43, 4, 45, 13, -40, -29, 29, 40, -13, -45, -4, 43, 21, -35, +-35, 21, 43, -4, -45, -13, 40, 29, -29, -40, 13, 45, 4, -43, -21, 35, +35, -21, -43, 4, 45, 13, -40, -29, 29, 40, -13, -45, -4, 43, 21, -35, +-35, 21, 43, -4, -45, -13, 40, 29, -29, -40, 13, 45, 4, -43, -21, 35}, +{ /* Row 29 */ +34, -24, -41, 12, 45, 1, -45, -14, 40, 26, -33, -36, 22, 42, -10, -45, +-3, 44, 16, -39, -28, 31, 37, -20, -43, 8, 45, 6, -44, -18, 38, 30, +-30, -38, 18, 44, -6, -45, -8, 43, 20, -37, -31, 28, 39, -16, -44, 3, +45, 10, -42, -22, 36, 33, -26, -40, 14, 45, -1, -45, -12, 41, 24, -34}, +{ /* Row 30 */ +34, -27, -39, 19, 43, -11, -45, 2, 45, 7, -44, -15, 41, 23, -36, -30, +30, 36, -23, -41, 15, 44, -7, -45, -2, 45, 11, -43, -19, 39, 27, -34, +-34, 27, 39, -19, -43, 11, 45, -2, -45, -7, 44, 15, -41, -23, 36, 30, +-30, -36, 23, 41, -15, -44, 7, 45, 2, -45, -11, 43, 19, -39, -27, 34}, +{ /* Row 31 */ +33, -30, -36, 26, 38, -22, -40, 18, 42, -14, -44, 10, 45, -6, -45, 1, +45, 3, -45, -8, 44, 12, -43, -16, 41, 20, -39, -24, 37, 28, -34, -31, +31, 34, -28, -37, 24, 39, -20, -41, 16, 43, -12, -44, 8, 45, -3, -45, +-1, 45, 6, -45, -10, 44, 14, -42, -18, 40, 22, -38, -26, 36, 30, -33}, +{ /* Row 32 */ +32, -32, -32, 32, 32, -32, -32, 32, 32, -32, -32, 32, 32, -32, -32, 32, +32, -32, -32, 32, 32, -32, -32, 32, 32, -32, -32, 32, 32, -32, -32, 32, +32, -32, -32, 32, 32, -32, -32, 32, 32, -32, -32, 32, 32, -32, -32, 32, +32, -32, -32, 32, 32, -32, -32, 32, 32, -32, -32, 32, 32, -32, -32, 32}, +{ /* Row 33 */ +31, -34, -28, 37, 24, -39, -20, 41, 16, -43, -12, 44, 8, -45, -3, 45, +-1, -45, 6, 45, -10, -44, 14, 42, -18, -40, 22, 38, -26, -36, 30, 33, +-33, -30, 36, 26, -38, -22, 40, 18, -42, -14, 44, 10, -45, -6, 45, 1, +-45, 3, 45, -8, -44, 12, 43, -16, -41, 20, 39, -24, -37, 28, 34, -31}, +{ /* Row 34 */ +30, -36, -23, 41, 15, -44, -7, 45, -2, -45, 11, 43, -19, -39, 27, 34, +-34, -27, 39, 19, -43, -11, 45, 2, -45, 7, 44, -15, -41, 23, 36, -30, +-30, 36, 23, -41, -15, 44, 7, -45, 2, 45, -11, -43, 19, 39, -27, -34, +34, 27, -39, -19, 43, 11, -45, -2, 45, -7, -44, 15, 41, -23, -36, 30}, +{ /* Row 35 */ +30, -38, -18, 44, 6, -45, 8, 43, -20, -37, 31, 28, -39, -16, 44, 3, +-45, 10, 42, -22, -36, 33, 26, -40, -14, 45, 1, -45, 12, 41, -24, -34, +34, 24, -41, -12, 45, -1, -45, 14, 40, -26, -33, 36, 22, -42, -10, 45, +-3, -44, 16, 39, -28, -31, 37, 20, -43, -8, 45, -6, -44, 18, 38, -30}, +{ /* Row 36 */ +29, -40, -13, 45, -4, -43, 21, 35, -35, -21, 43, 4, -45, 13, 40, -29, +-29, 40, 13, -45, 4, 43, -21, -35, 35, 21, -43, -4, 45, -13, -40, 29, +29, -40, -13, 45, -4, -43, 21, 35, -35, -21, 43, 4, -45, 13, 40, -29, +-29, 40, 13, -45, 4, 43, -21, -35, 35, 21, -43, -4, 45, -13, -40, 29}, +{ /* Row 37 */ +28, -41, -8, 45, -14, -38, 33, 22, -44, -1, 44, -20, -34, 37, 16, -45, +6, 42, -26, -30, 40, 10, -45, 12, 39, -31, -24, 43, 3, -45, 18, 36, +-36, -18, 45, -3, -43, 24, 31, -39, -12, 45, -10, -40, 30, 26, -42, -6, +45, -16, -37, 34, 20, -44, 1, 44, -22, -33, 38, 14, -45, 8, 41, -28}, +{ /* Row 38 */ +27, -43, -2, 44, -23, -30, 41, 7, -45, 19, 34, -39, -11, 45, -15, -36, +36, 15, -45, 11, 39, -34, -19, 45, -7, -41, 30, 23, -44, 2, 43, -27, +-27, 43, 2, -44, 23, 30, -41, -7, 45, -19, -34, 39, 11, -45, 15, 36, +-36, -15, 45, -11, -39, 34, 19, -45, 7, 41, -30, -23, 44, -2, -43, 27}, +{ /* Row 39 */ +26, -44, 3, 41, -31, -20, 45, -10, -38, 36, 14, -45, 16, 34, -39, -8, +45, -22, -30, 42, 1, -43, 28, 24, -44, 6, 40, -33, -18, 45, -12, -37, +37, 12, -45, 18, 33, -40, -6, 44, -24, -28, 43, -1, -42, 30, 22, -45, +8, 39, -34, -16, 45, -14, -36, 38, 10, -45, 20, 31, -41, -3, 44, -26}, +{ /* Row 40 */ +25, -44, 9, 38, -38, -9, 44, -25, -25, 44, -9, -38, 38, 9, -44, 25, +25, -44, 9, 38, -38, -9, 44, -25, -25, 44, -9, -38, 38, 9, -44, 25, +25, -44, 9, 38, -38, -9, 44, -25, -25, 44, -9, -38, 38, 9, -44, 25, +25, -44, 9, 38, -38, -9, 44, -25, -25, 44, -9, -38, 38, 9, -44, 25}, +{ /* Row 41 */ +24, -45, 14, 33, -42, 3, 39, -37, -8, 44, -30, -18, 45, -20, -28, 44, +-10, -36, 40, 1, -41, 34, 12, -45, 26, 22, -45, 16, 31, -43, 6, 38, +-38, -6, 43, -31, -16, 45, -22, -26, 45, -12, -34, 41, -1, -40, 36, 10, +-44, 28, 20, -45, 18, 30, -44, 8, 37, -39, -3, 42, -33, -14, 45, -24}, +{ /* Row 42 */ +23, -45, 19, 27, -45, 15, 30, -44, 11, 34, -43, 7, 36, -41, 2, 39, +-39, -2, 41, -36, -7, 43, -34, -11, 44, -30, -15, 45, -27, -19, 45, -23, +-23, 45, -19, -27, 45, -15, -30, 44, -11, -34, 43, -7, -36, 41, -2, -39, +39, 2, -41, 36, 7, -43, 34, 11, -44, 30, 15, -45, 27, 19, -45, 23}, +{ /* Row 43 */ +22, -45, 24, 20, -45, 26, 18, -45, 28, 16, -45, 30, 14, -44, 31, 12, +-44, 33, 10, -43, 34, 8, -42, 36, 6, -41, 37, 3, -40, 38, 1, -39, +39, -1, -38, 40, -3, -37, 41, -6, -36, 42, -8, -34, 43, -10, -33, 44, +-12, -31, 44, -14, -30, 45, -16, -28, 45, -18, -26, 45, -20, -24, 45, -22}, +{ /* Row 44 */ +21, -45, 29, 13, -43, 35, 4, -40, 40, -4, -35, 43, -13, -29, 45, -21, +-21, 45, -29, -13, 43, -35, -4, 40, -40, 4, 35, -43, 13, 29, -45, 21, +21, -45, 29, 13, -43, 35, 4, -40, 40, -4, -35, 43, -13, -29, 45, -21, +-21, 45, -29, -13, 43, -35, -4, 40, -40, 4, 35, -43, 13, 29, -45, 21}, +{ /* Row 45 */ +20, -45, 33, 6, -39, 41, -10, -30, 45, -24, -16, 44, -36, -1, 37, -43, +14, 26, -45, 28, 12, -42, 38, -3, -34, 44, -18, -22, 45, -31, -8, 40, +-40, 8, 31, -45, 22, 18, -44, 34, 3, -38, 42, -12, -28, 45, -26, -14, +43, -37, 1, 36, -44, 16, 24, -45, 30, 10, -41, 39, -6, -33, 45, -20}, +{ /* Row 46 */ +19, -44, 36, -2, -34, 45, -23, -15, 43, -39, 7, 30, -45, 27, 11, -41, +41, -11, -27, 45, -30, -7, 39, -43, 15, 23, -45, 34, 2, -36, 44, -19, +-19, 44, -36, 2, 34, -45, 23, 15, -43, 39, -7, -30, 45, -27, -11, 41, +-41, 11, 27, -45, 30, 7, -39, 43, -15, -23, 45, -34, -2, 36, -44, 19}, +{ /* Row 47 */ +18, -43, 39, -10, -26, 45, -34, 1, 33, -45, 28, 8, -38, 44, -20, -16, +42, -40, 12, 24, -45, 36, -3, -31, 45, -30, -6, 37, -44, 22, 14, -41, +41, -14, -22, 44, -37, 6, 30, -45, 31, 3, -36, 45, -24, -12, 40, -42, +16, 20, -44, 38, -8, -28, 45, -33, -1, 34, -45, 26, 10, -39, 43, -18}, +{ /* Row 48 */ +17, -42, 42, -17, -17, 42, -42, 17, 17, -42, 42, -17, -17, 42, -42, 17, +17, -42, 42, -17, -17, 42, -42, 17, 17, -42, 42, -17, -17, 42, -42, 17, +17, -42, 42, -17, -17, 42, -42, 17, 17, -42, 42, -17, -17, 42, -42, 17, +17, -42, 42, -17, -17, 42, -42, 17, 17, -42, 42, -17, -17, 42, -42, 17}, +{ /* Row 49 */ +16, -40, 44, -24, -8, 36, -45, 31, -1, -30, 45, -37, 10, 22, -43, 41, +-18, -14, 39, -44, 26, 6, -34, 45, -33, 3, 28, -45, 38, -12, -20, 42, +-42, 20, 12, -38, 45, -28, -3, 33, -45, 34, -6, -26, 44, -39, 14, 18, +-41, 43, -22, -10, 37, -45, 30, 1, -31, 45, -36, 8, 24, -44, 40, -16}, +{ /* Row 50 */ +15, -39, 45, -30, 2, 27, -44, 41, -19, -11, 36, -45, 34, -7, -23, 43, +-43, 23, 7, -34, 45, -36, 11, 19, -41, 44, -27, -2, 30, -45, 39, -15, +-15, 39, -45, 30, -2, -27, 44, -41, 19, 11, -36, 45, -34, 7, 23, -43, +43, -23, -7, 34, -45, 36, -11, -19, 41, -44, 27, 2, -30, 45, -39, 15}, +{ /* Row 51 */ +14, -37, 45, -36, 12, 16, -38, 45, -34, 10, 18, -39, 45, -33, 8, 20, +-40, 45, -31, 6, 22, -41, 44, -30, 3, 24, -42, 44, -28, 1, 26, -43, +43, -26, -1, 28, -44, 42, -24, -3, 30, -44, 41, -22, -6, 31, -45, 40, +-20, -8, 33, -45, 39, -18, -10, 34, -45, 38, -16, -12, 36, -45, 37, -14}, +{ /* Row 52 */ +13, -35, 45, -40, 21, 4, -29, 43, -43, 29, -4, -21, 40, -45, 35, -13, +-13, 35, -45, 40, -21, -4, 29, -43, 43, -29, 4, 21, -40, 45, -35, 13, +13, -35, 45, -40, 21, 4, -29, 43, -43, 29, -4, -21, 40, -45, 35, -13, +-13, 35, -45, 40, -21, -4, 29, -43, 43, -29, 4, 21, -40, 45, -35, 13}, +{ /* Row 53 */ +12, -33, 44, -43, 30, -8, -16, 36, -45, 41, -26, 3, 20, -38, 45, -39, +22, 1, -24, 40, -45, 37, -18, -6, 28, -42, 45, -34, 14, 10, -31, 44, +-44, 31, -10, -14, 34, -45, 42, -28, 6, 18, -37, 45, -40, 24, -1, -22, +39, -45, 38, -20, -3, 26, -41, 45, -36, 16, 8, -30, 43, -44, 33, -12}, +{ /* Row 54 */ +11, -30, 43, -45, 36, -19, -2, 23, -39, 45, -41, 27, -7, -15, 34, -44, +44, -34, 15, 7, -27, 41, -45, 39, -23, 2, 19, -36, 45, -43, 30, -11, +-11, 30, -43, 45, -36, 19, 2, -23, 39, -45, 41, -27, 7, 15, -34, 44, +-44, 34, -15, -7, 27, -41, 45, -39, 23, -2, -19, 36, -45, 43, -30, 11}, +{ /* Row 55 */ +10, -28, 40, -45, 41, -30, 12, 8, -26, 39, -45, 42, -31, 14, 6, -24, +38, -45, 43, -33, 16, 3, -22, 37, -45, 44, -34, 18, 1, -20, 36, -44, +44, -36, 20, -1, -18, 34, -44, 45, -37, 22, -3, -16, 33, -43, 45, -38, +24, -6, -14, 31, -42, 45, -39, 26, -8, -12, 30, -41, 45, -40, 28, -10}, +{ /* Row 56 */ +9, -25, 38, -44, 44, -38, 25, -9, -9, 25, -38, 44, -44, 38, -25, 9, +9, -25, 38, -44, 44, -38, 25, -9, -9, 25, -38, 44, -44, 38, -25, 9, +9, -25, 38, -44, 44, -38, 25, -9, -9, 25, -38, 44, -44, 38, -25, 9, +9, -25, 38, -44, 44, -38, 25, -9, -9, 25, -38, 44, -44, 38, -25, 9}, +{ /* Row 57 */ +8, -22, 34, -42, 45, -43, 36, -24, 10, 6, -20, 33, -41, 45, -44, 37, +-26, 12, 3, -18, 31, -40, 45, -44, 38, -28, 14, 1, -16, 30, -39, 45, +-45, 39, -30, 16, -1, -14, 28, -38, 44, -45, 40, -31, 18, -3, -12, 26, +-37, 44, -45, 41, -33, 20, -6, -10, 24, -36, 43, -45, 42, -34, 22, -8}, +{ /* Row 58 */ +7, -19, 30, -39, 44, -45, 43, -36, 27, -15, 2, 11, -23, 34, -41, 45, +-45, 41, -34, 23, -11, -2, 15, -27, 36, -43, 45, -44, 39, -30, 19, -7, +-7, 19, -30, 39, -44, 45, -43, 36, -27, 15, -2, -11, 23, -34, 41, -45, +45, -41, 34, -23, 11, 2, -15, 27, -36, 43, -45, 44, -39, 30, -19, 7}, +{ /* Row 59 */ +6, -16, 26, -34, 40, -44, 45, -44, 39, -33, 24, -14, 3, 8, -18, 28, +-36, 41, -45, 45, -43, 38, -31, 22, -12, 1, 10, -20, 30, -37, 42, -45, +45, -42, 37, -30, 20, -10, -1, 12, -22, 31, -38, 43, -45, 45, -41, 36, +-28, 18, -8, -3, 14, -24, 33, -39, 44, -45, 44, -40, 34, -26, 16, -6}, +{ /* Row 60 */ +4, -13, 21, -29, 35, -40, 43, -45, 45, -43, 40, -35, 29, -21, 13, -4, +-4, 13, -21, 29, -35, 40, -43, 45, -45, 43, -40, 35, -29, 21, -13, 4, +4, -13, 21, -29, 35, -40, 43, -45, 45, -43, 40, -35, 29, -21, 13, -4, +-4, 13, -21, 29, -35, 40, -43, 45, -45, 43, -40, 35, -29, 21, -13, 4}, +{ /* Row 61 */ +3, -10, 16, -22, 28, -33, 37, -40, 43, -45, 45, -45, 44, -41, 38, -34, +30, -24, 18, -12, 6, 1, -8, 14, -20, 26, -31, 36, -39, 42, -44, 45, +-45, 44, -42, 39, -36, 31, -26, 20, -14, 8, -1, -6, 12, -18, 24, -30, +34, -38, 41, -44, 45, -45, 45, -43, 40, -37, 33, -28, 22, -16, 10, -3}, +{ /* Row 62 */ +2, -7, 11, -15, 19, -23, 27, -30, 34, -36, 39, -41, 43, -44, 45, -45, +45, -45, 44, -43, 41, -39, 36, -34, 30, -27, 23, -19, 15, -11, 7, -2, +-2, 7, -11, 15, -19, 23, -27, 30, -34, 36, -39, 41, -43, 44, -45, 45, +-45, 45, -44, 43, -41, 39, -36, 34, -30, 27, -23, 19, -15, 11, -7, 2}, +{ /* Row 63 */ +1, -3, 6, -8, 10, -12, 14, -16, 18, -20, 22, -24, 26, -28, 30, -31, +33, -34, 36, -37, 38, -39, 40, -41, 42, -43, 44, -44, 45, -45, 45, -45, +45, -45, 45, -45, 44, -44, 43, -42, 41, -40, 39, -38, 37, -36, 34, -33, +31, -30, 28, -26, 24, -22, 20, -18, 16, -14, 12, -10, 8, -6, 3, -1} +}; + +static const uint32_t deblockFactor[13] = +{ 64, 71, 77, 84, 90, 96, 103, 109, 116, 122, 128, 128, 128 }; + + +SEIFilmGrainSynthesizer::SEIFilmGrainSynthesizer() + : m_width(0) + , m_height(0) + , m_chromaFormat(NUM_CHROMA_FORMAT) + , m_bitDepth(0) + , m_idrPicId(0) + , m_enableDeblocking(0) + , m_pGrainSynt(NULL) + , m_poc(0) + , m_errorCode(0) + , m_pFgcParameters(NULL) +{ + +} + +void SEIFilmGrainSynthesizer::create(uint32_t width, uint32_t height, ChromaFormat fmt, + uint8_t bitDepth, uint32_t idrPicId, uint8_t enableDeblocking) +{ + m_width = width; + m_height = height; + m_chromaFormat = fmt; + m_bitDepth = bitDepth; + m_idrPicId = idrPicId; + m_enableDeblocking = enableDeblocking; + m_pGrainSynt = NULL; + m_errorCode = 0; + m_pFgcParameters = NULL; +} + +SEIFilmGrainSynthesizer::~SEIFilmGrainSynthesizer() +{ + +} + +void SEIFilmGrainSynthesizer::fgsInit() +{ + m_pGrainSynt = new GrainSynthesisStruct; + dataBaseGen(); +} + +void SEIFilmGrainSynthesizer::fgsDeinit() +{ + delete m_pGrainSynt; +} + +void SEIFilmGrainSynthesizer::grainSynthesizeAndBlend(TComPicYuv* pGrainBuf, Bool isIdrPic) +{ + uint8_t numComp = MAX_NUM_COMPONENT, compCtr, blkId; /* number of color components */ + uint8_t log2ScaleFactor, h, v; + uint8_t bitDepth; /*grain bit depth and decoded bit depth are assumed to be same */ + uint8_t color_offset[MAX_NUM_COMPONENT]; + uint32_t widthComp[MAX_NUM_COMPONENT], heightComp[MAX_NUM_COMPONENT], strideComp[MAX_NUM_COMPONENT]; + Pel *decSampleBlk16, *decSampleBlk8, *decSampleOffsetY; + Pel *decComp[MAX_NUM_COMPONENT]; + uint16_t numSamples; + int16_t scaleFactor; + uint32_t kOffset, lOffset, grainStripeOffset, grainStripeOffsetBlk8, offsetBlk8x8; + int32_t *grainStripe;/* worth a row of 16x16 : Max size : 16xw;*/ + int32_t yOffset8x8, xOffset8x8; + uint32_t picOffset, x, y, intensityInt; + Pel blockAvg; + uint32_t pseudoRandValEc; /* ec : seed to be used for the psudo random generator for a given color component */ + uint32_t picOrderCntOffset=0; + + /* from SMPTE RDD5 */ + color_offset[0] = COLOUR_OFFSET_LUMA; + color_offset[1] = COLOUR_OFFSET_CR; + color_offset[2] = COLOUR_OFFSET_CB; + + bitDepth = m_bitDepth; + log2ScaleFactor = m_pFgcParameters->m_log2ScaleFactor; + + widthComp[0] = m_width; + widthComp[1] = m_width; + widthComp[2] = m_width; + heightComp[0] = m_height; + heightComp[1] = m_height; + heightComp[2] = m_height; + if (CHROMA_420 == m_chromaFormat) + { + widthComp[1] >>= 1; + widthComp[2] >>= 1; + heightComp[1] >>= 1; + heightComp[2] >>= 1; + } + else if (CHROMA_422 == m_chromaFormat) + { + widthComp[1] >>= 1; + widthComp[2] >>= 1; + } + else if (CHROMA_400 == m_chromaFormat) + { + numComp = 1; + } + + /* component offset positions*/ + decComp[0] = pGrainBuf->getAddr(COMPONENT_Y); + decComp[1] = pGrainBuf->getAddr(COMPONENT_Cb); + decComp[2] = pGrainBuf->getAddr(COMPONENT_Cr); + + /* component strides */ + strideComp[0] = pGrainBuf->getStride(COMPONENT_Y); + strideComp[1] = pGrainBuf->getStride(COMPONENT_Cb); + strideComp[2] = pGrainBuf->getStride(COMPONENT_Cr); + + grainStripe = (int32_t *)malloc(strideComp[0] * BLK_16 * sizeof(int32_t)); + + if (isIdrPic) + { + picOrderCntOffset = m_idrPicId; + } + + if (FGS_SUCCESS == m_errorCode) + { + if (0 == m_pFgcParameters->m_filmGrainCharacteristicsCancelFlag) + { + for (compCtr = 0; compCtr < numComp; compCtr++) + { + if (1 == m_pFgcParameters->m_compModel[compCtr].bPresentFlag) + { + picOffset = (m_poc) + (picOrderCntOffset << 5); + /* Seed initialization for current picture*/ + pseudoRandValEc = seedLUT[((picOffset + color_offset[compCtr]) % 256)]; + + decSampleOffsetY = decComp[compCtr]; + + /* Loop of 16x16 blocks */ + for (y = 0; y < heightComp[compCtr]; y += BLK_16) + { + /* Initialization of grain stripe of 16xwidth size */ + memset(grainStripe, 0, (strideComp[0] * BLK_16 * sizeof(int32_t))); + for (x = 0; x < widthComp[compCtr]; x += BLK_16) + { + /* start position offset of decoded sample in x direction */ + grainStripeOffset = x; + decSampleBlk16 = decSampleOffsetY + x; + + for (blkId = 0; blkId < NUM_8x8_BLKS_16x16; blkId++) + { + yOffset8x8 = (blkId >> 1) * BLK_8; + xOffset8x8 = (blkId & 0x1)* BLK_8; + offsetBlk8x8 = xOffset8x8 + (yOffset8x8 * strideComp[compCtr]); + grainStripeOffsetBlk8 = grainStripeOffset + offsetBlk8x8; + + decSampleBlk8 = decSampleBlk16 + offsetBlk8x8; + blockAvg = blockAverage(decSampleBlk8, strideComp[compCtr], &numSamples, + MIN(BLK_8, (heightComp[compCtr] - y - yOffset8x8)), + MIN(BLK_8, (widthComp[compCtr] - x - xOffset8x8)), + bitDepth); + + /* Handling of non 8x8 blocks along with 8x8 blocks */ + if (numSamples > 0) + { + /* Selection of the component model */ + intensityInt = m_pGrainSynt->intensityInterval[compCtr][blockAvg]; + + if (INTENSITY_INTERVAL_MATCH_FAIL != intensityInt) + { + /* 8x8 grain block offset using co-ordinates of decoded 8x8 block in the frame */ + kOffset = (MSB16(pseudoRandValEc) % 52); + kOffset &= 0xFFFC; + kOffset += (x + xOffset8x8) & 0x0008; + lOffset = (LSB16(pseudoRandValEc) % 56); + lOffset &= 0xFFF8; + lOffset += (y + yOffset8x8) & 0x0008; + scaleFactor = BIT0(pseudoRandValEc) ? -1 : 1; + scaleFactor *= + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityInt].compModelValue[0]; + h = m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityInt].compModelValue[1] - 2; + v = m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityInt].compModelValue[2] - 2; + + /* 8x8 block grain simulation */ + simulateGrainBlk8x8(grainStripe, grainStripeOffsetBlk8, + m_pGrainSynt, strideComp[compCtr], + log2ScaleFactor, scaleFactor, kOffset, lOffset, h, v, MIN(BLK_8, (widthComp[compCtr] - x - xOffset8x8))); + }/* only if average falls in any interval */ + } /* includes corner case handling */ + } /* 8x8 level block processing */ + + /* uppdate the PRNG once per 16x16 block of samples */ + pseudoRandValEc = prng(pseudoRandValEc); + } /* End of 16xwidth grain simulation */ + + /* deblocking at the vertical edges of 8x8 at 16xwidth*/ + if (m_enableDeblocking) + { + deblockGrainStripe(grainStripe, widthComp[compCtr], strideComp[compCtr]); + } + /* Blending of size 16xwidth*/ + blendStripe(decSampleOffsetY, grainStripe, + strideComp[compCtr], MIN(BLK_16, (heightComp[compCtr] - y)), bitDepth); + decSampleOffsetY += MIN(BLK_16, heightComp[compCtr] - y) * strideComp[compCtr]; + + } /* end of component loop */ + } + } + } + } + if (isIdrPic) + { + m_idrPicId++; + } + free(grainStripe); +} + +void SEIFilmGrainSynthesizer::dataBaseGen() +{ + uint32_t pseudoRandValEhv; + uint8_t h, v; /* Horizaontal and vertical cut off frequencies (+2)*/ + uint32_t ScaleCutOffFh, ScaleCutOffFv, l, r, i, j, k; + int32_t B[DATA_BASE_SIZE][DATA_BASE_SIZE], bIDCT[DATA_BASE_SIZE][DATA_BASE_SIZE]; + int32_t bGrain[DATA_BASE_SIZE][DATA_BASE_SIZE]; + int8_t R64_IDCT_TR[DATA_BASE_SIZE][DATA_BASE_SIZE]; /* Transpose of R64_IDCT[64][64]*/ + + for (l = 0; l < DATA_BASE_SIZE; l++) + { + for (k = 0; k < DATA_BASE_SIZE; k++) + { + R64_IDCT_TR[l][k] = R64_IDCT[k][l]; /* Matrix Transpose */ + } + } + + for (h = 0; h < NUM_CUT_OFF_FREQ; h++) + { + for (v = 0; v < NUM_CUT_OFF_FREQ; v++) + { + memset(&B, 0, DATA_BASE_SIZE*DATA_BASE_SIZE * sizeof(int32_t)); + memset(&bIDCT, 0, DATA_BASE_SIZE*DATA_BASE_SIZE * sizeof(int32_t)); + memset(&bGrain, 0, DATA_BASE_SIZE*DATA_BASE_SIZE * sizeof(int32_t)); + ScaleCutOffFh = ((h + 3) << 2) - 1; + ScaleCutOffFv = ((v + 3) << 2) - 1; + + /* ehv : seed to be used for the psudo random generator for a given h and v */ + pseudoRandValEhv = seedLUT[h + v * 13]; + + for (l = 0, r = 0; l <= ScaleCutOffFv; l++) + { + for (k = 0; k <= ScaleCutOffFh; k += 4) + { + B[k][l] = gaussianLUT[pseudoRandValEhv % 2048]; + B[k + 1][l] = gaussianLUT[(pseudoRandValEhv + 1) % 2048]; + B[k + 2][l] = gaussianLUT[(pseudoRandValEhv + 2) % 2048]; + B[k + 3][l] = gaussianLUT[(pseudoRandValEhv + 3) % 2048]; + r++; + pseudoRandValEhv = prng(pseudoRandValEhv); + } + } + B[0][0] = 0; + + for (i = 0; i < DATA_BASE_SIZE; i++) + { + for (j = 0; j < DATA_BASE_SIZE; j++) + { + for (k = 0; k < DATA_BASE_SIZE; k++) + { + bIDCT[i][j] += R64_IDCT_TR[i][k] * B[k][j]; + } + bIDCT[i][j] += 128; + bIDCT[i][j] = bIDCT[i][j] >> 8; + } + } + + for (i = 0; i < DATA_BASE_SIZE; i++) + { + for (j = 0; j < DATA_BASE_SIZE; j++) + { + for (k = 0; k < DATA_BASE_SIZE; k++) + { + bGrain[i][j] += bIDCT[i][k] * R64_IDCT[k][j]; + } + bGrain[i][j] += 128; + bGrain[i][j] = bGrain[i][j] >> 8; + m_pGrainSynt->dataBase[h][v][j][i] = CLIP3(-127, 127, bGrain[i][j]); + } + } + + /* De-blocking at horizontal 8×8 block edges */ + if (m_enableDeblocking) + { + for (l = 0; l < DATA_BASE_SIZE; l += 8) + { + for (k = 0; k < DATA_BASE_SIZE; k++) + { + m_pGrainSynt->dataBase[h][v][l][k] = ((m_pGrainSynt->dataBase[h][v][l][k]) * deblockFactor[v]) >> 7; + m_pGrainSynt->dataBase[h][v][l + 7][k] = ((m_pGrainSynt->dataBase[h][v][l + 7][k]) * deblockFactor[v]) >> 7; + } + } + } + + } + } + return; +} + +/* Function validates film grain parameters and returns 0 for valid parameters of SMPTE-RDD5 else 1*/ +/* Also down converts the chroma model values for 4:2:0 and 4:2:2 chroma_formats */ +uint8_t SEIFilmGrainSynthesizer::grainValidateParams() +{ + uint8_t numComp = MAX_NUM_COMPONENT; /* number of color components */ + uint8_t compCtr, intensityCtr, multiGrainCheck[MAX_NUM_COMPONENT][MAX_NUM_INTENSITIES] = { 0 }; + uint16_t multiGrainCtr; + uint8_t limitCompModelVal1[10] = { 0 }, limitCompModelVal2[10] = { 0 }; + uint8_t num_comp_model_pairs = 0, limitCompModelCtr, compPairMatch; + + memset(m_pGrainSynt->intensityInterval, INTENSITY_INTERVAL_MATCH_FAIL, + sizeof(m_pGrainSynt->intensityInterval)); + + if ((m_width < MIN_WIDTH) || (m_width > MAX_WIDTH) || (m_width % 4)) + { + return FGS_INVALID_WIDTH; /* Width not supported */ + } + if ((m_height < MIN_HEIGHT) || (m_height > MAX_HEIGHT) || (m_height % 4)) + { + return FGS_INVALID_HEIGHT; /* Height not supported */ + } + if ((m_chromaFormat < MIN_CHROMA_FORMAT_IDC) || (m_chromaFormat > MAX_CHROMA_FORMAT_IDC)) + { + return FGS_INVALID_CHROMA_FORMAT; /* Chroma format not supported */ + } + if (m_chromaFormat == MIN_CHROMA_FORMAT_IDC) /* Mono Chrome */ + { + numComp = 1; + } + + if ((m_bitDepth < MIN_BIT_DEPTH) || (m_bitDepth > MAX_BIT_DEPTH)) + { + return FGS_INVALID_BIT_DEPTH; /* Bit depth not supported */ + } + + if ((0 != m_pFgcParameters->m_filmGrainCharacteristicsCancelFlag) && + (1 != m_pFgcParameters->m_filmGrainCharacteristicsCancelFlag)) + { + return FGS_INVALID_FGC_CANCEL_FLAG; /* Film grain synthesis disabled */ + } + + if (FILM_GRAIN_MODEL_ID_VALUE != m_pFgcParameters->m_filmGrainModelId) + { + return FGS_INVALID_GRAIN_MODEL_ID; /* Not supported */ + } + + if (0 != m_pFgcParameters->m_separateColourDescriptionPresentFlag) + { + return FGS_INVALID_SEP_COL_DES_FLAG; /* Not supported */ + } + + if (BLENDING_MODE_VALUE != m_pFgcParameters->m_blendingModeId) + { + return FGS_INVALID_BLEND_MODE; /* Not supported */ + } + + if ((m_pFgcParameters->m_log2ScaleFactor < MIN_LOG2SCALE_VALUE) || + (m_pFgcParameters->m_log2ScaleFactor > MAX_LOG2SCALE_VALUE)) + { + return FGS_INVALID_LOG2_SCALE_FACTOR; /* Not supported */ + } + + /* validation of component model present flag */ + for (compCtr = 0; compCtr < numComp; compCtr++) + { + if ((m_pFgcParameters->m_compModel[compCtr].bPresentFlag != true) && + (m_pFgcParameters->m_compModel[compCtr].bPresentFlag != false)) + { + return FGS_INVALID_COMP_MODEL_PRESENT_FLAG; /* Not supported */ + } + if (m_pFgcParameters->m_compModel[compCtr].bPresentFlag && + (m_pFgcParameters->m_compModel[compCtr].numModelValues > MAX_ALLOWED_MODEL_VALUES)) + { + return FGS_INVALID_NUM_MODEL_VALUES; /* Not supported */ + } + } + + /* validation of intensity intervals and */ + for (compCtr = 0; compCtr < numComp; compCtr++) + { + if (m_pFgcParameters->m_compModel[compCtr].bPresentFlag) + { + for (intensityCtr = 0; intensityCtr < m_pFgcParameters->m_compModel[compCtr].intensityValues.size(); intensityCtr++) + { + + if (m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].intensityIntervalLowerBound > + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].intensityIntervalUpperBound) + { + return FGS_INVALID_INTENSITY_BOUNDARY_VALUES; /* Not supported */ + } + + for (multiGrainCtr = m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].intensityIntervalLowerBound; + multiGrainCtr <= m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].intensityIntervalUpperBound; multiGrainCtr++) + { + m_pGrainSynt->intensityInterval[compCtr][multiGrainCtr] = intensityCtr; + if (multiGrainCheck[compCtr][multiGrainCtr]) /* Non over lap */ + { + return FGS_INVALID_INTENSITY_BOUNDARY_VALUES; /* Not supported */ + } + else + { + multiGrainCheck[compCtr][multiGrainCtr] = 1; + } + } + + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue.resize(MAX_NUM_MODEL_VALUES); + /* default initialization for cut off frequencies */ + if (1 == m_pFgcParameters->m_compModel[compCtr].numModelValues) + { + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[1] = DEFAULT_HORZ_CUT_OFF_FREQUENCY; + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[2] = + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[1]; + } + else if (2 == m_pFgcParameters->m_compModel[compCtr].numModelValues) + { + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[2] = + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[1]; + } + + /* Error check on model component value */ + if (m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[0] > (MAX_STANDARD_DEVIATION << (m_bitDepth - BIT_DEPTH_8))) + { + return FGS_INVALID_STANDARD_DEVIATION; /* Not supported */ + } + else if ((m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[1] < MIN_CUT_OFF_FREQUENCY) || + (m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[1] > MAX_CUT_OFF_FREQUENCY)) + { + return FGS_INVALID_CUT_OFF_FREQUENCIES; /* Not supported */ + } + else if ((m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[2] < MIN_CUT_OFF_FREQUENCY) || + (m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[2] > MAX_CUT_OFF_FREQUENCY)) + { + return FGS_INVALID_CUT_OFF_FREQUENCIES; /* Not supported */ + } + + /* conversion of component model values for 4:2:0 and 4:4:4 */ + if ((CHROMA_444 != m_chromaFormat) && (compCtr > 0)) + { + if (CHROMA_420 == m_chromaFormat) /* 4:2:0 */ + { + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[0] >>= 1; + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[1] = + CLIP3(MIN_CUT_OFF_FREQUENCY, MAX_CUT_OFF_FREQUENCY, + (m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[1] << 1)); + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[2] = + CLIP3(MIN_CUT_OFF_FREQUENCY, MAX_CUT_OFF_FREQUENCY, + (m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[2] << 1)); + + } + else if (CHROMA_422 == m_chromaFormat)/* 4:2:2 */ + { + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[0] = + (m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[0] * SCALE_DOWN_422) >> Q_FORMAT_SCALING; + + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[1] = + CLIP3(MIN_CUT_OFF_FREQUENCY, MAX_CUT_OFF_FREQUENCY, + (m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[1] << 1)); + + } + } + + compPairMatch = 0; + for (limitCompModelCtr = 0; limitCompModelCtr <= num_comp_model_pairs; limitCompModelCtr++) + { + if ((limitCompModelVal1[limitCompModelCtr] == + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[1]) && + (limitCompModelVal2[limitCompModelCtr] == + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[2])) + { + compPairMatch = 1; + } + } + + if (0 == compPairMatch) + { + num_comp_model_pairs++; + /* max allowed pairs are 10 as per SMPTE -RDD5*/ + if (num_comp_model_pairs > MAX_ALLOWED_COMP_MODEL_PAIRS) + { + return FGS_INVALID_NUM_CUT_OFF_FREQ_PAIRS; /* Not supported */ + } + limitCompModelVal1[num_comp_model_pairs - 1] = + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[1]; + limitCompModelVal2[num_comp_model_pairs - 1] = + m_pFgcParameters->m_compModel[compCtr].intensityValues[intensityCtr].compModelValue[2]; + } + } + } + } + + if (0 != m_pFgcParameters->m_filmGrainCharacteristicsPersistenceFlag) + { + return FGS_INVALID_FGC_REPETETION_PERIOD; /* Not supported */ + } + return FGS_SUCCESS; /* Success */ +} + +uint32_t SEIFilmGrainSynthesizer::prng(uint32_t x_r) +{ + uint32_t addVal; + addVal = (1 + ((x_r & (POS_2)) > 0) + ((x_r & (POS_30)) > 0)) % 2; + x_r = (x_r << 1) + addVal; + return x_r; +} + +/* Function to calculate block average for bit depths > 8 */ +Pel SEIFilmGrainSynthesizer::blockAverage(Pel *decSampleBlk8, + uint32_t widthComp, + uint16_t *pNumSamples, + uint8_t ySize, + uint8_t xSize, + uint8_t bitDepth) +{ + uint32_t blockAvg = 0; + uint8_t k, l; + uint16_t numSamples = 0; + + for (k = 0; k < ySize; k++) + { + for (l = 0; l < xSize; l++) + { + blockAvg += *(decSampleBlk8 + l + (k*widthComp)); + numSamples++; + } + } + if (numSamples > 0) + { + blockAvg /= numSamples; + blockAvg >>= (bitDepth - BIT_DEPTH_8); /* to handle high bit depths */ + } + + assert(blockAvg < (1 << BIT_DEPTH_8)); + *pNumSamples = numSamples; + + blockAvg = CLIP3(0, (1 << BIT_DEPTH_8) - 1, blockAvg); + return blockAvg; +} +void SEIFilmGrainSynthesizer::deblockGrainStripe(int32_t *grainStripe, uint32_t widthComp, uint32_t strideComp) +{ + int32_t left1, left0, right0, right1; + uint32_t pos8, vertCtr; + + for (pos8 = 0; pos8 < (widthComp - BLK_8); pos8 += BLK_8) + { + for (vertCtr = 0; vertCtr < BLK_16; vertCtr++) /* Across 16 pels of the vertical boundary*/ + { + left1 = *(grainStripe + pos8 + 6 + (vertCtr*strideComp)); + left0 = *(grainStripe + pos8 + 7 + (vertCtr*strideComp)); + right0 = *(grainStripe + pos8 + BLK_8 + 0 + (vertCtr*strideComp)); + right1 = *(grainStripe + pos8 + BLK_8 + 1 + (vertCtr*strideComp)); + *(grainStripe + pos8 + BLK_8 + 0 + (vertCtr*strideComp)) = (left0 + (right0 << 1) + right1) >> 2; + *(grainStripe + pos8 + 7 + (vertCtr*strideComp)) = (left1 + (left0 << 1) + right0) >> 2; + } + } + return; +} +void SEIFilmGrainSynthesizer::blendStripe(Pel *decSampleOffsetY, int32_t *grainStripe, + uint32_t widthComp, uint32_t blockHeight, uint8_t bitDepth) +{ + uint32_t k, l; + int32_t grainSample; + Pel decodeSample; + uint16_t maxRange; + maxRange = (1 << bitDepth) - 1; + for (l = 0; l < blockHeight; l++) /* y direction */ + { + for (k = 0; k < widthComp; k++) /* x direction */ + { + decodeSample = *(decSampleOffsetY + k + (l*widthComp)); + grainSample = *(grainStripe + k + (l*widthComp)); + grainSample <<= (bitDepth - BIT_DEPTH_8); + grainSample = CLIP3(0, maxRange, grainSample + decodeSample); + *(decSampleOffsetY + k + (l*widthComp)) = (Pel)grainSample; + } + } + return; +} + + +void SEIFilmGrainSynthesizer::simulateGrainBlk8x8(int32_t *grainStripe, uint32_t grainStripeOffsetBlk8, + GrainSynthesisStruct *pGrainSynt, uint32_t width, uint8_t log2ScaleFactor, + int16_t scaleFactor, uint32_t kOffset, uint32_t lOffset, + uint8_t h, uint8_t v, uint32_t xSize) +{ + uint32_t k, l; + for (l = 0; l < BLK_8; l++) /* y direction */ + { + for (k = 0; k < xSize; k++) /* x direction */ + { + *(grainStripe + grainStripeOffsetBlk8 + k + (l*width)) = + ((scaleFactor * + pGrainSynt->dataBase[h][v][l + lOffset][k + kOffset]) >> (log2ScaleFactor + GRAIN_SCALE)); + } + } + return; +} + +#endif \ No newline at end of file diff --git a/source/Lib/TLibCommon/SEIFilmGrainSynthesizer.h b/source/Lib/TLibCommon/SEIFilmGrainSynthesizer.h new file mode 100644 index 000000000..0d45971e0 --- /dev/null +++ b/source/Lib/TLibCommon/SEIFilmGrainSynthesizer.h @@ -0,0 +1,210 @@ +/* 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(); + + void fgsInit(); + void fgsDeinit(); + void grainSynthesizeAndBlend(TComPicYuv* pGrainBuf, Bool isIdrPic); + uint8_t grainValidateParams(); + +private: + void dataBaseGen(); + uint32_t prng(uint32_t x_r); + Pel blockAverage(Pel *decSampleBlk8, + uint32_t widthComp, + uint16_t *pNumSamples, + uint8_t ySize, + uint8_t xSize, + uint8_t bitDepth); + void deblockGrainStripe(int32_t *grainStripe, uint32_t widthComp, uint32_t strideComp); + void blendStripe(Pel *decSampleOffsetY, int32_t *grainStripe, + uint32_t widthComp, uint32_t blockHeight, uint8_t bitDepth); + void simulateGrainBlk8x8(int32_t *grainStripe, uint32_t grainStripeOffsetBlk8, + GrainSynthesisStruct *pGrainSynt, uint32_t width, uint8_t log2ScaleFactor, + int16_t scaleFactor, uint32_t kOffset, uint32_t lOffset, + uint8_t h, uint8_t v, uint32_t xSize); + +};// END CLASS DEFINITION SEIFilmGrainSynthesizer + +#endif \ No newline at end of file diff --git a/source/Lib/TLibCommon/TComPic.cpp b/source/Lib/TLibCommon/TComPic.cpp index 099750428..91a76e2b4 100644 --- a/source/Lib/TLibCommon/TComPic.cpp +++ b/source/Lib/TLibCommon/TComPic.cpp @@ -60,6 +60,10 @@ TComPic::TComPic() { m_apcPicYuv[i] = NULL; } +#if FGS_RDD5_ENABLE + m_grainCharacteristic = NULL; + m_grainBuf = NULL; +#endif } TComPic::~TComPic() @@ -201,6 +205,9 @@ Void TComPic::destroy() } deleteSEIs(m_SEIs); +#if FGS_RDD5_ENABLE + m_grainBuf = NULL; +#endif } Void TComPic::compressMotion() @@ -257,5 +264,64 @@ UInt TComPic::getSubstreamForCtuAddr(const UInt ctuAddr, const Bool bAddressInRa return subStrm; } +#if FGS_RDD5_ENABLE +// initialization of RDD5 based film grain syntheis buffers and parameters +void TComPic::createGrainSynthesizer(Bool bFirstPictureInSequence, SEIFilmGrainSynthesizer* pGrainCharacteristics, TComPicYuv* pGrainBuf, const TComSPS* sps) +{ + m_grainCharacteristic = pGrainCharacteristics; + m_grainBuf = pGrainBuf; + + if (bFirstPictureInSequence) + { + // Create and initialize the Film Grain Synthesizer + m_grainCharacteristic->create(sps->getPicWidthInLumaSamples(), sps->getPicHeightInLumaSamples(), + sps->getChromaFormatIdc(), sps->getBitDepth(CHANNEL_TYPE_LUMA), 0, 1); + + //Frame level TComPicYuv buffer created to blend Film Grain Noise into it + m_grainBuf->createWithoutCUInfo(sps->getPicWidthInLumaSamples(), sps->getPicHeightInLumaSamples(), + sps->getChromaFormatIdc(), false, 0, 0); + + m_grainCharacteristic->fgsInit(); + } +} + +TComPicYuv* TComPic::getPicYuvDisp() +{ + int payloadType = 0; + std::list<SEI*>::iterator message; + + m_grainCharacteristic->m_errorCode = -1; + for (message = m_SEIs.begin(); message != m_SEIs.end(); ++message) + { + payloadType = (*message)->payloadType(); + if (payloadType == SEI::FILM_GRAIN_CHARACTERISTICS) + { + m_grainCharacteristic->m_pFgcParameters = static_cast<SEIFilmGrainCharacteristics*>(*message); + /* Validation of Film grain characteristic parameters for the constrains of SMPTE-RDD5*/ + m_grainCharacteristic->m_errorCode = m_grainCharacteristic->grainValidateParams(); + break; + } + } + + if (FGS_SUCCESS == m_grainCharacteristic->m_errorCode) + { + m_apcPicYuv[PIC_YUV_REC]->copyToPic(m_grainBuf); + m_grainCharacteristic->m_poc = getPOC(); + m_grainCharacteristic->grainSynthesizeAndBlend(m_grainBuf, getSlice(0)->getIdrPicFlag()); + return m_grainBuf; + } + else + { + if (payloadType == SEI::FILM_GRAIN_CHARACTERISTICS) + { + fprintf(stdout, "Film Grain synthesis is not performed. Error code: 0x%x \n", m_grainCharacteristic->m_errorCode); + } + return m_apcPicYuv[PIC_YUV_REC]; + } + +} + +#endif + //! \} diff --git a/source/Lib/TLibCommon/TComPic.h b/source/Lib/TLibCommon/TComPic.h index 39857cf55..75e3aa62e 100644 --- a/source/Lib/TLibCommon/TComPic.h +++ b/source/Lib/TLibCommon/TComPic.h @@ -43,6 +43,9 @@ #include "TComPicSym.h" #include "TComPicYuv.h" #include "TComBitStream.h" +#if FGS_RDD5_ENABLE +#include "SEIFilmGrainSynthesizer.h" +#endif //! \ingroup TLibCommon //! \{ @@ -119,6 +122,13 @@ public: TComPicYuv* getPicYuvOrg() { return m_apcPicYuv[PIC_YUV_ORG]; } TComPicYuv* getPicYuvRec() { return m_apcPicYuv[PIC_YUV_REC]; } +#if FGS_RDD5_ENABLE + void createGrainSynthesizer(bool bFirstPictureInSequence, SEIFilmGrainSynthesizer* pGrainCharacteristics, TComPicYuv* pGrainBuf, const TComSPS* sps); + SEIFilmGrainSynthesizer *m_grainCharacteristic; + TComPicYuv *m_grainBuf; + TComPicYuv* getPicYuvDisp(); +#endif + TComPicYuv* getPicYuvPred() { return m_pcPicYuvPred; } TComPicYuv* getPicYuvResi() { return m_pcPicYuvResi; } Void setPicYuvPred( TComPicYuv* pcPicYuv ) { m_pcPicYuvPred = pcPicYuv; } diff --git a/source/Lib/TLibCommon/TypeDef.h b/source/Lib/TLibCommon/TypeDef.h index d9a86d5cd..ab40fdc76 100644 --- a/source/Lib/TLibCommon/TypeDef.h +++ b/source/Lib/TLibCommon/TypeDef.h @@ -91,6 +91,7 @@ #define SHUTTER_INTERVAL_SEI_MESSAGE 1 ///< support for shutter interval SEI message #define SEI_ENCODER_CONTROL 1 ///< add encoder control for the following SEI: film grain characteristics, content light level, ambient viewing environment #define DPB_ENCODER_USAGE_CHECK 1 ///< Adds DPB encoder usage check. +#define FGS_RDD5_ENABLE 1 // SMPTE RDD5 based film grain synthesis enabled // ==================================================================================================================== // Tool Switches diff --git a/source/Lib/TLibDecoder/TDecTop.cpp b/source/Lib/TLibDecoder/TDecTop.cpp index 725e2add4..6776d0974 100644 --- a/source/Lib/TLibDecoder/TDecTop.cpp +++ b/source/Lib/TLibDecoder/TDecTop.cpp @@ -67,6 +67,11 @@ TDecTop::TDecTop() , m_prevPOC(MAX_INT) , m_prevTid0POC(0) , m_bFirstSliceInPicture(true) +#if FGS_RDD5_ENABLE + , m_bFirstPictureInSequence(true) + , m_grainCharacteristic() + , m_grainBuf() +#endif , m_bFirstSliceInSequence(true) , m_prevSliceSkipped(false) , m_skippedPOC(0) @@ -346,7 +351,11 @@ Void TDecTop::xActivateParameterSets() // Get a new picture buffer. This will also set up m_pcPic, and therefore give us a SPS and PPS pointer that we can use. xGetNewPicBuffer (*(sps), *(pps), m_pcPic, m_apcSlicePilot->getTLayer()); m_apcSlicePilot->applyReferencePictureSet(m_cListPic, m_apcSlicePilot->getRPS()); - +#if FGS_RDD5_ENABLE + // Initialization of film grain synthesizer + m_pcPic->createGrainSynthesizer(m_bFirstPictureInSequence, &m_grainCharacteristic, &m_grainBuf, sps); + m_bFirstPictureInSequence = false; +#endif // make the slice-pilot a real slice, and set up the slice-pilot for the next slice assert(m_pcPic->getNumAllocatedSlice() == (m_uiSliceIdx + 1)); m_apcSlicePilot = m_pcPic->getPicSym()->swapSliceObject(m_apcSlicePilot, m_uiSliceIdx); diff --git a/source/Lib/TLibDecoder/TDecTop.h b/source/Lib/TLibDecoder/TDecTop.h index db5fed53c..688af5d7c 100644 --- a/source/Lib/TLibDecoder/TDecTop.h +++ b/source/Lib/TLibDecoder/TDecTop.h @@ -100,6 +100,11 @@ private: Int m_prevPOC; Int m_prevTid0POC; Bool m_bFirstSliceInPicture; +#if FGS_RDD5_ENABLE + Bool m_bFirstPictureInSequence; + SEIFilmGrainSynthesizer m_grainCharacteristic; + TComPicYuv m_grainBuf; +#endif Bool m_bFirstSliceInSequence; Bool m_prevSliceSkipped; Int m_skippedPOC; diff --git a/source/Lib/TLibEncoder/SEIEncoder.cpp b/source/Lib/TLibEncoder/SEIEncoder.cpp index f64315243..32a799087 100644 --- a/source/Lib/TLibEncoder/SEIEncoder.cpp +++ b/source/Lib/TLibEncoder/SEIEncoder.cpp @@ -590,6 +590,23 @@ Void SEIEncoder::initSEIFilmGrainCharacteristics(SEIFilmGrainCharacteristics *se for (int i = 0; i < MAX_NUM_COMPONENT; i++) { seiFilmGrain->m_compModel[i].bPresentFlag = m_pcCfg->getFGCSEICompModelPresent(i); +#if FGS_RDD5_ENABLE + if (seiFilmGrain->m_compModel[i].bPresentFlag) + { + seiFilmGrain->m_compModel[i].numModelValues = 1 + m_pcCfg->getFGCSEINumModelValuesMinus1(i); + seiFilmGrain->m_compModel[i].intensityValues.resize(1 + m_pcCfg->getFGCSEINumIntensityIntervalMinus1(i)); + for (int j = 0; j <= m_pcCfg->getFGCSEINumIntensityIntervalMinus1(i); j++) + { + seiFilmGrain->m_compModel[i].intensityValues[j].intensityIntervalLowerBound = m_pcCfg->getFGCSEIIntensityIntervalLowerBound(i, j); + seiFilmGrain->m_compModel[i].intensityValues[j].intensityIntervalUpperBound = m_pcCfg->getFGCSEIIntensityIntervalUpperBound(i, j); + seiFilmGrain->m_compModel[i].intensityValues[j].compModelValue.resize(seiFilmGrain->m_compModel[i].numModelValues); + for (int k = 0; k < seiFilmGrain->m_compModel[i].numModelValues; k++) + { + seiFilmGrain->m_compModel[i].intensityValues[j].compModelValue[k] = m_pcCfg->getFGCSEICompModelValue(i, j, k); + } + } + } +#endif } } diff --git a/source/Lib/TLibEncoder/TEncCfg.h b/source/Lib/TLibEncoder/TEncCfg.h index 3f3ee966f..9d6aaf99d 100644 --- a/source/Lib/TLibEncoder/TEncCfg.h +++ b/source/Lib/TLibEncoder/TEncCfg.h @@ -447,6 +447,13 @@ protected: UChar m_fgcSEIBlendingModeID; UChar m_fgcSEILog2ScaleFactor; Bool m_fgcSEICompModelPresent[MAX_NUM_COMPONENT]; +#if FGS_RDD5_ENABLE + UChar m_fgcSEINumIntensityIntervalMinus1[MAX_NUM_COMPONENT]; + UChar m_fgcSEINumModelValuesMinus1[MAX_NUM_COMPONENT]; + UChar m_fgcSEIIntensityIntervalLowerBound[MAX_NUM_COMPONENT][MAX_NUM_INTENSITIES]; + UChar 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; UShort m_cllSEIMaxContentLevel; @@ -1017,6 +1024,18 @@ public: UChar getFilmGrainCharactersticsSEILog2ScaleFactor() { return m_fgcSEILog2ScaleFactor; } Void setFGCSEICompModelPresent(Bool b, Int index) { m_fgcSEICompModelPresent[index] = b; } Bool getFGCSEICompModelPresent(Int index) { return m_fgcSEICompModelPresent[index]; } +#if FGS_RDD5_ENABLE + void setFGCSEINumIntensityIntervalMinus1(UChar v, Int index) { m_fgcSEINumIntensityIntervalMinus1[index] = v; } + UChar getFGCSEINumIntensityIntervalMinus1(Int index) { return m_fgcSEINumIntensityIntervalMinus1[index]; } + void setFGCSEINumModelValuesMinus1(UChar v, Int index) { m_fgcSEINumModelValuesMinus1[index] = v; } + UChar getFGCSEINumModelValuesMinus1(Int index) { return m_fgcSEINumModelValuesMinus1[index]; } + void setFGCSEIIntensityIntervalLowerBound(UChar v, Int index, Int ctr) { m_fgcSEIIntensityIntervalLowerBound[index][ctr] = v; } + UChar getFGCSEIIntensityIntervalLowerBound(Int index, Int ctr) { return m_fgcSEIIntensityIntervalLowerBound[index][ctr]; } + void setFGCSEIIntensityIntervalUpperBound(UChar v, Int index, Int ctr) { m_fgcSEIIntensityIntervalUpperBound[index][ctr] = v; } + UChar getFGCSEIIntensityIntervalUpperBound(Int index, Int ctr) { return m_fgcSEIIntensityIntervalUpperBound[index][ctr]; } + void setFGCSEICompModelValue(UInt v, Int index, Int ctr, Int modelCtr) { m_fgcSEICompModelValue[index][ctr][modelCtr] = v; } + UInt getFGCSEICompModelValue(Int index, Int ctr, Int modelCtr) { return m_fgcSEICompModelValue[index][ctr][modelCtr]; } +#endif // cll SEI Void setCLLSEIEnabled(Bool b) { m_cllSEIEnabled = b; } Bool getCLLSEIEnabled() { return m_cllSEIEnabled; } diff --git a/source/Lib/TLibEncoder/TEncGOP.cpp b/source/Lib/TLibEncoder/TEncGOP.cpp index b7ea75daa..137a9ba8e 100644 --- a/source/Lib/TLibEncoder/TEncGOP.cpp +++ b/source/Lib/TLibEncoder/TEncGOP.cpp @@ -499,13 +499,15 @@ Void TEncGOP::xCreateIRAPLeadingSEIMessages (SEIMessages& seiMessages, const TCo #endif #if SEI_ENCODER_CONTROL -// film grain +#if !FGS_RDD5_ENABLE + // film grain if (m_pcCfg->getFilmGrainCharactersticsSEIEnabled()) { SEIFilmGrainCharacteristics *seiFGC = new SEIFilmGrainCharacteristics; m_seiEncoder.initSEIFilmGrainCharacteristics(seiFGC); seiMessages.push_back(seiFGC); } +#endif // content light level if (m_pcCfg->getCLLSEIEnabled()) { @@ -682,6 +684,15 @@ Void TEncGOP::xCreatePerPictureSEIMessages (Int picInGOP, SEIMessages& seiMessag delete seiRegionalNesting; } } +#if FGS_RDD5_ENABLE + // Film Grain Characteristics SEI insertion at at frame level + if (m_pcCfg->getFilmGrainCharactersticsSEIEnabled()) + { + SEIFilmGrainCharacteristics *fgcSEI = new SEIFilmGrainCharacteristics; + m_seiEncoder.initSEIFilmGrainCharacteristics(fgcSEI); + seiMessages.push_back(fgcSEI); + } +#endif } Void TEncGOP::xCreateScalableNestingSEI (SEIMessages& seiMessages, SEIMessages& nestedSeiMessages) -- GitLab From 2b3ea39fe75b92db5c86fb488db02cb3ce679294 Mon Sep 17 00:00:00 2001 From: Taoran Lu <tlu@dolby.com> Date: Thu, 30 Apr 2020 11:15:42 -0700 Subject: [PATCH 2/5] fix pipeline warning --- source/Lib/TLibCommon/SEIFilmGrainSynthesizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Lib/TLibCommon/SEIFilmGrainSynthesizer.cpp b/source/Lib/TLibCommon/SEIFilmGrainSynthesizer.cpp index 35608b970..d9c084aad 100644 --- a/source/Lib/TLibCommon/SEIFilmGrainSynthesizer.cpp +++ b/source/Lib/TLibCommon/SEIFilmGrainSynthesizer.cpp @@ -835,7 +835,7 @@ void SEIFilmGrainSynthesizer::dataBaseGen() uint8_t SEIFilmGrainSynthesizer::grainValidateParams() { uint8_t numComp = MAX_NUM_COMPONENT; /* number of color components */ - uint8_t compCtr, intensityCtr, multiGrainCheck[MAX_NUM_COMPONENT][MAX_NUM_INTENSITIES] = { 0 }; + uint8_t compCtr, intensityCtr, multiGrainCheck[MAX_NUM_COMPONENT][MAX_NUM_INTENSITIES] = {{ 0 }}; uint16_t multiGrainCtr; uint8_t limitCompModelVal1[10] = { 0 }, limitCompModelVal2[10] = { 0 }; uint8_t num_comp_model_pairs = 0, limitCompModelCtr, compPairMatch; -- GitLab From 2128e2d7e77b0c22c23fc2d4b9f920dc09688780 Mon Sep 17 00:00:00 2001 From: Taoran Lu <tlu@dolby.com> Date: Tue, 5 May 2020 14:35:59 -0700 Subject: [PATCH 3/5] address comments --- source/App/TAppEncoder/TAppEncCfg.cpp | 86 ++++++++++----------------- 1 file changed, 32 insertions(+), 54 deletions(-) diff --git a/source/App/TAppEncoder/TAppEncCfg.cpp b/source/App/TAppEncoder/TAppEncCfg.cpp index bc7cf9302..4e22d1d2d 100644 --- a/source/App/TAppEncoder/TAppEncCfg.cpp +++ b/source/App/TAppEncoder/TAppEncCfg.cpp @@ -729,15 +729,18 @@ Bool TAppEncCfg::parseCfg( Int argc, TChar* argv[] ) 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_FgcSEIIntensityIntervalLowerBoundComp0(0, 255, 0, 256); - SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalLowerBoundComp1(0, 255, 0, 256); - SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalLowerBoundComp2(0, 255, 0, 256); - SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalUpperBoundComp0(0, 255, 0, 256); - SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalUpperBoundComp1(0, 255, 0, 256); - SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalUpperBoundComp2(0, 255, 0, 256); - SMultiValueInput<UInt> cfg_FgcSEICompModelValueComp0(0, 65535, 0, 256 * 6); - SMultiValueInput<UInt> cfg_FgcSEICompModelValueComp1(0, 65535, 0, 256 * 6); - SMultiValueInput<UInt> cfg_FgcSEICompModelValueComp2(0, 65535, 0, 256 * 6); + //SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalLowerBoundComp0(0, 255, 0, 256); + //SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalLowerBoundComp1(0, 255, 0, 256); + //SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalLowerBoundComp2(0, 255, 0, 256); + //SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalUpperBoundComp0(0, 255, 0, 256); + //SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalUpperBoundComp1(0, 255, 0, 256); + //SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalUpperBoundComp2(0, 255, 0, 256); + //SMultiValueInput<UInt> cfg_FgcSEICompModelValueComp0(0, 65535, 0, 256 * 6); + //SMultiValueInput<UInt> cfg_FgcSEICompModelValueComp1(0, 65535, 0, 256 * 6); + //SMultiValueInput<UInt> cfg_FgcSEICompModelValueComp2(0, 65535, 0, 256 * 6); + 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); @@ -1234,15 +1237,15 @@ Bool TAppEncCfg::parseCfg( Int argc, TChar* argv[] ) ("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_FgcSEIIntensityIntervalLowerBoundComp0, cfg_FgcSEIIntensityIntervalLowerBoundComp0, "Specifies the lower bound for the intensity intervals on colour component 0.") - ("SEIFGCIntensityIntervalLowerBoundComp1", cfg_FgcSEIIntensityIntervalLowerBoundComp1, cfg_FgcSEIIntensityIntervalLowerBoundComp1, "Specifies the lower bound for the intensity intervals on colour component 1.") - ("SEIFGCIntensityIntervalLowerBoundComp2", cfg_FgcSEIIntensityIntervalLowerBoundComp2, cfg_FgcSEIIntensityIntervalLowerBoundComp2, "Specifies the lower bound for the intensity intervals on colour component 2.") - ("SEIFGCIntensityIntervalUpperBoundComp0", cfg_FgcSEIIntensityIntervalUpperBoundComp0, cfg_FgcSEIIntensityIntervalUpperBoundComp0, "Specifies the upper bound for the intensity intervals on colour component 0.") - ("SEIFGCIntensityIntervalUpperBoundComp1", cfg_FgcSEIIntensityIntervalUpperBoundComp1, cfg_FgcSEIIntensityIntervalUpperBoundComp1, "Specifies the upper bound for the intensity intervals on colour component 1.") - ("SEIFGCIntensityIntervalUpperBoundComp2", cfg_FgcSEIIntensityIntervalUpperBoundComp2, cfg_FgcSEIIntensityIntervalUpperBoundComp2, "Specifies the upper bound for the intensity intervals on colour component 2.") - ("SEIFGCCompModelValuesComp0", cfg_FgcSEICompModelValueComp0, cfg_FgcSEICompModelValueComp0, "Specifies the component model values on colour component 0.") - ("SEIFGCCompModelValuesComp1", cfg_FgcSEICompModelValueComp1, cfg_FgcSEICompModelValueComp1, "Specifies the component model values on colour component 1.") - ("SEIFGCCompModelValuesComp2", cfg_FgcSEICompModelValueComp2, cfg_FgcSEICompModelValueComp2, "Specifies the component model values 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") @@ -2079,45 +2082,20 @@ Bool TAppEncCfg::parseCfg( Int argc, TChar* argv[] ) if (m_fgcSEIEnabled) { UInt numModelCtr; - if (m_fgcSEICompModelPresent[0]) + for (int c = 0; c <= 2; c++ ) { - numModelCtr = 0; - for (UChar i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[0]; i++) + if (m_fgcSEICompModelPresent[c]) { - m_fgcSEIIntensityIntervalLowerBound[0][i] = UChar((cfg_FgcSEIIntensityIntervalLowerBoundComp0.values.size() > i) ? cfg_FgcSEIIntensityIntervalLowerBoundComp0.values[i] : 0); - m_fgcSEIIntensityIntervalUpperBound[0][i] = UChar((cfg_FgcSEIIntensityIntervalUpperBoundComp0.values.size() > i) ? cfg_FgcSEIIntensityIntervalUpperBoundComp0.values[i] : 0); - for (UChar j = 0; j <= m_fgcSEINumModelValuesMinus1[0]; j++) + numModelCtr = 0; + for (int i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[c]; i++) { - m_fgcSEICompModelValue[0][i][j] = UInt((cfg_FgcSEICompModelValueComp0.values.size() > numModelCtr) ? cfg_FgcSEICompModelValueComp0.values[numModelCtr] : 0); - numModelCtr++; - } - } - } - if (m_fgcSEICompModelPresent[1]) - { - numModelCtr = 0; - for (UChar i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[1]; i++) - { - m_fgcSEIIntensityIntervalLowerBound[1][i] = UChar((cfg_FgcSEIIntensityIntervalLowerBoundComp1.values.size() > i) ? cfg_FgcSEIIntensityIntervalLowerBoundComp1.values[i] : 0); - m_fgcSEIIntensityIntervalUpperBound[1][i] = UChar((cfg_FgcSEIIntensityIntervalUpperBoundComp1.values.size() > i) ? cfg_FgcSEIIntensityIntervalUpperBoundComp1.values[i] : 0); - for (UChar j = 0; j <= m_fgcSEINumModelValuesMinus1[1]; j++) - { - m_fgcSEICompModelValue[1][i][j] = UInt((cfg_FgcSEICompModelValueComp1.values.size() > numModelCtr) ? cfg_FgcSEICompModelValueComp1.values[numModelCtr] : 0); - numModelCtr++; - } - } - } - if (m_fgcSEICompModelPresent[2]) - { - numModelCtr = 0; - for (UChar i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[2]; i++) - { - m_fgcSEIIntensityIntervalLowerBound[2][i] = UChar((cfg_FgcSEIIntensityIntervalLowerBoundComp2.values.size() > i) ? cfg_FgcSEIIntensityIntervalLowerBoundComp2.values[i] : 0); - m_fgcSEIIntensityIntervalUpperBound[2][i] = UChar((cfg_FgcSEIIntensityIntervalUpperBoundComp2.values.size() > i) ? cfg_FgcSEIIntensityIntervalUpperBoundComp2.values[i] : 0); - for (UChar j = 0; j <= m_fgcSEINumModelValuesMinus1[2]; j++) - { - m_fgcSEICompModelValue[2][i][j] = UInt((cfg_FgcSEICompModelValueComp2.values.size() > numModelCtr) ? cfg_FgcSEICompModelValueComp2.values[numModelCtr] : 0); - numModelCtr++; + 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 (int 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++; + } } } } -- GitLab From c714bfa75744c1efe490135f0500b2b392397cdb Mon Sep 17 00:00:00 2001 From: Taoran Lu <tlu@dolby.com> Date: Tue, 5 May 2020 14:36:28 -0700 Subject: [PATCH 4/5] address comments --- source/App/TAppEncoder/TAppEncCfg.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/source/App/TAppEncoder/TAppEncCfg.cpp b/source/App/TAppEncoder/TAppEncCfg.cpp index 4e22d1d2d..881b4cc73 100644 --- a/source/App/TAppEncoder/TAppEncCfg.cpp +++ b/source/App/TAppEncoder/TAppEncCfg.cpp @@ -729,15 +729,6 @@ Bool TAppEncCfg::parseCfg( Int argc, TChar* argv[] ) 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_FgcSEIIntensityIntervalLowerBoundComp0(0, 255, 0, 256); - //SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalLowerBoundComp1(0, 255, 0, 256); - //SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalLowerBoundComp2(0, 255, 0, 256); - //SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalUpperBoundComp0(0, 255, 0, 256); - //SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalUpperBoundComp1(0, 255, 0, 256); - //SMultiValueInput<UInt> cfg_FgcSEIIntensityIntervalUpperBoundComp2(0, 255, 0, 256); - //SMultiValueInput<UInt> cfg_FgcSEICompModelValueComp0(0, 65535, 0, 256 * 6); - //SMultiValueInput<UInt> cfg_FgcSEICompModelValueComp1(0, 65535, 0, 256 * 6); - //SMultiValueInput<UInt> cfg_FgcSEICompModelValueComp2(0, 65535, 0, 256 * 6); 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)}; -- GitLab From 19cc9bd906aa1ee799fabca68dee599d7d5afdb9 Mon Sep 17 00:00:00 2001 From: Taoran Lu <tlu@dolby.com> Date: Wed, 6 May 2020 10:31:33 -0700 Subject: [PATCH 5/5] HM style variable type --- source/App/TAppEncoder/TAppEncCfg.cpp | 6 +++--- source/App/TAppEncoder/TAppEncTop.cpp | 4 ++-- source/Lib/TLibCommon/TComPic.cpp | 2 +- source/Lib/TLibCommon/TComPic.h | 2 +- source/Lib/TLibEncoder/SEIEncoder.cpp | 4 ++-- source/Lib/TLibEncoder/TEncCfg.h | 10 +++++----- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/source/App/TAppEncoder/TAppEncCfg.cpp b/source/App/TAppEncoder/TAppEncCfg.cpp index 881b4cc73..8edaf2db8 100644 --- a/source/App/TAppEncoder/TAppEncCfg.cpp +++ b/source/App/TAppEncoder/TAppEncCfg.cpp @@ -2073,16 +2073,16 @@ Bool TAppEncCfg::parseCfg( Int argc, TChar* argv[] ) if (m_fgcSEIEnabled) { UInt numModelCtr; - for (int c = 0; c <= 2; c++ ) + for (UInt c = 0; c <= 2; c++ ) { if (m_fgcSEICompModelPresent[c]) { numModelCtr = 0; - for (int i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[c]; i++) + 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 (int j = 0; j <= m_fgcSEINumModelValuesMinus1[c]; j++) + 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++; diff --git a/source/App/TAppEncoder/TAppEncTop.cpp b/source/App/TAppEncoder/TAppEncTop.cpp index cc9e3a9da..c4616bfee 100644 --- a/source/App/TAppEncoder/TAppEncTop.cpp +++ b/source/App/TAppEncoder/TAppEncTop.cpp @@ -437,10 +437,10 @@ Void TAppEncTop::xInitLibCfg() if (m_fgcSEICompModelPresent[i]) { m_cTEncTop.setFGCSEINumIntensityIntervalMinus1((UChar)m_fgcSEINumIntensityIntervalMinus1[i], i); m_cTEncTop.setFGCSEINumModelValuesMinus1((UChar)m_fgcSEINumModelValuesMinus1[i], i); - for (int j = 0; j <= m_fgcSEINumIntensityIntervalMinus1[i]; j++) { + 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 (int k = 0; k <= m_fgcSEINumModelValuesMinus1[i]; k++) { + for (UInt k = 0; k <= m_fgcSEINumModelValuesMinus1[i]; k++) { m_cTEncTop.setFGCSEICompModelValue(m_fgcSEICompModelValue[i][j][k], i, j, k); } } diff --git a/source/Lib/TLibCommon/TComPic.cpp b/source/Lib/TLibCommon/TComPic.cpp index 91a76e2b4..3c8a425bb 100644 --- a/source/Lib/TLibCommon/TComPic.cpp +++ b/source/Lib/TLibCommon/TComPic.cpp @@ -287,7 +287,7 @@ void TComPic::createGrainSynthesizer(Bool bFirstPictureInSequence, SEIFilmGrainS TComPicYuv* TComPic::getPicYuvDisp() { - int payloadType = 0; + Int payloadType = 0; std::list<SEI*>::iterator message; m_grainCharacteristic->m_errorCode = -1; diff --git a/source/Lib/TLibCommon/TComPic.h b/source/Lib/TLibCommon/TComPic.h index 75e3aa62e..6991e43f8 100644 --- a/source/Lib/TLibCommon/TComPic.h +++ b/source/Lib/TLibCommon/TComPic.h @@ -123,7 +123,7 @@ public: TComPicYuv* getPicYuvRec() { return m_apcPicYuv[PIC_YUV_REC]; } #if FGS_RDD5_ENABLE - void createGrainSynthesizer(bool bFirstPictureInSequence, SEIFilmGrainSynthesizer* pGrainCharacteristics, TComPicYuv* pGrainBuf, const TComSPS* sps); + Void createGrainSynthesizer(Bool bFirstPictureInSequence, SEIFilmGrainSynthesizer* pGrainCharacteristics, TComPicYuv* pGrainBuf, const TComSPS* sps); SEIFilmGrainSynthesizer *m_grainCharacteristic; TComPicYuv *m_grainBuf; TComPicYuv* getPicYuvDisp(); diff --git a/source/Lib/TLibEncoder/SEIEncoder.cpp b/source/Lib/TLibEncoder/SEIEncoder.cpp index 32a799087..fa369fb85 100644 --- a/source/Lib/TLibEncoder/SEIEncoder.cpp +++ b/source/Lib/TLibEncoder/SEIEncoder.cpp @@ -595,12 +595,12 @@ Void SEIEncoder::initSEIFilmGrainCharacteristics(SEIFilmGrainCharacteristics *se { seiFilmGrain->m_compModel[i].numModelValues = 1 + m_pcCfg->getFGCSEINumModelValuesMinus1(i); seiFilmGrain->m_compModel[i].intensityValues.resize(1 + m_pcCfg->getFGCSEINumIntensityIntervalMinus1(i)); - for (int j = 0; j <= m_pcCfg->getFGCSEINumIntensityIntervalMinus1(i); j++) + for (UInt j = 0; j <= m_pcCfg->getFGCSEINumIntensityIntervalMinus1(i); j++) { seiFilmGrain->m_compModel[i].intensityValues[j].intensityIntervalLowerBound = m_pcCfg->getFGCSEIIntensityIntervalLowerBound(i, j); seiFilmGrain->m_compModel[i].intensityValues[j].intensityIntervalUpperBound = m_pcCfg->getFGCSEIIntensityIntervalUpperBound(i, j); seiFilmGrain->m_compModel[i].intensityValues[j].compModelValue.resize(seiFilmGrain->m_compModel[i].numModelValues); - for (int k = 0; k < seiFilmGrain->m_compModel[i].numModelValues; k++) + for (UInt k = 0; k < seiFilmGrain->m_compModel[i].numModelValues; k++) { seiFilmGrain->m_compModel[i].intensityValues[j].compModelValue[k] = m_pcCfg->getFGCSEICompModelValue(i, j, k); } diff --git a/source/Lib/TLibEncoder/TEncCfg.h b/source/Lib/TLibEncoder/TEncCfg.h index 9d6aaf99d..8620b3607 100644 --- a/source/Lib/TLibEncoder/TEncCfg.h +++ b/source/Lib/TLibEncoder/TEncCfg.h @@ -1025,15 +1025,15 @@ public: Void setFGCSEICompModelPresent(Bool b, Int index) { m_fgcSEICompModelPresent[index] = b; } Bool getFGCSEICompModelPresent(Int index) { return m_fgcSEICompModelPresent[index]; } #if FGS_RDD5_ENABLE - void setFGCSEINumIntensityIntervalMinus1(UChar v, Int index) { m_fgcSEINumIntensityIntervalMinus1[index] = v; } + Void setFGCSEINumIntensityIntervalMinus1(UChar v, Int index) { m_fgcSEINumIntensityIntervalMinus1[index] = v; } UChar getFGCSEINumIntensityIntervalMinus1(Int index) { return m_fgcSEINumIntensityIntervalMinus1[index]; } - void setFGCSEINumModelValuesMinus1(UChar v, Int index) { m_fgcSEINumModelValuesMinus1[index] = v; } + Void setFGCSEINumModelValuesMinus1(UChar v, Int index) { m_fgcSEINumModelValuesMinus1[index] = v; } UChar getFGCSEINumModelValuesMinus1(Int index) { return m_fgcSEINumModelValuesMinus1[index]; } - void setFGCSEIIntensityIntervalLowerBound(UChar v, Int index, Int ctr) { m_fgcSEIIntensityIntervalLowerBound[index][ctr] = v; } + Void setFGCSEIIntensityIntervalLowerBound(UChar v, Int index, Int ctr) { m_fgcSEIIntensityIntervalLowerBound[index][ctr] = v; } UChar getFGCSEIIntensityIntervalLowerBound(Int index, Int ctr) { return m_fgcSEIIntensityIntervalLowerBound[index][ctr]; } - void setFGCSEIIntensityIntervalUpperBound(UChar v, Int index, Int ctr) { m_fgcSEIIntensityIntervalUpperBound[index][ctr] = v; } + Void setFGCSEIIntensityIntervalUpperBound(UChar v, Int index, Int ctr) { m_fgcSEIIntensityIntervalUpperBound[index][ctr] = v; } UChar getFGCSEIIntensityIntervalUpperBound(Int index, Int ctr) { return m_fgcSEIIntensityIntervalUpperBound[index][ctr]; } - void setFGCSEICompModelValue(UInt v, Int index, Int ctr, Int modelCtr) { m_fgcSEICompModelValue[index][ctr][modelCtr] = v; } + Void setFGCSEICompModelValue(UInt v, Int index, Int ctr, Int modelCtr) { m_fgcSEICompModelValue[index][ctr][modelCtr] = v; } UInt getFGCSEICompModelValue(Int index, Int ctr, Int modelCtr) { return m_fgcSEICompModelValue[index][ctr][modelCtr]; } #endif // cll SEI -- GitLab