source: SHVCSoftware/trunk/source/App/utils/BLRewrite/BLRewrite.c

Last change on this file was 778, checked in by nokia, 11 years ago

JCTVC-Q0078/R0042: Additional layer sets and independent non-base layer rewriting tool (utils/BLRewrite)

  • Property svn:eol-style set to native
File size: 7.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-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 <stdlib.h>
35#include <stdio.h>
36
37
38enum NalUnitType
39{
40  NAL_UNIT_CODED_SLICE_TRAIL_N = 0,   // 0
41  NAL_UNIT_CODED_SLICE_TRAIL_R,   // 1
42
43  NAL_UNIT_CODED_SLICE_TSA_N,     // 2
44  NAL_UNIT_CODED_SLICE_TSA_R,       // 3
45
46  NAL_UNIT_CODED_SLICE_STSA_N,    // 4
47  NAL_UNIT_CODED_SLICE_STSA_R,    // 5
48
49  NAL_UNIT_CODED_SLICE_RADL_N,    // 6
50  NAL_UNIT_CODED_SLICE_RADL_R,      // 7
51
52  NAL_UNIT_CODED_SLICE_RASL_N,    // 8
53  NAL_UNIT_CODED_SLICE_RASL_R,      // 9
54
55  NAL_UNIT_RESERVED_VCL_N10,
56  NAL_UNIT_RESERVED_VCL_R11,
57  NAL_UNIT_RESERVED_VCL_N12,
58  NAL_UNIT_RESERVED_VCL_R13,
59  NAL_UNIT_RESERVED_VCL_N14,
60  NAL_UNIT_RESERVED_VCL_R15,
61
62  NAL_UNIT_CODED_SLICE_BLA_W_LP,    // 16
63  NAL_UNIT_CODED_SLICE_BLA_W_RADL,  // 17
64  NAL_UNIT_CODED_SLICE_BLA_N_LP,  // 18
65  NAL_UNIT_CODED_SLICE_IDR_W_RADL,  // 19
66  NAL_UNIT_CODED_SLICE_IDR_N_LP,  // 20
67  NAL_UNIT_CODED_SLICE_CRA,       // 21
68  NAL_UNIT_RESERVED_IRAP_VCL22,
69  NAL_UNIT_RESERVED_IRAP_VCL23,
70
71  NAL_UNIT_RESERVED_VCL24,
72  NAL_UNIT_RESERVED_VCL25,
73  NAL_UNIT_RESERVED_VCL26,
74  NAL_UNIT_RESERVED_VCL27,
75  NAL_UNIT_RESERVED_VCL28,
76  NAL_UNIT_RESERVED_VCL29,
77  NAL_UNIT_RESERVED_VCL30,
78  NAL_UNIT_RESERVED_VCL31,
79
80  NAL_UNIT_VPS,                   // 32
81  NAL_UNIT_SPS,                   // 33
82  NAL_UNIT_PPS,                   // 34
83  NAL_UNIT_ACCESS_UNIT_DELIMITER, // 35
84  NAL_UNIT_EOS,                   // 36
85  NAL_UNIT_EOB,                   // 37
86  NAL_UNIT_FILLER_DATA,           // 38
87  NAL_UNIT_PREFIX_SEI,              // 39
88  NAL_UNIT_SUFFIX_SEI,              // 40
89  NAL_UNIT_RESERVED_NVCL41,
90  NAL_UNIT_RESERVED_NVCL42,
91  NAL_UNIT_RESERVED_NVCL43,
92  NAL_UNIT_RESERVED_NVCL44,
93  NAL_UNIT_RESERVED_NVCL45,
94  NAL_UNIT_RESERVED_NVCL46,
95  NAL_UNIT_RESERVED_NVCL47,
96  NAL_UNIT_UNSPECIFIED_48,
97  NAL_UNIT_UNSPECIFIED_49,
98  NAL_UNIT_UNSPECIFIED_50,
99  NAL_UNIT_UNSPECIFIED_51,
100  NAL_UNIT_UNSPECIFIED_52,
101  NAL_UNIT_UNSPECIFIED_53,
102  NAL_UNIT_UNSPECIFIED_54,
103  NAL_UNIT_UNSPECIFIED_55,
104  NAL_UNIT_UNSPECIFIED_56,
105  NAL_UNIT_UNSPECIFIED_57,
106  NAL_UNIT_UNSPECIFIED_58,
107  NAL_UNIT_UNSPECIFIED_59,
108  NAL_UNIT_UNSPECIFIED_60,
109  NAL_UNIT_UNSPECIFIED_61,
110  NAL_UNIT_UNSPECIFIED_62,
111  NAL_UNIT_UNSPECIFIED_63,
112  NAL_UNIT_INVALID,
113};
114
115typedef struct NalUnitHeader_s
116{
117  int nalUnitType;
118  int nuhLayerId;
119  int nuhTemporalIdPlus1;
120} NalUnitHeader;
121
122
123int findStartCodePrefix(FILE *inFile, int *numStartCodeZeros)
124{
125  int numZeros = 0;
126  int currByte;
127 
128  while (1)
129  {
130    currByte = fgetc(inFile);
131    if (currByte == EOF)
132    {
133      return 0;
134    }
135
136    if (currByte == 0x01 && numZeros > 1)
137    {
138      *numStartCodeZeros = numZeros;
139      return 1;
140    }
141    else if (currByte == 0)
142    {
143      numZeros++;
144    }
145    else
146    {
147      numZeros = 0;
148    }
149  }
150}
151
152int parseNalUnitHeader(FILE *inFile, NalUnitHeader *nalu)
153{
154  int byte0, byte1;
155
156  byte0 = fgetc(inFile);
157  byte1 = fgetc(inFile);
158
159  if (byte0 == EOF || byte1 == EOF)
160  {
161    return 0;
162  }
163
164  nalu->nalUnitType = (byte0 >> 1) & 0x3f;
165  nalu->nuhLayerId  = (((byte0 << 8) | byte1) >> 3) & 0x3f;
166  nalu->nuhTemporalIdPlus1 = byte1 & 0x07;
167
168  return 1;
169}
170
171void writeStartCodePrefixAndNUH(FILE *outFile, int numStartCodeZeros, NalUnitHeader *nalu)
172{
173  int byte0, byte1;
174  int i;
175
176  /* Start code prefix */
177  if (numStartCodeZeros > 3)
178  {
179    numStartCodeZeros = 3;
180  }
181  for (i = 0; i < numStartCodeZeros; i++)
182  {
183    fputc(0, outFile);
184  }
185  fputc(0x01, outFile);
186
187  /* NAL unit header */
188  byte0 = ((nalu->nalUnitType << 6) | nalu->nuhLayerId) >> 5;
189  byte1 = ((nalu->nuhLayerId << 3) | nalu->nuhTemporalIdPlus1) & 0xff;
190  fputc(byte0, outFile);
191  fputc(byte1, outFile);
192}
193
194int main(int argc, char **argv)
195{
196  FILE *inFile;
197  FILE *outFile;
198  int assignedBaseLayerId;
199  NalUnitHeader nalu;
200  int numStartCodeZeros;
201  int isSpsPpsEosEob;
202
203  if (argc < 3)
204  {
205    printf("Usage: Splicer <infile> <outfile> <assigned base layer ID>\n", argv[0]);
206  }
207
208  inFile = fopen(argv[1], "rb");
209  if (inFile == NULL)
210  {
211    fprintf(stderr, "Cannot open input file %s\n", argv[1]);
212    exit(1);
213  }
214
215  outFile = fopen(argv[2], "wb");
216  if (outFile == NULL)
217  {
218    fprintf(stderr, "Cannot open output file %s\n", argv[2]);
219    exit(1);
220  }
221
222  assignedBaseLayerId = atoi(argv[3]);
223
224  while (1)
225  {
226    if (!findStartCodePrefix(inFile, &numStartCodeZeros))
227    {
228      break;
229    }
230    if (!parseNalUnitHeader(inFile, &nalu))
231    {
232      break;
233    }
234
235    printf("NAL unit type: %i,  NUH layer ID: %i,  NUH Temporal ID: %i\n", nalu.nalUnitType, nalu.nuhLayerId, nalu.nuhTemporalIdPlus1 - 1);
236
237    isSpsPpsEosEob = (nalu.nalUnitType == NAL_UNIT_SPS || nalu.nalUnitType == NAL_UNIT_PPS || nalu.nalUnitType == NAL_UNIT_EOS || nalu.nalUnitType == NAL_UNIT_EOB);
238
239    if ((isSpsPpsEosEob && nalu.nuhLayerId == 0) || (!isSpsPpsEosEob && nalu.nuhLayerId == assignedBaseLayerId))
240    {
241      /* Write current NAL unit to output bitstream */
242
243      long naluBytesStartPos;
244      long numNaluBytes;
245      long i;
246
247      nalu.nuhLayerId = 0;
248      writeStartCodePrefixAndNUH(outFile, numStartCodeZeros, &nalu);
249
250      naluBytesStartPos = ftell(inFile);
251      /* Find beginning of the next NAL unit to calculate length of the current unit */
252      if (findStartCodePrefix(inFile, &numStartCodeZeros))
253      {
254        numNaluBytes = ftell(inFile) - naluBytesStartPos - numStartCodeZeros - 1;
255      }
256      else
257      {
258        numNaluBytes = ftell(inFile) - naluBytesStartPos;
259      }
260      fseek(inFile, naluBytesStartPos, SEEK_SET);
261
262      for (i = 0; i < numNaluBytes; i++)
263      {
264        fputc(fgetc(inFile), outFile);
265      }
266    }
267  }
268
269  fclose(inFile);
270  fclose(outFile);
271
272
273  return 0;
274}
Note: See TracBrowser for help on using the repository browser.