OpenCores
URL https://opencores.org/ocsvn/bluespec-h264/bluespec-h264/trunk

Subversion Repositories bluespec-h264

[/] [bluespec-h264/] [trunk/] [test/] [decoder/] [ldecod/] [src/] [annexb.c] - Blame information for rev 100

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jamey.hick
 
2
/*!
3
 *************************************************************************************
4
 * \file annexb.c
5
 *
6
 * \brief
7
 *    Annex B Byte Stream format
8
 *
9
 * \author
10
 *    Main contributors (see contributors.h for copyright, address and affiliation details)
11
 *      - Stephan Wenger                  <stewe@cs.tu-berlin.de>
12
 *************************************************************************************
13
 */
14
 
15
#include <stdlib.h>
16
#include <string.h>
17
 
18
#include "global.h"
19
#include "annexb.h"
20
#include "memalloc.h"
21
 
22
 
23
FILE *bits = NULL;                //!< the bit stream file
24
static int FindStartCode (unsigned char *Buf, int zeros_in_startcode);
25
 
26
int IsFirstByteStreamNALU=1;
27
int LastAccessUnitExists=0;
28
int NALUCount=0;
29
 
30
 
31
/*!
32
 ************************************************************************
33
 * \brief
34
 *    Returns the size of the NALU (bits between start codes in case of
35
 *    Annex B.  nalu->buf and nalu->len are filled.  Other field in
36
 *    nalu-> remain uninitialized (will be taken care of by NALUtoRBSP.
37
 *
38
 * \return
39
 *     0 if there is nothing any more to read (EOF)
40
 *    -1 in case of any error
41
 *
42
 *  \note Side-effect: Returns length of start-code in bytes.
43
 *
44
 * \note
45
 *   GetAnnexbNALU expects start codes at byte aligned positions in the file
46
 *
47
 ************************************************************************
48
 */
49
 
