1
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 "global.h"
16 #include "annexb.h"
17 #include "memalloc.h"
18 #include "fast_memory.h"
19
20 static const int IOBUFFERSIZE = 512*1024; //65536;
21
malloc_annex_b(VideoParameters * p_Vid,ANNEXB_t ** p_annex_b)22 void malloc_annex_b(VideoParameters *p_Vid, ANNEXB_t **p_annex_b)
23 {
24 if ( ((*p_annex_b) = (ANNEXB_t *) calloc(1, sizeof(ANNEXB_t))) == NULL)
25 {
26 snprintf(errortext, ET_SIZE, "Memory allocation for Annex_B file failed");
27 error(errortext,100);
28 }
29 if (((*p_annex_b)->Buf = (byte*) malloc(p_Vid->nalu->max_size)) == NULL)
30 {
31 error("malloc_annex_b: Buf", 101);
32 }
33 }
34
35
init_annex_b(ANNEXB_t * annex_b)36 void init_annex_b(ANNEXB_t *annex_b)
37 {
38 annex_b->BitStreamFile = -1;
39 annex_b->iobuffer = NULL;
40 annex_b->iobufferread = NULL;
41 annex_b->bytesinbuffer = 0;
42 annex_b->is_eof = FALSE;
43 annex_b->IsFirstByteStreamNALU = 1;
44 annex_b->nextstartcodebytes = 0;
45 }
46
free_annex_b(ANNEXB_t ** p_annex_b)47 void free_annex_b(ANNEXB_t **p_annex_b)
48 {
49 free((*p_annex_b)->Buf);
50 (*p_annex_b)->Buf = NULL;
51 free(*p_annex_b);
52 *p_annex_b = NULL;
53 }
54
55 /*!
56 ************************************************************************
57 * \brief
58 * fill IO buffer
59 ************************************************************************
60 */
getChunk(ANNEXB_t * annex_b)61 static inline int getChunk(ANNEXB_t *annex_b)
62 {
63 unsigned int readbytes = read (annex_b->BitStreamFile, annex_b->iobuffer, annex_b->iIOBufferSize);
64 if (0==readbytes)
65 {
66 annex_b->is_eof = TRUE;
67 return 0;
68 }
69
70 annex_b->bytesinbuffer = readbytes;
71 annex_b->iobufferread = annex_b->iobuffer;
72 return readbytes;
73 }
74
75 /*!
76 ************************************************************************
77 * \brief
78 * returns a byte from IO buffer
79 ************************************************************************
80 */
getfbyte(ANNEXB_t * annex_b)81 static inline byte getfbyte(ANNEXB_t *annex_b)
82 {
83 if (0 == annex_b->bytesinbuffer)
84 {
85 if (0 == getChunk(annex_b))
86 return 0;
87 }
88 annex_b->bytesinbuffer--;
89 return (*annex_b->iobufferread++);
90 }
91
92 /*!
93 ************************************************************************
94 * \brief
95 * returns if new start code is found at byte aligned position buf.
96 * new-startcode is of form N 0x00 bytes, followed by a 0x01 byte.
97 *
98 * \return
99 * 1 if start-code is found or \n
100 * 0, indicating that there is no start code
101 *
102 * \param Buf
103 * pointer to byte-stream
104 * \param zeros_in_startcode
105 * indicates number of 0x00 bytes in start-code.
106 ************************************************************************
107 */
FindStartCode(unsigned char * Buf,int zeros_in_startcode)108 static inline int FindStartCode (unsigned char *Buf, int zeros_in_startcode)
109 {
110 int i;
111
112 for (i = 0; i < zeros_in_startcode; i++)
113 {
114 if(*(Buf++) != 0)
115 {
116 return 0;
117 }
118 }
119
120 if(*Buf != 1)
121 return 0;
122
123 return 1;
124 }
125
126
127 /*!
128 ************************************************************************
129 * \brief
130 * Returns the size of the NALU (bits between start codes in case of
131 * Annex B. nalu->buf and nalu->len are filled. Other field in
132 * nalu-> remain uninitialized (will be taken care of by NALUtoRBSP.
133 *
134 * \return
135 * 0 if there is nothing any more to read (EOF)
136 * -1 in case of any error
137 *
138 * \note Side-effect: Returns length of start-code in bytes.
139 *
140 * \note
141 * get_annex_b_NALU expects start codes at byte aligned positions in the file
142 *
143 ************************************************************************
144 */
145
get_annex_b_NALU(VideoParameters * p_Vid,NALU_t * nalu,ANNEXB_t * annex_b)146 int get_annex_b_NALU (VideoParameters *p_Vid, NALU_t *nalu, ANNEXB_t *annex_b)
147 {
148 int i;
149 int info2 = 0, info3 = 0, pos = 0;
150 int StartCodeFound = 0;
151 int LeadingZero8BitsCount = 0;
152 byte *pBuf = annex_b->Buf;
153
154 if (annex_b->nextstartcodebytes != 0)
155 {
156 for (i=0; i<annex_b->nextstartcodebytes-1; i++)
157 {
158 (*pBuf++) = 0;
159 pos++;
160 }
161 (*pBuf++) = 1;
162 pos++;
163 }
164 else
165 {
166 while(!annex_b->is_eof)
167 {
168 pos++;
169 if ((*(pBuf++)= getfbyte(annex_b))!= 0)
170 break;
171 }
172 }
173 if(annex_b->is_eof == TRUE)
174 {
175 if(pos==0)
176 {
177 return 0;
178 }
179 else
180 {
181 printf( "get_annex_b_NALU can't read start code\n");
182 return -1;
183 }
184 }
185
186 if(*(pBuf - 1) != 1 || pos < 3)
187 {
188 printf ("get_annex_b_NALU: no Start Code at the beginning of the NALU, return -1\n");
189 return -1;
190 }
191
192 if (pos == 3)
193 {
194 nalu->startcodeprefix_len = 3;
195 }
196 else
197 {
198 LeadingZero8BitsCount = pos - 4;
199 nalu->startcodeprefix_len = 4;
200 }
201
202 //the 1st byte stream NAL unit can has leading_zero_8bits, but subsequent ones are not
203 //allowed to contain it since these zeros(if any) are considered trailing_zero_8bits
204 //of the previous byte stream NAL unit.
205 if(!annex_b->IsFirstByteStreamNALU && LeadingZero8BitsCount > 0)
206 {
207 printf ("get_annex_b_NALU: The leading_zero_8bits syntax can only be present in the first byte stream NAL unit, return -1\n");
208 return -1;
209 }
210
211 LeadingZero8BitsCount = pos;
212 annex_b->IsFirstByteStreamNALU = 0;
213
214 while (!StartCodeFound)
215 {
216 if (annex_b->is_eof == TRUE)
217 {
218 pBuf -= 2;
219 while(*(pBuf--)==0)
220 pos--;
221
222 nalu->len = (pos - 1) - LeadingZero8BitsCount;
223 memcpy (nalu->buf, annex_b->Buf + LeadingZero8BitsCount, nalu->len);
224 nalu->forbidden_bit = (*(nalu->buf) >> 7) & 1;
225 nalu->nal_reference_idc = (NalRefIdc) ((*(nalu->buf) >> 5) & 3);
226 nalu->nal_unit_type = (NaluType) ((*(nalu->buf)) & 0x1f);
227 annex_b->nextstartcodebytes = 0;
228
229 // printf ("get_annex_b_NALU, 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);
230
231 #if TRACE
232 fprintf (p_Dec->p_trace, "\n\nLast NALU in File\n\n");
233 fprintf (p_Dec->p_trace, "Annex B NALU w/ %s startcode, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d\n\n",
234 nalu->startcodeprefix_len == 4?"long":"short", nalu->len, nalu->forbidden_bit, nalu->nal_reference_idc, nalu->nal_unit_type);
235 fflush (p_Dec->p_trace);
236 #endif
237 return (pos - 1);
238 }
239
240 pos++;
241 *(pBuf ++) = getfbyte(annex_b);
242 info3 = FindStartCode(pBuf - 4, 3);
243 if(info3 != 1)
244 {
245 info2 = FindStartCode(pBuf - 3, 2);
246 StartCodeFound = info2 & 0x01;
247 }
248 else
249 StartCodeFound = 1;
250 }
251
252 // Here, we have found another start code (and read length of startcode bytes more than we should
253 // have. Hence, go back in the file
254 if(info3 == 1) //if the detected start code is 00 00 01, trailing_zero_8bits is sure not to be present
255 {
256 pBuf -= 5;
257 while(*(pBuf--) == 0)
258 pos--;
259 annex_b->nextstartcodebytes = 4;
260 }
261 else if (info2 == 1)
262 annex_b->nextstartcodebytes = 3;
263 else
264 {
265 printf(" Panic: Error in next start code search \n");
266 return -1;
267 }
268
269 pos -= annex_b->nextstartcodebytes;
270
271 // Here the leading zeros(if any), Start code, the complete NALU, trailing zeros(if any)
272 // and the next start code is in the Buf.
273 // The size of Buf is pos - rewind, pos are the number of bytes excluding the next
274 // start code, and (pos) - LeadingZero8BitsCount
275 // is the size of the NALU.
276
277 nalu->len = pos - LeadingZero8BitsCount;
278 fast_memcpy (nalu->buf, annex_b->Buf + LeadingZero8BitsCount, nalu->len);
279 nalu->forbidden_bit = (*(nalu->buf) >> 7) & 1;
280 nalu->nal_reference_idc = (NalRefIdc) ((*(nalu->buf) >> 5) & 3);
281 nalu->nal_unit_type = (NaluType) ((*(nalu->buf)) & 0x1f);
282 nalu->lost_packets = 0;
283
284
285 //printf ("get_annex_b_NALU, 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);
286 #if TRACE
287 fprintf (p_Dec->p_trace, "\n\nAnnex B NALU w/ %s startcode, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d\n\n",
288 nalu->startcodeprefix_len == 4?"long":"short", nalu->len, nalu->forbidden_bit, nalu->nal_reference_idc, nalu->nal_unit_type);
289 fflush (p_Dec->p_trace);
290 #endif
291
292 return (pos);
293
294 }
295
296
297
298 /*!
299 ************************************************************************
300 * \brief
301 * Opens the bit stream file named fn
302 * \return
303 * none
304 ************************************************************************
305 */
open_annex_b(char * fn,ANNEXB_t * annex_b)306 void open_annex_b (char *fn, ANNEXB_t *annex_b)
307 {
308 if (NULL != annex_b->iobuffer)
309 {
310 error ("open_annex_b: tried to open Annex B file twice",500);
311 }
312 if ((annex_b->BitStreamFile = open(fn, OPENFLAGS_READ)) == -1)
313 {
314 snprintf (errortext, ET_SIZE, "Cannot open Annex B ByteStream file '%s'", fn);
315 error(errortext,500);
316 }
317
318 annex_b->iIOBufferSize = IOBUFFERSIZE * sizeof (byte);
319 annex_b->iobuffer = malloc (annex_b->iIOBufferSize);
320 if (NULL == annex_b->iobuffer)
321 {
322 error ("open_annex_b: cannot allocate IO buffer",500);
323 }
324 annex_b->is_eof = FALSE;
325 getChunk(annex_b);
326 }
327
328
329 /*!
330 ************************************************************************
331 * \brief
332 * Closes the bit stream file
333 ************************************************************************
334 */
close_annex_b(ANNEXB_t * annex_b)335 void close_annex_b(ANNEXB_t *annex_b)
336 {
337 if (annex_b->BitStreamFile != -1)
338 {
339 close(annex_b->BitStreamFile);
340 annex_b->BitStreamFile = - 1;
341 }
342 free (annex_b->iobuffer);
343 annex_b->iobuffer = NULL;
344 }
345
346
reset_annex_b(ANNEXB_t * annex_b)347 void reset_annex_b(ANNEXB_t *annex_b)
348 {
349 annex_b->is_eof = FALSE;
350 annex_b->bytesinbuffer = 0;
351 annex_b->iobufferread = annex_b->iobuffer;
352 }
353