Changeset 1360 in 3DVCSoftware for branches/HTM-15.2-dev/source/App/TAppDecoder


Ignore:
Timestamp:
28 Oct 2015, 17:46:00 (9 years ago)
Author:
tech
Message:

Update to HM-16.7.

Location:
branches/HTM-15.2-dev/source/App/TAppDecoder
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/HTM-15.2-dev/source/App/TAppDecoder/TAppDecCfg.cpp

    r1356 r1360  
    6262    \param argv array of arguments
    6363 */
    64 Bool TAppDecCfg::parseCfg( Int argc, Char* argv[] )
     64Bool TAppDecCfg::parseCfg( Int argc, TChar* argv[] )
    6565{
    6666  Bool do_help = false;
    67   string cfg_BitstreamFile;
    68   string cfg_ReconFile;
    6967  string cfg_TargetDecLayerIdSetFile;
    7068#if NH_3D
     
    7977
    8078  ("help",                      do_help,                               false,      "this help text")
    81   ("BitstreamFile,b",           cfg_BitstreamFile,                     string(""), "bitstream input file name")
    82   ("ReconFile,o",               cfg_ReconFile,                         string(""), "reconstructed YUV output file name\n"
     79  ("BitstreamFile,b",           m_bitstreamFileName,                   string(""), "bitstream input file name")
     80  ("ReconFile,o",               m_reconFileName,                       string(""), "reconstructed YUV output file name\n"
    8381                                                                                   "YUV writing is skipped if omitted")
    8482#if NH_3D
     
    106104  ("PrintNalus,n",              m_printReceivedNalus,                 false,        "Print information on received NAL units")
    107105#endif
     106  ("SEIColourRemappingInfoFilename",  m_colourRemapSEIFileName,        string(""), "Colour Remapping YUV output file name. If empty, no remapping is applied (ignore SEI message)\n")
     107
    108108#if O0043_BEST_EFFORT_DECODING
    109109  ("ForceDecodeBitDepth",       m_forceDecodeBitDepth,                 0U,         "Force the decoder to operate at a particular bit-depth (best effort decoding)")
     
    119119  po::setDefaults(opts);
    120120  po::ErrorReporter err;
    121   const list<const Char*>& argv_unhandled = po::scanArgv(opts, argc, (const Char**) argv, err);
    122 
    123   for (list<const Char*>::const_iterator it = argv_unhandled.begin(); it != argv_unhandled.end(); it++)
     121  const list<const TChar*>& argv_unhandled = po::scanArgv(opts, argc, (const TChar**) argv, err);
     122
     123  for (list<const TChar*>::const_iterator it = argv_unhandled.begin(); it != argv_unhandled.end(); it++)
    124124  {
    125125    fprintf(stderr, "Unhandled argument ignored: `%s'\n", *it);
     
    148148  }
    149149
    150   /* convert std::string to c string for compatability */
    151   m_pchBitstreamFile = cfg_BitstreamFile.empty() ? NULL : strdup(cfg_BitstreamFile.c_str());
    152   m_pchReconFile = cfg_ReconFile.empty() ? NULL : strdup(cfg_ReconFile.c_str());
    153 
    154 #if NH_3D
    155   m_pchScaleOffsetFile = cfg_ScaleOffsetFile.empty() ? NULL : strdup(cfg_ScaleOffsetFile.c_str());
    156 #endif
    157 
    158   if (!m_pchBitstreamFile)
     150  if (m_bitstreamFileName.empty())
    159151  {
    160152    fprintf(stderr, "No input file specified, aborting\n");
     
    217209
    218210#if NH_MV
    219 Void TAppDecCfg::xAppendToFileNameEnd( Char* pchInputFileName, const Char* pchStringToAppend, Char*& rpchOutputFileName)
     211Void TAppDecCfg::xAppendToFileNameEnd( const TChar* pchInputFileName, const TChar* pchStringToAppend, TChar*& rpchOutputFileName)
    220212{
    221213  size_t iInLength     = strlen(pchInputFileName);
    222214  size_t iAppendLength = strlen(pchStringToAppend);
    223215
    224   rpchOutputFileName = (Char*) malloc(iInLength+iAppendLength+1);                       
    225   Char* pCDot = strrchr(pchInputFileName,'.');         
     216  rpchOutputFileName = (TChar*) malloc(iInLength+iAppendLength+1);                       
     217  const TChar* pCDot = strrchr(pchInputFileName,'.');         
    226218  pCDot = pCDot ? pCDot : pchInputFileName + iInLength;       
    227219  size_t iCharsToDot = pCDot - pchInputFileName ;
  • branches/HTM-15.2-dev/source/App/TAppDecoder/TAppDecCfg.h

    r1356 r1360  
    6060{
    6161protected:
    62   Char*         m_pchBitstreamFile;                     ///< input bitstream file name
    63   Char*         m_pchReconFile;                         ///< output reconstruction file name
     62  std::string   m_bitstreamFileName;                    ///< input bitstream file name
     63  std::string   m_reconFileName;                        ///< output reconstruction file name
    6464  Int           m_iSkipFrame;                           ///< counter for frames prior to the random access point to skip
    6565  Int           m_outputBitDepth[MAX_NUM_CHANNEL_TYPE]; ///< bit depth used for writing output
     
    6969  Int           m_decodedPictureHashSEIEnabled;       ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message
    7070  Bool          m_decodedNoDisplaySEIEnabled;         ///< Enable(true)/disable(false) writing only pictures that get displayed based on the no display SEI message
     71  std::string   m_colourRemapSEIFileName;             ///< output Colour Remapping file name
    7172  std::vector<Int> m_targetDecLayerIdSet;             ///< set of LayerIds to be included in the sub-bitstream extraction process.
    7273
     
    7879  Bool          m_bClipOutputVideoToRec709Range;      ///< If true, clip the output video to the Rec 709 range on saving.
    7980#if NH_MV
    80   std::vector<Char*> m_pchReconFiles;                   ///< array of output reconstruction file name create from output reconstruction file name
     81  std::vector<TChar*> m_pchReconFiles;                ///< array of output reconstruction file name create from output reconstruction file name
    8182
    82   Int           m_targetOptLayerSetIdx;                 ///< target output layer set index
     83  Int           m_targetOptLayerSetIdx;               ///< target output layer set index
    8384  Int           m_targetDecLayerSetIdx;
    8485  Int           m_baseLayerOutputFlag;
    8586  Int           m_baseLayerPicOutputFlag;
    8687  Int           m_auOutputFlag;
    87   Int           m_maxLayerId;                           ///< maximum nuh_layer_id decoded
     88  Int           m_maxLayerId;                         ///< maximum nuh_layer_id decoded
    8889  std::ifstream m_bitstreamFile;
    8990  Int           m_highestTid;
    9091  Bool          m_targetDecLayerIdSetFileEmpty;       ///< indication if target layers are given by file
    9192
    92   Bool          m_printVpsInfo;                      ///< Output VPS information
     93  Bool          m_printVpsInfo;                       ///< Output VPS information
    9394  Bool          m_printPicOutput;                     ///< Print information on picture output
    9495  Bool          m_printReceivedNalus;                 ///< Print information on received NAL units
    9596#if NH_3D
    96   Char*         m_pchScaleOffsetFile;                   ///< output coded scale and offset parameters
     97  TChar*        m_pchScaleOffsetFile;                   ///< output coded scale and offset parameters
    9798  Bool          m_depth420OutputFlag;                   ///< output depth layers in 4:2:0
    9899#endif
    99100
    100   Void xAppendToFileNameEnd( Char* pchInputFileName, const Char* pchStringToAppend, Char*& rpchOutputFileName); ///< create filenames
     101  Void xAppendToFileNameEnd( const TChar* pchInputFileName, const TChar* pchStringToAppend, TChar*& rpchOutputFileName); ///< create filenames
    101102#endif
    102103
    103104public:
    104105  TAppDecCfg()
    105   : m_pchBitstreamFile(NULL)
    106   , m_pchReconFile(NULL)
     106  : m_bitstreamFileName()
     107  , m_reconFileName()
    107108  , m_iSkipFrame(0)
     109  // m_outputBitDepth array initialised below
    108110  , m_outputColourSpaceConvert(IPCOLOURSPACE_UNCHANGED)
    109111  , m_iMaxTemporalLayer(-1)
    110112  , m_decodedPictureHashSEIEnabled(0)
    111113  , m_decodedNoDisplaySEIEnabled(false)
     114  , m_colourRemapSEIFileName()
     115  , m_targetDecLayerIdSet()
    112116  , m_respectDefDispWindow(0)
    113117#if O0043_BEST_EFFORT_DECODING
    114118  , m_forceDecodeBitDepth(0)
    115119#endif
     120  , m_outputDecodedSEIMessagesFilename()
     121  , m_bClipOutputVideoToRec709Range(false)
    116122#if NH_MV
    117123  , m_highestTid(-1)
     
    131137  virtual ~TAppDecCfg() {}
    132138
    133   Bool  parseCfg        ( Int argc, Char* argv[] );   ///< initialize option class from configuration
     139  Bool  parseCfg        ( Int argc, TChar* argv[] );   ///< initialize option class from configuration
    134140};
    135141
  • branches/HTM-15.2-dev/source/App/TAppDecoder/TAppDecTop.cpp

    r1321 r1360  
    6262: m_numDecoders( 0 )
    6363#endif
     64 ,m_pcSeiColourRemappingInfoPrevious(NULL)
    6465{
    6566#if NH_MV
     
    118119  xDestroyDecLib();
    119120#endif
    120 
    121   if (m_pchBitstreamFile)
    122   {
    123     free (m_pchBitstreamFile);
    124     m_pchBitstreamFile = NULL;
    125   }
     121  m_bitstreamFileName.clear();
    126122#if NH_MV
    127123  for (Int decIdx = 0; decIdx < m_numDecoders; decIdx++)
     
    134130  }
    135131#endif
    136   if (m_pchReconFile)
    137   {
    138     free (m_pchReconFile);
    139     m_pchReconFile = NULL;
    140   }
     132  m_reconFileName.clear();
    141133#if NH_3D
    142134  if (m_pchScaleOffsetFile)
     
    226218  TComList<TComPic*>* pcListPic = NULL;
    227219
    228   ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary);
     220  ifstream bitstreamFile(m_bitstreamFileName.c_str(), ifstream::in | ifstream::binary);
    229221  if (!bitstreamFile)
    230222  {
    231     fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_pchBitstreamFile);
     223    fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_bitstreamFileName.c_str());
    232224    exit(EXIT_FAILURE);
    233225  }
     
    250242
    251243  m_iPOCLastDisplay += m_iSkipFrame;      // set the last displayed POC correctly for skip forward.
     244
     245  // clear contents of colour-remap-information-SEI output file
     246  if (!m_colourRemapSEIFileName.empty())
     247  {
     248    std::ofstream ofile(m_colourRemapSEIFileName.c_str());
     249    if (!ofile.good() || !ofile.is_open())
     250    {
     251      fprintf(stderr, "\nUnable to open file '%s' for writing colour-remap-information-SEI video\n", m_colourRemapSEIFileName.c_str());
     252      exit(EXIT_FAILURE);
     253    }
     254  }
    252255
    253256  // main decoder loop
     
    336339    if( pcListPic )
    337340    {
    338       if ( m_pchReconFile && !openedReconFile )
     341      if ( (!m_reconFileName.empty()) && (!openedReconFile) )
    339342      {
    340343        const BitDepths &bitDepths=pcListPic->front()->getPicSym()->getSPS().getBitDepths(); // use bit depths of first reconstructed picture.
     
    346349          }
    347350        }
    348         m_cTVideoIOYuvReconFile.open( m_pchReconFile, true, m_outputBitDepth, m_outputBitDepth, bitDepths.recon ); // write mode
     351
     352        m_cTVideoIOYuvReconFile.open( m_reconFileName, true, m_outputBitDepth, m_outputBitDepth, bitDepths.recon ); // write mode
    349353        openedReconFile = true;
    350354      }
     
    436440  }
    437441#else
    438   if ( m_pchReconFile )
     442  if ( !m_reconFileName.empty() )
    439443  {
    440444    m_cTVideoIOYuvReconFile. close();
     
    444448  m_cTDecTop.destroy();
    445449#endif
     450  if (m_pcSeiColourRemappingInfoPrevious != NULL)
     451  {
     452    delete m_pcSeiColourRemappingInfoPrevious;
     453    m_pcSeiColourRemappingInfoPrevious = NULL;
     454  }
    446455#if NH_3D
    447456  m_cCamParsCollector.uninit();
     
    474483  }
    475484#endif
     485  if (m_pcSeiColourRemappingInfoPrevious != NULL)
     486  {
     487    delete m_pcSeiColourRemappingInfoPrevious;
     488    m_pcSeiColourRemappingInfoPrevious = NULL;
     489  }
    476490}
    477491
     
    549563        // write to file
    550564        numPicsNotYetDisplayed = numPicsNotYetDisplayed-2;
    551         if ( m_pchReconFile )
     565        if ( !m_reconFileName.empty() )
    552566        {
    553567          const Window &conf = pcPicTop->getConformanceWindow();
     
    617631          dpbFullness--;
    618632        }
    619         if ( m_pchReconFile )
     633        if ( !m_reconFileName.empty() )
    620634        {
    621635          const Window &conf    = pcPic->getConformanceWindow();
     
    631645        }
    632646
     647        if (!m_colourRemapSEIFileName.empty())
     648        {
     649          xOutputColourRemapPic(pcPic);
     650        }
     651
    633652        // update POC of display order
    634653        m_iPOCLastDisplay = pcPic->getPOC();
     
    678697        // write to file
    679698
    680         if ( m_pchReconFile )
     699        if ( !m_reconFileName.empty() )
    681700        {
    682701          const Window &conf = pcPicTop->getConformanceWindow();
     
    736755      {
    737756        // write to file
    738         if ( m_pchReconFile )
     757        if ( !m_reconFileName.empty() )
    739758        {
    740759          const Window &conf    = pcPic->getConformanceWindow();
     
    747766                                         conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(),
    748767                                         NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range );
     768        }
     769
     770        if (!m_colourRemapSEIFileName.empty())
     771        {
     772          xOutputColourRemapPic(pcPic);
    749773        }
    750774
     
    26712695
    26722696    // create recon file related stuff
    2673     Char* pchTempFilename = NULL;
    2674     if ( m_pchReconFile )
    2675     {
    2676       Char buffer[4];
     2697    TChar* pchTempFilename = NULL;
     2698    if ( !m_reconFileName.empty() )
     2699    {
     2700      TChar buffer[4];
    26772701      sprintf(buffer,"_%i", layerId );
    2678       assert ( m_pchReconFile );
    2679       xAppendToFileNameEnd( m_pchReconFile , buffer, pchTempFilename );
     2702      assert ( !m_reconFileName.empty() );
     2703      xAppendToFileNameEnd( m_reconFileName.c_str() , buffer, pchTempFilename );
    26802704      assert( m_pchReconFiles.size() == m_numDecoders );
    26812705    }
     
    28702894Void TAppDecTop::xInitFileIO()
    28712895{
    2872   m_bitstreamFile.open(m_pchBitstreamFile, ifstream::in | ifstream::binary);
     2896  m_bitstreamFile.open(m_bitstreamFileName.c_str(), ifstream::in | ifstream::binary);
    28732897
    28742898  if ( !m_bitstreamFile)
    28752899  {
    2876     fprintf(stderr, "\nUnable to open bitstream file `%s' for reading\n", m_pchBitstreamFile);
     2900    fprintf(stderr, "\nUnable to open bitstream file `%s' for reading\n", m_bitstreamFileName.c_str());
    28772901    exit(EXIT_FAILURE);
    28782902  }
     
    29052929  Int decIdx = xGetDecoderIdx( curPic->getLayerId() );
    29062930
    2907   if ( m_pchReconFile && !m_reconOpen[decIdx] )
     2931  if ( !m_reconFileName.empty() && !m_reconOpen[decIdx] )
    29082932  {
    29092933    const BitDepths &bitDepths= curPic->getPicSym()->getSPS().getBitDepths(); // use bit depths of first reconstructed picture.
     
    30073031
    30083032#endif
     3033
     3034Void TAppDecTop::xOutputColourRemapPic(TComPic* pcPic)
     3035{
     3036  const TComSPS &sps=pcPic->getPicSym()->getSPS();
     3037  SEIMessages colourRemappingInfo = getSeisByType(pcPic->getSEIs(), SEI::COLOUR_REMAPPING_INFO );
     3038  SEIColourRemappingInfo *seiColourRemappingInfo = ( colourRemappingInfo.size() > 0 ) ? (SEIColourRemappingInfo*) *(colourRemappingInfo.begin()) : NULL;
     3039
     3040  if (colourRemappingInfo.size() > 1)
     3041  {
     3042    printf ("Warning: Got multiple Colour Remapping Information SEI messages. Using first.");
     3043  }
     3044  if (seiColourRemappingInfo)
     3045  {
     3046    applyColourRemapping(*pcPic->getPicYuvRec(), *seiColourRemappingInfo, sps);
     3047
     3048    // save the last CRI SEI received
     3049    if (m_pcSeiColourRemappingInfoPrevious == NULL)
     3050    {
     3051      m_pcSeiColourRemappingInfoPrevious = new SEIColourRemappingInfo();
     3052    }
     3053    m_pcSeiColourRemappingInfoPrevious->copyFrom(*seiColourRemappingInfo);
     3054  }
     3055  else  // using the last CRI SEI received
     3056  {
     3057    // TODO: prevent persistence of CRI SEI across C(L)VS.
     3058    if (m_pcSeiColourRemappingInfoPrevious != NULL)
     3059    {
     3060      if (m_pcSeiColourRemappingInfoPrevious->m_colourRemapPersistenceFlag == false)
     3061      {
     3062        printf("Warning No SEI-CRI message is present for the current picture, persistence of the CRI is not managed\n");
     3063      }
     3064      applyColourRemapping(*pcPic->getPicYuvRec(), *m_pcSeiColourRemappingInfoPrevious, sps);
     3065    }
     3066  }
     3067}
     3068
     3069// compute lut from SEI
     3070// use at lutPoints points aligned on a power of 2 value
     3071// SEI Lut must be in ascending values of coded Values
     3072static std::vector<Int>
     3073initColourRemappingInfoLut(const Int                                          bitDepth_in,     // bit-depth of the input values of the LUT
     3074                           const Int                                          nbDecimalValues, // Position of the fixed point
     3075                           const std::vector<SEIColourRemappingInfo::CRIlut> &lut,
     3076                           const Int                                          maxValue, // maximum output value
     3077                           const Int                                          lutOffset)
     3078{
     3079  const Int lutPoints = (1 << bitDepth_in) + 1 ;
     3080  std::vector<Int> retLut(lutPoints);
     3081
     3082  // missing values: need to define default values before first definition (check codedValue[0] == 0)
     3083  Int iTargetPrev = (lut.size() && lut[0].codedValue == 0) ? lut[0].targetValue: 0;
     3084  Int startPivot = (lut.size())? ((lut[0].codedValue == 0)? 1: 0): 1;
     3085  Int iCodedPrev  = 0;
     3086  // set max value with the coded bit-depth
     3087  // + ((1 << nbDecimalValues) - 1) is for the added bits
     3088  const Int maxValueFixedPoint = (maxValue << nbDecimalValues) + ((1 << nbDecimalValues) - 1);
     3089
     3090  Int iValue = 0;
     3091
     3092  for ( Int iPivot=startPivot ; iPivot < (Int)lut.size(); iPivot++ )
     3093  {
     3094    Int iCodedNext  = lut[iPivot].codedValue;
     3095    Int iTargetNext = lut[iPivot].targetValue;
     3096
     3097    // ensure correct bit depth and avoid overflow in lut address
     3098    Int iCodedNext_bitDepth = std::min(iCodedNext, (1 << bitDepth_in));
     3099
     3100    const Int divValue =  (iCodedNext - iCodedPrev > 0)? (iCodedNext - iCodedPrev): 1;
     3101    const Int lutValInit = (lutOffset + iTargetPrev) << nbDecimalValues;
     3102    const Int roundValue = divValue / 2;
     3103    for ( ; iValue<iCodedNext_bitDepth; iValue++ )
     3104    {
     3105      Int value = iValue;
     3106      Int interpol = ((((value-iCodedPrev) * (iTargetNext - iTargetPrev)) << nbDecimalValues) + roundValue) / divValue;               
     3107      retLut[iValue]  = std::min(lutValInit + interpol , maxValueFixedPoint);
     3108    }
     3109    iCodedPrev  = iCodedNext;
     3110    iTargetPrev = iTargetNext;
     3111  }
     3112  // fill missing values if necessary
     3113  if(iCodedPrev < (1 << bitDepth_in)+1)
     3114  {
     3115    Int iCodedNext  = (1 << bitDepth_in);
     3116    Int iTargetNext = (1 << bitDepth_in) - 1;
     3117
     3118    const Int divValue =  (iCodedNext - iCodedPrev > 0)? (iCodedNext - iCodedPrev): 1;
     3119    const Int lutValInit = (lutOffset + iTargetPrev) << nbDecimalValues;
     3120    const Int roundValue = divValue / 2;
     3121
     3122    for ( ; iValue<=iCodedNext; iValue++ )
     3123    {
     3124      Int value = iValue;
     3125      Int interpol = ((((value-iCodedPrev) * (iTargetNext - iTargetPrev)) << nbDecimalValues) + roundValue) / divValue;
     3126      retLut[iValue]  = std::min(lutValInit + interpol , maxValueFixedPoint);
     3127    }
     3128  }
     3129  return retLut;
     3130}
     3131
     3132static Void
     3133initColourRemappingInfoLuts(std::vector<Int>      (&preLut)[3],
     3134                            std::vector<Int>      (&postLut)[3],
     3135                            SEIColourRemappingInfo &pCriSEI,
     3136                            const Int               maxBitDepth)
     3137{
     3138  Int internalBitDepth = pCriSEI.m_colourRemapBitDepth;
     3139  for ( Int c=0 ; c<3 ; c++ )
     3140  {
     3141    std::sort(pCriSEI.m_preLut[c].begin(), pCriSEI.m_preLut[c].end()); // ensure preLut is ordered in ascending values of codedValues   
     3142    preLut[c] = initColourRemappingInfoLut(pCriSEI.m_colourRemapInputBitDepth, maxBitDepth - pCriSEI.m_colourRemapInputBitDepth, pCriSEI.m_preLut[c], ((1 << internalBitDepth) - 1), 0); //Fill preLut
     3143
     3144    std::sort(pCriSEI.m_postLut[c].begin(), pCriSEI.m_postLut[c].end()); // ensure postLut is ordered in ascending values of codedValues       
     3145    postLut[c] = initColourRemappingInfoLut(pCriSEI.m_colourRemapBitDepth, maxBitDepth - pCriSEI.m_colourRemapBitDepth, pCriSEI.m_postLut[c], (1 << internalBitDepth) - 1, 0); //Fill postLut
     3146  }
     3147}
     3148
     3149// apply lut.
     3150// Input lut values are aligned on power of 2 boundaries
     3151static Int
     3152applyColourRemappingInfoLut1D(Int inVal, const std::vector<Int> &lut, const Int inValPrecisionBits)
     3153{
     3154  const Int roundValue = (inValPrecisionBits)? 1 << (inValPrecisionBits - 1): 0;
     3155  inVal = std::min(std::max(0, inVal), (Int)(((lut.size()-1) << inValPrecisionBits)));
     3156  Int index  = (Int) std::min((inVal >> inValPrecisionBits), (Int)(lut.size()-2));
     3157  Int outVal = (( inVal - (index<<inValPrecisionBits) ) * (lut[index+1] - lut[index]) + roundValue) >> inValPrecisionBits;
     3158  outVal +=  lut[index] ;
     3159
     3160  return outVal;
     3161
     3162
     3163static Int
     3164applyColourRemappingInfoMatrix(const Int (&colourRemapCoeffs)[3], const Int postOffsetShift, const Int p0, const Int p1, const Int p2, const Int offset)
     3165{
     3166  Int YUVMat = (colourRemapCoeffs[0]* p0 + colourRemapCoeffs[1]* p1 + colourRemapCoeffs[2]* p2  + offset) >> postOffsetShift;
     3167  return YUVMat;
     3168}
     3169
     3170static Void
     3171setColourRemappingInfoMatrixOffset(Int (&matrixOffset)[3], Int offset0, Int offset1, Int offset2)
     3172{
     3173  matrixOffset[0] = offset0;
     3174  matrixOffset[1] = offset1;
     3175  matrixOffset[2] = offset2;
     3176}
     3177
     3178static Void
     3179setColourRemappingInfoMatrixOffsets(      Int  (&matrixInputOffset)[3],
     3180                                          Int  (&matrixOutputOffset)[3],
     3181                                    const Int  bitDepth,
     3182                                    const Bool crInputFullRangeFlag,
     3183                                    const Int  crInputMatrixCoefficients,
     3184                                    const Bool crFullRangeFlag,
     3185                                    const Int  crMatrixCoefficients)
     3186{
     3187  // set static matrix offsets
     3188  Int crInputOffsetLuma = (crInputFullRangeFlag)? 0:-(16 << (bitDepth-8));
     3189  Int crOffsetLuma = (crFullRangeFlag)? 0:(16 << (bitDepth-8));
     3190  Int crInputOffsetChroma = 0;
     3191  Int crOffsetChroma = 0;
     3192
     3193  switch(crInputMatrixCoefficients)
     3194  {
     3195    case MATRIX_COEFFICIENTS_RGB:
     3196      crInputOffsetChroma = 0;
     3197      if(!crInputFullRangeFlag)
     3198      {
     3199        fprintf(stderr, "WARNING: crInputMatrixCoefficients set to MATRIX_COEFFICIENTS_RGB and crInputFullRangeFlag not set\n");
     3200        crInputOffsetLuma = 0;
     3201      }
     3202      break;
     3203    case MATRIX_COEFFICIENTS_UNSPECIFIED:
     3204    case MATRIX_COEFFICIENTS_BT709:
     3205    case MATRIX_COEFFICIENTS_BT2020_NON_CONSTANT_LUMINANCE:
     3206      crInputOffsetChroma = -(1 << (bitDepth-1));
     3207      break;
     3208    default:
     3209      fprintf(stderr, "WARNING: crInputMatrixCoefficients set to undefined value: %d\n", crInputMatrixCoefficients);
     3210  }
     3211
     3212  switch(crMatrixCoefficients)
     3213  {
     3214    case MATRIX_COEFFICIENTS_RGB:
     3215      crOffsetChroma = 0;
     3216      if(!crFullRangeFlag)
     3217      {
     3218        fprintf(stderr, "WARNING: crMatrixCoefficients set to MATRIX_COEFFICIENTS_RGB and crInputFullRangeFlag not set\n");
     3219        crOffsetLuma = 0;
     3220      }
     3221      break;
     3222    case MATRIX_COEFFICIENTS_UNSPECIFIED:
     3223    case MATRIX_COEFFICIENTS_BT709:
     3224    case MATRIX_COEFFICIENTS_BT2020_NON_CONSTANT_LUMINANCE:
     3225      crOffsetChroma = (1 << (bitDepth-1));
     3226      break;
     3227    default:
     3228      fprintf(stderr, "WARNING: crMatrixCoefficients set to undefined value: %d\n", crMatrixCoefficients);
     3229  }
     3230
     3231  setColourRemappingInfoMatrixOffset(matrixInputOffset, crInputOffsetLuma, crInputOffsetChroma, crInputOffsetChroma);
     3232  setColourRemappingInfoMatrixOffset(matrixOutputOffset, crOffsetLuma, crOffsetChroma, crOffsetChroma);
     3233}
     3234
     3235Void TAppDecTop::applyColourRemapping(const TComPicYuv& pic, SEIColourRemappingInfo& criSEI, const TComSPS &activeSPS)
     3236
     3237  const Int maxBitDepth = 16;
     3238
     3239  // create colour remapped picture
     3240  if( !criSEI.m_colourRemapCancelFlag && pic.getChromaFormat()!=CHROMA_400) // 4:0:0 not supported.
     3241  {
     3242    const Int          iHeight         = pic.getHeight(COMPONENT_Y);
     3243    const Int          iWidth          = pic.getWidth(COMPONENT_Y);
     3244    const ChromaFormat chromaFormatIDC = pic.getChromaFormat();
     3245
     3246    TComPicYuv picYuvColourRemapped;
     3247    picYuvColourRemapped.createWithoutCUInfo( iWidth, iHeight, chromaFormatIDC );
     3248
     3249    const Int  iStrideIn   = pic.getStride(COMPONENT_Y);
     3250    const Int  iCStrideIn  = pic.getStride(COMPONENT_Cb);
     3251    const Int  iStrideOut  = picYuvColourRemapped.getStride(COMPONENT_Y);
     3252    const Int  iCStrideOut = picYuvColourRemapped.getStride(COMPONENT_Cb);
     3253    const Bool b444        = ( pic.getChromaFormat() == CHROMA_444 );
     3254    const Bool b422        = ( pic.getChromaFormat() == CHROMA_422 );
     3255    const Bool b420        = ( pic.getChromaFormat() == CHROMA_420 );
     3256
     3257    std::vector<Int> preLut[3];
     3258    std::vector<Int> postLut[3];
     3259    Int matrixInputOffset[3];
     3260    Int matrixOutputOffset[3];
     3261    const Pel *YUVIn[MAX_NUM_COMPONENT];
     3262    Pel *YUVOut[MAX_NUM_COMPONENT];
     3263    YUVIn[COMPONENT_Y]  = pic.getAddr(COMPONENT_Y);
     3264    YUVIn[COMPONENT_Cb] = pic.getAddr(COMPONENT_Cb);
     3265    YUVIn[COMPONENT_Cr] = pic.getAddr(COMPONENT_Cr);
     3266    YUVOut[COMPONENT_Y]  = picYuvColourRemapped.getAddr(COMPONENT_Y);
     3267    YUVOut[COMPONENT_Cb] = picYuvColourRemapped.getAddr(COMPONENT_Cb);
     3268    YUVOut[COMPONENT_Cr] = picYuvColourRemapped.getAddr(COMPONENT_Cr);
     3269
     3270    const Int bitDepth = criSEI.m_colourRemapBitDepth;
     3271    BitDepths        bitDepthsCriFile;
     3272    bitDepthsCriFile.recon[CHANNEL_TYPE_LUMA]   = bitDepth;
     3273    bitDepthsCriFile.recon[CHANNEL_TYPE_CHROMA] = bitDepth; // Different bitdepth is not implemented
     3274
     3275    const Int postOffsetShift = criSEI.m_log2MatrixDenom;
     3276    const Int matrixRound = 1 << (postOffsetShift - 1);
     3277    const Int postLutInputPrecision = (maxBitDepth - criSEI.m_colourRemapBitDepth);
     3278
     3279    if ( ! criSEI.m_colourRemapVideoSignalInfoPresentFlag ) // setting default
     3280    {
     3281      setColourRemappingInfoMatrixOffsets(matrixInputOffset, matrixOutputOffset, maxBitDepth,
     3282          activeSPS.getVuiParameters()->getVideoFullRangeFlag(), activeSPS.getVuiParameters()->getMatrixCoefficients(),
     3283          activeSPS.getVuiParameters()->getVideoFullRangeFlag(), activeSPS.getVuiParameters()->getMatrixCoefficients());
     3284    }
     3285    else
     3286    {
     3287      setColourRemappingInfoMatrixOffsets(matrixInputOffset, matrixOutputOffset, maxBitDepth,
     3288          activeSPS.getVuiParameters()->getVideoFullRangeFlag(), activeSPS.getVuiParameters()->getMatrixCoefficients(),
     3289          criSEI.m_colourRemapFullRangeFlag, criSEI.m_colourRemapMatrixCoefficients);
     3290    }
     3291
     3292    // add matrix rounding to output matrix offsets
     3293    matrixOutputOffset[0] = (matrixOutputOffset[0] << postOffsetShift) + matrixRound;
     3294    matrixOutputOffset[1] = (matrixOutputOffset[1] << postOffsetShift) + matrixRound;
     3295    matrixOutputOffset[2] = (matrixOutputOffset[2] << postOffsetShift) + matrixRound;
     3296
     3297    // Merge   matrixInputOffset and matrixOutputOffset to matrixOutputOffset
     3298    matrixOutputOffset[0] += applyColourRemappingInfoMatrix(criSEI.m_colourRemapCoeffs[0], 0, matrixInputOffset[0], matrixInputOffset[1], matrixInputOffset[2], 0);
     3299    matrixOutputOffset[1] += applyColourRemappingInfoMatrix(criSEI.m_colourRemapCoeffs[1], 0, matrixInputOffset[0], matrixInputOffset[1], matrixInputOffset[2], 0);
     3300    matrixOutputOffset[2] += applyColourRemappingInfoMatrix(criSEI.m_colourRemapCoeffs[2], 0, matrixInputOffset[0], matrixInputOffset[1], matrixInputOffset[2], 0);
     3301
     3302    // rescaling output: include CRI/output frame difference
     3303    const Int scaleShiftOut_neg = abs(bitDepth - maxBitDepth);
     3304    const Int scaleOut_round = 1 << (scaleShiftOut_neg-1);
     3305
     3306    initColourRemappingInfoLuts(preLut, postLut, criSEI, maxBitDepth);
     3307
     3308    assert(pic.getChromaFormat() != CHROMA_400);
     3309    const Int hs = pic.getComponentScaleX(ComponentID(COMPONENT_Cb));
     3310    const Int maxOutputValue = (1 << bitDepth) - 1;
     3311
     3312    for( Int y = 0; y < iHeight; y++ )
     3313    {
     3314      for( Int x = 0; x < iWidth; x++ )
     3315      {
     3316        const Int xc = (x>>hs);
     3317        Bool computeChroma = b444 || ((b422 || !(y&1)) && !(x&1));
     3318
     3319        Int YUVPre_0 = applyColourRemappingInfoLut1D(YUVIn[COMPONENT_Y][x], preLut[0], 0);
     3320        Int YUVPre_1 = applyColourRemappingInfoLut1D(YUVIn[COMPONENT_Cb][xc], preLut[1], 0);
     3321        Int YUVPre_2 = applyColourRemappingInfoLut1D(YUVIn[COMPONENT_Cr][xc], preLut[2], 0);
     3322
     3323        Int YUVMat_0 = applyColourRemappingInfoMatrix(criSEI.m_colourRemapCoeffs[0], postOffsetShift, YUVPre_0, YUVPre_1, YUVPre_2, matrixOutputOffset[0]);
     3324        Int YUVLutB_0 = applyColourRemappingInfoLut1D(YUVMat_0, postLut[0], postLutInputPrecision);
     3325        YUVOut[COMPONENT_Y][x] = std::min(maxOutputValue, (YUVLutB_0 + scaleOut_round) >> scaleShiftOut_neg);
     3326
     3327        if( computeChroma )
     3328        {
     3329          Int YUVMat_1 = applyColourRemappingInfoMatrix(criSEI.m_colourRemapCoeffs[1], postOffsetShift, YUVPre_0, YUVPre_1, YUVPre_2, matrixOutputOffset[1]);
     3330          Int YUVLutB_1 = applyColourRemappingInfoLut1D(YUVMat_1, postLut[1], postLutInputPrecision);
     3331          YUVOut[COMPONENT_Cb][xc] = std::min(maxOutputValue, (YUVLutB_1 + scaleOut_round) >> scaleShiftOut_neg);
     3332
     3333          Int YUVMat_2 = applyColourRemappingInfoMatrix(criSEI.m_colourRemapCoeffs[2], postOffsetShift, YUVPre_0, YUVPre_1, YUVPre_2, matrixOutputOffset[2]);
     3334          Int YUVLutB_2 = applyColourRemappingInfoLut1D(YUVMat_2, postLut[2], postLutInputPrecision);
     3335          YUVOut[COMPONENT_Cr][xc] = std::min(maxOutputValue, (YUVLutB_2 + scaleOut_round) >> scaleShiftOut_neg);
     3336        }
     3337      }
     3338
     3339      YUVIn[COMPONENT_Y]  += iStrideIn;
     3340      YUVOut[COMPONENT_Y] += iStrideOut;
     3341      if( !(b420 && !(y&1)) )
     3342      {
     3343         YUVIn[COMPONENT_Cb]  += iCStrideIn;
     3344         YUVIn[COMPONENT_Cr]  += iCStrideIn;
     3345         YUVOut[COMPONENT_Cb] += iCStrideOut;
     3346         YUVOut[COMPONENT_Cr] += iCStrideOut;
     3347      }
     3348    }
     3349    //Write remapped picture in display order
     3350    picYuvColourRemapped.dump( m_colourRemapSEIFileName, bitDepthsCriFile, true );
     3351    picYuvColourRemapped.destroy();
     3352  }
     3353}
    30093354//! \}
  • branches/HTM-15.2-dev/source/App/TAppDecoder/TAppDecTop.h

    r1321 r1360  
    128128#endif
    129129  std::ofstream                   m_seiMessageFileStream;         ///< Used for outputing SEI messages. 
     130
     131  SEIColourRemappingInfo*         m_pcSeiColourRemappingInfoPrevious;
     132
    130133public:
    131134  TAppDecTop();
     
    206209  Void  xCropAndOutput                     ( TComPic* curPic ); 
    207210#endif
     211
     212private:
     213  Void applyColourRemapping(const TComPicYuv& pic, SEIColourRemappingInfo& pCriSEI, const TComSPS &activeSPS);
     214  Void xOutputColourRemapPic(TComPic* pcPic);
    208215};
    209216
Note: See TracChangeset for help on using the changeset viewer.