annexb.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:10k
源码类别:

Audio

开发平台:

Visual C++

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