source: 3DVCSoftware/trunk/source/Lib/TLibDecoder/SEIread.cpp @ 1327

Last change on this file since 1327 was 1313, checked in by tech, 9 years ago

Merged 14.1-update-dev1@1312.

  • Property svn:eol-style set to native
File size: 50.6 KB
RevLine 
[5]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 *
[1313]6 * Copyright (c) 2010-2015, ITU/ISO/IEC
[5]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.
[56]17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
[5]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 */
[2]33
[1313]34/**
[608]35 \file     SEIread.cpp
[1313]36 \brief    reading funtionality for SEI messages
[608]37 */
38
39#include "TLibCommon/CommonDef.h"
[56]40#include "TLibCommon/TComBitStream.h"
41#include "TLibCommon/SEI.h"
[608]42#include "TLibCommon/TComSlice.h"
43#include "SyntaxElementParser.h"
[56]44#include "SEIread.h"
[1313]45#include "TLibCommon/TComPicYuv.h"
46#include <iomanip>
[2]47
[1313]48
[56]49//! \ingroup TLibDecoder
50//! \{
[5]51
[1313]52
[608]53#if ENC_DEC_TRACE
54Void  xTraceSEIHeader()
55{
56  fprintf( g_hTrace, "=========== SEI message ===========\n");
57}
[2]58
[608]59Void  xTraceSEIMessageType(SEI::PayloadType payloadType)
60{
[1313]61  fprintf( g_hTrace, "=========== %s SEI message ===========\n", SEI::getSEIMessageString(payloadType));
62}
63#endif
64
65Void SEIReader::sei_read_code(std::ostream *pOS, UInt uiLength, UInt& ruiCode, const Char *pSymbolName)
66{
67  READ_CODE(uiLength, ruiCode, pSymbolName);
68  if (pOS)
[608]69  {
[1313]70    (*pOS) << "  " << std::setw(55) << pSymbolName << ": " << ruiCode << "\n";
[608]71  }
72}
73
[1313]74Void SEIReader::sei_read_uvlc(std::ostream *pOS, UInt& ruiCode, const Char *pSymbolName)
75{
76  READ_UVLC(ruiCode, pSymbolName);
77  if (pOS)
78  {
79    (*pOS) << "  " << std::setw(55) << pSymbolName << ": " << ruiCode << "\n";
80  }
81}
82
83Void SEIReader::sei_read_svlc(std::ostream *pOS, Int& ruiCode, const Char *pSymbolName)
84{
85  READ_SVLC(ruiCode, pSymbolName);
86  if (pOS)
87  {
88    (*pOS) << "  " << std::setw(55) << pSymbolName << ": " << ruiCode << "\n";
89  }
90}
91
92Void SEIReader::sei_read_flag(std::ostream *pOS, UInt& ruiCode, const Char *pSymbolName)
93{
94  READ_FLAG(ruiCode, pSymbolName);
95  if (pOS)
96  {
97    (*pOS) << "  " << std::setw(55) << pSymbolName << ": " << (ruiCode?1:0) << "\n";
98  }
99}
100
101static inline Void output_sei_message_header(SEI &sei, std::ostream *pDecodedMessageOutputStream, UInt payloadSize)
102{
103  if (pDecodedMessageOutputStream)
104  {
105    std::string seiMessageHdr(SEI::getSEIMessageString(sei.payloadType())); seiMessageHdr+=" SEI message";
106    (*pDecodedMessageOutputStream) << std::setfill('-') << std::setw(seiMessageHdr.size()) << "-" << std::setfill(' ') << "\n" << seiMessageHdr << " (" << payloadSize << " bytes)"<< "\n";
107  }
108}
109
110#undef READ_CODE
111#undef READ_SVLC
112#undef READ_UVLC
113#undef READ_FLAG
114
115
[2]116/**
[56]117 * unmarshal a single SEI message from bitstream bs
[2]118 */
[1313]119Void SEIReader::parseSEImessage(TComInputBitstream* bs, SEIMessages& seis, const NalUnitType nalUnitType, const TComSPS *sps, std::ostream *pDecodedMessageOutputStream)
[2]120{
[608]121  setBitstream(bs);
122
123  assert(!m_pcBitstream->getNumBitsUntilByteAligned());
124  do
[2]125  {
[1313]126    xReadSEImessage(seis, nalUnitType, sps, pDecodedMessageOutputStream);
127
[608]128    /* SEI messages are an integer number of bytes, something has failed
129    * in the parsing if bitstream not byte-aligned */
130    assert(!m_pcBitstream->getNumBitsUntilByteAligned());
[1313]131  }
132  while (m_pcBitstream->getNumBitsLeft() > 8);
[2]133
[1313]134  xReadRbspTrailingBits();
[608]135}
136
[1313]137Void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType, const TComSPS *sps, std::ostream *pDecodedMessageOutputStream)
[608]138{
139#if ENC_DEC_TRACE
140  xTraceSEIHeader();
141#endif
142  Int payloadType = 0;
143  UInt val = 0;
144
145  do
[2]146  {
[1313]147    sei_read_code(NULL, 8, val, "payload_type");
[608]148    payloadType += val;
149  } while (val==0xFF);
150
151  UInt payloadSize = 0;
152  do
153  {
[1313]154    sei_read_code(NULL, 8, val, "payload_size");
[608]155    payloadSize += val;
156  } while (val==0xFF);
157
158#if ENC_DEC_TRACE
159  xTraceSEIMessageType((SEI::PayloadType)payloadType);
160#endif
161
162  /* extract the payload for this single SEI message.
163   * This allows greater safety in erroneous parsing of an SEI message
164   * from affecting subsequent messages.
165   * After parsing the payload, bs needs to be restored as the primary
166   * bitstream.
167   */
168  TComInputBitstream *bs = getBitstream();
169  setBitstream(bs->extractSubstream(payloadSize * 8));
170
171  SEI *sei = NULL;
172
173  if(nalUnitType == NAL_UNIT_PREFIX_SEI)
174  {
175    switch (payloadType)
176    {
177    case SEI::USER_DATA_UNREGISTERED:
178      sei = new SEIuserDataUnregistered;
[1313]179      xParseSEIuserDataUnregistered((SEIuserDataUnregistered&) *sei, payloadSize, pDecodedMessageOutputStream);
[608]180      break;
181    case SEI::ACTIVE_PARAMETER_SETS:
[1313]182      sei = new SEIActiveParameterSets;
183      xParseSEIActiveParameterSets((SEIActiveParameterSets&) *sei, payloadSize, pDecodedMessageOutputStream);
184      break;
[608]185    case SEI::DECODING_UNIT_INFO:
186      if (!sps)
187      {
188        printf ("Warning: Found Decoding unit SEI message, but no active SPS is available. Ignoring.");
189      }
190      else
191      {
[1313]192        sei = new SEIDecodingUnitInfo;
193        xParseSEIDecodingUnitInfo((SEIDecodingUnitInfo&) *sei, payloadSize, sps, pDecodedMessageOutputStream);
[608]194      }
[1313]195      break;
[608]196    case SEI::BUFFERING_PERIOD:
197      if (!sps)
198      {
199        printf ("Warning: Found Buffering period SEI message, but no active SPS is available. Ignoring.");
200      }
201      else
202      {
203        sei = new SEIBufferingPeriod;
[1313]204        xParseSEIBufferingPeriod((SEIBufferingPeriod&) *sei, payloadSize, sps, pDecodedMessageOutputStream);
[608]205      }
206      break;
207    case SEI::PICTURE_TIMING:
208      if (!sps)
209      {
210        printf ("Warning: Found Picture timing SEI message, but no active SPS is available. Ignoring.");
211      }
212      else
213      {
214        sei = new SEIPictureTiming;
[1313]215        xParseSEIPictureTiming((SEIPictureTiming&)*sei, payloadSize, sps, pDecodedMessageOutputStream);
[608]216      }
217      break;
218    case SEI::RECOVERY_POINT:
219      sei = new SEIRecoveryPoint;
[1313]220      xParseSEIRecoveryPoint((SEIRecoveryPoint&) *sei, payloadSize, pDecodedMessageOutputStream);
[608]221      break;
222    case SEI::FRAME_PACKING:
223      sei = new SEIFramePacking;
[1313]224      xParseSEIFramePacking((SEIFramePacking&) *sei, payloadSize, pDecodedMessageOutputStream);
[608]225      break;
[1313]226    case SEI::SEGM_RECT_FRAME_PACKING:
227      sei = new SEISegmentedRectFramePacking;
228      xParseSEISegmentedRectFramePacking((SEISegmentedRectFramePacking&) *sei, payloadSize, pDecodedMessageOutputStream);
229      break;
[608]230    case SEI::DISPLAY_ORIENTATION:
231      sei = new SEIDisplayOrientation;
[1313]232      xParseSEIDisplayOrientation((SEIDisplayOrientation&) *sei, payloadSize, pDecodedMessageOutputStream);
[608]233      break;
234    case SEI::TEMPORAL_LEVEL0_INDEX:
235      sei = new SEITemporalLevel0Index;
[1313]236      xParseSEITemporalLevel0Index((SEITemporalLevel0Index&) *sei, payloadSize, pDecodedMessageOutputStream);
[608]237      break;
238    case SEI::REGION_REFRESH_INFO:
239      sei = new SEIGradualDecodingRefreshInfo;
[1313]240      xParseSEIRegionRefreshInfo((SEIGradualDecodingRefreshInfo&) *sei, payloadSize, pDecodedMessageOutputStream);
[608]241      break;
[1313]242    case SEI::NO_DISPLAY:
243      sei = new SEINoDisplay;
244      xParseSEINoDisplay((SEINoDisplay&) *sei, payloadSize, pDecodedMessageOutputStream);
245      break;
[608]246    case SEI::TONE_MAPPING_INFO:
247      sei = new SEIToneMappingInfo;
[1313]248      xParseSEIToneMappingInfo((SEIToneMappingInfo&) *sei, payloadSize, pDecodedMessageOutputStream);
[608]249      break;
250    case SEI::SOP_DESCRIPTION:
251      sei = new SEISOPDescription;
[1313]252      xParseSEISOPDescription((SEISOPDescription&) *sei, payloadSize, pDecodedMessageOutputStream);
[608]253      break;
254    case SEI::SCALABLE_NESTING:
255      sei = new SEIScalableNesting;
[1313]256      xParseSEIScalableNesting((SEIScalableNesting&) *sei, nalUnitType, payloadSize, sps, pDecodedMessageOutputStream);
[608]257      break;
[1313]258    case SEI::TEMP_MOTION_CONSTRAINED_TILE_SETS:
259      sei = new SEITempMotionConstrainedTileSets;
260      xParseSEITempMotionConstraintsTileSets((SEITempMotionConstrainedTileSets&) *sei, payloadSize, pDecodedMessageOutputStream);
261      break;
262    case SEI::TIME_CODE:
263      sei = new SEITimeCode;
264      xParseSEITimeCode((SEITimeCode&) *sei, payloadSize, pDecodedMessageOutputStream);
265      break;
266    case SEI::CHROMA_SAMPLING_FILTER_HINT:
267      sei = new SEIChromaSamplingFilterHint;
268      xParseSEIChromaSamplingFilterHint((SEIChromaSamplingFilterHint&) *sei, payloadSize/*, sps*/, pDecodedMessageOutputStream);
269      //}
270      break;
271    case SEI::KNEE_FUNCTION_INFO:
272      sei = new SEIKneeFunctionInfo;
273      xParseSEIKneeFunctionInfo((SEIKneeFunctionInfo&) *sei, payloadSize, pDecodedMessageOutputStream);
274      break;
275    case SEI::MASTERING_DISPLAY_COLOUR_VOLUME:
276      sei = new SEIMasteringDisplayColourVolume;
277      xParseSEIMasteringDisplayColourVolume((SEIMasteringDisplayColourVolume&) *sei, payloadSize, pDecodedMessageOutputStream);
278      break;
279#if NH_MV
280    case SEI::SUB_BITSTREAM_PROPERTY:
281      sei = new SEISubBitstreamProperty;
282      xParseSEISubBitstreamProperty((SEISubBitstreamProperty&) *sei, payloadSize, pDecodedMessageOutputStream );
283      break;
[872]284#endif
[608]285    default:
286      for (UInt i = 0; i < payloadSize; i++)
287      {
288        UInt seiByte;
[1313]289        sei_read_code (NULL, 8, seiByte, "unknown prefix SEI payload byte");
[608]290      }
291      printf ("Unknown prefix SEI message (payloadType = %d) was found!\n", payloadType);
[1313]292      if (pDecodedMessageOutputStream)
293      {
294        (*pDecodedMessageOutputStream) << "Unknown prefix SEI message (payloadType = " << payloadType << ") was found!\n";
295      }
296      break;
[608]297    }
[2]298  }
[608]299  else
300  {
301    switch (payloadType)
302    {
303      case SEI::USER_DATA_UNREGISTERED:
304        sei = new SEIuserDataUnregistered;
[1313]305        xParseSEIuserDataUnregistered((SEIuserDataUnregistered&) *sei, payloadSize, pDecodedMessageOutputStream);
[608]306        break;
307      case SEI::DECODED_PICTURE_HASH:
308        sei = new SEIDecodedPictureHash;
[1313]309        xParseSEIDecodedPictureHash((SEIDecodedPictureHash&) *sei, payloadSize, pDecodedMessageOutputStream);
[608]310        break;
311      default:
312        for (UInt i = 0; i < payloadSize; i++)
313        {
314          UInt seiByte;
[1313]315          sei_read_code( NULL, 8, seiByte, "unknown suffix SEI payload byte");
[608]316        }
317        printf ("Unknown suffix SEI message (payloadType = %d) was found!\n", payloadType);
[1313]318        if (pDecodedMessageOutputStream)
319        {
320          (*pDecodedMessageOutputStream) << "Unknown suffix SEI message (payloadType = " << payloadType << ") was found!\n";
321        }
322        break;
[608]323    }
324  }
[1313]325
[608]326  if (sei != NULL)
327  {
328    seis.push_back(sei);
329  }
[2]330
[608]331  /* By definition the underlying bitstream terminates in a byte-aligned manner.
332   * 1. Extract all bar the last MIN(bitsremaining,nine) bits as reserved_payload_extension_data
333   * 2. Examine the final 8 bits to determine the payload_bit_equal_to_one marker
334   * 3. Extract the remainingreserved_payload_extension_data bits.
335   *
336   * If there are fewer than 9 bits available, extract them.
337   */
338  Int payloadBitsRemaining = getBitstream()->getNumBitsLeft();
339  if (payloadBitsRemaining) /* more_data_in_payload() */
[2]340  {
[608]341    for (; payloadBitsRemaining > 9; payloadBitsRemaining--)
342    {
343      UInt reservedPayloadExtensionData;
[1313]344      sei_read_code ( pDecodedMessageOutputStream, 1, reservedPayloadExtensionData, "reserved_payload_extension_data");
[608]345    }
346
347    /* 2 */
348    Int finalBits = getBitstream()->peekBits(payloadBitsRemaining);
349    Int finalPayloadBits = 0;
350    for (Int mask = 0xff; finalBits & (mask >> finalPayloadBits); finalPayloadBits++)
351    {
352      continue;
353    }
354
355    /* 3 */
356    for (; payloadBitsRemaining > 9 - finalPayloadBits; payloadBitsRemaining--)
357    {
358      UInt reservedPayloadExtensionData;
[1313]359      sei_read_flag ( 0, reservedPayloadExtensionData, "reserved_payload_extension_data");
[608]360    }
361
362    UInt dummy;
[1313]363    sei_read_flag( 0, dummy, "payload_bit_equal_to_one"); payloadBitsRemaining--;
[608]364    while (payloadBitsRemaining)
365    {
[1313]366      sei_read_flag( 0, dummy, "payload_bit_equal_to_zero"); payloadBitsRemaining--;
[608]367    }
[2]368  }
[608]369
370  /* restore primary bitstream for sei_message */
371  delete getBitstream();
372  setBitstream(bs);
[2]373}
374
375/**
[56]376 * parse bitstream bs and unpack a user_data_unregistered SEI message
377 * of payloasSize bytes into sei.
[2]378 */
[1313]379
380Void SEIReader::xParseSEIuserDataUnregistered(SEIuserDataUnregistered &sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
[2]381{
[1313]382  assert(payloadSize >= ISO_IEC_11578_LEN);
[608]383  UInt val;
[1313]384  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
[608]385
[1313]386  for (UInt i = 0; i < ISO_IEC_11578_LEN; i++)
[2]387  {
[1313]388    sei_read_code( pDecodedMessageOutputStream, 8, val, "uuid_iso_iec_11578");
[608]389    sei.uuid_iso_iec_11578[i] = val;
[2]390  }
391
[1313]392  sei.userDataLength = payloadSize - ISO_IEC_11578_LEN;
[2]393  if (!sei.userDataLength)
394  {
395    sei.userData = 0;
396    return;
397  }
398
[608]399  sei.userData = new UChar[sei.userDataLength];
400  for (UInt i = 0; i < sei.userDataLength; i++)
[2]401  {
[1313]402    sei_read_code( NULL, 8, val, "user_data_payload_byte" );
[608]403    sei.userData[i] = val;
[2]404  }
[1313]405  if (pDecodedMessageOutputStream)
406  {
407    (*pDecodedMessageOutputStream) << "  User data payload size: " << sei.userDataLength << "\n";
408  }
[2]409}
410
411/**
[608]412 * parse bitstream bs and unpack a decoded picture hash SEI message
[56]413 * of payloadSize bytes into sei.
[2]414 */
[1313]415Void SEIReader::xParseSEIDecodedPictureHash(SEIDecodedPictureHash& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
[2]416{
[1313]417  UInt bytesRead = 0;
418  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
419
[608]420  UInt val;
[1313]421  sei_read_code( pDecodedMessageOutputStream, 8, val, "hash_type");
422  sei.method = static_cast<SEIDecodedPictureHash::Method>(val); bytesRead++;
423
424  const Char *traceString="\0";
425  switch (sei.method)
[2]426  {
[1313]427    case SEIDecodedPictureHash::MD5: traceString="picture_md5"; break;
428    case SEIDecodedPictureHash::CRC: traceString="picture_crc"; break;
429    case SEIDecodedPictureHash::CHECKSUM: traceString="picture_checksum"; break;
430    default: assert(false); break;
431  }
432
433  if (pDecodedMessageOutputStream)
434  {
435    (*pDecodedMessageOutputStream) << "  " << std::setw(55) << traceString << ": " << std::hex << std::setfill('0');
436  }
437
438  sei.m_pictureHash.hash.clear();
439  for(;bytesRead < payloadSize; bytesRead++)
440  {
441    sei_read_code( NULL, 8, val, traceString);
442    sei.m_pictureHash.hash.push_back((UChar)val);
443    if (pDecodedMessageOutputStream)
[608]444    {
[1313]445      (*pDecodedMessageOutputStream) << std::setw(2) << val;
[608]446    }
[2]447  }
[1313]448
449  if (pDecodedMessageOutputStream)
450  {
451    (*pDecodedMessageOutputStream) << std::dec << std::setfill(' ') << "\n";
452  }
[2]453}
[1313]454
455Void SEIReader::xParseSEIActiveParameterSets(SEIActiveParameterSets& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
[608]456{
457  UInt val; 
[1313]458  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
[2]459
[1313]460  sei_read_code( pDecodedMessageOutputStream, 4, val, "active_video_parameter_set_id");   sei.activeVPSId = val;
461  sei_read_flag( pDecodedMessageOutputStream,    val, "self_contained_cvs_flag");         sei.m_selfContainedCvsFlag     = (val != 0);
462  sei_read_flag( pDecodedMessageOutputStream,    val, "no_parameter_set_update_flag");    sei.m_noParameterSetUpdateFlag = (val != 0);
463  sei_read_uvlc( pDecodedMessageOutputStream,    val, "num_sps_ids_minus1");              sei.numSpsIdsMinus1 = val;
464
[964]465  sei.activeSeqParameterSetId.resize(sei.numSpsIdsMinus1 + 1);
[608]466  for (Int i=0; i < (sei.numSpsIdsMinus1 + 1); i++)
467  {
[1313]468    sei_read_uvlc( pDecodedMessageOutputStream, val, "active_seq_parameter_set_id[i]");    sei.activeSeqParameterSetId[i] = val;
[608]469  }
470}
471
[1313]472Void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, UInt payloadSize, const TComSPS *sps, std::ostream *pDecodedMessageOutputStream)
[608]473{
474  UInt val;
[1313]475  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
476  sei_read_uvlc( pDecodedMessageOutputStream, val, "decoding_unit_idx");
[608]477  sei.m_decodingUnitIdx = val;
478
[1313]479  const TComVUI *vui = sps->getVuiParameters();
[608]480  if(vui->getHrdParameters()->getSubPicCpbParamsInPicTimingSEIFlag())
481  {
[1313]482    sei_read_code( pDecodedMessageOutputStream, ( vui->getHrdParameters()->getDuCpbRemovalDelayLengthMinus1() + 1 ), val, "du_spt_cpb_removal_delay_increment");
[608]483    sei.m_duSptCpbRemovalDelay = val;
484  }
485  else
486  {
487    sei.m_duSptCpbRemovalDelay = 0;
488  }
[1313]489  sei_read_flag( pDecodedMessageOutputStream, val, "dpb_output_du_delay_present_flag"); sei.m_dpbOutputDuDelayPresentFlag = (val != 0);
[608]490  if(sei.m_dpbOutputDuDelayPresentFlag)
491  {
[1313]492    sei_read_code( pDecodedMessageOutputStream, vui->getHrdParameters()->getDpbOutputDelayDuLengthMinus1() + 1, val, "pic_spt_dpb_output_du_delay");
[608]493    sei.m_picSptDpbOutputDuDelay = val;
494  }
495}
496
[1313]497Void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, UInt payloadSize, const TComSPS *sps, std::ostream *pDecodedMessageOutputStream)
[608]498{
499  Int i, nalOrVcl;
500  UInt code;
501
[1313]502  const TComVUI *pVUI = sps->getVuiParameters();
503  const TComHRD *pHRD = pVUI->getHrdParameters();
[608]504
[1313]505  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
506
507  sei_read_uvlc( pDecodedMessageOutputStream, code, "bp_seq_parameter_set_id" );                         sei.m_bpSeqParameterSetId     = code;
[608]508  if( !pHRD->getSubPicCpbParamsPresentFlag() )
509  {
[1313]510    sei_read_flag( pDecodedMessageOutputStream, code, "irap_cpb_params_present_flag" );                   sei.m_rapCpbParamsPresentFlag = code;
[608]511  }
[872]512  if( sei.m_rapCpbParamsPresentFlag )
513  {
[1313]514    sei_read_code( pDecodedMessageOutputStream, pHRD->getCpbRemovalDelayLengthMinus1() + 1, code, "cpb_delay_offset" );      sei.m_cpbDelayOffset = code;
515    sei_read_code( pDecodedMessageOutputStream, pHRD->getDpbOutputDelayLengthMinus1()  + 1, code, "dpb_delay_offset" );      sei.m_dpbDelayOffset = code;
[872]516  }
[1313]517
[608]518  //read splicing flag and cpb_removal_delay_delta
[1313]519  sei_read_flag( pDecodedMessageOutputStream, code, "concatenation_flag");
[608]520  sei.m_concatenationFlag = code;
[1313]521  sei_read_code( pDecodedMessageOutputStream, ( pHRD->getCpbRemovalDelayLengthMinus1() + 1 ), code, "au_cpb_removal_delay_delta_minus1" );
[608]522  sei.m_auCpbRemovalDelayDelta = code + 1;
[1313]523
[608]524  for( nalOrVcl = 0; nalOrVcl < 2; nalOrVcl ++ )
525  {
526    if( ( ( nalOrVcl == 0 ) && ( pHRD->getNalHrdParametersPresentFlag() ) ) ||
527        ( ( nalOrVcl == 1 ) && ( pHRD->getVclHrdParametersPresentFlag() ) ) )
528    {
529      for( i = 0; i < ( pHRD->getCpbCntMinus1( 0 ) + 1 ); i ++ )
530      {
[1313]531        sei_read_code( pDecodedMessageOutputStream, ( pHRD->getInitialCpbRemovalDelayLengthMinus1() + 1 ) , code, nalOrVcl?"vcl_initial_cpb_removal_delay":"nal_initial_cpb_removal_delay" );
[608]532        sei.m_initialCpbRemovalDelay[i][nalOrVcl] = code;
[1313]533        sei_read_code( pDecodedMessageOutputStream, ( pHRD->getInitialCpbRemovalDelayLengthMinus1() + 1 ) , code, nalOrVcl?"vcl_initial_cpb_removal_offset":"vcl_initial_cpb_removal_offset" );
[608]534        sei.m_initialCpbRemovalDelayOffset[i][nalOrVcl] = code;
535        if( pHRD->getSubPicCpbParamsPresentFlag() || sei.m_rapCpbParamsPresentFlag )
536        {
[1313]537          sei_read_code( pDecodedMessageOutputStream, ( pHRD->getInitialCpbRemovalDelayLengthMinus1() + 1 ) , code, nalOrVcl?"vcl_initial_alt_cpb_removal_delay":"vcl_initial_alt_cpb_removal_delay" );
[608]538          sei.m_initialAltCpbRemovalDelay[i][nalOrVcl] = code;
[1313]539          sei_read_code( pDecodedMessageOutputStream, ( pHRD->getInitialCpbRemovalDelayLengthMinus1() + 1 ) , code, nalOrVcl?"vcl_initial_alt_cpb_removal_offset":"vcl_initial_alt_cpb_removal_offset" );
[608]540          sei.m_initialAltCpbRemovalDelayOffset[i][nalOrVcl] = code;
541        }
542      }
543    }
544  }
545}
[1313]546
547Void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, UInt payloadSize, const TComSPS *sps, std::ostream *pDecodedMessageOutputStream)
[608]548{
549  Int i;
550  UInt code;
551
[1313]552  const TComVUI *vui = sps->getVuiParameters();
553  const TComHRD *hrd = vui->getHrdParameters();
554  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
[608]555
556  if( vui->getFrameFieldInfoPresentFlag() )
557  {
[1313]558    sei_read_code( pDecodedMessageOutputStream, 4, code, "pic_struct" );             sei.m_picStruct            = code;
559    sei_read_code( pDecodedMessageOutputStream, 2, code, "source_scan_type" );       sei.m_sourceScanType       = code;
560    sei_read_flag( pDecodedMessageOutputStream,    code, "duplicate_flag" );         sei.m_duplicateFlag        = (code == 1);
[608]561  }
562
563  if( hrd->getCpbDpbDelaysPresentFlag())
564  {
[1313]565    sei_read_code( pDecodedMessageOutputStream, ( hrd->getCpbRemovalDelayLengthMinus1() + 1 ), code, "au_cpb_removal_delay_minus1" );
[608]566    sei.m_auCpbRemovalDelay = code + 1;
[1313]567    sei_read_code( pDecodedMessageOutputStream, ( hrd->getDpbOutputDelayLengthMinus1() + 1 ), code, "pic_dpb_output_delay" );
[608]568    sei.m_picDpbOutputDelay = code;
569
570    if(hrd->getSubPicCpbParamsPresentFlag())
571    {
[1313]572      sei_read_code( pDecodedMessageOutputStream, hrd->getDpbOutputDelayDuLengthMinus1()+1, code, "pic_dpb_output_du_delay" );
[608]573      sei.m_picDpbOutputDuDelay = code;
574    }
[1313]575
[608]576    if( hrd->getSubPicCpbParamsPresentFlag() && hrd->getSubPicCpbParamsInPicTimingSEIFlag() )
577    {
[1313]578      sei_read_uvlc( pDecodedMessageOutputStream, code, "num_decoding_units_minus1");
[608]579      sei.m_numDecodingUnitsMinus1 = code;
[1313]580      sei_read_flag( pDecodedMessageOutputStream, code, "du_common_cpb_removal_delay_flag" );
[608]581      sei.m_duCommonCpbRemovalDelayFlag = code;
582      if( sei.m_duCommonCpbRemovalDelayFlag )
583      {
[1313]584        sei_read_code( pDecodedMessageOutputStream, ( hrd->getDuCpbRemovalDelayLengthMinus1() + 1 ), code, "du_common_cpb_removal_delay_increment_minus1" );
[608]585        sei.m_duCommonCpbRemovalDelayMinus1 = code;
586      }
[1313]587      sei.m_numNalusInDuMinus1.resize(sei.m_numDecodingUnitsMinus1 + 1 );
588      sei.m_duCpbRemovalDelayMinus1.resize( sei.m_numDecodingUnitsMinus1 + 1 );
[608]589
590      for( i = 0; i <= sei.m_numDecodingUnitsMinus1; i ++ )
591      {
[1313]592        sei_read_uvlc( pDecodedMessageOutputStream, code, "num_nalus_in_du_minus1[i]");
[608]593        sei.m_numNalusInDuMinus1[ i ] = code;
594        if( ( !sei.m_duCommonCpbRemovalDelayFlag ) && ( i < sei.m_numDecodingUnitsMinus1 ) )
595        {
[1313]596          sei_read_code( pDecodedMessageOutputStream, ( hrd->getDuCpbRemovalDelayLengthMinus1() + 1 ), code, "du_cpb_removal_delay_minus1[i]" );
[608]597          sei.m_duCpbRemovalDelayMinus1[ i ] = code;
598        }
599      }
600    }
601  }
602}
[1313]603
604Void SEIReader::xParseSEIRecoveryPoint(SEIRecoveryPoint& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
[608]605{
606  Int  iCode;
607  UInt uiCode;
[1313]608  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
609
610  sei_read_svlc( pDecodedMessageOutputStream, iCode,  "recovery_poc_cnt" );      sei.m_recoveryPocCnt     = iCode;
611  sei_read_flag( pDecodedMessageOutputStream, uiCode, "exact_matching_flag" );   sei.m_exactMatchingFlag  = uiCode;
612  sei_read_flag( pDecodedMessageOutputStream, uiCode, "broken_link_flag" );      sei.m_brokenLinkFlag     = uiCode;
[608]613}
[1313]614
615Void SEIReader::xParseSEIFramePacking(SEIFramePacking& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
[608]616{
617  UInt val;
[1313]618  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
[608]619
[1313]620  sei_read_uvlc( pDecodedMessageOutputStream, val, "frame_packing_arrangement_id" );                 sei.m_arrangementId = val;
621  sei_read_flag( pDecodedMessageOutputStream, val, "frame_packing_arrangement_cancel_flag" );        sei.m_arrangementCancelFlag = val;
622
[608]623  if ( !sei.m_arrangementCancelFlag )
624  {
[1313]625    sei_read_code( pDecodedMessageOutputStream, 7, val, "frame_packing_arrangement_type" );          sei.m_arrangementType = val;
[608]626    assert((sei.m_arrangementType > 2) && (sei.m_arrangementType < 6) );
627
[1313]628    sei_read_flag( pDecodedMessageOutputStream, val, "quincunx_sampling_flag" );                     sei.m_quincunxSamplingFlag = val;
[608]629
[1313]630    sei_read_code( pDecodedMessageOutputStream, 6, val, "content_interpretation_type" );             sei.m_contentInterpretationType = val;
631    sei_read_flag( pDecodedMessageOutputStream, val, "spatial_flipping_flag" );                      sei.m_spatialFlippingFlag = val;
632    sei_read_flag( pDecodedMessageOutputStream, val, "frame0_flipped_flag" );                        sei.m_frame0FlippedFlag = val;
633    sei_read_flag( pDecodedMessageOutputStream, val, "field_views_flag" );                           sei.m_fieldViewsFlag = val;
634    sei_read_flag( pDecodedMessageOutputStream, val, "current_frame_is_frame0_flag" );               sei.m_currentFrameIsFrame0Flag = val;
635    sei_read_flag( pDecodedMessageOutputStream, val, "frame0_self_contained_flag" );                 sei.m_frame0SelfContainedFlag = val;
636    sei_read_flag( pDecodedMessageOutputStream, val, "frame1_self_contained_flag" );                 sei.m_frame1SelfContainedFlag = val;
637
[608]638    if ( sei.m_quincunxSamplingFlag == 0 && sei.m_arrangementType != 5)
639    {
[1313]640      sei_read_code( pDecodedMessageOutputStream, 4, val, "frame0_grid_position_x" );                sei.m_frame0GridPositionX = val;
641      sei_read_code( pDecodedMessageOutputStream, 4, val, "frame0_grid_position_y" );                sei.m_frame0GridPositionY = val;
642      sei_read_code( pDecodedMessageOutputStream, 4, val, "frame1_grid_position_x" );                sei.m_frame1GridPositionX = val;
643      sei_read_code( pDecodedMessageOutputStream, 4, val, "frame1_grid_position_y" );                sei.m_frame1GridPositionY = val;
[608]644    }
645
[1313]646    sei_read_code( pDecodedMessageOutputStream, 8, val, "frame_packing_arrangement_reserved_byte" );   sei.m_arrangementReservedByte = val;
647    sei_read_flag( pDecodedMessageOutputStream, val,  "frame_packing_arrangement_persistence_flag" );  sei.m_arrangementPersistenceFlag = (val != 0);
[608]648  }
[1313]649  sei_read_flag( pDecodedMessageOutputStream, val, "upsampled_aspect_ratio_flag" );                  sei.m_upsampledAspectRatio = val;
650}
[608]651
[1313]652Void SEIReader::xParseSEISegmentedRectFramePacking(SEISegmentedRectFramePacking& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
653{
654  UInt val;
655  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
656  sei_read_flag( pDecodedMessageOutputStream, val,       "segmented_rect_frame_packing_arrangement_cancel_flag" );       sei.m_arrangementCancelFlag            = val;
657  if( !sei.m_arrangementCancelFlag )
658  {
659    sei_read_code( pDecodedMessageOutputStream, 2, val, "segmented_rect_content_interpretation_type" );                sei.m_contentInterpretationType = val;
660    sei_read_flag( pDecodedMessageOutputStream, val,     "segmented_rect_frame_packing_arrangement_persistence" );                              sei.m_arrangementPersistenceFlag               = val;
661  }
[608]662}
663
[1313]664Void SEIReader::xParseSEIDisplayOrientation(SEIDisplayOrientation& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
[608]665{
666  UInt val;
[1313]667  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
668  sei_read_flag( pDecodedMessageOutputStream, val,       "display_orientation_cancel_flag" );       sei.cancelFlag            = val;
669  if( !sei.cancelFlag )
[608]670  {
[1313]671    sei_read_flag( pDecodedMessageOutputStream, val,     "hor_flip" );                              sei.horFlip               = val;
672    sei_read_flag( pDecodedMessageOutputStream, val,     "ver_flip" );                              sei.verFlip               = val;
673    sei_read_code( pDecodedMessageOutputStream, 16, val, "anticlockwise_rotation" );                sei.anticlockwiseRotation = val;
674    sei_read_flag( pDecodedMessageOutputStream, val,     "display_orientation_persistence_flag" );  sei.persistenceFlag       = val;
[608]675  }
676}
677
[1313]678Void SEIReader::xParseSEITemporalLevel0Index(SEITemporalLevel0Index& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
[608]679{
680  UInt val;
[1313]681  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
682  sei_read_code( pDecodedMessageOutputStream, 8, val, "temporal_sub_layer_zero_idx" );  sei.tl0Idx = val;
683  sei_read_code( pDecodedMessageOutputStream, 8, val, "irap_pic_id" );  sei.rapIdx = val;
[608]684}
685
[1313]686Void SEIReader::xParseSEIRegionRefreshInfo(SEIGradualDecodingRefreshInfo& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
[608]687{
688  UInt val;
[1313]689  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
690  sei_read_flag( pDecodedMessageOutputStream, val, "refreshed_region_flag" ); sei.m_gdrForegroundFlag = val ? 1 : 0;
[608]691}
692
[1313]693Void SEIReader::xParseSEINoDisplay(SEINoDisplay& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
[608]694{
[1313]695  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
696  sei.m_noDisplay = true;
697}
698
699Void SEIReader::xParseSEIToneMappingInfo(SEIToneMappingInfo& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
700{
[608]701  Int i;
702  UInt val;
[1313]703  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
704  sei_read_uvlc( pDecodedMessageOutputStream, val, "tone_map_id" );                         sei.m_toneMapId = val;
705  sei_read_flag( pDecodedMessageOutputStream, val, "tone_map_cancel_flag" );                sei.m_toneMapCancelFlag = val;
[608]706
707  if ( !sei.m_toneMapCancelFlag )
708  {
[1313]709    sei_read_flag( pDecodedMessageOutputStream, val, "tone_map_persistence_flag" );         sei.m_toneMapPersistenceFlag = val;
710    sei_read_code( pDecodedMessageOutputStream, 8, val, "coded_data_bit_depth" );           sei.m_codedDataBitDepth = val;
711    sei_read_code( pDecodedMessageOutputStream, 8, val, "target_bit_depth" );               sei.m_targetBitDepth = val;
712    sei_read_uvlc( pDecodedMessageOutputStream, val, "tone_map_model_id" );                 sei.m_modelId = val;
[608]713    switch(sei.m_modelId)
714    {
715    case 0:
716      {
[1313]717        sei_read_code( pDecodedMessageOutputStream, 32, val, "min_value" );                 sei.m_minValue = val;
718        sei_read_code( pDecodedMessageOutputStream, 32, val, "max_value" );                 sei.m_maxValue = val;
[608]719        break;
720      }
721    case 1:
722      {
[1313]723        sei_read_code( pDecodedMessageOutputStream, 32, val, "sigmoid_midpoint" );          sei.m_sigmoidMidpoint = val;
724        sei_read_code( pDecodedMessageOutputStream, 32, val, "sigmoid_width" );             sei.m_sigmoidWidth = val;
[608]725        break;
726      }
727    case 2:
728      {
729        UInt num = 1u << sei.m_targetBitDepth;
730        sei.m_startOfCodedInterval.resize(num+1);
731        for(i = 0; i < num; i++)
732        {
[1313]733          sei_read_code( pDecodedMessageOutputStream, ((( sei.m_codedDataBitDepth + 7 ) >> 3 ) << 3), val, "start_of_coded_interval[i]" );
[608]734          sei.m_startOfCodedInterval[i] = val;
735        }
736        sei.m_startOfCodedInterval[num] = 1u << sei.m_codedDataBitDepth;
737        break;
738      }
739    case 3:
740      {
[1313]741        sei_read_code( pDecodedMessageOutputStream, 16, val,  "num_pivots" );                       sei.m_numPivots = val;
[608]742        sei.m_codedPivotValue.resize(sei.m_numPivots);
743        sei.m_targetPivotValue.resize(sei.m_numPivots);
744        for(i = 0; i < sei.m_numPivots; i++ )
745        {
[1313]746          sei_read_code( pDecodedMessageOutputStream, ((( sei.m_codedDataBitDepth + 7 ) >> 3 ) << 3), val, "coded_pivot_value[i]" );
[608]747          sei.m_codedPivotValue[i] = val;
[1313]748          sei_read_code( pDecodedMessageOutputStream, ((( sei.m_targetBitDepth + 7 ) >> 3 ) << 3),    val, "target_pivot_value[i]" );
[608]749          sei.m_targetPivotValue[i] = val;
750        }
751        break;
752      }
753    case 4:
754      {
[1313]755        sei_read_code( pDecodedMessageOutputStream, 8, val, "camera_iso_speed_idc" );                     sei.m_cameraIsoSpeedIdc = val;
[964]756        if( sei.m_cameraIsoSpeedIdc == 255) //Extended_ISO
[608]757        {
[1313]758          sei_read_code( pDecodedMessageOutputStream, 32,   val,   "camera_iso_speed_value" );            sei.m_cameraIsoSpeedValue = val;
[608]759        }
[1313]760        sei_read_code( pDecodedMessageOutputStream, 8, val, "exposure_index_idc" );                       sei.m_exposureIndexIdc = val;
[964]761        if( sei.m_exposureIndexIdc == 255) //Extended_ISO
762        {
[1313]763          sei_read_code( pDecodedMessageOutputStream, 32,   val,   "exposure_index_value" );              sei.m_exposureIndexValue = val;
[964]764        }
[1313]765        sei_read_flag( pDecodedMessageOutputStream, val, "exposure_compensation_value_sign_flag" );       sei.m_exposureCompensationValueSignFlag = val;
766        sei_read_code( pDecodedMessageOutputStream, 16, val, "exposure_compensation_value_numerator" );   sei.m_exposureCompensationValueNumerator = val;
767        sei_read_code( pDecodedMessageOutputStream, 16, val, "exposure_compensation_value_denom_idc" );   sei.m_exposureCompensationValueDenomIdc = val;
768        sei_read_code( pDecodedMessageOutputStream, 32, val, "ref_screen_luminance_white" );              sei.m_refScreenLuminanceWhite = val;
769        sei_read_code( pDecodedMessageOutputStream, 32, val, "extended_range_white_level" );              sei.m_extendedRangeWhiteLevel = val;
770        sei_read_code( pDecodedMessageOutputStream, 16, val, "nominal_black_level_code_value" );          sei.m_nominalBlackLevelLumaCodeValue = val;
771        sei_read_code( pDecodedMessageOutputStream, 16, val, "nominal_white_level_code_value" );          sei.m_nominalWhiteLevelLumaCodeValue= val;
772        sei_read_code( pDecodedMessageOutputStream, 16, val, "extended_white_level_code_value" );         sei.m_extendedWhiteLevelLumaCodeValue = val;
[608]773        break;
774      }
775    default:
776      {
777        assert(!"Undefined SEIToneMapModelId");
778        break;
779      }
780    }//switch model id
[1313]781  }// if(!sei.m_toneMapCancelFlag)
[608]782}
783
[1313]784Void SEIReader::xParseSEISOPDescription(SEISOPDescription &sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
[608]785{
786  Int iCode;
787  UInt uiCode;
[1313]788  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
[608]789
[1313]790  sei_read_uvlc( pDecodedMessageOutputStream, uiCode,           "sop_seq_parameter_set_id"            ); sei.m_sopSeqParameterSetId = uiCode;
791  sei_read_uvlc( pDecodedMessageOutputStream, uiCode,           "num_pics_in_sop_minus1"              ); sei.m_numPicsInSopMinus1 = uiCode;
[608]792  for (UInt i = 0; i <= sei.m_numPicsInSopMinus1; i++)
793  {
[1313]794    sei_read_code( pDecodedMessageOutputStream, 6, uiCode,                     "sop_vcl_nut[i]" );  sei.m_sopDescVclNaluType[i] = uiCode;
795    sei_read_code( pDecodedMessageOutputStream, 3, sei.m_sopDescTemporalId[i], "sop_temporal_id[i]"   );  sei.m_sopDescTemporalId[i] = uiCode;
[608]796    if (sei.m_sopDescVclNaluType[i] != NAL_UNIT_CODED_SLICE_IDR_W_RADL && sei.m_sopDescVclNaluType[i] != NAL_UNIT_CODED_SLICE_IDR_N_LP)
797    {
[1313]798      sei_read_uvlc( pDecodedMessageOutputStream, sei.m_sopDescStRpsIdx[i],    "sop_short_term_rps_idx[i]"    ); sei.m_sopDescStRpsIdx[i] = uiCode;
[608]799    }
800    if (i > 0)
801    {
[1313]802      sei_read_svlc( pDecodedMessageOutputStream, iCode,                       "sop_poc_delta[i]"     ); sei.m_sopDescPocDelta[i] = iCode;
[608]803    }
804  }
805}
806
[1313]807Void SEIReader::xParseSEIScalableNesting(SEIScalableNesting& sei, const NalUnitType nalUnitType, UInt payloadSize, const TComSPS *sps, std::ostream *pDecodedMessageOutputStream)
[608]808{
809  UInt uiCode;
810  SEIMessages seis;
[1313]811  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
[608]812
[1313]813  sei_read_flag( pDecodedMessageOutputStream, uiCode,            "bitstream_subset_flag"         ); sei.m_bitStreamSubsetFlag = uiCode;
814  sei_read_flag( pDecodedMessageOutputStream, uiCode,            "nesting_op_flag"               ); sei.m_nestingOpFlag = uiCode;
[608]815  if (sei.m_nestingOpFlag)
816  {
[1313]817    sei_read_flag( pDecodedMessageOutputStream, uiCode,            "default_op_flag"               ); sei.m_defaultOpFlag = uiCode;
818    sei_read_uvlc( pDecodedMessageOutputStream, uiCode,            "nesting_num_ops_minus1"        ); sei.m_nestingNumOpsMinus1 = uiCode;
[608]819    for (UInt i = sei.m_defaultOpFlag; i <= sei.m_nestingNumOpsMinus1; i++)
820    {
[1313]821      sei_read_code( pDecodedMessageOutputStream, 3,        uiCode,  "nesting_max_temporal_id_plus1[i]"   ); sei.m_nestingMaxTemporalIdPlus1[i] = uiCode;
822      sei_read_uvlc( pDecodedMessageOutputStream, uiCode,            "nesting_op_idx[i]"                  ); sei.m_nestingOpIdx[i] = uiCode;
[608]823    }
824  }
825  else
826  {
[1313]827    sei_read_flag( pDecodedMessageOutputStream, uiCode,            "all_layers_flag"               ); sei.m_allLayersFlag       = uiCode;
[608]828    if (!sei.m_allLayersFlag)
829    {
[1313]830      sei_read_code( pDecodedMessageOutputStream, 3,        uiCode,  "nesting_no_op_max_temporal_id_plus1"  ); sei.m_nestingNoOpMaxTemporalIdPlus1 = uiCode;
831      sei_read_uvlc( pDecodedMessageOutputStream, uiCode,            "nesting_num_layers_minus1"            ); sei.m_nestingNumLayersMinus1        = uiCode;
[608]832      for (UInt i = 0; i <= sei.m_nestingNumLayersMinus1; i++)
833      {
[1313]834        sei_read_code( pDecodedMessageOutputStream, 6,           uiCode,     "nesting_layer_id[i]"      ); sei.m_nestingLayerId[i]   = uiCode;
[608]835      }
836    }
837  }
838
839  // byte alignment
840  while ( m_pcBitstream->getNumBitsRead() % 8 != 0 )
841  {
842    UInt code;
[1313]843    sei_read_flag( pDecodedMessageOutputStream, code, "nesting_zero_bit" );
[608]844  }
845
846  // read nested SEI messages
[1313]847  do
848  {
849    xReadSEImessage(sei.m_nestedSEIs, nalUnitType, sps, pDecodedMessageOutputStream);
[608]850  } while (m_pcBitstream->getNumBitsLeft() > 8);
851
[1313]852  if (pDecodedMessageOutputStream)
853  {
854    (*pDecodedMessageOutputStream) << "End of scalable nesting SEI message\n";
855  }
[608]856}
[1313]857
858#if NH_MV
859Void SEIReader::xParseSEISubBitstreamProperty(SEISubBitstreamProperty &sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream )
[872]860{
[1313]861  UInt code;
862  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
863  sei_read_code( pDecodedMessageOutputStream, 4, code, "active_vps_id" );                      sei.m_activeVpsId = code;
864  sei_read_uvlc( pDecodedMessageOutputStream, code, "num_additional_sub_streams_minus1" );     sei.m_numAdditionalSubStreams = code + 1;
[608]865
[872]866  xResizeSubBitstreamPropertySeiArrays(sei);
867  for( Int i = 0; i < sei.m_numAdditionalSubStreams; i++ )
868  {
[1313]869    sei_read_code( pDecodedMessageOutputStream,   2, code, "sub_bitstream_mode[i]"           ); sei.m_subBitstreamMode[i] = code;
870    sei_read_uvlc( pDecodedMessageOutputStream,  code, "output_layer_set_idx_to_vps[i]"      ); sei.m_outputLayerSetIdxToVps[i] = code;
871    sei_read_code( pDecodedMessageOutputStream,   3, code, "highest_sub_layer_id[i]"         ); sei.m_highestSublayerId[i] = code;
872    sei_read_code( pDecodedMessageOutputStream,  16, code, "avg_bit_rate[i]"                 ); sei.m_avgBitRate[i] = code;
873    sei_read_code( pDecodedMessageOutputStream,  16, code, "max_bit_rate[i]"                 ); sei.m_maxBitRate[i] = code;
874  } 
[872]875}
[1313]876
[872]877Void SEIReader::xResizeSubBitstreamPropertySeiArrays(SEISubBitstreamProperty &sei)
878{
879  sei.m_subBitstreamMode.resize( sei.m_numAdditionalSubStreams );
880  sei.m_outputLayerSetIdxToVps.resize( sei.m_numAdditionalSubStreams );
881  sei.m_highestSublayerId.resize( sei.m_numAdditionalSubStreams );
882  sei.m_avgBitRate.resize( sei.m_numAdditionalSubStreams );
883  sei.m_maxBitRate.resize( sei.m_numAdditionalSubStreams );
884}
885#endif
886
[1313]887
888Void SEIReader::xParseSEITempMotionConstraintsTileSets(SEITempMotionConstrainedTileSets& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
[608]889{
890  UInt code;
[1313]891  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
892  sei_read_flag( pDecodedMessageOutputStream, code, "mc_all_tiles_exact_sample_value_match_flag");  sei.m_mc_all_tiles_exact_sample_value_match_flag = (code != 0);
893  sei_read_flag( pDecodedMessageOutputStream, code, "each_tile_one_tile_set_flag");                 sei.m_each_tile_one_tile_set_flag                = (code != 0);
894
895  if(!sei.m_each_tile_one_tile_set_flag)
[608]896  {
[1313]897    sei_read_flag( pDecodedMessageOutputStream, code, "limited_tile_set_display_flag");  sei.m_limited_tile_set_display_flag = (code != 0);
898    sei_read_uvlc( pDecodedMessageOutputStream, code, "num_sets_in_message_minus1");     sei.setNumberOfTileSets(code + 1);
899
900    if(sei.getNumberOfTileSets() != 0)
901    {
902      for(Int i = 0; i < sei.getNumberOfTileSets(); i++)
903      {
904        sei_read_uvlc( pDecodedMessageOutputStream, code, "mcts_id");  sei.tileSetData(i).m_mcts_id = code;
905
906        if(sei.m_limited_tile_set_display_flag)
907        {
908          sei_read_flag( pDecodedMessageOutputStream, code, "display_tile_set_flag");  sei.tileSetData(i).m_display_tile_set_flag = (code != 1);
909        }
910
911        sei_read_uvlc( pDecodedMessageOutputStream, code, "num_tile_rects_in_set_minus1");  sei.tileSetData(i).setNumberOfTileRects(code + 1);
912
913        for(Int j=0; j<sei.tileSetData(i).getNumberOfTileRects(); j++)
914        {
915          sei_read_uvlc( pDecodedMessageOutputStream, code, "top_left_tile_index");      sei.tileSetData(i).topLeftTileIndex(j)     = code;
916          sei_read_uvlc( pDecodedMessageOutputStream, code, "bottom_right_tile_index");  sei.tileSetData(i).bottomRightTileIndex(j) = code;
917        }
918
919        if(!sei.m_mc_all_tiles_exact_sample_value_match_flag)
920        {
921          sei_read_flag( pDecodedMessageOutputStream, code, "exact_sample_value_match_flag");   sei.tileSetData(i).m_exact_sample_value_match_flag    = (code != 0);
922        }
923        sei_read_flag( pDecodedMessageOutputStream, code, "mcts_tier_level_idc_present_flag");  sei.tileSetData(i).m_mcts_tier_level_idc_present_flag = (code != 0);
924
925        if(sei.tileSetData(i).m_mcts_tier_level_idc_present_flag)
926        {
927          sei_read_flag( pDecodedMessageOutputStream, code,    "mcts_tier_flag"); sei.tileSetData(i).m_mcts_tier_flag = (code != 0);
928          sei_read_code( pDecodedMessageOutputStream, 8, code, "mcts_level_idc"); sei.tileSetData(i).m_mcts_level_idc =  code;
929        }
930      }
931    }
[608]932  }
[1313]933  else
[608]934  {
[1313]935    sei_read_flag( pDecodedMessageOutputStream, code, "max_mcs_tier_level_idc_present_flag");  sei.m_max_mcs_tier_level_idc_present_flag = code;
936    if(sei.m_max_mcs_tier_level_idc_present_flag)
937    {
938      sei_read_flag( pDecodedMessageOutputStream, code, "max_mcts_tier_flag");  sei.m_max_mcts_tier_flag = code;
939      sei_read_code( pDecodedMessageOutputStream, 8, code, "max_mcts_level_idc"); sei.m_max_mcts_level_idc = code;
940    }
[608]941  }
942}
[1313]943
944Void SEIReader::xParseSEITimeCode(SEITimeCode& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
945{
946  UInt code;
947  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
948  sei_read_code( pDecodedMessageOutputStream, 2, code, "num_clock_ts"); sei.numClockTs = code;
949  for(Int i = 0; i < sei.numClockTs; i++)
950  {
951    TComSEITimeSet currentTimeSet;
952    sei_read_flag( pDecodedMessageOutputStream, code, "clock_time_stamp_flag[i]"); currentTimeSet.clockTimeStampFlag = code;
953    if(currentTimeSet.clockTimeStampFlag)
954    {
955      sei_read_flag( pDecodedMessageOutputStream, code, "nuit_field_based_flag"); currentTimeSet.numUnitFieldBasedFlag = code;
956      sei_read_code( pDecodedMessageOutputStream, 5, code, "counting_type"); currentTimeSet.countingType = code;
957      sei_read_flag( pDecodedMessageOutputStream, code, "full_timestamp_flag"); currentTimeSet.fullTimeStampFlag = code;
958      sei_read_flag( pDecodedMessageOutputStream, code, "discontinuity_flag"); currentTimeSet.discontinuityFlag = code;
959      sei_read_flag( pDecodedMessageOutputStream, code, "cnt_dropped_flag"); currentTimeSet.cntDroppedFlag = code;
960      sei_read_code( pDecodedMessageOutputStream, 9, code, "n_frames"); currentTimeSet.numberOfFrames = code;
961      if(currentTimeSet.fullTimeStampFlag)
962      {
963        sei_read_code( pDecodedMessageOutputStream, 6, code, "seconds_value"); currentTimeSet.secondsValue = code;
964        sei_read_code( pDecodedMessageOutputStream, 6, code, "minutes_value"); currentTimeSet.minutesValue = code;
965        sei_read_code( pDecodedMessageOutputStream, 5, code, "hours_value"); currentTimeSet.hoursValue = code;
966      }
967      else
968      {
969        sei_read_flag( pDecodedMessageOutputStream, code, "seconds_flag"); currentTimeSet.secondsFlag = code;
970        if(currentTimeSet.secondsFlag)
971        {
972          sei_read_code( pDecodedMessageOutputStream, 6, code, "seconds_value"); currentTimeSet.secondsValue = code;
973          sei_read_flag( pDecodedMessageOutputStream, code, "minutes_flag"); currentTimeSet.minutesFlag = code;
974          if(currentTimeSet.minutesFlag)
975          {
976            sei_read_code( pDecodedMessageOutputStream, 6, code, "minutes_value"); currentTimeSet.minutesValue = code;
977            sei_read_flag( pDecodedMessageOutputStream, code, "hours_flag"); currentTimeSet.hoursFlag = code;
978            if(currentTimeSet.hoursFlag)
979            {
980              sei_read_code( pDecodedMessageOutputStream, 5, code, "hours_value"); currentTimeSet.hoursValue = code;
981            }
982          }
983        }
984      }
985      sei_read_code( pDecodedMessageOutputStream, 5, code, "time_offset_length"); currentTimeSet.timeOffsetLength = code;
986      if(currentTimeSet.timeOffsetLength > 0)
987      {
988        sei_read_code( pDecodedMessageOutputStream, currentTimeSet.timeOffsetLength, code, "time_offset_value");
989        if((code & (1 << (currentTimeSet.timeOffsetLength-1))) == 0)
990        {
991          currentTimeSet.timeOffsetValue = code;
992        }
993        else
994        {
995          code &= (1<< (currentTimeSet.timeOffsetLength-1)) - 1;
996          currentTimeSet.timeOffsetValue = ~code + 1;
997        }
998      }
999    }
1000    sei.timeSetArray[i] = currentTimeSet;
1001  }
1002}
1003
1004Void SEIReader::xParseSEIChromaSamplingFilterHint(SEIChromaSamplingFilterHint& sei, UInt payloadSize/*, TComSPS* sps*/, std::ostream *pDecodedMessageOutputStream)
1005{
1006  UInt uiCode;
1007  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
1008
1009  sei_read_code( pDecodedMessageOutputStream, 8, uiCode, "ver_chroma_filter_idc"); sei.m_verChromaFilterIdc = uiCode;
1010  sei_read_code( pDecodedMessageOutputStream, 8, uiCode, "hor_chroma_filter_idc"); sei.m_horChromaFilterIdc = uiCode;
1011  sei_read_flag( pDecodedMessageOutputStream, uiCode, "ver_filtering_process_flag"); sei.m_verFilteringProcessFlag = uiCode;
1012  if(sei.m_verChromaFilterIdc == 1 || sei.m_horChromaFilterIdc == 1)
1013  {
1014    sei_read_uvlc( pDecodedMessageOutputStream, uiCode, "target_format_idc"); sei.m_targetFormatIdc = uiCode;
1015    if(sei.m_verChromaFilterIdc == 1)
1016    {
1017      sei_read_uvlc( pDecodedMessageOutputStream, uiCode, "num_vertical_filters"); sei.m_numVerticalFilters = uiCode;
1018      if(sei.m_numVerticalFilters > 0)
1019      {
1020        sei.m_verTapLengthMinus1 = (Int*)malloc(sei.m_numVerticalFilters * sizeof(Int));
1021        sei.m_verFilterCoeff = (Int**)malloc(sei.m_numVerticalFilters * sizeof(Int*));
1022        for(Int i = 0; i < sei.m_numVerticalFilters; i ++)
1023        {
1024          sei_read_uvlc( pDecodedMessageOutputStream, uiCode, "ver_tap_length_minus_1"); sei.m_verTapLengthMinus1[i] = uiCode;
1025          sei.m_verFilterCoeff[i] = (Int*)malloc(sei.m_verTapLengthMinus1[i] * sizeof(Int));
1026          for(Int j = 0; j < sei.m_verTapLengthMinus1[i]; j ++)
1027          {
1028            sei_read_svlc( pDecodedMessageOutputStream, sei.m_verFilterCoeff[i][j], "ver_filter_coeff");
1029          }
1030        }
1031      }
1032    }
1033    if(sei.m_horChromaFilterIdc == 1)
1034    {
1035      sei_read_uvlc( pDecodedMessageOutputStream, uiCode, "num_horizontal_filters"); sei.m_numHorizontalFilters = uiCode;
1036      if(sei.m_numHorizontalFilters  > 0)
1037      {
1038        sei.m_horTapLengthMinus1 = (Int*)malloc(sei.m_numHorizontalFilters * sizeof(Int));
1039        sei.m_horFilterCoeff = (Int**)malloc(sei.m_numHorizontalFilters * sizeof(Int*));
1040        for(Int i = 0; i < sei.m_numHorizontalFilters; i ++)
1041        {
1042          sei_read_uvlc( pDecodedMessageOutputStream, uiCode, "hor_tap_length_minus_1"); sei.m_horTapLengthMinus1[i] = uiCode;
1043          sei.m_horFilterCoeff[i] = (Int*)malloc(sei.m_horTapLengthMinus1[i] * sizeof(Int));
1044          for(Int j = 0; j < sei.m_horTapLengthMinus1[i]; j ++)
1045          {
1046            sei_read_svlc( pDecodedMessageOutputStream, sei.m_horFilterCoeff[i][j], "hor_filter_coeff");
1047          }
1048        }
1049      }
1050    }
1051  }
1052}
1053
1054Void SEIReader::xParseSEIKneeFunctionInfo(SEIKneeFunctionInfo& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
1055{
1056  Int i;
1057  UInt val;
1058  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
1059
1060  sei_read_uvlc( pDecodedMessageOutputStream, val, "knee_function_id" );                   sei.m_kneeId = val;
1061  sei_read_flag( pDecodedMessageOutputStream, val, "knee_function_cancel_flag" );          sei.m_kneeCancelFlag = val;
1062  if ( !sei.m_kneeCancelFlag )
1063  {
1064    sei_read_flag( pDecodedMessageOutputStream, val, "knee_function_persistence_flag" );   sei.m_kneePersistenceFlag = val;
1065    sei_read_code( pDecodedMessageOutputStream, 32, val, "input_d_range" );                sei.m_kneeInputDrange = val;
1066    sei_read_code( pDecodedMessageOutputStream, 32, val, "input_disp_luminance" );         sei.m_kneeInputDispLuminance = val;
1067    sei_read_code( pDecodedMessageOutputStream, 32, val, "output_d_range" );               sei.m_kneeOutputDrange = val;
1068    sei_read_code( pDecodedMessageOutputStream, 32, val, "output_disp_luminance" );        sei.m_kneeOutputDispLuminance = val;
1069    sei_read_uvlc( pDecodedMessageOutputStream, val, "num_knee_points_minus1" );           sei.m_kneeNumKneePointsMinus1 = val;
1070    assert( sei.m_kneeNumKneePointsMinus1 > 0 );
1071    sei.m_kneeInputKneePoint.resize(sei.m_kneeNumKneePointsMinus1+1);
1072    sei.m_kneeOutputKneePoint.resize(sei.m_kneeNumKneePointsMinus1+1);
1073    for(i = 0; i <= sei.m_kneeNumKneePointsMinus1; i++ )
1074    {
1075      sei_read_code( pDecodedMessageOutputStream, 10, val, "input_knee_point" );           sei.m_kneeInputKneePoint[i] = val;
1076      sei_read_code( pDecodedMessageOutputStream, 10, val, "output_knee_point" );          sei.m_kneeOutputKneePoint[i] = val;
1077    }
1078  }
1079}
1080
1081Void SEIReader::xParseSEIMasteringDisplayColourVolume(SEIMasteringDisplayColourVolume& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
1082{
1083  UInt code;
1084  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
1085
1086  sei_read_code( pDecodedMessageOutputStream, 16, code, "display_primaries_x[0]" ); sei.values.primaries[0][0] = code;
1087  sei_read_code( pDecodedMessageOutputStream, 16, code, "display_primaries_y[0]" ); sei.values.primaries[0][1] = code;
1088
1089  sei_read_code( pDecodedMessageOutputStream, 16, code, "display_primaries_x[1]" ); sei.values.primaries[1][0] = code;
1090  sei_read_code( pDecodedMessageOutputStream, 16, code, "display_primaries_y[1]" ); sei.values.primaries[1][1] = code;
1091
1092  sei_read_code( pDecodedMessageOutputStream, 16, code, "display_primaries_x[2]" ); sei.values.primaries[2][0] = code;
1093  sei_read_code( pDecodedMessageOutputStream, 16, code, "display_primaries_y[2]" ); sei.values.primaries[2][1] = code;
1094
1095
1096  sei_read_code( pDecodedMessageOutputStream, 16, code, "white_point_x" ); sei.values.whitePoint[0] = code;
1097  sei_read_code( pDecodedMessageOutputStream, 16, code, "white_point_y" ); sei.values.whitePoint[1] = code;
1098
1099  sei_read_code( pDecodedMessageOutputStream, 32, code, "max_display_mastering_luminance" ); sei.values.maxLuminance = code;
1100  sei_read_code( pDecodedMessageOutputStream, 32, code, "min_display_mastering_luminance" ); sei.values.minLuminance = code;
1101}
1102
[56]1103//! \}
Note: See TracBrowser for help on using the repository browser.