00001
00015 #include "global.h"
00016 #include "annexb.h"
00017 #include "memalloc.h"
00018
00019 static const unsigned int IOBUFFERSIZE = 65536;
00020
00021 void malloc_annex_b(ImageParameters *p_Img)
00022 {
00023 if ( (p_Img->annex_b = (ANNEXB_t *) calloc(1, sizeof(ANNEXB_t))) == NULL)
00024 {
00025 snprintf(errortext, ET_SIZE, "Memory allocation for Annex_B file failed");
00026 error(errortext,100);
00027 }
00028 }
00029
00030 void init_annex_b(ANNEXB_t *annex_b)
00031 {
00032 annex_b->BitStreamFile = -1;
00033 annex_b->iobuffer = NULL;
00034 annex_b->iobufferread = NULL;
00035 annex_b->bytesinbuffer = 0;
00036 annex_b->is_eof = FALSE;
00037 annex_b->IsFirstByteStreamNALU = 1;
00038 annex_b->nextstartcodebytes = 0;
00039 }
00040
00041 void free_annex_b(ImageParameters *p_Img)
00042 {
00043 free(p_Img->annex_b);
00044 p_Img->annex_b = NULL;
00045 }
00046
00053 static inline int getChunk(ANNEXB_t *annex_b)
00054 {
00055 unsigned int readbytes = read (annex_b->BitStreamFile, annex_b->iobuffer, IOBUFFERSIZE);
00056 if (0==readbytes)
00057 {
00058 annex_b->is_eof = TRUE;
00059 return 0;
00060 }
00061
00062 annex_b->bytesinbuffer = readbytes;
00063 annex_b->iobufferread = annex_b->iobuffer;
00064 return readbytes;
00065 }
00066
00067
00074 static inline byte getfbyte(ANNEXB_t *annex_b)
00075 {
00076 if (0 == annex_b->bytesinbuffer)
00077 {
00078 if (0 == getChunk(annex_b))
00079 return 0;
00080 }
00081 annex_b->bytesinbuffer--;
00082 return (*annex_b->iobufferread++);
00083 }
00084
00085
00102 static inline int FindStartCode (unsigned char *Buf, int zeros_in_startcode)
00103 {
00104 int i;
00105
00106 for (i = 0; i < zeros_in_startcode; i++)
00107 {
00108 if(*(Buf++) != 0)
00109 {
00110 return 0;
00111 }
00112 }
00113
00114 if(*Buf != 1)
00115 return 0;
00116
00117 return 1;
00118 }
00119
00120
00139 int GetAnnexbNALU (ImageParameters *p_Img, NALU_t *nalu)
00140 {
00141 ANNEXB_t *annex_b = p_Img->annex_b;
00142 int i;
00143 int info2 = 0, info3 = 0, pos = 0;
00144 int StartCodeFound = 0;
00145 int LeadingZero8BitsCount = 0;
00146 byte *pBuf;
00147
00148 if ((annex_b->Buf = (byte*) calloc (nalu->max_size , sizeof(char))) == NULL)
00149 no_mem_exit("GetAnnexbNALU: Buf");
00150
00151 pBuf = annex_b->Buf;
00152
00153 if (annex_b->nextstartcodebytes != 0)
00154 {
00155 for (i=0; i<annex_b->nextstartcodebytes-1; i++)
00156 {
00157 (*pBuf++) = 0;
00158 pos++;
00159 }
00160 (*pBuf++) = 1;
00161 pos++;
00162 }
00163 else
00164 {
00165 while(!annex_b->is_eof)
00166 {
00167 pos++;
00168 if ((*(pBuf++)= getfbyte(annex_b))!= 0)
00169 break;
00170 }
00171 }
00172 if(annex_b->is_eof == TRUE)
00173 {
00174 free (annex_b->Buf);
00175 if(pos==0)
00176 {
00177 return 0;
00178 }
00179 else
00180 {
00181 printf( "GetAnnexbNALU can't read start code\n");
00182 return -1;
00183 }
00184 }
00185
00186 if(*(pBuf - 1) != 1 || pos < 3)
00187 {
00188 printf ("GetAnnexbNALU: no Start Code at the beginning of the NALU, return -1\n");
00189 free (annex_b->Buf);
00190 return -1;
00191 }
00192
00193 if (pos == 3)
00194 {
00195 nalu->startcodeprefix_len = 3;
00196 }
00197 else
00198 {
00199 LeadingZero8BitsCount = pos - 4;
00200 nalu->startcodeprefix_len = 4;
00201 }
00202
00203
00204
00205
00206 if(!annex_b->IsFirstByteStreamNALU && LeadingZero8BitsCount > 0)
00207 {
00208 printf ("GetAnnexbNALU: The leading_zero_8bits syntax can only be present in the first byte stream NAL unit, return -1\n");
00209 free (annex_b->Buf);
00210 return -1;
00211 }
00212
00213 LeadingZero8BitsCount = pos;
00214 annex_b->IsFirstByteStreamNALU = 0;
00215
00216 while (!StartCodeFound)
00217 {
00218 if (annex_b->is_eof == TRUE)
00219 {
00220 pBuf -= 2;
00221 while(*(pBuf--)==0)
00222 pos--;
00223
00224 nalu->len = (pos - 1) - LeadingZero8BitsCount;
00225 memcpy (nalu->buf, annex_b->Buf + LeadingZero8BitsCount, nalu->len);
00226 nalu->forbidden_bit = (*(nalu->buf) >> 7) & 1;
00227 nalu->nal_reference_idc = (NalRefIdc) ((*(nalu->buf) >> 5) & 3);
00228 nalu->nal_unit_type = (NaluType) ((*(nalu->buf)) & 0x1f);
00229 annex_b->nextstartcodebytes = 0;
00230
00231
00232
00233 #if TRACE
00234 fprintf (p_Dec->p_trace, "\n\nLast NALU in File\n\n");
00235 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",
00236 nalu->startcodeprefix_len == 4?"long":"short", nalu->len, nalu->forbidden_bit, nalu->nal_reference_idc, nalu->nal_unit_type);
00237 fflush (p_Dec->p_trace);
00238 #endif
00239
00240 free (annex_b->Buf);
00241 return (pos - 1);
00242 }
00243
00244 pos++;
00245 *(pBuf ++) = getfbyte(annex_b);
00246 info3 = FindStartCode(pBuf - 4, 3);
00247 if(info3 != 1)
00248 {
00249 info2 = FindStartCode(pBuf - 3, 2);
00250 StartCodeFound = (info2 == 1);
00251 }
00252 else
00253 StartCodeFound = 1;
00254 }
00255
00256
00257
00258 if(info3 == 1)
00259 {
00260 pBuf -= 5;
00261 while(*(pBuf--) == 0)
00262 pos--;
00263 annex_b->nextstartcodebytes = 4;
00264 }
00265 else if (info2 == 1)
00266 annex_b->nextstartcodebytes = 3;
00267 else
00268 {
00269 printf(" Panic: Error in next start code search \n");
00270 free (annex_b->Buf);
00271 return -1;
00272 }
00273
00274 pos -= annex_b->nextstartcodebytes;
00275
00276
00277
00278
00279
00280
00281
00282 nalu->len = pos - LeadingZero8BitsCount;
00283 memcpy (nalu->buf, annex_b->Buf + LeadingZero8BitsCount, nalu->len);
00284 nalu->forbidden_bit = (*(nalu->buf) >> 7) & 1;
00285 nalu->nal_reference_idc = (NalRefIdc) ((*(nalu->buf) >> 5) & 3);
00286 nalu->nal_unit_type = (NaluType) ((*(nalu->buf)) & 0x1f);
00287 nalu->lost_packets = 0;
00288
00289
00290
00291 #if TRACE
00292 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",
00293 nalu->startcodeprefix_len == 4?"long":"short", nalu->len, nalu->forbidden_bit, nalu->nal_reference_idc, nalu->nal_unit_type);
00294 fflush (p_Dec->p_trace);
00295 #endif
00296
00297 free (annex_b->Buf);
00298 return (pos);
00299 }
00300
00301
00310 void OpenAnnexBFile (ImageParameters *p_Img, char *fn)
00311 {
00312 ANNEXB_t *annex_b = p_Img->annex_b;
00313 if (NULL != annex_b->iobuffer)
00314 {
00315 error ("OpenAnnexBFile: tried to open Annex B file twice",500);
00316 }
00317 if ((annex_b->BitStreamFile = open(fn, OPENFLAGS_READ)) == -1)
00318 {
00319 snprintf (errortext, ET_SIZE, "Cannot open Annex B ByteStream file '%s'", fn);
00320 error(errortext,500);
00321 }
00322 annex_b->iobuffer = malloc (IOBUFFERSIZE * sizeof (byte));
00323 if (NULL == annex_b->iobuffer)
00324 {
00325 error ("OpenAnnexBFile: cannot allocate IO buffer",500);
00326 }
00327 annex_b->is_eof = FALSE;
00328 getChunk(annex_b);
00329 }
00330
00331
00338 void CloseAnnexBFile(ImageParameters *p_Img)
00339 {
00340 ANNEXB_t *annex_b = p_Img->annex_b;
00341 if (annex_b->BitStreamFile != -1)
00342 {
00343 close(annex_b->BitStreamFile);
00344 annex_b->BitStreamFile = - 1;
00345 }
00346 free (annex_b->iobuffer);
00347 annex_b->iobuffer = NULL;
00348 }
00349