source: 3DVCSoftware/branches/HTM-DEV-2.0-dev1-QC-INTRA-MTK/source/App/utils/annexBbytecount.cpp @ 586

Last change on this file since 586 was 324, checked in by tech, 12 years ago

Initial development version for update to latest HM version.
Includes MV-HEVC and basic extensions for 3D-HEVC.

  • Property svn:eol-style set to native
File size: 9.2 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 <stdint.h>
35#include <cassert>
36#include <fstream>
37#include <sstream>
38#include <iostream>
39#include <string.h>
40
41#include "TLibDecoder/AnnexBread.h"
42
43using namespace std;
44
45static struct {
46  AnnexBStats expected;
47  unsigned data_len;
48  const char data[10];
49} tests[] = {
50  /* trivial cases: startcode, no payload */
51  {{0, 0, 3, 0, 0}, 3, {0,0,1}},
52  {{0, 1, 3, 0, 0}, 4, {0,0,0,1}},
53  {{2, 1, 3, 0, 0}, 6, {0,0,0,0,0,1}},
54  /* trivial cases: startcode, payload */
55  {{0, 0, 3, 1, 0}, 4, {0,0,1,2}},
56  {{0, 0, 3, 2, 0}, 5, {0,0,1,2,0}},
57  {{0, 0, 3, 3, 0}, 6, {0,0,1,2,0,0}},
58  {{0, 0, 3, 1, 3}, 7, {0,0,1,2,0,0,0}},
59  /* trivial cases: two nal units: extract the first */
60  {{0, 0, 3, 1, 0}, 8, {0,0,1,2,0,0,1,3}},
61  {{0, 0, 3, 1, 0}, 9, {0,0,1,2,0,0,0,1,3}},
62  {{0, 0, 3, 1, 1}, 10, {0,0,1,2,0,0,0,0,1,3}},
63  /* edge cases with EOF near start*/
64  {{0, 0, 0, 0, 0}, 0, {}},
65  {{1, 0, 0, 0, 0}, 1, {0}},
66  {{2, 0, 0, 0, 0}, 2, {0,0}},
67  {{3, 0, 0, 0, 0}, 3, {0,0,0}},
68};
69
70void selftest()
71{
72  /* test */
73  for (unsigned i = 0; i < sizeof(tests)/sizeof(*tests); i++)
74  {
75    istringstream in(string(tests[i].data, tests[i].data_len));
76    InputByteStream bs(in);
77
78    AnnexBStats actual = AnnexBStats();
79    vector<uint8_t> nalUnit;
80
81    byteStreamNALUnit(bs, nalUnit, actual);
82
83    cout << "Self-Test: " << i << ", {";
84    for (unsigned j = 0; j < tests[i].data_len; j++)
85    {
86      cout << hex << (unsigned int)tests[i].data[j] << dec;
87      if (j < tests[i].data_len-1)
88        cout << ",";
89    }
90    cout << "} ";
91
92    bool ok = true;
93#define VERIFY(a,b,m) \
94  if (a.m != b.m) { \
95    ok = false; \
96    cout << endl << "  MISSMATCH " #m << ", E(" << b.m << ") != " << a.m; \
97  }
98    VERIFY(actual, tests[i].expected, m_numLeadingZero8BitsBytes);
99    VERIFY(actual, tests[i].expected, m_numZeroByteBytes);
100    VERIFY(actual, tests[i].expected, m_numStartCodePrefixBytes);
101    VERIFY(actual, tests[i].expected, m_numBytesInNALUnit);
102    VERIFY(actual, tests[i].expected, m_numTrailingZero8BitsBytes);
103#undef VERIFY
104    if (ok)
105      cout << "OK";
106    cout << endl;
107  }
108}
109
110int main(int argc, char*argv[])
111{
112  selftest();
113
114  if (argc != 2)
115    return 0;
116
117  ifstream in(argv[1], ifstream::in | ifstream::binary);
118  InputByteStream bs(in);
119
120  AnnexBStats annexBStatsTotal = AnnexBStats();
121  AnnexBStats annexBStatsTotal_VCL = AnnexBStats();
122  AnnexBStats annexBStatsTotal_Filler = AnnexBStats();
123  AnnexBStats annexBStatsTotal_Other = AnnexBStats();
124  unsigned numNALUnits = 0;
125
126  cout << "NALUnits:" << endl;
127  while (!!in)
128  {
129    AnnexBStats annexBStatsSingle = AnnexBStats();
130    vector<uint8_t> nalUnit;
131
132    byteStreamNALUnit(bs, nalUnit, annexBStatsSingle);
133
134    int nal_unit_type = -1;
135    if (annexBStatsSingle.m_numBytesInNALUnit)
136    {
137      nal_unit_type = nalUnit[0] & 0x1f;
138    }
139
140    cout << " - NALU: #" << numNALUnits << " nal_unit_type:" << nal_unit_type << endl
141         << "   num_bytes(leading_zero_8bits): " << annexBStatsSingle.m_numLeadingZero8BitsBytes << endl
142         << "   num_bytes(zero_byte): " << annexBStatsSingle.m_numZeroByteBytes << endl
143         << "   num_bytes(start_code_prefix_one_3bytes): " << annexBStatsSingle.m_numStartCodePrefixBytes << endl
144         << "   NumBytesInNALunit: " << annexBStatsSingle.m_numBytesInNALUnit << endl
145         << "   num_bytes(trailing_zero_8bits): " << annexBStatsSingle.m_numTrailingZero8BitsBytes << endl
146         ;
147
148    annexBStatsTotal += annexBStatsSingle;
149    numNALUnits++;
150
151    if (!annexBStatsSingle.m_numBytesInNALUnit)
152      continue;
153
154    /* identify the NAL unit type and add stats to the correct
155     * accumulators */
156    switch (nalUnit[0] & 0x1f) {
157    case 1: case 2: case 3: case 4: case 5:
158      annexBStatsTotal_VCL += annexBStatsSingle;
159      break;
160    case 12:
161      annexBStatsTotal_Filler += annexBStatsSingle;
162      break;
163    default:
164      annexBStatsTotal_Other += annexBStatsSingle;
165    };
166  }
167
168  cout << "Summary: " << endl
169       << "  num_bytes(leading_zero_8bits): " << annexBStatsTotal.m_numLeadingZero8BitsBytes << endl
170       << "  num_bytes(zero_byte): " << annexBStatsTotal.m_numZeroByteBytes << endl
171       << "  num_bytes(start_code_prefix_one_3bytes): " << annexBStatsTotal.m_numStartCodePrefixBytes << endl
172       << "  NumBytesInNALunit: " << annexBStatsTotal.m_numBytesInNALUnit << endl
173       << "  num_bytes(trailing_zero_8bits): " << annexBStatsTotal.m_numTrailingZero8BitsBytes << endl
174       ;
175
176  cout << "Summary(VCL): " << endl
177       << "  num_bytes(leading_zero_8bits): " << annexBStatsTotal_VCL.m_numLeadingZero8BitsBytes << endl
178       << "  num_bytes(zero_byte): " << annexBStatsTotal_VCL.m_numZeroByteBytes << endl
179       << "  num_bytes(start_code_prefix_one_3bytes): " << annexBStatsTotal_VCL.m_numStartCodePrefixBytes << endl
180       << "  NumBytesInNALunit: " << annexBStatsTotal_VCL.m_numBytesInNALUnit << endl
181       << "  num_bytes(trailing_zero_8bits): " << annexBStatsTotal_VCL.m_numTrailingZero8BitsBytes << endl
182       ;
183
184  cout << "Summary(Filler): " << endl
185       << "  num_bytes(leading_zero_8bits): " << annexBStatsTotal_Filler.m_numLeadingZero8BitsBytes << endl
186       << "  num_bytes(zero_byte): " << annexBStatsTotal_Filler.m_numZeroByteBytes << endl
187       << "  num_bytes(start_code_prefix_one_3bytes): " << annexBStatsTotal_Filler.m_numStartCodePrefixBytes << endl
188       << "  NumBytesInNALunit: " << annexBStatsTotal_Filler.m_numBytesInNALUnit << endl
189       << "  num_bytes(trailing_zero_8bits): " << annexBStatsTotal_Filler.m_numTrailingZero8BitsBytes << endl
190       ;
191
192  cout << "Summary(Other): " << endl
193       << "  num_bytes(leading_zero_8bits): " << annexBStatsTotal_Other.m_numLeadingZero8BitsBytes << endl
194       << "  num_bytes(zero_byte): " << annexBStatsTotal_Other.m_numZeroByteBytes << endl
195       << "  num_bytes(start_code_prefix_one_3bytes): " << annexBStatsTotal_Other.m_numStartCodePrefixBytes << endl
196       << "  NumBytesInNALunit: " << annexBStatsTotal_Other.m_numBytesInNALUnit << endl
197       << "  num_bytes(trailing_zero_8bits): " << annexBStatsTotal_Other.m_numTrailingZero8BitsBytes << endl
198       ;
199
200  /* The first such type of bitstream, called Type I bitstream, is a
201   * NAL unit stream containing only the VCL NAL units and filler data
202   * NAL units for all access units in the bitstream.
203   */
204  unsigned totalBytes_T1HRD = annexBStatsTotal_VCL.m_numBytesInNALUnit + annexBStatsTotal_Filler.m_numBytesInNALUnit;
205
206  /*The second type of bitstream, called a Type II bitstream,
207   * contains, in addition to the VCL NAL units and filler data NAL
208   * units for all access units in the bitstream, at least one of
209   * the following:
210   *  (a) additional non-VCL NAL units other than filler data NAL
211   *      units.
212   */
213  unsigned totalBytes_T2aHRD = annexBStatsTotal.m_numBytesInNALUnit;
214
215  /*  (b) all leading_zero_8bits, zero_byte,
216   *      start_code_prefix_one_3bytes, and trailing_zero_8bits syntax
217   *      elements that form a byte stream from the NAL unit stream (as
218   *      specified in Annex B)
219   */
220  unsigned totalBytes_T2abHRD = 0;
221  totalBytes_T2abHRD += annexBStatsTotal.m_numLeadingZero8BitsBytes;
222  totalBytes_T2abHRD += annexBStatsTotal.m_numZeroByteBytes;
223  totalBytes_T2abHRD += annexBStatsTotal.m_numStartCodePrefixBytes;
224  totalBytes_T2abHRD += annexBStatsTotal.m_numBytesInNALUnit;
225  totalBytes_T2abHRD += annexBStatsTotal.m_numTrailingZero8BitsBytes;
226
227  cout << "Totals (bytes):" << endl;
228  cout << "  Type1 HRD: " << totalBytes_T1HRD << endl;
229  cout << "  Type2 HRD: " << totalBytes_T2aHRD << endl;
230  cout << "  Type2b HRD: " << totalBytes_T2abHRD << endl;
231
232  return 0;
233}
Note: See TracBrowser for help on using the repository browser.