50
int GetAnnexbNALU (NALU_t *nalu)
51
{
52
  int info2, info3, pos = 0;
53
  int StartCodeFound, rewind;
54
  unsigned char *Buf;
55
  int LeadingZero8BitsCount=0, TrailingZero8Bits=0;
56
 
57
  if ((Buf = (unsigned char*)calloc (nalu->max_size , sizeof(char))) == NULL) no_mem_exit("GetAnnexbNALU: Buf");
58
 
59
  while(!feof(bits) && (Buf[pos++]=fgetc(bits))==0);
60
 
61
  if(feof(bits))
62
  {
63
    if(pos==0)
64
    {
65
      free (Buf);
66
      return 0;
67
    }
68
    else
69
    {
70
      printf( "GetAnnexbNALU can't read start code\n");
71
      free(Buf);
72
      return -1;
73
    }
74
  }
75
 
76
  if(Buf[pos-1]!=1)
77
  {
78
    printf ("GetAnnexbNALU: no Start Code at the begin of the NALU, return -1\n");
79
    free(Buf);
80
    return -1;
81
  }
82
 
83
  if(pos<3)
84
  {
85
    printf ("GetAnnexbNALU: no Start Code at the begin of the NALU, return -1\n");
86
    free(Buf);
87
    return -1;
88
  }
89
  else if(pos==3)
90
  {
91
    nalu->startcodeprefix_len = 3;
92
    LeadingZero8BitsCount = 0;
93
  }
94
  else
95
  {
96
    LeadingZero8BitsCount = pos-4;
97
    nalu->startcodeprefix_len = 4;
98
  }
99
 
100
  //the 1st byte stream NAL unit can has leading_zero_8bits, but subsequent ones are not
101
  //allowed to contain it since these zeros(if any) are considered trailing_zero_8bits
102
  //of the previous byte stream NAL unit.
103
  if(!IsFirstByteStreamNALU && LeadingZero8BitsCount>0)
104
  {
105
    printf ("GetAnnexbNALU: The leading_zero_8bits syntax can only be present in the first byte stream NAL unit, return -1\n");
106
    free(Buf);
107
    return -1;
108
  }
109
  IsFirstByteStreamNALU=0;
110
 
111
  StartCodeFound = 0;
112
  info2 = 0;
113
  info3 = 0;
114
 
115
  while (!StartCodeFound)
116
  {
117
    if (feof (bits))
118
    {
119
      //Count the trailing_zero_8bits
120
      while(Buf[pos-2-TrailingZero8Bits]==0)
121
        TrailingZero8Bits++;
122
      nalu->len = (pos-1)-nalu->startcodeprefix_len-LeadingZero8BitsCount-TrailingZero8Bits;
123
      memcpy (nalu->buf, &Buf[LeadingZero8BitsCount+nalu->startcodeprefix_len], nalu->len);
124
      nalu->forbidden_bit = (nalu->buf[0]>>7) & 1;
125
      nalu->nal_reference_idc = (nalu->buf[0]>>5) & 3;
126
      nalu->nal_unit_type = (nalu->buf[0]) & 0x1f;
127
 
128
// printf ("GetAnnexbNALU, eof case: pos %d nalu->len %d, nalu->reference_idc %d, nal_unit_type %d \n", pos, nalu->len, nalu->nal_reference_idc, nalu->nal_unit_type);
129
 
130
#if TRACE
131
  fprintf (p_trace, "\n\nLast NALU in File\n\n");
132
  fprintf (p_trace, "Annex B NALU w/ %s startcode, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d\n\n",
133
    nalu->startcodeprefix_len == 4?"long":"short", nalu->len, nalu->forbidden_bit, nalu->nal_reference_idc, nalu->nal_unit_type);
134
  fflush (p_trace);
135
#endif
136
      free(Buf);
137
      return pos-1;
138
    }
139
    Buf[pos++] = fgetc (bits);
140
    info3 = FindStartCode(&Buf[pos-4], 3);
141
    if(info3 != 1)
142
      info2 = FindStartCode(&Buf[pos-3], 2);
143
    StartCodeFound = (info2 == 1 || info3 == 1);
144
  }
145
 
146
  //Count the trailing_zero_8bits
147
  if(info3==1)  //if the detected start code is 00 00 01, trailing_zero_8bits is sure not to be present
148
  {
149
    while(Buf[pos-5-TrailingZero8Bits]==0)
150
      TrailingZero8Bits++;
151
  }
152
  // Here, we have found another start code (and read length of startcode bytes more than we should
153
  // have.  Hence, go back in the file
154
  rewind = 0;
155
  if(info3 == 1)
156
    rewind = -4;
157
  else if (info2 == 1)
158
    rewind = -3;
159
  else
160
    printf(" Panic: Error in next start code search \n");
161
 
162
  if (0 != fseek (bits, rewind, SEEK_CUR))
163
  {
164
    snprintf (errortext, ET_SIZE, "GetAnnexbNALU: Cannot fseek %d in the bit stream file", rewind);
165
    free(Buf);
166
    error(errortext, 600);
167
  }
168
 
169
  // Here the leading zeros(if any), Start code, the complete NALU, trailing zeros(if any)
170
  // and the next start code is in the Buf.
171
  // The size of Buf is pos, pos+rewind are the number of bytes excluding the next
172
  // start code, and (pos+rewind)-startcodeprefix_len-LeadingZero8BitsCount-TrailingZero8Bits
173
  // is the size of the NALU.
174
 
175
  nalu->len = (pos+rewind)-nalu->startcodeprefix_len-LeadingZero8BitsCount-TrailingZero8Bits;
176
  memcpy (nalu->buf, &Buf[LeadingZero8BitsCount+nalu->startcodeprefix_len], nalu->len);
177
  nalu->forbidden_bit = (nalu->buf[0]>>7) & 1;
178
  nalu->nal_reference_idc = (nalu->buf[0]>>5) & 3;
179
  nalu->nal_unit_type = (nalu->buf[0]) & 0x1f;
180
 
181
 
182
//printf ("GetAnnexbNALU, regular case: pos %d nalu->len %d, nalu->reference_idc %d, nal_unit_type %d \n", pos, nalu->len, nalu->nal_reference_idc, nalu->nal_unit_type);
183
#if TRACE
184
  fprintf (p_trace, "\n\nAnnex B NALU w/ %s startcode, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d\n\n",
185
    nalu->startcodeprefix_len == 4?"long":"short", nalu->len, nalu->forbidden_bit, nalu->nal_reference_idc, nalu->nal_unit_type);
186
  fflush (p_trace);
187
#endif
188
 
189
  free(Buf);
190
 
191
  return (pos+rewind);
192
}
193
 
194
 
195
 
196
 
