source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/SEIEncoder.cpp

Last change on this file was 1413, checked in by tech, 6 years ago

Merged HTM-16.2-dev@1412

  • Property svn:eol-style set to native
File size: 30.5 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2017, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include "TLibCommon/CommonDef.h"
35#include "TLibCommon/SEI.h"
36#include "TEncGOP.h"
37#include "TEncTop.h"
38
39//! \ingroup TLibEncoder
40//! \{
41
42Void SEIEncoder::initSEIActiveParameterSets (SEIActiveParameterSets *seiActiveParameterSets, const TComVPS *vps, const TComSPS *sps)
43{
44  assert (m_isInitialized);
45  assert (seiActiveParameterSets!=NULL);
46  assert (vps!=NULL);
47  assert (sps!=NULL);
48
49  seiActiveParameterSets->activeVPSId = vps->getVPSId(); 
50  seiActiveParameterSets->m_selfContainedCvsFlag = false;
51  seiActiveParameterSets->m_noParameterSetUpdateFlag = false;
52  seiActiveParameterSets->numSpsIdsMinus1 = 0;
53  seiActiveParameterSets->activeSeqParameterSetId.resize(seiActiveParameterSets->numSpsIdsMinus1 + 1);
54  seiActiveParameterSets->activeSeqParameterSetId[0] = sps->getSPSId();
55}
56
57Void SEIEncoder::initSEIFramePacking(SEIFramePacking *seiFramePacking, Int currPicNum)
58{
59  assert (m_isInitialized);
60  assert (seiFramePacking!=NULL);
61
62  seiFramePacking->m_arrangementId = m_pcCfg->getFramePackingArrangementSEIId();
63  seiFramePacking->m_arrangementCancelFlag = 0;
64  seiFramePacking->m_arrangementType = m_pcCfg->getFramePackingArrangementSEIType();
65  assert((seiFramePacking->m_arrangementType > 2) && (seiFramePacking->m_arrangementType < 6) );
66  seiFramePacking->m_quincunxSamplingFlag = m_pcCfg->getFramePackingArrangementSEIQuincunx();
67  seiFramePacking->m_contentInterpretationType = m_pcCfg->getFramePackingArrangementSEIInterpretation();
68  seiFramePacking->m_spatialFlippingFlag = 0;
69  seiFramePacking->m_frame0FlippedFlag = 0;
70  seiFramePacking->m_fieldViewsFlag = (seiFramePacking->m_arrangementType == 2);
71  seiFramePacking->m_currentFrameIsFrame0Flag = ((seiFramePacking->m_arrangementType == 5) && (currPicNum&1) );
72  seiFramePacking->m_frame0SelfContainedFlag = 0;
73  seiFramePacking->m_frame1SelfContainedFlag = 0;
74  seiFramePacking->m_frame0GridPositionX = 0;
75  seiFramePacking->m_frame0GridPositionY = 0;
76  seiFramePacking->m_frame1GridPositionX = 0;
77  seiFramePacking->m_frame1GridPositionY = 0;
78  seiFramePacking->m_arrangementReservedByte = 0;
79  seiFramePacking->m_arrangementPersistenceFlag = true;
80  seiFramePacking->m_upsampledAspectRatio = 0;
81}
82
83Void SEIEncoder::initSEISegmentedRectFramePacking(SEISegmentedRectFramePacking *seiSegmentedRectFramePacking)
84{
85  assert (m_isInitialized);
86  assert (seiSegmentedRectFramePacking!=NULL);
87
88  seiSegmentedRectFramePacking->m_arrangementCancelFlag = m_pcCfg->getSegmentedRectFramePackingArrangementSEICancel();
89  seiSegmentedRectFramePacking->m_contentInterpretationType = m_pcCfg->getSegmentedRectFramePackingArrangementSEIType();
90  seiSegmentedRectFramePacking->m_arrangementPersistenceFlag = m_pcCfg->getSegmentedRectFramePackingArrangementSEIPersistence();
91}
92
93Void SEIEncoder::initSEIDisplayOrientation(SEIDisplayOrientation* seiDisplayOrientation)
94{
95  assert (m_isInitialized);
96  assert (seiDisplayOrientation!=NULL);
97
98  seiDisplayOrientation->cancelFlag = false;
99  seiDisplayOrientation->horFlip = false;
100  seiDisplayOrientation->verFlip = false;
101  seiDisplayOrientation->anticlockwiseRotation = m_pcCfg->getDisplayOrientationSEIAngle();
102}
103
104Void SEIEncoder::initSEIToneMappingInfo(SEIToneMappingInfo *seiToneMappingInfo)
105{
106  assert (m_isInitialized);
107  assert (seiToneMappingInfo!=NULL);
108
109  seiToneMappingInfo->m_toneMapId = m_pcCfg->getTMISEIToneMapId();
110  seiToneMappingInfo->m_toneMapCancelFlag = m_pcCfg->getTMISEIToneMapCancelFlag();
111  seiToneMappingInfo->m_toneMapPersistenceFlag = m_pcCfg->getTMISEIToneMapPersistenceFlag();
112
113  seiToneMappingInfo->m_codedDataBitDepth = m_pcCfg->getTMISEICodedDataBitDepth();
114  assert(seiToneMappingInfo->m_codedDataBitDepth >= 8 && seiToneMappingInfo->m_codedDataBitDepth <= 14);
115  seiToneMappingInfo->m_targetBitDepth = m_pcCfg->getTMISEITargetBitDepth();
116  assert(seiToneMappingInfo->m_targetBitDepth >= 1 && seiToneMappingInfo->m_targetBitDepth <= 17);
117  seiToneMappingInfo->m_modelId = m_pcCfg->getTMISEIModelID();
118  assert(seiToneMappingInfo->m_modelId >=0 &&seiToneMappingInfo->m_modelId<=4);
119
120  switch( seiToneMappingInfo->m_modelId)
121  {
122  case 0:
123    {
124      seiToneMappingInfo->m_minValue = m_pcCfg->getTMISEIMinValue();
125      seiToneMappingInfo->m_maxValue = m_pcCfg->getTMISEIMaxValue();
126      break;
127    }
128  case 1:
129    {
130      seiToneMappingInfo->m_sigmoidMidpoint = m_pcCfg->getTMISEISigmoidMidpoint();
131      seiToneMappingInfo->m_sigmoidWidth = m_pcCfg->getTMISEISigmoidWidth();
132      break;
133    }
134  case 2:
135    {
136      UInt num = 1u<<(seiToneMappingInfo->m_targetBitDepth);
137      seiToneMappingInfo->m_startOfCodedInterval.resize(num);
138      Int* ptmp = m_pcCfg->getTMISEIStartOfCodedInterva();
139      if(ptmp)
140      {
141        for(Int i=0; i<num;i++)
142        {
143          seiToneMappingInfo->m_startOfCodedInterval[i] = ptmp[i];
144        }
145      }
146      break;
147    }
148  case 3:
149    {
150      seiToneMappingInfo->m_numPivots = m_pcCfg->getTMISEINumPivots();
151      seiToneMappingInfo->m_codedPivotValue.resize(seiToneMappingInfo->m_numPivots);
152      seiToneMappingInfo->m_targetPivotValue.resize(seiToneMappingInfo->m_numPivots);
153      Int* ptmpcoded = m_pcCfg->getTMISEICodedPivotValue();
154      Int* ptmptarget = m_pcCfg->getTMISEITargetPivotValue();
155      if(ptmpcoded&&ptmptarget)
156      {
157        for(Int i=0; i<(seiToneMappingInfo->m_numPivots);i++)
158        {
159          seiToneMappingInfo->m_codedPivotValue[i]=ptmpcoded[i];
160          seiToneMappingInfo->m_targetPivotValue[i]=ptmptarget[i];
161        }
162      }
163      break;
164    }
165  case 4:
166    {
167      seiToneMappingInfo->m_cameraIsoSpeedIdc = m_pcCfg->getTMISEICameraIsoSpeedIdc();
168      seiToneMappingInfo->m_cameraIsoSpeedValue = m_pcCfg->getTMISEICameraIsoSpeedValue();
169      assert( seiToneMappingInfo->m_cameraIsoSpeedValue !=0 );
170      seiToneMappingInfo->m_exposureIndexIdc = m_pcCfg->getTMISEIExposurIndexIdc();
171      seiToneMappingInfo->m_exposureIndexValue = m_pcCfg->getTMISEIExposurIndexValue();
172      assert( seiToneMappingInfo->m_exposureIndexValue !=0 );
173      seiToneMappingInfo->m_exposureCompensationValueSignFlag = m_pcCfg->getTMISEIExposureCompensationValueSignFlag();
174      seiToneMappingInfo->m_exposureCompensationValueNumerator = m_pcCfg->getTMISEIExposureCompensationValueNumerator();
175      seiToneMappingInfo->m_exposureCompensationValueDenomIdc = m_pcCfg->getTMISEIExposureCompensationValueDenomIdc();
176      seiToneMappingInfo->m_refScreenLuminanceWhite = m_pcCfg->getTMISEIRefScreenLuminanceWhite();
177      seiToneMappingInfo->m_extendedRangeWhiteLevel = m_pcCfg->getTMISEIExtendedRangeWhiteLevel();
178      assert( seiToneMappingInfo->m_extendedRangeWhiteLevel >= 100 );
179      seiToneMappingInfo->m_nominalBlackLevelLumaCodeValue = m_pcCfg->getTMISEINominalBlackLevelLumaCodeValue();
180      seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue = m_pcCfg->getTMISEINominalWhiteLevelLumaCodeValue();
181      assert( seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue > seiToneMappingInfo->m_nominalBlackLevelLumaCodeValue );
182      seiToneMappingInfo->m_extendedWhiteLevelLumaCodeValue = m_pcCfg->getTMISEIExtendedWhiteLevelLumaCodeValue();
183      assert( seiToneMappingInfo->m_extendedWhiteLevelLumaCodeValue >= seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue );
184      break;
185    }
186  default:
187    {
188      assert(!"Undefined SEIToneMapModelId");
189      break;
190    }
191  }
192}
193
194Void SEIEncoder::initSEISOPDescription(SEISOPDescription *sopDescriptionSEI, TComSlice *slice, Int picInGOP, Int lastIdr, Int currGOPSize)
195{
196  assert (m_isInitialized);
197  assert (sopDescriptionSEI != NULL);
198  assert (slice != NULL);
199
200  Int sopCurrPOC = slice->getPOC();
201  sopDescriptionSEI->m_sopSeqParameterSetId = slice->getSPS()->getSPSId();
202
203  Int i = 0;
204  Int prevEntryId = picInGOP;
205  for (Int j = picInGOP; j < currGOPSize; j++)
206  {
207    Int deltaPOC = m_pcCfg->getGOPEntry(j).m_POC - m_pcCfg->getGOPEntry(prevEntryId).m_POC;
208    if ((sopCurrPOC + deltaPOC) < m_pcCfg->getFramesToBeEncoded())
209    {
210      sopCurrPOC += deltaPOC;
211      sopDescriptionSEI->m_sopDescVclNaluType[i] = m_pcEncGOP->getNalUnitType(sopCurrPOC, lastIdr, slice->getPic()->isField());
212      sopDescriptionSEI->m_sopDescTemporalId[i] = m_pcCfg->getGOPEntry(j).m_temporalId;
213      sopDescriptionSEI->m_sopDescStRpsIdx[i] = m_pcEncTop->getReferencePictureSetIdxForSOP(sopCurrPOC, j);
214      sopDescriptionSEI->m_sopDescPocDelta[i] = deltaPOC;
215
216      prevEntryId = j;
217      i++;
218    }
219  }
220
221  sopDescriptionSEI->m_numPicsInSopMinus1 = i - 1;
222}
223
224Void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod *bufferingPeriodSEI, TComSlice *slice)
225{
226  assert (m_isInitialized);
227  assert (bufferingPeriodSEI != NULL);
228  assert (slice != NULL);
229
230  UInt uiInitialCpbRemovalDelay = (90000/2);                      // 0.5 sec
231  bufferingPeriodSEI->m_initialCpbRemovalDelay      [0][0]     = uiInitialCpbRemovalDelay;
232  bufferingPeriodSEI->m_initialCpbRemovalDelayOffset[0][0]     = uiInitialCpbRemovalDelay;
233  bufferingPeriodSEI->m_initialCpbRemovalDelay      [0][1]     = uiInitialCpbRemovalDelay;
234  bufferingPeriodSEI->m_initialCpbRemovalDelayOffset[0][1]     = uiInitialCpbRemovalDelay;
235
236  Double dTmp = (Double)slice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)slice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale();
237
238  UInt uiTmp = (UInt)( dTmp * 90000.0 );
239  uiInitialCpbRemovalDelay -= uiTmp;
240  uiInitialCpbRemovalDelay -= uiTmp / ( slice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 );
241  bufferingPeriodSEI->m_initialAltCpbRemovalDelay      [0][0]  = uiInitialCpbRemovalDelay;
242  bufferingPeriodSEI->m_initialAltCpbRemovalDelayOffset[0][0]  = uiInitialCpbRemovalDelay;
243  bufferingPeriodSEI->m_initialAltCpbRemovalDelay      [0][1]  = uiInitialCpbRemovalDelay;
244  bufferingPeriodSEI->m_initialAltCpbRemovalDelayOffset[0][1]  = uiInitialCpbRemovalDelay;
245
246  bufferingPeriodSEI->m_rapCpbParamsPresentFlag = 0;
247  //for the concatenation, it can be set to one during splicing.
248  bufferingPeriodSEI->m_concatenationFlag = 0;
249  //since the temporal layer HRD is not ready, we assumed it is fixed
250  bufferingPeriodSEI->m_auCpbRemovalDelayDelta = 1;
251  bufferingPeriodSEI->m_cpbDelayOffset = 0;
252  bufferingPeriodSEI->m_dpbDelayOffset = 0;
253}
254
255//! initialize scalable nesting SEI message.
256//! Note: The SEI message structures input into this function will become part of the scalable nesting SEI and will be
257//!       automatically freed, when the nesting SEI is disposed.
258Void SEIEncoder::initSEIScalableNesting(SEIScalableNesting *scalableNestingSEI, SEIMessages &nestedSEIs)
259{
260  assert (m_isInitialized);
261  assert (scalableNestingSEI != NULL);
262
263  scalableNestingSEI->m_bitStreamSubsetFlag           = 1;      // If the nested SEI messages are picture buffering SEI messages, picture timing SEI messages or sub-picture timing SEI messages, bitstream_subset_flag shall be equal to 1
264  scalableNestingSEI->m_nestingOpFlag                 = 0;
265  scalableNestingSEI->m_nestingNumOpsMinus1           = 0;      //nesting_num_ops_minus1
266  scalableNestingSEI->m_allLayersFlag                 = 0;
267  scalableNestingSEI->m_nestingNoOpMaxTemporalIdPlus1 = 6 + 1;  //nesting_no_op_max_temporal_id_plus1
268  scalableNestingSEI->m_nestingNumLayersMinus1        = 1 - 1;  //nesting_num_layers_minus1
269  scalableNestingSEI->m_nestingLayerId[0]             = 0;
270
271  scalableNestingSEI->m_nestedSEIs.clear();
272  for (SEIMessages::iterator it=nestedSEIs.begin(); it!=nestedSEIs.end(); it++)
273  {
274    scalableNestingSEI->m_nestedSEIs.push_back((*it));
275  }
276}
277
278Void SEIEncoder::initSEIRecoveryPoint(SEIRecoveryPoint *recoveryPointSEI, TComSlice *slice)
279{
280  assert (m_isInitialized);
281  assert (recoveryPointSEI != NULL);
282  assert (slice != NULL);
283
284  recoveryPointSEI->m_recoveryPocCnt    = 0;
285  recoveryPointSEI->m_exactMatchingFlag = ( slice->getPOC() == 0 ) ? (true) : (false);
286  recoveryPointSEI->m_brokenLinkFlag    = false;
287}
288
289//! calculate hashes for entire reconstructed picture
290Void SEIEncoder::initDecodedPictureHashSEI(SEIDecodedPictureHash *decodedPictureHashSEI, TComPic *pcPic, std::string &rHashString, const BitDepths &bitDepths)
291{
292  assert (m_isInitialized);
293  assert (decodedPictureHashSEI!=NULL);
294  assert (pcPic!=NULL);
295
296  decodedPictureHashSEI->method = m_pcCfg->getDecodedPictureHashSEIType();
297  switch (m_pcCfg->getDecodedPictureHashSEIType())
298  {
299    case HASHTYPE_MD5:
300  {
301    UInt numChar=calcMD5(*pcPic->getPicYuvRec(), decodedPictureHashSEI->m_pictureHash, bitDepths);
302    rHashString = hashToString(decodedPictureHashSEI->m_pictureHash, numChar);
303  }
304      break;
305    case HASHTYPE_CRC:
306  {
307    UInt numChar=calcCRC(*pcPic->getPicYuvRec(), decodedPictureHashSEI->m_pictureHash, bitDepths);
308    rHashString = hashToString(decodedPictureHashSEI->m_pictureHash, numChar);
309  }
310      break;
311    case HASHTYPE_CHECKSUM:
312    default:
313  {
314    UInt numChar=calcChecksum(*pcPic->getPicYuvRec(), decodedPictureHashSEI->m_pictureHash, bitDepths);
315    rHashString = hashToString(decodedPictureHashSEI->m_pictureHash, numChar);
316  }
317      break;
318  }
319}
320
321Void SEIEncoder::initTemporalLevel0IndexSEI(SEITemporalLevel0Index *temporalLevel0IndexSEI, TComSlice *slice)
322{
323  assert (m_isInitialized);
324  assert (temporalLevel0IndexSEI!=NULL);
325  assert (slice!=NULL);
326
327  if (slice->getRapPicFlag())
328  {
329    m_tl0Idx = 0;
330    m_rapIdx = (m_rapIdx + 1) & 0xFF;
331  }
332  else
333  {
334    m_tl0Idx = (m_tl0Idx + (slice->getTLayer() ? 0 : 1)) & 0xFF;
335  }
336  temporalLevel0IndexSEI->tl0Idx = m_tl0Idx;
337  temporalLevel0IndexSEI->rapIdx = m_rapIdx;
338}
339
340Void SEIEncoder::initSEITempMotionConstrainedTileSets (SEITempMotionConstrainedTileSets *sei, const TComPPS *pps)
341{
342  assert (m_isInitialized);
343  assert (sei!=NULL);
344  assert (pps!=NULL);
345
346  if(pps->getTilesEnabledFlag())
347  {
348#if MCTS_ENC_CHECK
349    if (m_pcCfg->getTMCTSSEITileConstraint())
350    {
351      sei->m_mc_all_tiles_exact_sample_value_match_flag = true;
352      sei->m_each_tile_one_tile_set_flag = true;
353      sei->m_limited_tile_set_display_flag = false;
354      sei->m_max_mcs_tier_level_idc_present_flag = false;
355      sei->setNumberOfTileSets(0);
356    }
357    else
358    {
359#endif
360    sei->m_mc_all_tiles_exact_sample_value_match_flag = false;
361    sei->m_each_tile_one_tile_set_flag                = false;
362    sei->m_limited_tile_set_display_flag              = false;
363    sei->setNumberOfTileSets((pps->getNumTileColumnsMinus1() + 1) * (pps->getNumTileRowsMinus1() + 1));
364
365    for(Int i=0; i < sei->getNumberOfTileSets(); i++)
366    {
367      sei->tileSetData(i).m_mcts_id = i;  //depends the application;
368      sei->tileSetData(i).setNumberOfTileRects(1);
369
370      for(Int j=0; j<sei->tileSetData(i).getNumberOfTileRects(); j++)
371      {
372        sei->tileSetData(i).topLeftTileIndex(j)     = i+j;
373        sei->tileSetData(i).bottomRightTileIndex(j) = i+j;
374      }
375
376      sei->tileSetData(i).m_exact_sample_value_match_flag    = false;
377      sei->tileSetData(i).m_mcts_tier_level_idc_present_flag = false;
378    }
379#if MCTS_ENC_CHECK
380    }
381#endif
382  }
383  else
384  {
385    assert(!"Tile is not enabled");
386  }
387}
388
389Void SEIEncoder::initSEIKneeFunctionInfo(SEIKneeFunctionInfo *seiKneeFunctionInfo)
390{
391  assert (m_isInitialized);
392  assert (seiKneeFunctionInfo!=NULL);
393
394  seiKneeFunctionInfo->m_kneeId = m_pcCfg->getKneeSEIId();
395  seiKneeFunctionInfo->m_kneeCancelFlag = m_pcCfg->getKneeSEICancelFlag();
396  if ( !seiKneeFunctionInfo->m_kneeCancelFlag )
397  {
398    seiKneeFunctionInfo->m_kneePersistenceFlag = m_pcCfg->getKneeSEIPersistenceFlag();
399    seiKneeFunctionInfo->m_kneeInputDrange = m_pcCfg->getKneeSEIInputDrange();
400    seiKneeFunctionInfo->m_kneeInputDispLuminance = m_pcCfg->getKneeSEIInputDispLuminance();
401    seiKneeFunctionInfo->m_kneeOutputDrange = m_pcCfg->getKneeSEIOutputDrange();
402    seiKneeFunctionInfo->m_kneeOutputDispLuminance = m_pcCfg->getKneeSEIOutputDispLuminance();
403
404    seiKneeFunctionInfo->m_kneeNumKneePointsMinus1 = m_pcCfg->getKneeSEINumKneePointsMinus1();
405    Int* piInputKneePoint  = m_pcCfg->getKneeSEIInputKneePoint();
406    Int* piOutputKneePoint = m_pcCfg->getKneeSEIOutputKneePoint();
407    if(piInputKneePoint&&piOutputKneePoint)
408    {
409      seiKneeFunctionInfo->m_kneeInputKneePoint.resize(seiKneeFunctionInfo->m_kneeNumKneePointsMinus1+1);
410      seiKneeFunctionInfo->m_kneeOutputKneePoint.resize(seiKneeFunctionInfo->m_kneeNumKneePointsMinus1+1);
411      for(Int i=0; i<=seiKneeFunctionInfo->m_kneeNumKneePointsMinus1; i++)
412      {
413        seiKneeFunctionInfo->m_kneeInputKneePoint[i] = piInputKneePoint[i];
414        seiKneeFunctionInfo->m_kneeOutputKneePoint[i] = piOutputKneePoint[i];
415      }
416    }
417  }
418}
419template <typename T>
420static Void readTokenValue(T            &returnedValue, /// value returned
421                           Bool         &failed,        /// used and updated
422                           std::istream &is,            /// stream to read token from
423                           const TChar  *pToken)        /// token string
424{
425  returnedValue=T();
426  if (failed)
427  {
428    return;
429  }
430
431  Int c;
432  // Ignore any whitespace
433  while ((c=is.get())!=EOF && isspace(c));
434  // test for comment mark
435  while (c=='#')
436  {
437    // Ignore to the end of the line
438    while ((c=is.get())!=EOF && (c!=10 && c!=13));
439    // Ignore any white space at the start of the next line
440    while ((c=is.get())!=EOF && isspace(c));
441  }
442  // test first character of token
443  failed=(c!=pToken[0]);
444  // test remaining characters of token
445  Int pos;
446  for(pos=1;!failed && pToken[pos]!=0 && is.get()==pToken[pos]; pos++);
447  failed|=(pToken[pos]!=0);
448  // Ignore any whitespace before the ':'
449  while (!failed && (c=is.get())!=EOF && isspace(c));
450  failed|=(c!=':');
451  // Now read the value associated with the token:
452  if (!failed)
453  {
454    is >> returnedValue;
455    failed=!is.good();
456    if (!failed)
457    {
458      c=is.get();
459      failed=(c!=EOF && !isspace(c));
460    }
461  }
462  if (failed)
463  {
464    std::cerr << "Unable to read token '" << pToken << "'\n";
465  }
466}
467
468template <typename T>
469static Void readTokenValueAndValidate(T            &returnedValue, /// value returned
470                                      Bool         &failed,        /// used and updated
471                                      std::istream &is,            /// stream to read token from
472                                      const TChar  *pToken,        /// token string
473                                      const T      &minInclusive,  /// minimum value allowed, inclusive
474                                      const T      &maxInclusive)  /// maximum value allowed, inclusive
475{
476  readTokenValue(returnedValue, failed, is, pToken);
477  if (!failed)
478  {
479    if (returnedValue<minInclusive || returnedValue>maxInclusive)
480    {
481      failed=true;
482      std::cerr << "Value for token " << pToken << " must be in the range " << minInclusive << " to " << maxInclusive << " (inclusive); value read: " << returnedValue << std::endl;
483    }
484  }
485}
486
487// Bool version does not have maximum and minimum values.
488static Void readTokenValueAndValidate(Bool         &returnedValue, /// value returned
489                                      Bool         &failed,        /// used and updated
490                                      std::istream &is,            /// stream to read token from
491                                      const TChar  *pToken)        /// token string
492{
493  readTokenValue(returnedValue, failed, is, pToken);
494}
495
496Bool SEIEncoder::initSEIColourRemappingInfo(SEIColourRemappingInfo* seiColourRemappingInfo, Int currPOC) // returns true on success, false on failure.
497{
498  assert (m_isInitialized);
499  assert (seiColourRemappingInfo!=NULL);
500
501  // reading external Colour Remapping Information SEI message parameters from file
502  if( !m_pcCfg->getColourRemapInfoSEIFileRoot().empty())
503  {
504    Bool failed=false;
505
506    // building the CRI file name with poc num in prefix "_poc.txt"
507    std::string colourRemapSEIFileWithPoc(m_pcCfg->getColourRemapInfoSEIFileRoot());
508    {
509      std::stringstream suffix;
510      suffix << "_" << currPOC << ".txt";
511      colourRemapSEIFileWithPoc+=suffix.str();
512    }
513
514    std::ifstream fic(colourRemapSEIFileWithPoc.c_str());
515    if (!fic.good() || !fic.is_open())
516    {
517      std::cerr <<  "No Colour Remapping Information SEI parameters file " << colourRemapSEIFileWithPoc << " for POC " << currPOC << std::endl;
518      return false;
519    }
520
521    // TODO: identify and remove duplication with decoder parsing through abstraction.
522
523    readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapId,         failed, fic, "colour_remap_id",        UInt(0), UInt(0x7fffffff) );
524    readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapCancelFlag, failed, fic, "colour_remap_cancel_flag" );
525    if( !seiColourRemappingInfo->m_colourRemapCancelFlag )
526    {
527      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapPersistenceFlag,            failed, fic, "colour_remap_persistence_flag" );
528      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapVideoSignalInfoPresentFlag, failed, fic, "colour_remap_video_signal_info_present_flag");
529      if( seiColourRemappingInfo->m_colourRemapVideoSignalInfoPresentFlag )
530      {
531        readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapFullRangeFlag,      failed, fic, "colour_remap_full_range_flag" );
532        readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapPrimaries,          failed, fic, "colour_remap_primaries",           Int(0), Int(255) );
533        readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapTransferFunction,   failed, fic, "colour_remap_transfer_function",   Int(0), Int(255) );
534        readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapMatrixCoefficients, failed, fic, "colour_remap_matrix_coefficients", Int(0), Int(255) );
535      }
536      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapInputBitDepth, failed, fic, "colour_remap_input_bit_depth",            Int(8), Int(16) );
537      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapBitDepth,      failed, fic, "colour_remap_bit_depth",                  Int(8), Int(16) );
538
539      const Int maximumInputValue    = (1 << (((seiColourRemappingInfo->m_colourRemapInputBitDepth + 7) >> 3) << 3)) - 1;
540      const Int maximumRemappedValue = (1 << (((seiColourRemappingInfo->m_colourRemapBitDepth      + 7) >> 3) << 3)) - 1;
541
542      for( Int c=0 ; c<3 ; c++ )
543      {
544        readTokenValueAndValidate(seiColourRemappingInfo->m_preLutNumValMinus1[c],         failed, fic, "pre_lut_num_val_minus1[c]",        Int(0), Int(32) );
545        if( seiColourRemappingInfo->m_preLutNumValMinus1[c]>0 )
546        {
547          seiColourRemappingInfo->m_preLut[c].resize(seiColourRemappingInfo->m_preLutNumValMinus1[c]+1);
548          for( Int i=0 ; i<=seiColourRemappingInfo->m_preLutNumValMinus1[c] ; i++ )
549          {
550            readTokenValueAndValidate(seiColourRemappingInfo->m_preLut[c][i].codedValue,   failed, fic, "pre_lut_coded_value[c][i]",  Int(0), maximumInputValue    );
551            readTokenValueAndValidate(seiColourRemappingInfo->m_preLut[c][i].targetValue,  failed, fic, "pre_lut_target_value[c][i]", Int(0), maximumRemappedValue );
552          }
553        }
554      }
555      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapMatrixPresentFlag, failed, fic, "colour_remap_matrix_present_flag" );
556      if( seiColourRemappingInfo->m_colourRemapMatrixPresentFlag )
557      {
558        readTokenValueAndValidate(seiColourRemappingInfo->m_log2MatrixDenom, failed, fic, "log2_matrix_denom", Int(0), Int(15) );
559        for( Int c=0 ; c<3 ; c++ )
560        {
561          for( Int i=0 ; i<3 ; i++ )
562          {
563            readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapCoeffs[c][i], failed, fic, "colour_remap_coeffs[c][i]", -32768, 32767 );
564          }
565        }
566      }
567      for( Int c=0 ; c<3 ; c++ )
568      {
569        readTokenValueAndValidate(seiColourRemappingInfo->m_postLutNumValMinus1[c], failed, fic, "post_lut_num_val_minus1[c]", Int(0), Int(32) );
570        if( seiColourRemappingInfo->m_postLutNumValMinus1[c]>0 )
571        {
572          seiColourRemappingInfo->m_postLut[c].resize(seiColourRemappingInfo->m_postLutNumValMinus1[c]+1);
573          for( Int i=0 ; i<=seiColourRemappingInfo->m_postLutNumValMinus1[c] ; i++ )
574          {
575            readTokenValueAndValidate(seiColourRemappingInfo->m_postLut[c][i].codedValue,  failed, fic, "post_lut_coded_value[c][i]",  Int(0), maximumRemappedValue );
576            readTokenValueAndValidate(seiColourRemappingInfo->m_postLut[c][i].targetValue, failed, fic, "post_lut_target_value[c][i]", Int(0), maximumRemappedValue );
577          }
578        }
579      }
580    }
581
582    if( failed )
583    {
584      std::cerr << "Error while reading Colour Remapping Information SEI parameters file '" << colourRemapSEIFileWithPoc << "'" << std::endl;
585      exit(EXIT_FAILURE);
586    }
587  }
588  return true;
589}
590
591
592Void SEIEncoder::initSEIChromaResamplingFilterHint(SEIChromaResamplingFilterHint *seiChromaResamplingFilterHint, Int iHorFilterIndex, Int iVerFilterIndex)
593{
594  assert (m_isInitialized);
595  assert (seiChromaResamplingFilterHint!=NULL);
596
597  seiChromaResamplingFilterHint->m_verChromaFilterIdc = iVerFilterIndex;
598  seiChromaResamplingFilterHint->m_horChromaFilterIdc = iHorFilterIndex;
599  seiChromaResamplingFilterHint->m_verFilteringFieldProcessingFlag = 1;
600  seiChromaResamplingFilterHint->m_targetFormatIdc = 3;
601  seiChromaResamplingFilterHint->m_perfectReconstructionFlag = false;
602
603  // this creates some example filter values, if explicit filter definition is selected
604  if (seiChromaResamplingFilterHint->m_verChromaFilterIdc == 1)
605    {
606    const Int numVerticalFilters = 3;
607    const Int verTapLengthMinus1[] = {5,3,3};
608
609    seiChromaResamplingFilterHint->m_verFilterCoeff.resize(numVerticalFilters);
610    for(Int i = 0; i < numVerticalFilters; i ++)
611      {
612      seiChromaResamplingFilterHint->m_verFilterCoeff[i].resize(verTapLengthMinus1[i]+1);
613    }
614    // Note: C++11 -> seiChromaResamplingFilterHint->m_verFilterCoeff[0] = {-3,13,31,23,3,-3};
615    seiChromaResamplingFilterHint->m_verFilterCoeff[0][0] = -3;
616    seiChromaResamplingFilterHint->m_verFilterCoeff[0][1] = 13;
617    seiChromaResamplingFilterHint->m_verFilterCoeff[0][2] = 31;
618    seiChromaResamplingFilterHint->m_verFilterCoeff[0][3] = 23;
619    seiChromaResamplingFilterHint->m_verFilterCoeff[0][4] = 3;
620    seiChromaResamplingFilterHint->m_verFilterCoeff[0][5] = -3;
621
622    seiChromaResamplingFilterHint->m_verFilterCoeff[1][0] = -1;
623    seiChromaResamplingFilterHint->m_verFilterCoeff[1][1] = 25;
624    seiChromaResamplingFilterHint->m_verFilterCoeff[1][2] = 247;
625    seiChromaResamplingFilterHint->m_verFilterCoeff[1][3] = -15;
626
627    seiChromaResamplingFilterHint->m_verFilterCoeff[2][0] = -20;
628    seiChromaResamplingFilterHint->m_verFilterCoeff[2][1] = 186;
629    seiChromaResamplingFilterHint->m_verFilterCoeff[2][2] = 100;
630    seiChromaResamplingFilterHint->m_verFilterCoeff[2][3] = -10;
631  }
632  else
633  {
634    seiChromaResamplingFilterHint->m_verFilterCoeff.resize(0);
635  }
636
637  if (seiChromaResamplingFilterHint->m_horChromaFilterIdc == 1)
638    {
639    Int const numHorizontalFilters = 1;
640    const Int horTapLengthMinus1[] = {3};
641
642    seiChromaResamplingFilterHint->m_horFilterCoeff.resize(numHorizontalFilters);
643    for(Int i = 0; i < numHorizontalFilters; i ++)
644      {
645      seiChromaResamplingFilterHint->m_horFilterCoeff[i].resize(horTapLengthMinus1[i]+1);
646    }
647    seiChromaResamplingFilterHint->m_horFilterCoeff[0][0] = 1;
648    seiChromaResamplingFilterHint->m_horFilterCoeff[0][1] = 6;
649    seiChromaResamplingFilterHint->m_horFilterCoeff[0][2] = 1;
650  }
651  else
652  {
653    seiChromaResamplingFilterHint->m_horFilterCoeff.resize(0);
654  }
655}
656
657Void SEIEncoder::initSEITimeCode(SEITimeCode *seiTimeCode)
658{
659  assert (m_isInitialized);
660  assert (seiTimeCode!=NULL);
661  //  Set data as per command line options
662  seiTimeCode->numClockTs = m_pcCfg->getNumberOfTimesets();
663  for(Int i = 0; i < seiTimeCode->numClockTs; i++)
664  {
665    seiTimeCode->timeSetArray[i] = m_pcCfg->getTimeSet(i);
666  }
667}
668Void SEIEncoder::initSEIAlternativeTransferCharacteristics(SEIAlternativeTransferCharacteristics *seiAltTransCharacteristics)
669{
670  assert (m_isInitialized);
671  assert (seiAltTransCharacteristics!=NULL);
672  //  Set SEI message parameters read from command line options
673  seiAltTransCharacteristics->m_preferredTransferCharacteristics = m_pcCfg->getSEIPreferredTransferCharacteristics();
674}
675
676Void SEIEncoder::initSEIGreenMetadataInfo(SEIGreenMetadataInfo *seiGreenMetadataInfo, UInt u)
677{
678    assert (m_isInitialized);
679    assert (seiGreenMetadataInfo!=NULL);
680
681    seiGreenMetadataInfo->m_greenMetadataType = m_pcCfg->getSEIGreenMetadataType();
682    seiGreenMetadataInfo->m_xsdMetricType = m_pcCfg->getSEIXSDMetricType();
683    seiGreenMetadataInfo->m_xsdMetricValue = u;
684}
685
686
687#if NH_MV
688Void SEIEncoder::createAnnexFGISeiMessages( SEIMessages& seiMessage, const TComSlice* slice )
689{
690  const SEIMessages* seiMessageCfg = m_pcCfg->getSeiMessages(); 
691
692  for( SEIMessages::const_iterator itS = seiMessageCfg->begin(); itS != seiMessageCfg->end(); itS++ )   
693  {     
694    const SEI* curSei = (*itS); 
695    SEI* newSei; 
696    if ( curSei->insertSei( slice->getLayerId(), slice->getPOC(), slice->getTemporalId(), slice->getNalUnitType() ) )
697    {
698      newSei = curSei->getCopy( ) ;
699
700      if ( curSei->m_modifyByEncoder )
701      {
702        newSei->setupFromSlice  ( slice ); 
703      } 
704
705      if ( newSei   ->checkCfg( slice ) )
706      {
707        std::cout << "--> Omit sending SEI."  <<  std::endl; 
708        delete newSei; 
709      }
710      else
711      {
712        seiMessage.push_back(newSei); 
713      }
714
715    }
716  }
717}
718#endif
719
720//! \}
Note: See TracBrowser for help on using the repository browser.