source: SHVCSoftware/branches/0.1.1-bugfix/source/Lib/TLibEncoder/SEIwrite.cpp

Last change on this file was 2, checked in by seregin, 12 years ago

Initial import by Vadim Seregin <vseregin@…>

File size: 10.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-2012, 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 "SEIwrite.h"
39
40//! \ingroup TLibEncoder
41//! \{
42
43#if ENC_DEC_TRACE
44Void  xTraceSEIHeader()
45{
46  fprintf( g_hTrace, "=========== SEI message ===========\n");
47}
48
49Void  xTraceSEIMessageType(SEI::PayloadType payloadType)
50{
51  switch (payloadType)
52  {
53  case SEI::DECODED_PICTURE_HASH:
54    fprintf( g_hTrace, "=========== Decoded picture hash SEI message ===========\n");
55    break;
56  case SEI::USER_DATA_UNREGISTERED:
57    fprintf( g_hTrace, "=========== User Data Unregistered SEI message ===========\n");
58    break;
59#if ACTIVE_PARAMETER_SETS_SEI_MESSAGE
60  case SEI::ACTIVE_PARAMETER_SETS:
61    fprintf( g_hTrace, "=========== Active Parameter sets SEI message ===========\n");
62    break;
63#endif
64  default:
65    fprintf( g_hTrace, "=========== Unknown SEI message ===========\n");
66    break;
67  }
68}
69#endif
70
71void SEIWriter::xWriteSEIpayloadData(const SEI& sei)
72{
73  switch (sei.payloadType())
74  {
75  case SEI::USER_DATA_UNREGISTERED:
76    xWriteSEIuserDataUnregistered(*static_cast<const SEIuserDataUnregistered*>(&sei));
77    break;
78#if ACTIVE_PARAMETER_SETS_SEI_MESSAGE 
79  case SEI::ACTIVE_PARAMETER_SETS:
80    xWriteSEIActiveParameterSets(*static_cast<const SEIActiveParameterSets*>(& sei)); 
81    break; 
82#endif
83  case SEI::DECODED_PICTURE_HASH:
84    xWriteSEIDecodedPictureHash(*static_cast<const SEIDecodedPictureHash*>(&sei));
85    break;
86#if BUFFERING_PERIOD_AND_TIMING_SEI
87  case SEI::BUFFERING_PERIOD:
88    xWriteSEIBufferingPeriod(*static_cast<const SEIBufferingPeriod*>(&sei));
89    break;
90  case SEI::PICTURE_TIMING:
91    xWriteSEIPictureTiming(*static_cast<const SEIPictureTiming*>(&sei));
92    break;
93#endif
94#if RECOVERY_POINT_SEI
95  case SEI::RECOVERY_POINT:
96    xWriteSEIRecoveryPoint(*static_cast<const SEIRecoveryPoint*>(&sei));
97    break;
98#endif
99  default:
100    assert(!"Unhandled SEI message");
101  }
102}
103
104/**
105 * marshal a single SEI message sei, storing the marshalled representation
106 * in bitstream bs.
107 */
108Void SEIWriter::writeSEImessage(TComBitIf& bs, const SEI& sei)
109{
110  /* calculate how large the payload data is */
111  /* TODO: this would be far nicer if it used vectored buffers */
112  TComBitCounter bs_count;
113  bs_count.resetBits();
114  setBitstream(&bs_count);
115
116#if ENC_DEC_TRACE
117  g_HLSTraceEnable = false;
118#endif
119  xWriteSEIpayloadData(sei);
120#if ENC_DEC_TRACE
121  g_HLSTraceEnable = true;
122#endif
123  unsigned payload_data_num_bits = bs_count.getNumberOfWrittenBits();
124  assert(0 == payload_data_num_bits % 8);
125
126  setBitstream(&bs);
127
128#if ENC_DEC_TRACE
129  xTraceSEIHeader();
130#endif
131
132  UInt payloadType = sei.payloadType();
133  for (; payloadType >= 0xff; payloadType -= 0xff)
134  {
135    WRITE_CODE(0xff, 8, "payload_type");
136  }
137  WRITE_CODE(payloadType, 8, "payload_type");
138
139  UInt payloadSize = payload_data_num_bits/8;
140  for (; payloadSize >= 0xff; payloadSize -= 0xff)
141  {
142    WRITE_CODE(0xff, 8, "payload_size");
143  }
144  WRITE_CODE(payloadSize, 8, "payload_size");
145
146  /* payloadData */
147#if ENC_DEC_TRACE
148  xTraceSEIMessageType(sei.payloadType());
149#endif
150
151  xWriteSEIpayloadData(sei);
152}
153
154/**
155 * marshal a user_data_unregistered SEI message sei, storing the marshalled
156 * representation in bitstream bs.
157 */
158Void SEIWriter::xWriteSEIuserDataUnregistered(const SEIuserDataUnregistered &sei)
159{
160  for (UInt i = 0; i < 16; i++)
161  {
162    WRITE_CODE(sei.uuid_iso_iec_11578[i], 8 , "sei.uuid_iso_iec_11578[i]");
163  }
164
165  for (UInt i = 0; i < sei.userDataLength; i++)
166  {
167    WRITE_CODE(sei.userData[i], 8 , "user_data");
168  }
169}
170
171/**
172 * marshal a decoded picture hash SEI message, storing the marshalled
173 * representation in bitstream bs.
174 */
175Void SEIWriter::xWriteSEIDecodedPictureHash(const SEIDecodedPictureHash& sei)
176{
177  UInt val;
178
179  WRITE_CODE(sei.method, 8, "hash_type");
180
181  for(int yuvIdx = 0; yuvIdx < 3; yuvIdx++)
182  {
183    if(sei.method == SEIDecodedPictureHash::MD5)
184    {
185      for (unsigned i = 0; i < 16; i++)
186      {
187        WRITE_CODE(sei.digest[yuvIdx][i], 8, "picture_md5");
188      }
189    }
190    else if(sei.method == SEIDecodedPictureHash::CRC)
191    {
192      val = (sei.digest[yuvIdx][0] << 8)  + sei.digest[yuvIdx][1];
193      WRITE_CODE(val, 16, "picture_crc");
194    }
195    else if(sei.method == SEIDecodedPictureHash::CHECKSUM)
196    {
197      val = (sei.digest[yuvIdx][0] << 24)  + (sei.digest[yuvIdx][1] << 16) + (sei.digest[yuvIdx][2] << 8) + sei.digest[yuvIdx][3];
198      WRITE_CODE(val, 32, "picture_checksum");
199    }
200  }
201}
202
203#if ACTIVE_PARAMETER_SETS_SEI_MESSAGE 
204Void SEIWriter::xWriteSEIActiveParameterSets(const SEIActiveParameterSets& sei)
205{
206  WRITE_CODE(sei.activeVPSId, 4, "active_vps_id");
207  WRITE_CODE(sei.activeSPSIdPresentFlag, 1, "active_sps_id_present_flag");
208
209  if (sei.activeSPSIdPresentFlag) 
210  {
211    WRITE_UVLC(sei.activeSeqParamSetId, "active_seq_param_set_id"); 
212  }
213
214  WRITE_CODE(sei.activeParamSetSEIExtensionFlag, 1, "active_param_set_sei_extension_flag"); 
215
216  unsigned uiBits = m_pcBitIf->getNumberOfWrittenBits(); 
217  UInt uiAlignedBits = ( 8 - (uiBits&7) ) % 8; 
218  if(uiAlignedBits) 
219  {
220    WRITE_FLAG(1, "alignment_bit" );
221    uiAlignedBits--; 
222    while(uiAlignedBits--)
223    {
224      WRITE_FLAG(0, "alignment_bit" );
225    }
226  }
227}
228#endif
229
230#if BUFFERING_PERIOD_AND_TIMING_SEI
231Void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei)
232{
233  Int i, nalOrVcl;
234  TComVUI *vui = sei.m_sps->getVuiParameters();
235  WRITE_UVLC( sei.m_seqParameterSetId, "seq_parameter_set_id" );
236  if( !vui->getSubPicCpbParamsPresentFlag() )
237  {
238    WRITE_FLAG( sei.m_altCpbParamsPresentFlag, "alt_cpb_params_present_flag" );
239  }
240  for( nalOrVcl = 0; nalOrVcl < 2; nalOrVcl ++ )
241  {
242    if( ( ( nalOrVcl == 0 ) && ( vui->getNalHrdParametersPresentFlag() ) ) ||
243        ( ( nalOrVcl == 1 ) && ( vui->getVclHrdParametersPresentFlag() ) ) )
244    {
245      for( i = 0; i < ( vui->getCpbCntMinus1( 0 ) + 1 ); i ++ )
246      {
247        WRITE_CODE( sei.m_initialCpbRemovalDelay[i][nalOrVcl],( vui->getInitialCpbRemovalDelayLengthMinus1() + 1 ) ,           "initial_cpb_removal_delay" );
248        WRITE_CODE( sei.m_initialCpbRemovalDelayOffset[i][nalOrVcl],( vui->getInitialCpbRemovalDelayLengthMinus1() + 1 ),      "initial_cpb_removal_delay_offset" );
249        if( vui->getSubPicCpbParamsPresentFlag() || sei.m_altCpbParamsPresentFlag )
250        {
251          WRITE_CODE( sei.m_initialAltCpbRemovalDelay[i][nalOrVcl], ( vui->getInitialCpbRemovalDelayLengthMinus1() + 1 ) ,     "initial_alt_cpb_removal_delay" );
252          WRITE_CODE( sei.m_initialAltCpbRemovalDelayOffset[i][nalOrVcl], ( vui->getInitialCpbRemovalDelayLengthMinus1() + 1 ),"initial_alt_cpb_removal_delay_offset" );
253        }
254      }
255    }
256  }
257  xWriteByteAlign();
258}
259Void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei)
260{
261  Int i;
262  TComVUI *vui = sei.m_sps->getVuiParameters();
263
264  if( !vui->getNalHrdParametersPresentFlag() && !vui->getVclHrdParametersPresentFlag() )
265    return;
266
267  WRITE_CODE( sei.m_auCpbRemovalDelay, ( vui->getCpbRemovalDelayLengthMinus1() + 1 ),                                         "au_cpb_removal_delay" );
268  WRITE_CODE( sei.m_picDpbOutputDelay, ( vui->getDpbOutputDelayLengthMinus1() + 1 ),                                          "pic_dpb_output_delay" );
269  if( sei.m_sps->getVuiParameters()->getSubPicCpbParamsPresentFlag() )
270  {
271    WRITE_UVLC( sei.m_numDecodingUnitsMinus1,     "num_decoding_units_minus1" );
272    WRITE_FLAG( sei.m_duCommonCpbRemovalDelayFlag, "du_common_cpb_removal_delay_flag" );
273    if( sei.m_duCommonCpbRemovalDelayFlag )
274    {
275      WRITE_CODE( sei.m_duCommonCpbRemovalDelayMinus1, ( vui->getDuCpbRemovalDelayLengthMinus1() + 1 ),                       "du_common_cpb_removal_delay_minus1" );
276    }
277    else
278    {
279      for( i = 0; i < ( sei.m_numDecodingUnitsMinus1 + 1 ); i ++ )
280      {
281        WRITE_UVLC( sei.m_numNalusInDuMinus1[ i ],  "num_nalus_in_du_minus1");
282        WRITE_CODE( sei.m_duCpbRemovalDelayMinus1[ i ], ( vui->getDuCpbRemovalDelayLengthMinus1() + 1 ),                        "du_cpb_removal_delay_minus1" );
283      }
284    }
285  }
286  xWriteByteAlign();
287}
288#endif
289#if RECOVERY_POINT_SEI
290Void SEIWriter::xWriteSEIRecoveryPoint(const SEIRecoveryPoint& sei)
291{
292  WRITE_SVLC( sei.m_recoveryPocCnt,    "recovery_poc_cnt"    );
293  WRITE_FLAG( sei.m_exactMatchingFlag, "exact_matching_flag" );
294  WRITE_FLAG( sei.m_brokenLinkFlag,    "broken_link_flag"    );
295  xWriteByteAlign();
296}
297#endif
298
299#if RECOVERY_POINT_SEI || BUFFERING_PERIOD_AND_TIMING_SEI
300Void SEIWriter::xWriteByteAlign()
301{
302  if( m_pcBitIf->getNumberOfWrittenBits() % 8 != 0)
303  {
304    WRITE_FLAG( 1, "bit_equal_to_one" );
305    while( m_pcBitIf->getNumberOfWrittenBits() % 8 != 0 )
306    {
307      WRITE_FLAG( 0, "bit_equal_to_zero" );
308    }
309  }
310};
311#endif
312
313//! \}
Note: See TracBrowser for help on using the repository browser.