197
/*!
198
 ************************************************************************
199
 * \brief
200
 *    Opens the bit stream file named fn
201
 * \return
202
 *    none
203
 ************************************************************************
204
 */
205
void OpenBitstreamFile (char *fn)
206
{
207
  if (NULL == (bits=fopen(fn, "rb")))
208
  {
209
    snprintf (errortext, ET_SIZE, "Cannot open Annex B ByteStream file '%s'", input->infile);
210
    error(errortext,500);
211
  }
212
}
213
 
214
 
215
/*!
216
 ************************************************************************
217
 * \brief
218
 *    Closes the bit stream file
219
 ************************************************************************
220
 */
221
void CloseBitstreamFile()
222
{
223
  fclose (bits);
224
}
225
 
226
 
227
/*!
228
 ************************************************************************
229
 * \brief
230
 *    returns if new start code is found at byte aligned position buf.
231
 *    new-startcode is of form N 0x00 bytes, followed by a 0x01 byte.
232
 *
233
 *  \return
234
 *     1 if start-code is found or                      \n
235
 *     0, indicating that there is no start code
236
 *
237
 *  \param Buf
238
 *     pointer to byte-stream
239
 *  \param zeros_in_startcode
240
 *     indicates number of 0x00 bytes in start-code.
241
 ************************************************************************
242
 */
243
static int FindStartCode (unsigned char *Buf, int zeros_in_startcode)
244
{
245
  int info;
246
  int i;
247
 
248
  info = 1;
249
  for (i = 0; i < zeros_in_startcode; i++)
250
    if(Buf[i] != 0)
251
      info = 0;
252
 
253
  if(Buf[i] != 1)
254
    info = 0;
255
  return info;
256
}
257
 
258
void CheckZeroByteNonVCL(NALU_t *nalu, int * ret)
259
{
260
  int CheckZeroByte=0;
261
 
262
  //This function deals only with non-VCL NAL units
263
  if(nalu->nal_unit_type>=1&&nalu->nal_unit_type<=5)
264
    return;
265
 
266
  //for SPS and PPS, zero_byte shall exist
267
  if(nalu->nal_unit_type==NALU_TYPE_SPS || nalu->nal_unit_type==NALU_TYPE_PPS)
268
    CheckZeroByte=1;
269
  //check the possibility of the current NALU to be the start of a new access unit, according to 7.4.1.2.3
270
  if(nalu->nal_unit_type==NALU_TYPE_AUD  || nalu->nal_unit_type==NALU_TYPE_SPS ||
271
     nalu->nal_unit_type==NALU_TYPE_PPS || nalu->nal_unit_type==NALU_TYPE_SEI ||
272
    (nalu->nal_unit_type>=13 && nalu->nal_unit_type<=18))
273
  {
274
    if(LastAccessUnitExists)
275
    {
276
      LastAccessUnitExists=0;    //deliver the last access unit to decoder
277
      NALUCount=0;
278
    }
279
  }
280
  NALUCount++;
281
  //for the first NAL unit in an access unit, zero_byte shall exists
282
  if(NALUCount==1)
283
    CheckZeroByte=1;
284
  if(CheckZeroByte && nalu->startcodeprefix_len==3)
285
  {
286
    printf("warning: zero_byte shall exist\n");
287
    //because it is not a very serious problem, we may not indicate an error by setting ret to -1
288
    //*ret=-1;
289
  }
290
}
291
 
292
void CheckZeroByteVCL(NALU_t *nalu, int * ret)
293
{
294
  int CheckZeroByte=0;
295
 
296
  //This function deals only with VCL NAL units
297
  if(!(nalu->nal_unit_type>=1&&nalu->nal_unit_type<=5))
298
    return;
299
 
300
  if(LastAccessUnitExists)
301
  {
302
    NALUCount=0;
303
  }
304
  NALUCount++;
305
  //the first VCL NAL unit that is the first NAL unit after last VCL NAL unit indicates
306
  //the start of a new access unit and hence the first NAL unit of the new access unit.           (sounds like a tongue twister :-)
307
  if(NALUCount==1)
308
    CheckZeroByte=1;
309
  LastAccessUnitExists=1;
310
  if(CheckZeroByte && nalu->startcodeprefix_len==3)
311
  {
312
    printf("warning: zero_byte shall exist\n");
313
    //because it is not a very serious problem, we may not indicate an error by setting ret to -1
314
    //*ret=-1;
315
  }
316
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.