source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibEncoder/SEIwrite.cpp @ 1079

Last change on this file since 1079 was 1077, checked in by seregin, 10 years ago

update the older Visual Studio project files and some fixes to avoid implicit cast warnings, patch was provided by Karsten Sühring <karsten.suehring@…>

  • Property svn:eol-style set to native
File size: 60.6 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-2014, 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/TComBitCounter.h"
35#include "TLibCommon/TComBitStream.h"
36#include "TLibCommon/SEI.h"
37#include "TLibCommon/TComSlice.h"
38#include "TLibCommon/TComPicYuv.h"
39#include "SEIwrite.h"
40
41//! \ingroup TLibEncoder
42//! \{
43
44#if ENC_DEC_TRACE
45Void  xTraceSEIHeader()
46{
47  fprintf( g_hTrace, "=========== SEI message ===========\n");
48}
49
50Void  xTraceSEIMessageType(SEI::PayloadType payloadType)
51{
52  fprintf( g_hTrace, "=========== %s SEI message ===========\n", SEI::getSEIMessageString(payloadType));
53}
54#endif
55
56#if O0164_MULTI_LAYER_HRD
57#if VPS_VUI_BSP_HRD_PARAMS
58Void SEIWriter::xWriteSEIpayloadData(TComBitIf& bs, const SEI& sei, TComVPS *vps, TComSPS *sps, const SEIScalableNesting* nestingSeiPtr, const SEIBspNesting* bspNestingSeiPtr)
59#else
60Void SEIWriter::xWriteSEIpayloadData(TComBitIf& bs, const SEI& sei, TComVPS *vps, TComSPS *sps, const SEIScalableNesting& nestingSei, const SEIBspNesting& bspNestingSei)
61#endif
62#else
63Void SEIWriter::xWriteSEIpayloadData(TComBitIf& bs, const SEI& sei, TComSPS *sps)
64#endif
65{
66#if VPS_VUI_BSP_HRD_PARAMS
67  SEIScalableNesting nestingSei;
68  SEIBspNesting      bspNestingSei;
69  if( nestingSeiPtr )
70  {
71    nestingSei = *nestingSeiPtr;
72  }
73  if( bspNestingSeiPtr )
74  {
75    bspNestingSei = *bspNestingSeiPtr;
76  }
77#endif
78  switch (sei.payloadType())
79  {
80  case SEI::USER_DATA_UNREGISTERED:
81    xWriteSEIuserDataUnregistered(*static_cast<const SEIuserDataUnregistered*>(&sei));
82    break;
83  case SEI::ACTIVE_PARAMETER_SETS:
84    xWriteSEIActiveParameterSets(*static_cast<const SEIActiveParameterSets*>(& sei));
85    break; 
86  case SEI::DECODED_PICTURE_HASH:
87    xWriteSEIDecodedPictureHash(*static_cast<const SEIDecodedPictureHash*>(&sei));
88    break;
89#if VPS_VUI_BSP_HRD_PARAMS
90  case SEI::DECODING_UNIT_INFO:
91    xWriteSEIDecodingUnitInfo(*static_cast<const SEIDecodingUnitInfo*>(& sei), sps, nestingSeiPtr, bspNestingSeiPtr, vps);
92    break;
93  case SEI::BUFFERING_PERIOD:
94    xWriteSEIBufferingPeriod(*static_cast<const SEIBufferingPeriod*>(&sei), sps, nestingSeiPtr, bspNestingSeiPtr, vps);
95    break;
96  case SEI::PICTURE_TIMING:
97    xWriteSEIPictureTiming(*static_cast<const SEIPictureTiming*>(&sei), sps, nestingSeiPtr, bspNestingSeiPtr, vps);
98    break;
99#else
100  case SEI::DECODING_UNIT_INFO:
101    xWriteSEIDecodingUnitInfo(*static_cast<const SEIDecodingUnitInfo*>(& sei), sps);
102    break;
103  case SEI::BUFFERING_PERIOD:
104    xWriteSEIBufferingPeriod(*static_cast<const SEIBufferingPeriod*>(&sei), sps);
105    break;
106  case SEI::PICTURE_TIMING:
107    xWriteSEIPictureTiming(*static_cast<const SEIPictureTiming*>(&sei), sps);
108    break;
109#endif
110  case SEI::RECOVERY_POINT:
111    xWriteSEIRecoveryPoint(*static_cast<const SEIRecoveryPoint*>(&sei));
112    break;
113  case SEI::FRAME_PACKING:
114    xWriteSEIFramePacking(*static_cast<const SEIFramePacking*>(&sei));
115    break;
116  case SEI::SEGM_RECT_FRAME_PACKING:
117    xWriteSEISegmentedRectFramePacking(*static_cast<const SEISegmentedRectFramePacking*>(&sei));
118    break;
119  case SEI::DISPLAY_ORIENTATION:
120    xWriteSEIDisplayOrientation(*static_cast<const SEIDisplayOrientation*>(&sei));
121    break;
122  case SEI::TEMPORAL_LEVEL0_INDEX:
123    xWriteSEITemporalLevel0Index(*static_cast<const SEITemporalLevel0Index*>(&sei));
124    break;
125  case SEI::REGION_REFRESH_INFO:
126    xWriteSEIGradualDecodingRefreshInfo(*static_cast<const SEIGradualDecodingRefreshInfo*>(&sei));
127    break;
128  case SEI::NO_DISPLAY:
129    xWriteSEINoDisplay(*static_cast<const SEINoDisplay*>(&sei));
130    break;
131  case SEI::TONE_MAPPING_INFO:
132    xWriteSEIToneMappingInfo(*static_cast<const SEIToneMappingInfo*>(&sei));
133    break;
134  case SEI::SOP_DESCRIPTION:
135    xWriteSEISOPDescription(*static_cast<const SEISOPDescription*>(&sei));
136    break;
137  case SEI::SCALABLE_NESTING:
138#if O0164_MULTI_LAYER_HRD
139    xWriteSEIScalableNesting(bs, *static_cast<const SEIScalableNesting*>(&sei), vps, sps);
140#else
141    xWriteSEIScalableNesting(bs, *static_cast<const SEIScalableNesting*>(&sei), sps);
142#endif
143    break;
144  case SEI::CHROMA_SAMPLING_FILTER_HINT:
145    xWriteSEIChromaSamplingFilterHint(*static_cast<const SEIChromaSamplingFilterHint*>(&sei)/*, sps*/);
146    break;
147  case SEI::TEMP_MOTION_CONSTRAINED_TILE_SETS:
148    xWriteSEITempMotionConstrainedTileSets(bs, *static_cast<const SEITempMotionConstrainedTileSets*>(&sei));
149    break;
150  case SEI::TIME_CODE:
151    xWriteSEITimeCode(*static_cast<const SEITimeCode*>(&sei));
152    break;
153  case SEI::KNEE_FUNCTION_INFO:
154    xWriteSEIKneeFunctionInfo(*static_cast<const SEIKneeFunctionInfo*>(&sei));
155    break;
156  case SEI::MASTERING_DISPLAY_COLOUR_VOLUME:
157    xWriteSEIMasteringDisplayColourVolume(*static_cast<const SEIMasteringDisplayColourVolume*>(&sei));
158    break;
159#if Q0074_COLOUR_REMAPPING_SEI
160  case SEI::COLOUR_REMAPPING_INFO:
161    xWriteSEIColourRemappingInfo(*static_cast<const SEIColourRemappingInfo*>(&sei));
162    break;
163#endif
164#if SVC_EXTENSION
165#if LAYERS_NOT_PRESENT_SEI
166  case SEI::LAYERS_NOT_PRESENT:
167    xWriteSEILayersNotPresent(*static_cast<const SEILayersNotPresent*>(&sei));
168    break;
169#endif
170#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
171  case SEI::INTER_LAYER_CONSTRAINED_TILE_SETS:
172    xWriteSEIInterLayerConstrainedTileSets(*static_cast<const SEIInterLayerConstrainedTileSets*>(&sei));
173    break;
174#endif
175#if SUB_BITSTREAM_PROPERTY_SEI
176   case SEI::SUB_BITSTREAM_PROPERTY:
177     xWriteSEISubBitstreamProperty(*static_cast<const SEISubBitstreamProperty*>(&sei));
178     break;
179#endif
180#if O0164_MULTI_LAYER_HRD
181   case SEI::BSP_NESTING:
182     xWriteSEIBspNesting(bs, *static_cast<const SEIBspNesting*>(&sei), vps, sps, nestingSei);
183     break;
184   case SEI::BSP_INITIAL_ARRIVAL_TIME:
185     xWriteSEIBspInitialArrivalTime(*static_cast<const SEIBspInitialArrivalTime*>(&sei), vps, sps, nestingSei, bspNestingSei);
186     break;
187#if !REMOVE_BSP_HRD_SEI
188   case SEI::BSP_HRD:
189     xWriteSEIBspHrd(*static_cast<const SEIBspHrd*>(&sei), sps, nestingSei);
190     break;
191#endif
192#endif
193#if Q0078_ADD_LAYER_SETS
194   case SEI::OUTPUT_LAYER_SET_NESTING:
195     xWriteSEIOutputLayerSetNesting(bs, *static_cast<const SEIOutputLayerSetNesting*>(&sei), vps, sps);
196     break;
197   case SEI::VPS_REWRITING:
198     xWriteSEIVPSRewriting(*static_cast<const SEIVPSRewriting*>(&sei));
199     break;
200#endif
201#if Q0189_TMVP_CONSTRAINTS
202   case SEI::TMVP_CONSTRAINTS:
203     xWriteSEITMVPConstraints(*static_cast<const SEITMVPConstrains*>(&sei));
204     break;
205#endif
206#if Q0247_FRAME_FIELD_INFO
207   case SEI::FRAME_FIELD_INFO:
208     xWriteSEIFrameFieldInfo(*static_cast<const SEIFrameFieldInfo*>(&sei));
209     break;
210#endif
211#if P0123_ALPHA_CHANNEL_SEI
212   case SEI::ALPHA_CHANNEL_INFO:
213     xWriteSEIAlphaChannelInfo(*static_cast<const SEIAlphaChannelInfo*>(&sei));
214     break;
215#endif
216#if Q0096_OVERLAY_SEI
217   case SEI::OVERLAY_INFO:
218     xWriteSEIOverlayInfo(*static_cast<const SEIOverlayInfo*>(&sei));
219     break;
220#endif
221#endif //SVC_EXTENSION
222  default:
223    assert(!"Unhandled SEI message");
224    break;
225  }
226  xWriteByteAlign();
227}
228
229/**
230 * marshal a single SEI message sei, storing the marshalled representation
231 * in bitstream bs.
232 */
233#if O0164_MULTI_LAYER_HRD
234Void SEIWriter::writeSEImessage(TComBitIf& bs, const SEI& sei, TComVPS *vps, TComSPS *sps, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei)
235#else
236Void SEIWriter::writeSEImessage(TComBitIf& bs, const SEI& sei, TComSPS *sps)
237#endif
238{
239  /* calculate how large the payload data is */
240  /* TODO: this would be far nicer if it used vectored buffers */
241  TComBitCounter bs_count;
242  bs_count.resetBits();
243  setBitstream(&bs_count);
244
245
246#if ENC_DEC_TRACE
247  Bool traceEnable = g_HLSTraceEnable;
248  g_HLSTraceEnable = false;
249#endif
250#if O0164_MULTI_LAYER_HRD
251#if VPS_VUI_BSP_HRD_PARAMS
252  xWriteSEIpayloadData(bs_count, sei, vps, sps, nestingSei, bspNestingSei);
253#else
254  xWriteSEIpayloadData(bs_count, sei, vps, sps, *nestingSei, *bspNestingSei);
255#endif
256#else
257  xWriteSEIpayloadData(bs_count, sei, sps);
258#endif
259#if ENC_DEC_TRACE
260  g_HLSTraceEnable = traceEnable;
261#endif
262
263  UInt payload_data_num_bits = bs_count.getNumberOfWrittenBits();
264  assert(0 == payload_data_num_bits % 8);
265
266  setBitstream(&bs);
267
268#if ENC_DEC_TRACE
269  if (g_HLSTraceEnable)
270  xTraceSEIHeader();
271#endif
272
273  UInt payloadType = sei.payloadType();
274  for (; payloadType >= 0xff; payloadType -= 0xff)
275  {
276    WRITE_CODE(0xff, 8, "payload_type");
277  }
278  WRITE_CODE(payloadType, 8, "payload_type");
279
280  UInt payloadSize = payload_data_num_bits/8;
281  for (; payloadSize >= 0xff; payloadSize -= 0xff)
282  {
283    WRITE_CODE(0xff, 8, "payload_size");
284  }
285  WRITE_CODE(payloadSize, 8, "payload_size");
286
287  /* payloadData */
288#if ENC_DEC_TRACE
289  if (g_HLSTraceEnable)
290  xTraceSEIMessageType(sei.payloadType());
291#endif
292
293#if O0164_MULTI_LAYER_HRD
294#if VPS_VUI_BSP_HRD_PARAMS
295  xWriteSEIpayloadData(bs, sei, vps, sps, nestingSei, bspNestingSei);
296#else
297  xWriteSEIpayloadData(bs, sei, vps, sps, *nestingSei, *bspNestingSei);
298#endif
299#else
300  xWriteSEIpayloadData(bs, sei, sps);
301#endif
302}
303
304/**
305 * marshal a user_data_unregistered SEI message sei, storing the marshalled
306 * representation in bitstream bs.
307 */
308Void SEIWriter::xWriteSEIuserDataUnregistered(const SEIuserDataUnregistered &sei)
309{
310  for (UInt i = 0; i < ISO_IEC_11578_LEN; i++)
311  {
312    WRITE_CODE(sei.uuid_iso_iec_11578[i], 8 , "sei.uuid_iso_iec_11578[i]");
313  }
314
315  for (UInt i = 0; i < sei.userDataLength; i++)
316  {
317    WRITE_CODE(sei.userData[i], 8 , "user_data");
318  }
319}
320
321/**
322 * marshal a decoded picture hash SEI message, storing the marshalled
323 * representation in bitstream bs.
324 */
325Void SEIWriter::xWriteSEIDecodedPictureHash(const SEIDecodedPictureHash& sei)
326{
327  const Char *traceString="\0";
328  switch (sei.method)
329  {
330    case SEIDecodedPictureHash::MD5: traceString="picture_md5"; break;
331    case SEIDecodedPictureHash::CRC: traceString="picture_crc"; break;
332    case SEIDecodedPictureHash::CHECKSUM: traceString="picture_checksum"; break;
333    default: assert(false); break;
334  }
335
336  if (traceString != 0) //use of this variable is needed to avoid a compiler error with G++ 4.6.1
337  {
338    WRITE_CODE(sei.method, 8, "hash_type");
339    for(UInt i=0; i<UInt(sei.m_digest.hash.size()); i++)
340    {
341      WRITE_CODE(sei.m_digest.hash[i], 8, traceString);
342    }
343  }
344}
345
346Void SEIWriter::xWriteSEIActiveParameterSets(const SEIActiveParameterSets& sei)
347{
348  WRITE_CODE(sei.activeVPSId,     4,         "active_video_parameter_set_id");
349  WRITE_FLAG(sei.m_selfContainedCvsFlag,     "self_contained_cvs_flag");
350  WRITE_FLAG(sei.m_noParameterSetUpdateFlag, "no_parameter_set_update_flag");
351  WRITE_UVLC(sei.numSpsIdsMinus1,            "num_sps_ids_minus1");
352
353  assert (sei.activeSeqParameterSetId.size() == (sei.numSpsIdsMinus1 + 1));
354
355  for (Int i = 0; i < sei.activeSeqParameterSetId.size(); i++)
356  {
357    WRITE_UVLC(sei.activeSeqParameterSetId[i], "active_seq_parameter_set_id"); 
358  }
359#if R0247_SEI_ACTIVE
360  for (Int i = 1; i < sei.activeSeqParameterSetId.size(); i++)
361  {
362    WRITE_UVLC(sei.layerSpsIdx[i], "layer_sps_idx"); 
363  }
364#endif
365}
366
367#if VPS_VUI_BSP_HRD_PARAMS
368Void SEIWriter::xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, TComSPS *sps, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei, TComVPS *vps)
369#else
370Void SEIWriter::xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, TComSPS *sps)
371#endif
372{
373#if VPS_VUI_BSP_HRD_PARAMS
374  TComHRD *hrd;
375  if( bspNestingSei )   // If DU info SEI contained inside a BSP nesting SEI message
376  {
377    assert( nestingSei );
378    Int psIdx = bspNestingSei->m_seiPartitioningSchemeIdx;
379    Int seiOlsIdx = bspNestingSei->m_seiOlsIdx;
380    Int maxTemporalId = nestingSei->m_nestingMaxTemporalIdPlus1[0] - 1;
381    Int maxValues = vps->getNumBspSchedulesMinus1(seiOlsIdx, psIdx, maxTemporalId) + 1;
382    std::vector<Int> hrdIdx(maxValues, 0);
383    std::vector<TComHRD *> hrdVec;
384    std::vector<Int> syntaxElemLen(maxValues, 0);
385    for(Int i = 0; i < maxValues; i++)
386    {
387      hrdIdx[i] = vps->getBspHrdIdx( seiOlsIdx, psIdx, maxTemporalId, i, bspNestingSei->m_bspIdx);
388      hrdVec.push_back(vps->getBspHrd(hrdIdx[i]));
389   
390      syntaxElemLen[i] = hrdVec[i]->getInitialCpbRemovalDelayLengthMinus1() + 1;
391      if ( !(hrdVec[i]->getNalHrdParametersPresentFlag() || hrdVec[i]->getVclHrdParametersPresentFlag()) )
392      {
393        assert( syntaxElemLen[i] == 24 ); // Default of value init_cpb_removal_delay_length_minus1 is 23
394      }
395      if( i > 0 )
396      {
397        assert( hrdVec[i]->getSubPicCpbParamsPresentFlag()    == hrdVec[i-1]->getSubPicCpbParamsPresentFlag() );
398        assert( hrdVec[i]->getSubPicCpbParamsInPicTimingSEIFlag()   == hrdVec[i-1]->getSubPicCpbParamsInPicTimingSEIFlag() );
399        assert( hrdVec[i]->getDpbOutputDelayDuLengthMinus1()  == hrdVec[i-1]->getDpbOutputDelayDuLengthMinus1() );
400        // To be done: Check CpbDpbDelaysPresentFlag
401      }
402    }
403    hrd = hrdVec[0];
404  }
405  else
406  {
407    TComVUI *vui = sps->getVuiParameters();
408    hrd = vui->getHrdParameters();
409  }
410
411  WRITE_UVLC(sei.m_decodingUnitIdx, "decoding_unit_idx");
412  if(hrd->getSubPicCpbParamsInPicTimingSEIFlag())
413  {
414    WRITE_CODE( sei.m_duSptCpbRemovalDelay, (hrd->getDuCpbRemovalDelayLengthMinus1() + 1), "du_spt_cpb_removal_delay");
415  }
416  WRITE_FLAG( sei.m_dpbOutputDuDelayPresentFlag, "dpb_output_du_delay_present_flag");
417  if(sei.m_dpbOutputDuDelayPresentFlag)
418  {
419    WRITE_CODE(sei.m_picSptDpbOutputDuDelay, hrd->getDpbOutputDelayDuLengthMinus1() + 1, "pic_spt_dpb_output_du_delay");
420  }
421#else
422  TComVUI *vui = sps->getVuiParameters();
423  WRITE_UVLC(sei.m_decodingUnitIdx, "decoding_unit_idx");
424  if(vui->getHrdParameters()->getSubPicCpbParamsInPicTimingSEIFlag())
425  {
426    WRITE_CODE( sei.m_duSptCpbRemovalDelay, (vui->getHrdParameters()->getDuCpbRemovalDelayLengthMinus1() + 1), "du_spt_cpb_removal_delay");
427  }
428  WRITE_FLAG( sei.m_dpbOutputDuDelayPresentFlag, "dpb_output_du_delay_present_flag");
429  if(sei.m_dpbOutputDuDelayPresentFlag)
430  {
431    WRITE_CODE(sei.m_picSptDpbOutputDuDelay, vui->getHrdParameters()->getDpbOutputDelayDuLengthMinus1() + 1, "pic_spt_dpb_output_du_delay");
432  }
433#endif
434}
435
436#if VPS_VUI_BSP_HRD_PARAMS
437Void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, TComSPS *sps, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei, TComVPS *vps)
438#else
439Void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, TComSPS *sps)
440#endif
441{
442  Int i, nalOrVcl;
443#if VPS_VUI_BSP_HRD_PARAMS
444  TComHRD *hrd;
445  if( bspNestingSei )   // If BP SEI contained inside a BSP nesting SEI message
446  {
447    assert( nestingSei );
448    Int psIdx = bspNestingSei->m_seiPartitioningSchemeIdx;
449    Int seiOlsIdx = bspNestingSei->m_seiOlsIdx;
450    Int maxTemporalId = nestingSei->m_nestingMaxTemporalIdPlus1[0] - 1;
451    Int maxValues = vps->getNumBspSchedulesMinus1(seiOlsIdx, psIdx, maxTemporalId) + 1;
452    std::vector<Int> hrdIdx(maxValues, 0);
453    std::vector<TComHRD *> hrdVec;
454    std::vector<Int> syntaxElemLen(maxValues, 0);
455    for(i = 0; i < maxValues; i++)
456    {
457      hrdIdx[i] = vps->getBspHrdIdx( seiOlsIdx, psIdx, maxTemporalId, i, bspNestingSei->m_bspIdx);
458      hrdVec.push_back(vps->getBspHrd(hrdIdx[i]));
459   
460      syntaxElemLen[i] = hrdVec[i]->getInitialCpbRemovalDelayLengthMinus1() + 1;
461      if ( !(hrdVec[i]->getNalHrdParametersPresentFlag() || hrdVec[i]->getVclHrdParametersPresentFlag()) )
462      {
463        assert( syntaxElemLen[i] == 24 ); // Default of value init_cpb_removal_delay_length_minus1 is 23
464      }
465      if( i > 0 )
466      {
467        assert( hrdVec[i]->getCpbRemovalDelayLengthMinus1()   == hrdVec[i-1]->getCpbRemovalDelayLengthMinus1() );
468        assert( hrdVec[i]->getDpbOutputDelayDuLengthMinus1()  == hrdVec[i-1]->getDpbOutputDelayDuLengthMinus1() );
469        assert( hrdVec[i]->getSubPicCpbParamsPresentFlag()    == hrdVec[i-1]->getSubPicCpbParamsPresentFlag() );
470      }
471    }
472    hrd = hrdVec[i];
473  }
474  else
475  {
476    TComVUI *vui = sps->getVuiParameters();
477    hrd = vui->getHrdParameters();
478  }
479  // To be done: When contained in an BSP HRD SEI message, the hrd structure is to be chosen differently.
480#else
481  TComVUI *vui = sps->getVuiParameters();
482  TComHRD *hrd = vui->getHrdParameters();
483#endif
484
485  WRITE_UVLC( sei.m_bpSeqParameterSetId, "bp_seq_parameter_set_id" );
486  if( !hrd->getSubPicCpbParamsPresentFlag() )
487  {
488    WRITE_FLAG( sei.m_rapCpbParamsPresentFlag, "irap_cpb_params_present_flag" );
489  }
490  if( sei.m_rapCpbParamsPresentFlag )
491  {
492    WRITE_CODE( sei.m_cpbDelayOffset, hrd->getCpbRemovalDelayLengthMinus1() + 1, "cpb_delay_offset" );
493    WRITE_CODE( sei.m_dpbDelayOffset, hrd->getDpbOutputDelayLengthMinus1()  + 1, "dpb_delay_offset" );
494  }
495  WRITE_FLAG( sei.m_concatenationFlag, "concatenation_flag");
496  WRITE_CODE( sei.m_auCpbRemovalDelayDelta - 1, ( hrd->getCpbRemovalDelayLengthMinus1() + 1 ), "au_cpb_removal_delay_delta_minus1" );
497  for( nalOrVcl = 0; nalOrVcl < 2; nalOrVcl ++ )
498  {
499    if( ( ( nalOrVcl == 0 ) && ( hrd->getNalHrdParametersPresentFlag() ) ) ||
500        ( ( nalOrVcl == 1 ) && ( hrd->getVclHrdParametersPresentFlag() ) ) )
501    {
502      for( i = 0; i < ( hrd->getCpbCntMinus1( 0 ) + 1 ); i ++ )
503      {
504        WRITE_CODE( sei.m_initialCpbRemovalDelay[i][nalOrVcl],( hrd->getInitialCpbRemovalDelayLengthMinus1() + 1 ) ,           "initial_cpb_removal_delay" );
505        WRITE_CODE( sei.m_initialCpbRemovalDelayOffset[i][nalOrVcl],( hrd->getInitialCpbRemovalDelayLengthMinus1() + 1 ),      "initial_cpb_removal_delay_offset" );
506        if( hrd->getSubPicCpbParamsPresentFlag() || sei.m_rapCpbParamsPresentFlag )
507        {
508          WRITE_CODE( sei.m_initialAltCpbRemovalDelay[i][nalOrVcl], ( hrd->getInitialCpbRemovalDelayLengthMinus1() + 1 ) ,     "initial_alt_cpb_removal_delay" );
509          WRITE_CODE( sei.m_initialAltCpbRemovalDelayOffset[i][nalOrVcl], ( hrd->getInitialCpbRemovalDelayLengthMinus1() + 1 ),"initial_alt_cpb_removal_delay_offset" );
510        }
511      }
512    }
513  }
514#if P0138_USE_ALT_CPB_PARAMS_FLAG
515  if (sei.m_useAltCpbParamsFlagPresent)
516  {
517    WRITE_FLAG( sei.m_useAltCpbParamsFlag, "use_alt_cpb_params_flag");
518  }
519#endif
520}
521#if VPS_VUI_BSP_HRD_PARAMS
522Void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei,  TComSPS *sps, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei, TComVPS *vps)
523#else
524Void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei,  TComSPS *sps)
525#endif
526{
527  Int i;
528#if VPS_VUI_BSP_HRD_PARAMS
529  TComHRD *hrd;   
530  TComVUI *vui = sps->getVuiParameters(); 
531  if( bspNestingSei )   // If BP SEI contained inside a BSP nesting SEI message
532  {
533    assert( nestingSei );
534    Int psIdx = bspNestingSei->m_seiPartitioningSchemeIdx;
535    Int seiOlsIdx = bspNestingSei->m_seiOlsIdx;
536    Int maxTemporalId = nestingSei->m_nestingMaxTemporalIdPlus1[0] - 1;
537    Int maxValues = vps->getNumBspSchedulesMinus1(seiOlsIdx, psIdx, maxTemporalId) + 1;
538    std::vector<Int> hrdIdx(maxValues, 0);
539    std::vector<TComHRD *> hrdVec;
540    std::vector<Int> syntaxElemLen(maxValues, 0);
541    for(i = 0; i < maxValues; i++)
542    {
543      hrdIdx[i] = vps->getBspHrdIdx( seiOlsIdx, psIdx, maxTemporalId, i, bspNestingSei->m_bspIdx);
544      hrdVec.push_back(vps->getBspHrd(hrdIdx[i]));
545   
546      syntaxElemLen[i] = hrdVec[i]->getInitialCpbRemovalDelayLengthMinus1() + 1;
547      if ( !(hrdVec[i]->getNalHrdParametersPresentFlag() || hrdVec[i]->getVclHrdParametersPresentFlag()) )
548      {
549        assert( syntaxElemLen[i] == 24 ); // Default of value init_cpb_removal_delay_length_minus1 is 23
550      }
551      if( i > 0 )
552      {
553        assert( hrdVec[i]->getSubPicCpbParamsPresentFlag()    == hrdVec[i-1]->getSubPicCpbParamsPresentFlag() );
554        assert( hrdVec[i]->getSubPicCpbParamsInPicTimingSEIFlag()   == hrdVec[i-1]->getSubPicCpbParamsInPicTimingSEIFlag() );
555        assert( hrdVec[i]->getCpbRemovalDelayLengthMinus1()  == hrdVec[i-1]->getCpbRemovalDelayLengthMinus1() );
556        assert( hrdVec[i]->getDpbOutputDelayLengthMinus1()  == hrdVec[i-1]->getDpbOutputDelayLengthMinus1() );
557        assert( hrdVec[i]->getDpbOutputDelayDuLengthMinus1()  == hrdVec[i-1]->getDpbOutputDelayDuLengthMinus1() );
558        assert( hrdVec[i]->getDuCpbRemovalDelayLengthMinus1()  == hrdVec[i-1]->getDuCpbRemovalDelayLengthMinus1() );
559        // To be done: Check CpbDpbDelaysPresentFlag
560      }
561    }
562    hrd = hrdVec[0];
563  }
564  else
565  {
566    hrd = vui->getHrdParameters();
567  }
568  // To be done: When contained in an BSP HRD SEI message, the hrd structure is to be chosen differently.
569#else
570  TComVUI *vui = sps->getVuiParameters();
571  TComHRD *hrd = vui->getHrdParameters();
572#endif
573
574  if( vui->getFrameFieldInfoPresentFlag() )
575  {
576    WRITE_CODE( sei.m_picStruct, 4,              "pic_struct" );
577    WRITE_CODE( sei.m_sourceScanType, 2,         "source_scan_type" );
578    WRITE_FLAG( sei.m_duplicateFlag ? 1 : 0,     "duplicate_flag" );
579  }
580
581  if( hrd->getCpbDpbDelaysPresentFlag() )
582  {
583    WRITE_CODE( sei.m_auCpbRemovalDelay - 1, ( hrd->getCpbRemovalDelayLengthMinus1() + 1 ),                                         "au_cpb_removal_delay_minus1" );
584    WRITE_CODE( sei.m_picDpbOutputDelay, ( hrd->getDpbOutputDelayLengthMinus1() + 1 ),                                          "pic_dpb_output_delay" );
585    if(hrd->getSubPicCpbParamsPresentFlag())
586    {
587      WRITE_CODE(sei.m_picDpbOutputDuDelay, hrd->getDpbOutputDelayDuLengthMinus1()+1, "pic_dpb_output_du_delay" );
588    }
589    if( hrd->getSubPicCpbParamsPresentFlag() && hrd->getSubPicCpbParamsInPicTimingSEIFlag() )
590    {
591      WRITE_UVLC( sei.m_numDecodingUnitsMinus1,     "num_decoding_units_minus1" );
592      WRITE_FLAG( sei.m_duCommonCpbRemovalDelayFlag, "du_common_cpb_removal_delay_flag" );
593      if( sei.m_duCommonCpbRemovalDelayFlag )
594      {
595        WRITE_CODE( sei.m_duCommonCpbRemovalDelayMinus1, ( hrd->getDuCpbRemovalDelayLengthMinus1() + 1 ),                       "du_common_cpb_removal_delay_minus1" );
596      }
597      for( i = 0; i <= sei.m_numDecodingUnitsMinus1; i ++ )
598      {
599        WRITE_UVLC( sei.m_numNalusInDuMinus1[ i ],  "num_nalus_in_du_minus1");
600        if( ( !sei.m_duCommonCpbRemovalDelayFlag ) && ( i < sei.m_numDecodingUnitsMinus1 ) )
601        {
602          WRITE_CODE( sei.m_duCpbRemovalDelayMinus1[ i ], ( hrd->getDuCpbRemovalDelayLengthMinus1() + 1 ),                        "du_cpb_removal_delay_minus1" );
603        }
604      }
605    }
606  }
607}
608Void SEIWriter::xWriteSEIRecoveryPoint(const SEIRecoveryPoint& sei)
609{
610  WRITE_SVLC( sei.m_recoveryPocCnt,    "recovery_poc_cnt"    );
611  WRITE_FLAG( sei.m_exactMatchingFlag, "exact_matching_flag" );
612  WRITE_FLAG( sei.m_brokenLinkFlag,    "broken_link_flag"    );
613}
614Void SEIWriter::xWriteSEIFramePacking(const SEIFramePacking& sei)
615{
616  WRITE_UVLC( sei.m_arrangementId,                  "frame_packing_arrangement_id" );
617  WRITE_FLAG( sei.m_arrangementCancelFlag,          "frame_packing_arrangement_cancel_flag" );
618
619  if( sei.m_arrangementCancelFlag == 0 ) {
620    WRITE_CODE( sei.m_arrangementType, 7,           "frame_packing_arrangement_type" );
621
622    WRITE_FLAG( sei.m_quincunxSamplingFlag,         "quincunx_sampling_flag" );
623    WRITE_CODE( sei.m_contentInterpretationType, 6, "content_interpretation_type" );
624    WRITE_FLAG( sei.m_spatialFlippingFlag,          "spatial_flipping_flag" );
625    WRITE_FLAG( sei.m_frame0FlippedFlag,            "frame0_flipped_flag" );
626    WRITE_FLAG( sei.m_fieldViewsFlag,               "field_views_flag" );
627    WRITE_FLAG( sei.m_currentFrameIsFrame0Flag,     "current_frame_is_frame0_flag" );
628
629    WRITE_FLAG( sei.m_frame0SelfContainedFlag,      "frame0_self_contained_flag" );
630    WRITE_FLAG( sei.m_frame1SelfContainedFlag,      "frame1_self_contained_flag" );
631
632    if(sei.m_quincunxSamplingFlag == 0 && sei.m_arrangementType != 5)
633    {
634      WRITE_CODE( sei.m_frame0GridPositionX, 4,     "frame0_grid_position_x" );
635      WRITE_CODE( sei.m_frame0GridPositionY, 4,     "frame0_grid_position_y" );
636      WRITE_CODE( sei.m_frame1GridPositionX, 4,     "frame1_grid_position_x" );
637      WRITE_CODE( sei.m_frame1GridPositionY, 4,     "frame1_grid_position_y" );
638    }
639
640    WRITE_CODE( sei.m_arrangementReservedByte, 8,   "frame_packing_arrangement_reserved_byte" );
641    WRITE_FLAG( sei.m_arrangementPersistenceFlag,   "frame_packing_arrangement_persistence_flag" );
642  }
643
644  WRITE_FLAG( sei.m_upsampledAspectRatio,           "upsampled_aspect_ratio" );
645}
646
647Void SEIWriter::xWriteSEISegmentedRectFramePacking(const SEISegmentedRectFramePacking& sei)
648{
649  WRITE_FLAG( sei.m_arrangementCancelFlag,          "segmented_rect_frame_packing_arrangement_cancel_flag" );
650  if( sei.m_arrangementCancelFlag == 0 ) 
651  {
652    WRITE_CODE( sei.m_contentInterpretationType, 2, "segmented_rect_content_interpretation_type" );
653    WRITE_FLAG( sei.m_arrangementPersistenceFlag,   "segmented_rect_frame_packing_arrangement_persistence" );
654  }
655}
656
657Void SEIWriter::xWriteSEIToneMappingInfo(const SEIToneMappingInfo& sei)
658{
659  Int i;
660  WRITE_UVLC( sei.m_toneMapId,                    "tone_map_id" );
661  WRITE_FLAG( sei.m_toneMapCancelFlag,            "tone_map_cancel_flag" );
662  if( !sei.m_toneMapCancelFlag )
663  {
664    WRITE_FLAG( sei.m_toneMapPersistenceFlag,     "tone_map_persistence_flag" );
665    WRITE_CODE( sei.m_codedDataBitDepth,    8,    "coded_data_bit_depth" );
666    WRITE_CODE( sei.m_targetBitDepth,       8,    "target_bit_depth" );
667    WRITE_UVLC( sei.m_modelId,                    "model_id" );
668    switch(sei.m_modelId)
669    {
670    case 0:
671      {
672        WRITE_CODE( sei.m_minValue,  32,        "min_value" );
673        WRITE_CODE( sei.m_maxValue, 32,         "max_value" );
674        break;
675      }
676    case 1:
677      {
678        WRITE_CODE( sei.m_sigmoidMidpoint, 32,  "sigmoid_midpoint" );
679        WRITE_CODE( sei.m_sigmoidWidth,    32,  "sigmoid_width"    );
680        break;
681      }
682    case 2:
683      {
684        UInt num = 1u << sei.m_targetBitDepth;
685        for(i = 0; i < num; i++)
686        {
687          WRITE_CODE( sei.m_startOfCodedInterval[i], (( sei.m_codedDataBitDepth + 7 ) >> 3 ) << 3,  "start_of_coded_interval" );
688        }
689        break;
690      }
691    case 3:
692      {
693        WRITE_CODE( sei.m_numPivots, 16,          "num_pivots" );
694        for(i = 0; i < sei.m_numPivots; i++ )
695        {
696          WRITE_CODE( sei.m_codedPivotValue[i], (( sei.m_codedDataBitDepth + 7 ) >> 3 ) << 3,       "coded_pivot_value" );
697          WRITE_CODE( sei.m_targetPivotValue[i], (( sei.m_targetBitDepth + 7 ) >> 3 ) << 3,         "target_pivot_value");
698        }
699        break;
700      }
701    case 4:
702      {
703        WRITE_CODE( sei.m_cameraIsoSpeedIdc,    8,    "camera_iso_speed_idc" );
704        if( sei.m_cameraIsoSpeedIdc == 255) //Extended_ISO
705        {
706          WRITE_CODE( sei.m_cameraIsoSpeedValue,    32,    "camera_iso_speed_value" );
707        }
708        WRITE_CODE( sei.m_exposureIndexIdc,     8,    "exposure_index_idc" );
709        if( sei.m_exposureIndexIdc == 255) //Extended_ISO
710        {
711          WRITE_CODE( sei.m_exposureIndexValue,     32,    "exposure_index_value" );
712        }
713        WRITE_FLAG( sei.m_exposureCompensationValueSignFlag,           "exposure_compensation_value_sign_flag" );
714        WRITE_CODE( sei.m_exposureCompensationValueNumerator,     16,  "exposure_compensation_value_numerator" );
715        WRITE_CODE( sei.m_exposureCompensationValueDenomIdc,      16,  "exposure_compensation_value_denom_idc" );
716        WRITE_CODE( sei.m_refScreenLuminanceWhite,                32,  "ref_screen_luminance_white" );
717        WRITE_CODE( sei.m_extendedRangeWhiteLevel,                32,  "extended_range_white_level" );
718        WRITE_CODE( sei.m_nominalBlackLevelLumaCodeValue,         16,  "nominal_black_level_luma_code_value" );
719        WRITE_CODE( sei.m_nominalWhiteLevelLumaCodeValue,         16,  "nominal_white_level_luma_code_value" );
720        WRITE_CODE( sei.m_extendedWhiteLevelLumaCodeValue,        16,  "extended_white_level_luma_code_value" );
721        break;
722      }
723    default:
724      {
725        assert(!"Undefined SEIToneMapModelId");
726        break;
727      }
728    }//switch m_modelId
729  }//if(!sei.m_toneMapCancelFlag)
730}
731
732Void SEIWriter::xWriteSEIDisplayOrientation(const SEIDisplayOrientation &sei)
733{
734  WRITE_FLAG( sei.cancelFlag,           "display_orientation_cancel_flag" );
735  if( !sei.cancelFlag )
736  {
737    WRITE_FLAG( sei.horFlip,                   "hor_flip" );
738    WRITE_FLAG( sei.verFlip,                   "ver_flip" );
739    WRITE_CODE( sei.anticlockwiseRotation, 16, "anticlockwise_rotation" );
740    WRITE_FLAG( sei.persistenceFlag,          "display_orientation_persistence_flag" );
741  }
742}
743
744Void SEIWriter::xWriteSEITemporalLevel0Index(const SEITemporalLevel0Index &sei)
745{
746  WRITE_CODE( sei.tl0Idx, 8 , "tl0_idx" );
747  WRITE_CODE( sei.rapIdx, 8 , "rap_idx" );
748}
749
750Void SEIWriter::xWriteSEIGradualDecodingRefreshInfo(const SEIGradualDecodingRefreshInfo &sei)
751{
752  WRITE_FLAG( sei.m_gdrForegroundFlag, "gdr_foreground_flag");
753}
754
755Void SEIWriter::xWriteSEINoDisplay(const SEINoDisplay &sei)
756{
757}
758
759Void SEIWriter::xWriteSEISOPDescription(const SEISOPDescription& sei)
760{
761  WRITE_UVLC( sei.m_sopSeqParameterSetId,           "sop_seq_parameter_set_id"               );
762  WRITE_UVLC( sei.m_numPicsInSopMinus1,             "num_pics_in_sop_minus1"               );
763  for (UInt i = 0; i <= sei.m_numPicsInSopMinus1; i++)
764  {
765    WRITE_CODE( sei.m_sopDescVclNaluType[i], 6, "sop_desc_vcl_nalu_type" );
766    WRITE_CODE( sei.m_sopDescTemporalId[i],  3, "sop_desc_temporal_id" );
767    if (sei.m_sopDescVclNaluType[i] != NAL_UNIT_CODED_SLICE_IDR_W_RADL && sei.m_sopDescVclNaluType[i] != NAL_UNIT_CODED_SLICE_IDR_N_LP)
768    {
769      WRITE_UVLC( sei.m_sopDescStRpsIdx[i],           "sop_desc_st_rps_idx"               );
770    }
771    if (i > 0)
772    {
773      WRITE_SVLC( sei.m_sopDescPocDelta[i],           "sop_desc_poc_delta"               );
774    }
775  }
776}
777
778#if O0164_MULTI_LAYER_HRD
779Void SEIWriter::xWriteSEIScalableNesting(TComBitIf& bs, const SEIScalableNesting& sei, TComVPS *vps, TComSPS *sps)
780#else
781Void SEIWriter::xWriteSEIScalableNesting(TComBitIf& bs, const SEIScalableNesting& sei, TComSPS *sps)
782#endif
783{
784  WRITE_FLAG( sei.m_bitStreamSubsetFlag,             "bitstream_subset_flag"         );
785  WRITE_FLAG( sei.m_nestingOpFlag,                   "nesting_op_flag      "         );
786  if (sei.m_nestingOpFlag)
787  {
788    WRITE_FLAG( sei.m_defaultOpFlag,                 "default_op_flag"               );
789    WRITE_UVLC( sei.m_nestingNumOpsMinus1,           "nesting_num_ops_minus1"        );
790    for (UInt i = (sei.m_defaultOpFlag ? 1 : 0); i <= sei.m_nestingNumOpsMinus1; i++)
791    {
792      WRITE_CODE( sei.m_nestingMaxTemporalIdPlus1[i], 3,  "nesting_max_temporal_id_plus1" );
793      WRITE_UVLC( sei.m_nestingOpIdx[i],                  "nesting_op_idx"                );
794    }
795  }
796  else
797  {
798    WRITE_FLAG( sei.m_allLayersFlag,                      "all_layers_flag"               );
799    if (!sei.m_allLayersFlag)
800    {
801      WRITE_CODE( sei.m_nestingNoOpMaxTemporalIdPlus1, 3, "nesting_no_op_max_temporal_id_plus1" );
802      WRITE_UVLC( sei.m_nestingNumLayersMinus1,           "nesting_num_layers"                  );
803      for (UInt i = 0; i <= sei.m_nestingNumLayersMinus1; i++)
804      {
805        WRITE_CODE( sei.m_nestingLayerId[i], 6,           "nesting_layer_id"              );
806      }
807    }
808  }
809
810  // byte alignment
811  while ( m_pcBitIf->getNumberOfWrittenBits() % 8 != 0 )
812  {
813    WRITE_FLAG( 0, "nesting_zero_bit" );
814  }
815
816  // write nested SEI messages
817  for (SEIMessages::const_iterator it = sei.m_nestedSEIs.begin(); it != sei.m_nestedSEIs.end(); it++)
818  {
819#if O0164_MULTI_LAYER_HRD
820    writeSEImessage(bs, *(*it), vps, sps, &sei);
821#else
822    writeSEImessage(bs, *(*it), sps);
823#endif
824  }
825}
826
827Void SEIWriter::xWriteSEITempMotionConstrainedTileSets(TComBitIf& bs, const SEITempMotionConstrainedTileSets& sei)
828{
829  //UInt code;
830  WRITE_FLAG((sei.m_mc_all_tiles_exact_sample_value_match_flag ? 1 : 0), "mc_all_tiles_exact_sample_value_match_flag"); 
831  WRITE_FLAG((sei.m_each_tile_one_tile_set_flag                ? 1 : 0), "each_tile_one_tile_set_flag"               );
832
833  if(!sei.m_each_tile_one_tile_set_flag)
834  {
835    WRITE_FLAG((sei.m_limited_tile_set_display_flag ? 1 : 0), "limited_tile_set_display_flag");
836    WRITE_UVLC((sei.getNumberOfTileSets() - 1),               "num_sets_in_message_minus1"   );
837
838    if(sei.getNumberOfTileSets() > 0)
839    {
840      for(Int i = 0; i < sei.getNumberOfTileSets(); i++)
841      {
842        WRITE_UVLC(sei.tileSetData(i).m_mcts_id, "mcts_id");
843
844        if(sei.m_limited_tile_set_display_flag)
845        { 
846          WRITE_FLAG((sei.tileSetData(i).m_display_tile_set_flag ? 1 : 0), "display_tile_set_flag"); 
847        }
848
849        WRITE_UVLC((sei.tileSetData(i).getNumberOfTileRects() - 1), "num_tile_rects_in_set_minus1"); 
850       
851        for(Int j = 0; j < sei.tileSetData(i).getNumberOfTileRects(); j++)
852        {
853          WRITE_UVLC(sei.tileSetData(i).topLeftTileIndex    (j), "top_left_tile_index"); 
854          WRITE_UVLC(sei.tileSetData(i).bottomRightTileIndex(j), "bottom_right_tile_index"); 
855        }
856
857        if(!sei.m_mc_all_tiles_exact_sample_value_match_flag)
858        {
859          WRITE_FLAG((sei.tileSetData(i).m_exact_sample_value_match_flag ? 1 : 0), "exact_sample_value_match_flag"); 
860        }
861
862        WRITE_FLAG((sei.tileSetData(i).m_mcts_tier_level_idc_present_flag ? 1 : 0), "mcts_tier_level_idc_present_flag");
863
864        if(sei.tileSetData(i).m_mcts_tier_level_idc_present_flag)
865        {
866          WRITE_FLAG((sei.tileSetData(i).m_mcts_tier_flag ? 1 : 0), "mcts_tier_flag");
867          WRITE_CODE( sei.tileSetData(i).m_mcts_level_idc, 8,       "mcts_level_idc"); 
868        }
869      }
870    }
871  }
872  else
873  {
874    WRITE_FLAG((sei.m_max_mcs_tier_level_idc_present_flag ? 1 : 0), "max_mcs_tier_level_idc_present_flag");
875
876    if(sei.m_max_mcs_tier_level_idc_present_flag)
877    {
878      WRITE_FLAG((sei.m_max_mcts_tier_flag ? 1 : 0), "max_mcts_tier_flag"); 
879      WRITE_CODE( sei.m_max_mcts_level_idc, 8,       "max_mcts_level_idc"); 
880    }
881  }
882}
883
884Void SEIWriter::xWriteSEITimeCode(const SEITimeCode& sei)
885{
886  WRITE_CODE(sei.numClockTs, 2, "num_clock_ts");
887  for(Int i = 0; i < sei.numClockTs; i++)
888  {
889    const TComSEITimeSet &currentTimeSet = sei.timeSetArray[i];
890    WRITE_FLAG(currentTimeSet.clockTimeStampFlag, "clock_time_stamp_flag");
891    if(currentTimeSet.clockTimeStampFlag)
892    {
893      WRITE_FLAG(currentTimeSet.numUnitFieldBasedFlag, "units_field_based_flag");
894      WRITE_CODE(currentTimeSet.countingType, 5, "counting_type");
895      WRITE_FLAG(currentTimeSet.fullTimeStampFlag, "full_timestamp_flag");
896      WRITE_FLAG(currentTimeSet.discontinuityFlag, "discontinuity_flag");
897      WRITE_FLAG(currentTimeSet.cntDroppedFlag, "cnt_dropped_flag");
898      WRITE_CODE(currentTimeSet.numberOfFrames, 9, "n_frames");
899      if(currentTimeSet.fullTimeStampFlag)
900      {
901        WRITE_CODE(currentTimeSet.secondsValue, 6, "seconds_value");
902        WRITE_CODE(currentTimeSet.minutesValue, 6, "minutes_value");
903        WRITE_CODE(currentTimeSet.hoursValue, 5, "hours_value");
904      }
905      else
906      {
907        WRITE_FLAG(currentTimeSet.secondsFlag, "seconds_flag");
908        if(currentTimeSet.secondsFlag)
909        {
910          WRITE_CODE(currentTimeSet.secondsValue, 6, "seconds_value");
911          WRITE_FLAG(currentTimeSet.minutesFlag, "minutes_flag");
912          if(currentTimeSet.minutesFlag)
913          {
914            WRITE_CODE(currentTimeSet.minutesValue, 6, "minutes_value");
915            WRITE_FLAG(currentTimeSet.hoursFlag, "hours_flag");
916            if(currentTimeSet.hoursFlag)
917              WRITE_CODE(currentTimeSet.hoursValue, 5, "hours_value");
918          }
919        }
920      }
921      WRITE_CODE(currentTimeSet.timeOffsetLength, 5, "time_offset_length");
922      if(currentTimeSet.timeOffsetLength > 0)
923      {
924        if(currentTimeSet.timeOffsetValue >= 0)
925        {
926          WRITE_CODE((UInt)currentTimeSet.timeOffsetValue, currentTimeSet.timeOffsetLength, "time_offset_value");
927        }
928        else
929        {
930          //  Two's complement conversion
931          UInt offsetValue = ~(currentTimeSet.timeOffsetValue) + 1;
932          offsetValue |= (1 << (currentTimeSet.timeOffsetLength-1));
933          WRITE_CODE(offsetValue, currentTimeSet.timeOffsetLength, "time_offset_value");
934        }
935      }
936    }
937  }
938}
939
940Void SEIWriter::xWriteSEIChromaSamplingFilterHint(const SEIChromaSamplingFilterHint &sei/*, TComSPS* sps*/)
941{
942  WRITE_CODE(sei.m_verChromaFilterIdc, 8, "ver_chroma_filter_idc");
943  WRITE_CODE(sei.m_horChromaFilterIdc, 8, "hor_chroma_filter_idc");
944  WRITE_FLAG(sei.m_verFilteringProcessFlag, "ver_filtering_process_flag");
945  if(sei.m_verChromaFilterIdc == 1 || sei.m_horChromaFilterIdc == 1)
946  {
947    writeUserDefinedCoefficients(sei);
948  }
949}
950
951// write hardcoded chroma filter coefficients in the SEI messages
952Void SEIWriter::writeUserDefinedCoefficients(const SEIChromaSamplingFilterHint &sei)
953{
954  Int const iNumVerticalFilters = 3;
955  Int verticalTapLength_minus1[iNumVerticalFilters] = {5,3,3};
956  Int* userVerticalCoefficients[iNumVerticalFilters];
957  for(Int i = 0; i < iNumVerticalFilters; i ++)
958  {
959    userVerticalCoefficients[i] = (Int*)malloc( (verticalTapLength_minus1[i]+1) * sizeof(Int));
960  }
961  userVerticalCoefficients[0][0] = -3;
962  userVerticalCoefficients[0][1] = 13;
963  userVerticalCoefficients[0][2] = 31;
964  userVerticalCoefficients[0][3] = 23;
965  userVerticalCoefficients[0][4] = 3;
966  userVerticalCoefficients[0][5] = -3;
967
968  userVerticalCoefficients[1][0] = -1;
969  userVerticalCoefficients[1][1] = 25;
970  userVerticalCoefficients[1][2] = 247;
971  userVerticalCoefficients[1][3] = -15;
972
973  userVerticalCoefficients[2][0] = -20;
974  userVerticalCoefficients[2][1] = 186;
975  userVerticalCoefficients[2][2] = 100;
976  userVerticalCoefficients[2][3] = -10;
977 
978  Int const iNumHorizontalFilters = 1;
979  Int horizontalTapLength_minus1[iNumHorizontalFilters] = {3};
980  Int* userHorizontalCoefficients[iNumHorizontalFilters];
981  for(Int i = 0; i < iNumHorizontalFilters; i ++)
982  {
983    userHorizontalCoefficients[i] = (Int*)malloc( (horizontalTapLength_minus1[i]+1) * sizeof(Int));
984  }
985  userHorizontalCoefficients[0][0] = 1;
986  userHorizontalCoefficients[0][1] = 6;
987  userHorizontalCoefficients[0][2] = 1;
988
989  WRITE_UVLC(3, "target_format_idc");
990  if(sei.m_verChromaFilterIdc == 1)
991  {
992    WRITE_UVLC(iNumVerticalFilters, "num_vertical_filters");
993    if(iNumVerticalFilters > 0)
994    {
995      for(Int i = 0; i < iNumVerticalFilters; i ++)
996      {
997        WRITE_UVLC(verticalTapLength_minus1[i], "ver_tap_length_minus_1");
998        for(Int j = 0; j < verticalTapLength_minus1[i]; j ++)
999        {
1000          WRITE_SVLC(userVerticalCoefficients[i][j], "ver_filter_coeff");
1001        }
1002      }
1003    }
1004  }
1005  if(sei.m_horChromaFilterIdc == 1)
1006  {
1007    WRITE_UVLC(iNumHorizontalFilters, "num_horizontal_filters");
1008    if(iNumHorizontalFilters > 0)
1009    {
1010      for(Int i = 0; i < iNumHorizontalFilters; i ++)
1011      {
1012        WRITE_UVLC(horizontalTapLength_minus1[i], "hor_tap_length_minus_1");
1013        for(Int j = 0; j < horizontalTapLength_minus1[i]; j ++)
1014        {
1015          WRITE_SVLC(userHorizontalCoefficients[i][j], "hor_filter_coeff");
1016        }
1017      }
1018    }
1019  }
1020}
1021
1022Void SEIWriter::xWriteSEIKneeFunctionInfo(const SEIKneeFunctionInfo &sei)
1023{
1024  WRITE_UVLC( sei.m_kneeId, "knee_function_id" );
1025  WRITE_FLAG( sei.m_kneeCancelFlag, "knee_function_cancel_flag" ); 
1026  if ( !sei.m_kneeCancelFlag )
1027  {
1028    WRITE_FLAG( sei.m_kneePersistenceFlag, "knee_function_persistence_flag" );
1029    WRITE_CODE( (UInt)sei.m_kneeInputDrange , 32,  "input_d_range" );
1030    WRITE_CODE( (UInt)sei.m_kneeInputDispLuminance, 32,  "input_disp_luminance" );
1031    WRITE_CODE( (UInt)sei.m_kneeOutputDrange, 32,  "output_d_range" );
1032    WRITE_CODE( (UInt)sei.m_kneeOutputDispLuminance, 32,  "output_disp_luminance" );
1033    WRITE_UVLC( sei.m_kneeNumKneePointsMinus1, "num_knee_points_minus1" );
1034    for(Int i = 0; i <= sei.m_kneeNumKneePointsMinus1; i++ )
1035    {
1036      WRITE_CODE( (UInt)sei.m_kneeInputKneePoint[i], 10,"input_knee_point" );
1037      WRITE_CODE( (UInt)sei.m_kneeOutputKneePoint[i], 10, "output_knee_point" );
1038    }
1039  }
1040}
1041
1042
1043Void SEIWriter::xWriteSEIMasteringDisplayColourVolume(const SEIMasteringDisplayColourVolume& sei)
1044{
1045  WRITE_CODE( sei.values.primaries[0][0],  16,  "display_primaries_x[0]" );
1046  WRITE_CODE( sei.values.primaries[0][1],  16,  "display_primaries_y[0]" );
1047
1048  WRITE_CODE( sei.values.primaries[1][0],  16,  "display_primaries_x[1]" );
1049  WRITE_CODE( sei.values.primaries[1][1],  16,  "display_primaries_y[1]" );
1050
1051  WRITE_CODE( sei.values.primaries[2][0],  16,  "display_primaries_x[2]" );
1052  WRITE_CODE( sei.values.primaries[2][1],  16,  "display_primaries_y[2]" );
1053
1054  WRITE_CODE( sei.values.whitePoint[0],    16,  "white_point_x" );
1055  WRITE_CODE( sei.values.whitePoint[1],    16,  "white_point_y" );
1056   
1057  WRITE_CODE( sei.values.maxLuminance,     32,  "max_display_mastering_luminance" );
1058  WRITE_CODE( sei.values.minLuminance,     32,  "min_display_mastering_luminance" );
1059}
1060
1061
1062Void SEIWriter::xWriteByteAlign()
1063{
1064  if( m_pcBitIf->getNumberOfWrittenBits() % 8 != 0)
1065  {
1066    WRITE_FLAG( 1, "payload_bit_equal_to_one" );
1067    while( m_pcBitIf->getNumberOfWrittenBits() % 8 != 0 )
1068    {
1069      WRITE_FLAG( 0, "payload_bit_equal_to_zero" );
1070    }
1071  }
1072}
1073
1074#if SVC_EXTENSION
1075#if LAYERS_NOT_PRESENT_SEI
1076Void SEIWriter::xWriteSEILayersNotPresent(const SEILayersNotPresent& sei)
1077{
1078  WRITE_UVLC( sei.m_activeVpsId,           "lp_sei_active_vps_id" );
1079  for (UInt i = 0; i < sei.m_vpsMaxLayers; i++)
1080  {
1081    WRITE_FLAG( sei.m_layerNotPresentFlag[i], "layer_not_present_flag"   );
1082  } 
1083}
1084#endif
1085
1086#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
1087Void SEIWriter::xWriteSEIInterLayerConstrainedTileSets(const SEIInterLayerConstrainedTileSets& sei)
1088{
1089  WRITE_FLAG( sei.m_ilAllTilesExactSampleValueMatchFlag,  "il_all_tiles_exact_sample_value_match_flag"   );
1090  WRITE_FLAG( sei.m_ilOneTilePerTileSetFlag,              "il_one_tile_per_tile_set_flag"                );
1091  if( !sei.m_ilOneTilePerTileSetFlag )
1092  {
1093    WRITE_UVLC( sei.m_ilNumSetsInMessageMinus1,             "il_num_sets_in_message_minus1"                );
1094    if( sei.m_ilNumSetsInMessageMinus1 )
1095    {
1096      WRITE_FLAG( sei.m_skippedTileSetPresentFlag,            "skipped_tile_set_present_flag"                );
1097    }
1098    UInt numSignificantSets = sei.m_ilNumSetsInMessageMinus1 - (sei.m_skippedTileSetPresentFlag ? 1 : 0) + 1;
1099    for( UInt i = 0; i < numSignificantSets; i++ )
1100    {
1101      WRITE_UVLC( sei.m_ilctsId[i],                           "ilcts_id"                                     );
1102      WRITE_UVLC( sei.m_ilNumTileRectsInSetMinus1[i],         "il_num_tile_rects_in_set_minus1"              );
1103      for( UInt j = 0; j <= sei.m_ilNumTileRectsInSetMinus1[i]; j++ )
1104      {
1105        WRITE_UVLC( sei.m_ilTopLeftTileIndex[i][j],             "il_top_left_tile_index"                       );
1106        WRITE_UVLC( sei.m_ilBottomRightTileIndex[i][j],         "il_bottom_right_tile_index"                   );
1107      }
1108      WRITE_CODE( sei.m_ilcIdc[i], 2,                         "ilc_idc"                                      );
1109      if( sei.m_ilAllTilesExactSampleValueMatchFlag )
1110      {
1111        WRITE_FLAG( sei.m_ilExactSampleValueMatchFlag[i],        "il_exact_sample_value_match_flag"            );
1112      }
1113    }
1114  }
1115  else
1116  {
1117    WRITE_CODE( sei.m_allTilesIlcIdc, 2,                    "all_tiles_ilc_idc"                          );
1118  }
1119}
1120#endif
1121#if SUB_BITSTREAM_PROPERTY_SEI
1122Void SEIWriter::xWriteSEISubBitstreamProperty(const SEISubBitstreamProperty &sei)
1123{
1124  WRITE_CODE( sei.m_activeVpsId, 4, "active_vps_id" );
1125  assert( sei.m_numAdditionalSubStreams >= 1 );
1126  WRITE_UVLC( sei.m_numAdditionalSubStreams - 1, "num_additional_sub_streams_minus1" );
1127
1128  for( Int i = 0; i < sei.m_numAdditionalSubStreams; i++ )
1129  {
1130    WRITE_CODE( sei.m_subBitstreamMode[i],       2, "sub_bitstream_mode[i]"           );
1131    WRITE_UVLC( sei.m_outputLayerSetIdxToVps[i],    "output_layer_set_idx_to_vps[i]"  );
1132    WRITE_CODE( sei.m_highestSublayerId[i],      3, "highest_sub_layer_id[i]"         );
1133    WRITE_CODE( sei.m_avgBitRate[i],            16, "avg_bit_rate[i]"                 );
1134    WRITE_CODE( sei.m_maxBitRate[i],            16, "max_bit_rate[i]"                 );
1135  } 
1136}
1137#endif
1138
1139#if Q0189_TMVP_CONSTRAINTS
1140Void SEIWriter::xWriteSEITMVPConstraints (const SEITMVPConstrains &sei)
1141{
1142  WRITE_UVLC( sei.prev_pics_not_used_flag ,    "prev_pics_not_used_flag"  );
1143  WRITE_UVLC( sei.no_intra_layer_col_pic_flag ,    "no_intra_layer_col_pic_flag"  ); 
1144}
1145#endif
1146
1147#if Q0247_FRAME_FIELD_INFO
1148Void SEIWriter::xWriteSEIFrameFieldInfo  (const SEIFrameFieldInfo &sei)
1149{
1150  WRITE_CODE( sei.m_ffinfo_picStruct , 4,             "ffinfo_pic_struct" );
1151  WRITE_CODE( sei.m_ffinfo_sourceScanType, 2,         "ffinfo_source_scan_type" );
1152  WRITE_FLAG( sei.m_ffinfo_duplicateFlag ? 1 : 0,     "ffinfo_duplicate_flag" );
1153}
1154#endif
1155
1156#if O0164_MULTI_LAYER_HRD
1157Void SEIWriter::xWriteSEIBspNesting(TComBitIf& bs, const SEIBspNesting &sei, TComVPS *vps, TComSPS *sps, const SEIScalableNesting &nestingSei)
1158{
1159  WRITE_UVLC( sei.m_bspIdx, "bsp_idx" );
1160
1161  while ( m_pcBitIf->getNumberOfWrittenBits() % 8 != 0 )
1162  {
1163    WRITE_FLAG( 0, "bsp_nesting_zero_bit" );
1164  }
1165#if NESTING_SEI_EXTENSIBILITY
1166  assert( sei.m_nestedSEIs.size() <= MAX_SEIS_IN_BSP_NESTING );
1167  WRITE_UVLC( (UInt)sei.m_nestedSEIs.size(), "num_seis_in_bsp_minus1" );
1168#endif
1169  // write nested SEI messages
1170  for (SEIMessages::const_iterator it = sei.m_nestedSEIs.begin(); it != sei.m_nestedSEIs.end(); it++)
1171  {
1172    writeSEImessage(bs, *(*it), vps, sps, &nestingSei, &sei);
1173  }
1174}
1175
1176Void SEIWriter::xWriteSEIBspInitialArrivalTime(const SEIBspInitialArrivalTime &sei, TComVPS *vps, TComSPS *sps, const SEIScalableNesting &nestingSei, const SEIBspNesting &bspNestingSei)
1177{
1178  assert(vps->getVpsVuiPresentFlag());
1179
1180#if VPS_VUI_BSP_HRD_PARAMS
1181  Int psIdx = bspNestingSei.m_seiPartitioningSchemeIdx;
1182  Int seiOlsIdx = bspNestingSei.m_seiOlsIdx;
1183  Int maxTemporalId = nestingSei.m_nestingMaxTemporalIdPlus1[0] - 1;
1184  Int maxValues = vps->getNumBspSchedulesMinus1(seiOlsIdx, psIdx, maxTemporalId) + 1;
1185  std::vector<Int> hrdIdx(maxValues, 0);
1186  std::vector<TComHRD *> hrdVec;
1187  std::vector<Int> syntaxElemLen(maxValues, 0);
1188  for(Int i = 0; i < maxValues; i++)
1189  {
1190    hrdIdx[i] = vps->getBspHrdIdx( seiOlsIdx, psIdx, maxTemporalId, i, bspNestingSei.m_bspIdx);
1191    hrdVec.push_back(vps->getBspHrd(hrdIdx[i]));
1192   
1193    syntaxElemLen[i] = hrdVec[i]->getInitialCpbRemovalDelayLengthMinus1() + 1;
1194    if ( !(hrdVec[i]->getNalHrdParametersPresentFlag() || hrdVec[i]->getVclHrdParametersPresentFlag()) )
1195    {
1196      assert( syntaxElemLen[i] == 24 ); // Default of value init_cpb_removal_delay_length_minus1 is 23
1197    }
1198    if( i > 0 )
1199    {
1200      assert( hrdVec[i]->getNalHrdParametersPresentFlag() == hrdVec[i-1]->getNalHrdParametersPresentFlag() );
1201      assert( hrdVec[i]->getVclHrdParametersPresentFlag() == hrdVec[i-1]->getVclHrdParametersPresentFlag() );
1202    }
1203  }
1204  if (hrdVec[0]->getNalHrdParametersPresentFlag())
1205  {
1206    for(UInt i = 0; i < maxValues; i++)
1207    {
1208      WRITE_CODE( sei.m_nalInitialArrivalDelay[i], syntaxElemLen[i], "nal_initial_arrival_delay[i]" );
1209    }
1210  }
1211  if( hrdVec[0]->getVclHrdParametersPresentFlag() )
1212  {
1213    for(UInt i = 0; i < maxValues; i++)
1214    {
1215      WRITE_CODE( sei.m_vclInitialArrivalDelay[i], syntaxElemLen[i], "vcl_initial_arrival_delay[i]" );
1216    }
1217  }
1218#else
1219  UInt schedCombCnt = vps->getNumBspSchedCombinations(nestingSei.m_nestingOpIdx[0]);
1220  UInt len;
1221  UInt hrdIdx;
1222
1223  if (schedCombCnt > 0)
1224  {
1225    hrdIdx = vps->getBspCombHrdIdx(nestingSei.m_nestingOpIdx[0], 0, bspNestingSei.m_bspIdx);
1226  }
1227  else
1228  {
1229    hrdIdx = 0;
1230  }
1231
1232  TComHRD *hrd = vps->getBspHrd(hrdIdx);
1233
1234  if (hrd->getNalHrdParametersPresentFlag() || hrd->getVclHrdParametersPresentFlag())
1235  {
1236    len = hrd->getInitialCpbRemovalDelayLengthMinus1() + 1;
1237  }
1238  else
1239  {
1240    len = 23 + 1;
1241  }
1242
1243  if (hrd->getNalHrdParametersPresentFlag())
1244  {
1245    for(UInt i = 0; i < schedCombCnt; i++)
1246    {
1247      WRITE_CODE( sei.m_nalInitialArrivalDelay[i], len, "nal_initial_arrival_delay" );
1248    }
1249  }
1250#if BSP_INIT_ARRIVAL_SEI
1251  if( hrd->getVclHrdParametersPresentFlag() )
1252#else
1253  else
1254#endif
1255  {
1256    for(UInt i = 0; i < schedCombCnt; i++)
1257    {
1258      WRITE_CODE( sei.m_vclInitialArrivalDelay[i], len, "vcl_initial_arrival_delay" );
1259    }
1260  }
1261#endif
1262}
1263
1264#if !REMOVE_BSP_HRD_SEI
1265Void SEIWriter::xWriteSEIBspHrd(const SEIBspHrd &sei, TComSPS *sps, const SEIScalableNesting &nestingSei)
1266{
1267  WRITE_UVLC( sei.m_seiNumBspHrdParametersMinus1, "sei_num_bsp_hrd_parameters_minus1" );
1268  for (UInt i = 0; i <= sei.m_seiNumBspHrdParametersMinus1; i++)
1269  {
1270    if (i > 0)
1271    {
1272      WRITE_FLAG( sei.m_seiBspCprmsPresentFlag[i], "sei_bsp_cprms_present_flag" );
1273    }
1274    xCodeHrdParameters(sei.hrd, i==0 ? 1 : sei.m_seiBspCprmsPresentFlag[i], nestingSei.m_nestingMaxTemporalIdPlus1[0]-1);
1275  }
1276  for (UInt h = 0; h <= nestingSei.m_nestingNumOpsMinus1; h++)
1277  {
1278    UInt lsIdx = nestingSei.m_nestingOpIdx[h];
1279    WRITE_UVLC( sei.m_seiNumBitstreamPartitionsMinus1[lsIdx], "num_sei_bitstream_partitions_minus1[i]");
1280    for (UInt i = 0; i <= sei.m_seiNumBitstreamPartitionsMinus1[lsIdx]; i++)
1281    {
1282#if HRD_BPB
1283      UInt nl=0;
1284      for (UInt j = 0; j < sei.m_vpsMaxLayers; j++)
1285      {
1286        if (sei.m_layerIdIncludedFlag[lsIdx][j])
1287        {
1288          nl++;
1289        }
1290      }
1291      for (UInt j = 0; j < nl; j++)
1292      {
1293#else
1294      for (UInt j = 0; j < sei.m_vpsMaxLayers; j++)
1295      {
1296        if (sei.m_layerIdIncludedFlag[lsIdx][j])
1297        {
1298#endif
1299          WRITE_FLAG( sei.m_seiLayerInBspFlag[lsIdx][i][j], "sei_layer_in_bsp_flag[lsIdx][i][j]" );
1300        }
1301#if !HRD_BPB
1302      }
1303#endif
1304    }
1305    WRITE_UVLC( sei.m_seiNumBspSchedCombinationsMinus1[lsIdx], "sei_num_bsp_sched_combinations_minus1[i]");
1306    for (UInt i = 0; i <= sei.m_seiNumBspSchedCombinationsMinus1[lsIdx]; i++)
1307    {
1308      for (UInt j = 0; j <= sei.m_seiNumBitstreamPartitionsMinus1[lsIdx]; j++)
1309      {
1310        WRITE_UVLC( sei.m_seiBspCombHrdIdx[lsIdx][i][j], "sei_bsp_comb_hrd_idx[lsIdx][i][j]");
1311        WRITE_UVLC( sei.m_seiBspCombScheddx[lsIdx][i][j], "sei_bsp_comb_sched_idx[lsIdx][i][j]");
1312      }
1313    }
1314  }
1315}
1316#endif
1317
1318Void SEIWriter::xCodeHrdParameters( TComHRD *hrd, Bool commonInfPresentFlag, UInt maxNumSubLayersMinus1 )
1319{
1320  if( commonInfPresentFlag )
1321  {
1322    WRITE_FLAG( hrd->getNalHrdParametersPresentFlag() ? 1 : 0 ,  "nal_hrd_parameters_present_flag" );
1323    WRITE_FLAG( hrd->getVclHrdParametersPresentFlag() ? 1 : 0 ,  "vcl_hrd_parameters_present_flag" );
1324    if( hrd->getNalHrdParametersPresentFlag() || hrd->getVclHrdParametersPresentFlag() )
1325    {
1326      WRITE_FLAG( hrd->getSubPicCpbParamsPresentFlag() ? 1 : 0,  "sub_pic_cpb_params_present_flag" );
1327      if( hrd->getSubPicCpbParamsPresentFlag() )
1328      {
1329        WRITE_CODE( hrd->getTickDivisorMinus2(), 8,              "tick_divisor_minus2" );
1330        WRITE_CODE( hrd->getDuCpbRemovalDelayLengthMinus1(), 5,  "du_cpb_removal_delay_length_minus1" );
1331        WRITE_FLAG( hrd->getSubPicCpbParamsInPicTimingSEIFlag() ? 1 : 0, "sub_pic_cpb_params_in_pic_timing_sei_flag" );
1332        WRITE_CODE( hrd->getDpbOutputDelayDuLengthMinus1(), 5,   "dpb_output_delay_du_length_minus1"  );
1333      }
1334      WRITE_CODE( hrd->getBitRateScale(), 4,                     "bit_rate_scale" );
1335      WRITE_CODE( hrd->getCpbSizeScale(), 4,                     "cpb_size_scale" );
1336      if( hrd->getSubPicCpbParamsPresentFlag() )
1337      {
1338        WRITE_CODE( hrd->getDuCpbSizeScale(), 4,                "du_cpb_size_scale" ); 
1339      }
1340      WRITE_CODE( hrd->getInitialCpbRemovalDelayLengthMinus1(), 5, "initial_cpb_removal_delay_length_minus1" );
1341      WRITE_CODE( hrd->getCpbRemovalDelayLengthMinus1(),        5, "au_cpb_removal_delay_length_minus1" );
1342      WRITE_CODE( hrd->getDpbOutputDelayLengthMinus1(),         5, "dpb_output_delay_length_minus1" );
1343    }
1344  }
1345  Int i, j, nalOrVcl;
1346  for( i = 0; i <= maxNumSubLayersMinus1; i ++ )
1347  {
1348    WRITE_FLAG( hrd->getFixedPicRateFlag( i ) ? 1 : 0,          "fixed_pic_rate_general_flag");
1349    if( !hrd->getFixedPicRateFlag( i ) )
1350    {
1351      WRITE_FLAG( hrd->getFixedPicRateWithinCvsFlag( i ) ? 1 : 0, "fixed_pic_rate_within_cvs_flag");
1352    }
1353    else
1354    {
1355      hrd->setFixedPicRateWithinCvsFlag( i, true );
1356    }
1357    if( hrd->getFixedPicRateWithinCvsFlag( i ) )
1358    {
1359      WRITE_UVLC( hrd->getPicDurationInTcMinus1( i ),           "elemental_duration_in_tc_minus1");
1360    }
1361    else
1362    {
1363      WRITE_FLAG( hrd->getLowDelayHrdFlag( i ) ? 1 : 0,           "low_delay_hrd_flag");
1364    }
1365    if (!hrd->getLowDelayHrdFlag( i ))
1366    {
1367      WRITE_UVLC( hrd->getCpbCntMinus1( i ),                      "cpb_cnt_minus1");
1368    }
1369   
1370    for( nalOrVcl = 0; nalOrVcl < 2; nalOrVcl ++ )
1371    {
1372      if( ( ( nalOrVcl == 0 ) && ( hrd->getNalHrdParametersPresentFlag() ) ) ||
1373          ( ( nalOrVcl == 1 ) && ( hrd->getVclHrdParametersPresentFlag() ) ) )
1374      {
1375        for( j = 0; j <= ( hrd->getCpbCntMinus1( i ) ); j ++ )
1376        {
1377          WRITE_UVLC( hrd->getBitRateValueMinus1( i, j, nalOrVcl ), "bit_rate_value_minus1");
1378          WRITE_UVLC( hrd->getCpbSizeValueMinus1( i, j, nalOrVcl ), "cpb_size_value_minus1");
1379          if( hrd->getSubPicCpbParamsPresentFlag() )
1380          {
1381            WRITE_UVLC( hrd->getDuCpbSizeValueMinus1( i, j, nalOrVcl ), "cpb_size_du_value_minus1"); 
1382            WRITE_UVLC( hrd->getDuBitRateValueMinus1( i, j, nalOrVcl ), "bit_rate_du_value_minus1");
1383          }
1384          WRITE_FLAG( hrd->getCbrFlag( i, j, nalOrVcl ) ? 1 : 0, "cbr_flag");
1385        }
1386      }
1387    }
1388  }
1389}
1390
1391#endif
1392
1393#if Q0078_ADD_LAYER_SETS
1394
1395Void SEIWriter::xWriteSEIOutputLayerSetNesting(TComBitIf& bs, const SEIOutputLayerSetNesting &sei, TComVPS *vps, TComSPS *sps)
1396{
1397  WRITE_FLAG(sei.m_olsFlag, "ols_flag");
1398  WRITE_UVLC(sei.m_numOlsIndicesMinus1, "num_ols_indices_minus1");
1399
1400  for (Int i = 0; i <= sei.m_numOlsIndicesMinus1; i++)
1401  {
1402    WRITE_UVLC(sei.m_olsIdx[i], "ols_idx[i]");
1403  }
1404
1405  while (m_pcBitIf->getNumberOfWrittenBits() % 8 != 0)
1406  {
1407    WRITE_FLAG(0, "ols_nesting_zero_bit");
1408  }
1409
1410  // write nested SEI messages
1411  for (SEIMessages::const_iterator it = sei.m_nestedSEIs.begin(); it != sei.m_nestedSEIs.end(); it++)
1412  {
1413    writeSEImessage(bs, *(*it), vps, sps);
1414  }
1415}
1416
1417Void SEIWriter::xWriteSEIVPSRewriting(const SEIVPSRewriting &sei)
1418{
1419  //sei.nalu->
1420}
1421
1422#endif
1423
1424#if P0123_ALPHA_CHANNEL_SEI
1425Void SEIWriter::xWriteSEIAlphaChannelInfo(const SEIAlphaChannelInfo &sei)
1426{
1427  WRITE_FLAG(sei.m_alphaChannelCancelFlag, "alpha_channel_cancel_flag");
1428  if(!sei.m_alphaChannelCancelFlag)
1429  {
1430    WRITE_CODE(sei.m_alphaChannelUseIdc, 3, "alpha_channel_use_idc");
1431    WRITE_CODE(sei.m_alphaChannelBitDepthMinus8, 3, "alpha_channel_bit_depth_minus8");
1432    WRITE_CODE(sei.m_alphaTransparentValue, sei.m_alphaChannelBitDepthMinus8 + 9, "alpha_transparent_value");
1433    WRITE_CODE(sei.m_alphaOpaqueValue, sei.m_alphaChannelBitDepthMinus8 + 9, "alpha_opaque_value");
1434    WRITE_FLAG(sei.m_alphaChannelIncrFlag, "alpha_channel_incr_flag");
1435    WRITE_FLAG(sei.m_alphaChannelClipFlag, "alpha_channel_clip_flag");
1436    if(sei.m_alphaChannelClipFlag)
1437    {
1438      WRITE_FLAG(sei.m_alphaChannelClipTypeFlag, "alpha_channel_clip_type_flag");
1439    }
1440  }
1441  xWriteByteAlign();
1442}
1443#endif
1444
1445#if Q0096_OVERLAY_SEI
1446Void SEIWriter::xWriteSEIOverlayInfo(const SEIOverlayInfo &sei)
1447{
1448  Int i,j;
1449  WRITE_FLAG( sei.m_overlayInfoCancelFlag, "overlay_info_cancel_flag" );
1450  if ( !sei.m_overlayInfoCancelFlag )
1451  {
1452    WRITE_UVLC( sei.m_overlayContentAuxIdMinus128, "overlay_content_aux_id_minus128" );
1453    WRITE_UVLC( sei.m_overlayLabelAuxIdMinus128, "overlay_label_aux_id_minus128" );
1454    WRITE_UVLC( sei.m_overlayAlphaAuxIdMinus128, "overlay_alpha_aux_id_minus128" );
1455    WRITE_UVLC( sei.m_overlayElementLabelValueLengthMinus8, "overlay_element_label_value_length_minus8" );
1456    assert( sei.m_numOverlaysMinus1 < MAX_OVERLAYS );
1457    WRITE_UVLC( sei.m_numOverlaysMinus1, "num_overlays_minus1" );
1458    for (i=0 ; i<=sei.m_numOverlaysMinus1 ; i++)
1459    {
1460      WRITE_UVLC( sei.m_overlayIdx[i], "overlay_idx" );
1461      WRITE_FLAG( sei.m_languageOverlayPresentFlag[i], "language_overlay_present_flag" );
1462      WRITE_CODE( sei.m_overlayContentLayerId[i], 6, "overlay_content_layer_id");
1463      WRITE_FLAG( sei.m_overlayLabelPresentFlag[i], "overlay_label_present_flag" );
1464      if ( sei.m_overlayLabelPresentFlag[i] )
1465      {
1466        WRITE_CODE(  sei.m_overlayLabelLayerId[i], 6, "overlay_label_layer_id");
1467      }
1468      WRITE_FLAG( sei.m_overlayAlphaPresentFlag[i], "overlay_alpha_present_flag" );
1469      if ( sei.m_overlayAlphaPresentFlag[i] )
1470      {
1471        WRITE_CODE( sei.m_overlayAlphaLayerId[i], 6, "overlay_alpha_layer_id");
1472      }
1473      if ( sei.m_overlayLabelPresentFlag[i] )
1474      {
1475        assert( sei.m_numOverlayElementsMinus1[i] < MAX_OVERLAY_ELEMENTS );
1476        WRITE_UVLC( sei.m_numOverlayElementsMinus1[i], "num_overlay_elements_minus1");
1477        for ( j=0 ; j<=sei.m_numOverlayElementsMinus1[i] ; j++ )
1478        {
1479          WRITE_CODE(sei.m_overlayElementLabelMin[i][j], sei.m_overlayElementLabelValueLengthMinus8 + 8, "overlay_element_label_min");
1480          WRITE_CODE(sei.m_overlayElementLabelMax[i][j], sei.m_overlayElementLabelValueLengthMinus8 + 8, "overlay_element_label_max"); 
1481        }
1482      }
1483    }
1484
1485
1486    // byte alignment
1487    while ( m_pcBitIf->getNumberOfWrittenBits() % 8 != 0 )
1488    {
1489      WRITE_FLAG( 0, "overlay_zero_bit" );
1490    }
1491
1492    for ( i=0 ; i<=sei.m_numOverlaysMinus1 ; i++ )
1493    {
1494      if ( sei.m_languageOverlayPresentFlag[i] )
1495      {
1496        WRITE_STRING( sei.m_overlayLanguage[i], sei.m_overlayLanguageLength[i], "overlay_language" );    //WRITE_STRING adds zero-termination byte
1497      }
1498      WRITE_STRING( sei.m_overlayName[i], sei.m_overlayNameLength[i], "overlay_name" );
1499      if ( sei.m_overlayLabelPresentFlag[i] )
1500      {
1501        for ( j=0 ; j<=sei.m_numOverlayElementsMinus1[i] ; j++)
1502        {
1503          WRITE_STRING( sei.m_overlayElementName[i][j], sei.m_overlayElementNameLength[i][j], "overlay_element_name" );
1504        }
1505      }
1506    }
1507    WRITE_FLAG( sei.m_overlayInfoPersistenceFlag, "overlay_info_persistence_flag" );
1508  }
1509}
1510#endif
1511
1512#endif //SVC_EXTENSION
1513
1514#if Q0074_COLOUR_REMAPPING_SEI
1515Void SEIWriter::xWriteSEIColourRemappingInfo(const SEIColourRemappingInfo& sei)
1516{
1517  WRITE_UVLC( sei.m_colourRemapId,                             "colour_remap_id" );
1518  WRITE_FLAG( sei.m_colourRemapCancelFlag,                     "colour_remap_cancel_flag" );
1519  if( !sei.m_colourRemapCancelFlag ) 
1520  {
1521    WRITE_FLAG( sei.m_colourRemapPersistenceFlag,              "colour_remap_persistence_flag" );
1522    WRITE_FLAG( sei.m_colourRemapVideoSignalInfoPresentFlag,   "colour_remap_video_signal_info_present_flag" );
1523    if ( sei.m_colourRemapVideoSignalInfoPresentFlag )
1524    {
1525      WRITE_FLAG( sei.m_colourRemapFullRangeFlag,              "colour_remap_full_range_flag" );
1526      WRITE_CODE( sei.m_colourRemapPrimaries,               8, "colour_remap_primaries" );
1527      WRITE_CODE( sei.m_colourRemapTransferFunction,        8, "colour_remap_transfer_function" );
1528      WRITE_CODE( sei.m_colourRemapMatrixCoefficients,      8, "colour_remap_matrix_coefficients" );
1529    }
1530    WRITE_CODE( sei.m_colourRemapInputBitDepth,             8, "colour_remap_input_bit_depth" );
1531    WRITE_CODE( sei.m_colourRemapBitDepth,                  8, "colour_remap_bit_depth" );
1532    for( Int c=0 ; c<3 ; c++ )
1533    {
1534      WRITE_CODE( sei.m_preLutNumValMinus1[c],              8, "pre_lut_num_val_minus1[c]" );
1535      if( sei.m_preLutNumValMinus1[c]>0 )
1536        for( Int i=0 ; i<=sei.m_preLutNumValMinus1[c] ; i++ )
1537        {
1538          WRITE_CODE( sei.m_preLutCodedValue[c][i], (( sei.m_colourRemapInputBitDepth + 7 ) >> 3 ) << 3, "pre_lut_coded_value[c][i]" );
1539          WRITE_CODE( sei.m_preLutTargetValue[c][i], (( sei.m_colourRemapBitDepth + 7 ) >> 3 ) << 3, "pre_lut_target_value[c][i]" );
1540        }
1541    }
1542    WRITE_FLAG( sei.m_colourRemapMatrixPresentFlag,            "colour_remap_matrix_present_flag" );
1543    if( sei.m_colourRemapMatrixPresentFlag )
1544    {
1545      WRITE_CODE( sei.m_log2MatrixDenom,                    4, "log2_matrix_denom" );
1546      for( Int c=0 ; c<3 ; c++ )
1547        for( Int i=0 ; i<3 ; i++ )
1548          WRITE_SVLC( sei.m_colourRemapCoeffs[c][i],           "colour_remap_coeffs[c][i]" );
1549    }
1550
1551    for( Int c=0 ; c<3 ; c++ )
1552    {
1553      WRITE_CODE( sei.m_postLutNumValMinus1[c],             8, "m_postLutNumValMinus1[c]" );
1554      if( sei.m_postLutNumValMinus1[c]>0 )
1555        for( Int i=0 ; i<=sei.m_postLutNumValMinus1[c] ; i++ )
1556        {
1557          WRITE_CODE( sei.m_postLutCodedValue[c][i], (( sei.m_colourRemapBitDepth + 7 ) >> 3 ) << 3, "post_lut_coded_value[c][i]" );       
1558          WRITE_CODE( sei.m_postLutTargetValue[c][i], (( sei.m_colourRemapBitDepth + 7 ) >> 3 ) << 3, "post_lut_target_value[c][i]" );
1559        }
1560    }
1561  }
1562}
1563#endif
1564
1565//! \}
Note: See TracBrowser for help on using the repository browser.