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