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

Last change on this file since 1265 was 1259, checked in by seregin, 9 years ago

port rev 4256

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