source: 3DVCSoftware/branches/HTM-15.2-dev/source/Lib/TLibEncoder/SEIEncoder.cpp @ 1374

Last change on this file since 1374 was 1374, checked in by tech, 8 years ago

Macro cleanups.

  • Property svn:eol-style set to native
File size: 29.4 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-2015, 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    sei->m_mc_all_tiles_exact_sample_value_match_flag = false;
349    sei->m_each_tile_one_tile_set_flag                = false;
350    sei->m_limited_tile_set_display_flag              = false;
351    sei->setNumberOfTileSets((pps->getNumTileColumnsMinus1() + 1) * (pps->getNumTileRowsMinus1() + 1));
352
353    for(Int i=0; i < sei->getNumberOfTileSets(); i++)
354    {
355      sei->tileSetData(i).m_mcts_id = i;  //depends the application;
356      sei->tileSetData(i).setNumberOfTileRects(1);
357
358      for(Int j=0; j<sei->tileSetData(i).getNumberOfTileRects(); j++)
359      {
360        sei->tileSetData(i).topLeftTileIndex(j)     = i+j;
361        sei->tileSetData(i).bottomRightTileIndex(j) = i+j;
362      }
363
364      sei->tileSetData(i).m_exact_sample_value_match_flag    = false;
365      sei->tileSetData(i).m_mcts_tier_level_idc_present_flag = false;
366    }
367  }
368  else
369  {
370    assert(!"Tile is not enabled");
371  }
372}
373
374Void SEIEncoder::initSEIKneeFunctionInfo(SEIKneeFunctionInfo *seiKneeFunctionInfo)
375{
376  assert (m_isInitialized);
377  assert (seiKneeFunctionInfo!=NULL);
378
379  seiKneeFunctionInfo->m_kneeId = m_pcCfg->getKneeSEIId();
380  seiKneeFunctionInfo->m_kneeCancelFlag = m_pcCfg->getKneeSEICancelFlag();
381  if ( !seiKneeFunctionInfo->m_kneeCancelFlag )
382  {
383    seiKneeFunctionInfo->m_kneePersistenceFlag = m_pcCfg->getKneeSEIPersistenceFlag();
384    seiKneeFunctionInfo->m_kneeInputDrange = m_pcCfg->getKneeSEIInputDrange();
385    seiKneeFunctionInfo->m_kneeInputDispLuminance = m_pcCfg->getKneeSEIInputDispLuminance();
386    seiKneeFunctionInfo->m_kneeOutputDrange = m_pcCfg->getKneeSEIOutputDrange();
387    seiKneeFunctionInfo->m_kneeOutputDispLuminance = m_pcCfg->getKneeSEIOutputDispLuminance();
388
389    seiKneeFunctionInfo->m_kneeNumKneePointsMinus1 = m_pcCfg->getKneeSEINumKneePointsMinus1();
390    Int* piInputKneePoint  = m_pcCfg->getKneeSEIInputKneePoint();
391    Int* piOutputKneePoint = m_pcCfg->getKneeSEIOutputKneePoint();
392    if(piInputKneePoint&&piOutputKneePoint)
393    {
394      seiKneeFunctionInfo->m_kneeInputKneePoint.resize(seiKneeFunctionInfo->m_kneeNumKneePointsMinus1+1);
395      seiKneeFunctionInfo->m_kneeOutputKneePoint.resize(seiKneeFunctionInfo->m_kneeNumKneePointsMinus1+1);
396      for(Int i=0; i<=seiKneeFunctionInfo->m_kneeNumKneePointsMinus1; i++)
397      {
398        seiKneeFunctionInfo->m_kneeInputKneePoint[i] = piInputKneePoint[i];
399        seiKneeFunctionInfo->m_kneeOutputKneePoint[i] = piOutputKneePoint[i];
400      }
401    }
402  }
403}
404template <typename T>
405static Void readTokenValue(T            &returnedValue, /// value returned
406                           Bool         &failed,        /// used and updated
407                           std::istream &is,            /// stream to read token from
408                           const TChar  *pToken)        /// token string
409{
410  returnedValue=T();
411  if (failed)
412  {
413    return;
414  }
415
416  Int c;
417  // Ignore any whitespace
418  while ((c=is.get())!=EOF && isspace(c));
419  // test for comment mark
420  while (c=='#')
421  {
422    // Ignore to the end of the line
423    while ((c=is.get())!=EOF && (c!=10 && c!=13));
424    // Ignore any white space at the start of the next line
425    while ((c=is.get())!=EOF && isspace(c));
426  }
427  // test first character of token
428  failed=(c!=pToken[0]);
429  // test remaining characters of token
430  Int pos;
431  for(pos=1;!failed && pToken[pos]!=0 && is.get()==pToken[pos]; pos++);
432  failed|=(pToken[pos]!=0);
433  // Ignore any whitespace before the ':'
434  while (!failed && (c=is.get())!=EOF && isspace(c));
435  failed|=(c!=':');
436  // Now read the value associated with the token:
437  if (!failed)
438  {
439    is >> returnedValue;
440    failed=!is.good();
441    if (!failed)
442    {
443      c=is.get();
444      failed=(c!=EOF && !isspace(c));
445    }
446  }
447  if (failed)
448  {
449    std::cerr << "Unable to read token '" << pToken << "'\n";
450  }
451}
452
453template <typename T>
454static Void readTokenValueAndValidate(T            &returnedValue, /// value returned
455                                      Bool         &failed,        /// used and updated
456                                      std::istream &is,            /// stream to read token from
457                                      const TChar  *pToken,        /// token string
458                                      const T      &minInclusive,  /// minimum value allowed, inclusive
459                                      const T      &maxInclusive)  /// maximum value allowed, inclusive
460{
461  readTokenValue(returnedValue, failed, is, pToken);
462  if (!failed)
463  {
464    if (returnedValue<minInclusive || returnedValue>maxInclusive)
465    {
466      failed=true;
467      std::cerr << "Value for token " << pToken << " must be in the range " << minInclusive << " to " << maxInclusive << " (inclusive); value read: " << returnedValue << std::endl;
468    }
469  }
470}
471
472// Bool version does not have maximum and minimum values.
473static Void readTokenValueAndValidate(Bool         &returnedValue, /// value returned
474                                      Bool         &failed,        /// used and updated
475                                      std::istream &is,            /// stream to read token from
476                                      const TChar  *pToken)        /// token string
477{
478  readTokenValue(returnedValue, failed, is, pToken);
479}
480
481Bool SEIEncoder::initSEIColourRemappingInfo(SEIColourRemappingInfo* seiColourRemappingInfo, Int currPOC) // returns true on success, false on failure.
482{
483  assert (m_isInitialized);
484  assert (seiColourRemappingInfo!=NULL);
485
486  // reading external Colour Remapping Information SEI message parameters from file
487  if( !m_pcCfg->getColourRemapInfoSEIFileRoot().empty())
488  {
489    Bool failed=false;
490
491    // building the CRI file name with poc num in prefix "_poc.txt"
492    std::string colourRemapSEIFileWithPoc(m_pcCfg->getColourRemapInfoSEIFileRoot());
493    {
494      std::stringstream suffix;
495      suffix << "_" << currPOC << ".txt";
496      colourRemapSEIFileWithPoc+=suffix.str();
497    }
498
499    std::ifstream fic(colourRemapSEIFileWithPoc.c_str());
500    if (!fic.good() || !fic.is_open())
501    {
502      std::cerr <<  "No Colour Remapping Information SEI parameters file " << colourRemapSEIFileWithPoc << " for POC " << currPOC << std::endl;
503      return false;
504    }
505
506    // TODO: identify and remove duplication with decoder parsing through abstraction.
507
508    readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapId,         failed, fic, "colour_remap_id",        UInt(0), UInt(0x7fffffff) );
509    readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapCancelFlag, failed, fic, "colour_remap_cancel_flag" );
510    if( !seiColourRemappingInfo->m_colourRemapCancelFlag )
511    {
512      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapPersistenceFlag,            failed, fic, "colour_remap_persistence_flag" );
513      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapVideoSignalInfoPresentFlag, failed, fic, "colour_remap_video_signal_info_present_flag");
514      if( seiColourRemappingInfo->m_colourRemapVideoSignalInfoPresentFlag )
515      {
516        readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapFullRangeFlag,      failed, fic, "colour_remap_full_range_flag" );
517        readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapPrimaries,          failed, fic, "colour_remap_primaries",           Int(0), Int(255) );
518        readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapTransferFunction,   failed, fic, "colour_remap_transfer_function",   Int(0), Int(255) );
519        readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapMatrixCoefficients, failed, fic, "colour_remap_matrix_coefficients", Int(0), Int(255) );
520      }
521      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapInputBitDepth, failed, fic, "colour_remap_input_bit_depth",            Int(8), Int(16) );
522      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapBitDepth,      failed, fic, "colour_remap_bit_depth",                  Int(8), Int(16) );
523
524      const Int maximumInputValue    = (1 << (((seiColourRemappingInfo->m_colourRemapInputBitDepth + 7) >> 3) << 3)) - 1;
525      const Int maximumRemappedValue = (1 << (((seiColourRemappingInfo->m_colourRemapBitDepth      + 7) >> 3) << 3)) - 1;
526
527      for( Int c=0 ; c<3 ; c++ )
528      {
529        readTokenValueAndValidate(seiColourRemappingInfo->m_preLutNumValMinus1[c],         failed, fic, "pre_lut_num_val_minus1[c]",        Int(0), Int(32) );
530        if( seiColourRemappingInfo->m_preLutNumValMinus1[c]>0 )
531        {
532          seiColourRemappingInfo->m_preLut[c].resize(seiColourRemappingInfo->m_preLutNumValMinus1[c]+1);
533          for( Int i=0 ; i<=seiColourRemappingInfo->m_preLutNumValMinus1[c] ; i++ )
534          {
535            readTokenValueAndValidate(seiColourRemappingInfo->m_preLut[c][i].codedValue,   failed, fic, "pre_lut_coded_value[c][i]",  Int(0), maximumInputValue    );
536            readTokenValueAndValidate(seiColourRemappingInfo->m_preLut[c][i].targetValue,  failed, fic, "pre_lut_target_value[c][i]", Int(0), maximumRemappedValue );
537          }
538        }
539      }
540      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapMatrixPresentFlag, failed, fic, "colour_remap_matrix_present_flag" );
541      if( seiColourRemappingInfo->m_colourRemapMatrixPresentFlag )
542      {
543        readTokenValueAndValidate(seiColourRemappingInfo->m_log2MatrixDenom, failed, fic, "log2_matrix_denom", Int(0), Int(15) );
544        for( Int c=0 ; c<3 ; c++ )
545        {
546          for( Int i=0 ; i<3 ; i++ )
547          {
548            readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapCoeffs[c][i], failed, fic, "colour_remap_coeffs[c][i]", -32768, 32767 );
549          }
550        }
551      }
552      for( Int c=0 ; c<3 ; c++ )
553      {
554        readTokenValueAndValidate(seiColourRemappingInfo->m_postLutNumValMinus1[c], failed, fic, "post_lut_num_val_minus1[c]", Int(0), Int(32) );
555        if( seiColourRemappingInfo->m_postLutNumValMinus1[c]>0 )
556        {
557          seiColourRemappingInfo->m_postLut[c].resize(seiColourRemappingInfo->m_postLutNumValMinus1[c]+1);
558          for( Int i=0 ; i<=seiColourRemappingInfo->m_postLutNumValMinus1[c] ; i++ )
559          {
560            readTokenValueAndValidate(seiColourRemappingInfo->m_postLut[c][i].codedValue,  failed, fic, "post_lut_coded_value[c][i]",  Int(0), maximumRemappedValue );
561            readTokenValueAndValidate(seiColourRemappingInfo->m_postLut[c][i].targetValue, failed, fic, "post_lut_target_value[c][i]", Int(0), maximumRemappedValue );
562          }
563        }
564      }
565    }
566
567    if( failed )
568    {
569      std::cerr << "Error while reading Colour Remapping Information SEI parameters file '" << colourRemapSEIFileWithPoc << "'" << std::endl;
570      exit(EXIT_FAILURE);
571    }
572  }
573  return true;
574}
575
576
577Void SEIEncoder::initSEIChromaResamplingFilterHint(SEIChromaResamplingFilterHint *seiChromaResamplingFilterHint, Int iHorFilterIndex, Int iVerFilterIndex)
578{
579  assert (m_isInitialized);
580  assert (seiChromaResamplingFilterHint!=NULL);
581
582  seiChromaResamplingFilterHint->m_verChromaFilterIdc = iVerFilterIndex;
583  seiChromaResamplingFilterHint->m_horChromaFilterIdc = iHorFilterIndex;
584  seiChromaResamplingFilterHint->m_verFilteringFieldProcessingFlag = 1;
585  seiChromaResamplingFilterHint->m_targetFormatIdc = 3;
586  seiChromaResamplingFilterHint->m_perfectReconstructionFlag = false;
587
588  // this creates some example filter values, if explicit filter definition is selected
589  if (seiChromaResamplingFilterHint->m_verChromaFilterIdc == 1)
590    {
591    const Int numVerticalFilters = 3;
592    const Int verTapLengthMinus1[] = {5,3,3};
593
594    seiChromaResamplingFilterHint->m_verFilterCoeff.resize(numVerticalFilters);
595    for(Int i = 0; i < numVerticalFilters; i ++)
596      {
597      seiChromaResamplingFilterHint->m_verFilterCoeff[i].resize(verTapLengthMinus1[i]+1);
598    }
599    // Note: C++11 -> seiChromaResamplingFilterHint->m_verFilterCoeff[0] = {-3,13,31,23,3,-3};
600    seiChromaResamplingFilterHint->m_verFilterCoeff[0][0] = -3;
601    seiChromaResamplingFilterHint->m_verFilterCoeff[0][1] = 13;
602    seiChromaResamplingFilterHint->m_verFilterCoeff[0][2] = 31;
603    seiChromaResamplingFilterHint->m_verFilterCoeff[0][3] = 23;
604    seiChromaResamplingFilterHint->m_verFilterCoeff[0][4] = 3;
605    seiChromaResamplingFilterHint->m_verFilterCoeff[0][5] = -3;
606
607    seiChromaResamplingFilterHint->m_verFilterCoeff[1][0] = -1;
608    seiChromaResamplingFilterHint->m_verFilterCoeff[1][1] = 25;
609    seiChromaResamplingFilterHint->m_verFilterCoeff[1][2] = 247;
610    seiChromaResamplingFilterHint->m_verFilterCoeff[1][3] = -15;
611
612    seiChromaResamplingFilterHint->m_verFilterCoeff[2][0] = -20;
613    seiChromaResamplingFilterHint->m_verFilterCoeff[2][1] = 186;
614    seiChromaResamplingFilterHint->m_verFilterCoeff[2][2] = 100;
615    seiChromaResamplingFilterHint->m_verFilterCoeff[2][3] = -10;
616  }
617  else
618  {
619    seiChromaResamplingFilterHint->m_verFilterCoeff.resize(0);
620  }
621
622  if (seiChromaResamplingFilterHint->m_horChromaFilterIdc == 1)
623    {
624    Int const numHorizontalFilters = 1;
625    const Int horTapLengthMinus1[] = {3};
626
627    seiChromaResamplingFilterHint->m_horFilterCoeff.resize(numHorizontalFilters);
628    for(Int i = 0; i < numHorizontalFilters; i ++)
629      {
630      seiChromaResamplingFilterHint->m_horFilterCoeff[i].resize(horTapLengthMinus1[i]+1);
631    }
632    seiChromaResamplingFilterHint->m_horFilterCoeff[0][0] = 1;
633    seiChromaResamplingFilterHint->m_horFilterCoeff[0][1] = 6;
634    seiChromaResamplingFilterHint->m_horFilterCoeff[0][2] = 1;
635  }
636  else
637  {
638    seiChromaResamplingFilterHint->m_horFilterCoeff.resize(0);
639  }
640}
641
642Void SEIEncoder::initSEITimeCode(SEITimeCode *seiTimeCode)
643{
644  assert (m_isInitialized);
645  assert (seiTimeCode!=NULL);
646  //  Set data as per command line options
647  seiTimeCode->numClockTs = m_pcCfg->getNumberOfTimesets();
648  for(Int i = 0; i < seiTimeCode->numClockTs; i++)
649  {
650    seiTimeCode->timeSetArray[i] = m_pcCfg->getTimeSet(i);
651  }
652}
653
654#if NH_MV
655Void SEIEncoder::createAnnexFGISeiMessages( SEIMessages& seiMessage, const TComSlice* slice )
656{
657  const SEIMessages* seiMessageCfg = m_pcCfg->getSeiMessages(); 
658
659  for( SEIMessages::const_iterator itS = seiMessageCfg->begin(); itS != seiMessageCfg->end(); itS++ )   
660  {     
661    const SEI* curSei = (*itS); 
662    SEI* newSei; 
663    if ( curSei->insertSei( slice->getLayerId(), slice->getPOC(), slice->getTemporalId(), slice->getNalUnitType() ) )
664    {
665      newSei = curSei->getCopy( ) ;
666
667      if ( curSei->m_modifyByEncoder )
668      {
669        newSei->setupFromSlice  ( slice ); 
670      } 
671
672      if ( newSei   ->checkCfg( slice ) )
673      {
674        std::cout << "--> Omit sending SEI."  <<  std::endl; 
675        delete newSei; 
676      }
677      else
678      {
679        seiMessage.push_back(newSei); 
680      }
681
682    }
683  }
684}
685#endif
686
687//! \}
Note: See TracBrowser for help on using the repository browser.