www.pudn.com > h.264的源代码.rar > annexb.c


/* 
*********************************************************************** 
* COPYRIGHT AND WARRANTY INFORMATION 
* 
* Copyright 2001, International Telecommunications Union, Geneva 
* 
* DISCLAIMER OF WARRANTY 
* 
* These software programs are available to the user without any 
* license fee or royalty on an "as is" basis. The ITU disclaims 
* any and all warranties, whether express, implied, or 
* statutory, including any implied warranties of merchantability 
* or of fitness for a particular purpose.  In no event shall the 
* contributor or the ITU be liable for any incidental, punitive, or 
* consequential damages of any kind whatsoever arising from the 
* use of these programs. 
* 
* This disclaimer of warranty extends to the user of these programs 
* and user's customers, employees, agents, transferees, successors, 
* and assigns. 
* 
* The ITU does not represent or warrant that the programs furnished 
* hereunder are free of infringement of any third-party patents. 
* Commercial implementations of ITU-T Recommendations, including 
* shareware, may be subject to royalty fees to patent holders. 
* Information regarding the ITU-T patent policy is available from 
* the ITU Web site at http://www.itu.int. 
* 
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY. 
************************************************************************ 
*/ 
 
/*! 
 ************************************************************************************* 
 * \file annexb.c 
 * 
 * \brief 
 *    Annex B Byte Stream format 
 * 
 * \author 
 *    Main contributors (see contributors.h for copyright, address and affiliation details) 
 *      - Stephan Wenger                   
 ************************************************************************************* 
 */ 
 
#include  
#include  
#include  
 
#include "global.h" 
#include "annexb.h" 
#include "memalloc.h" 
 
 
FILE *bits = NULL;                //!< the bit stream file 
static int FindStartCode (unsigned char *Buf, int zeros_in_startcode); 
 
 
/*! 
 ************************************************************************ 
 * \brief 
 *    Returns the size of the NALU (bits between start codes in case of 
 *    Annex B.  nalu->buf and nalu->len are filled.  Other field in 
 *    nalu-> remain uninitialized (will be taken care of by NALUtoRBSP. 
 * 
 * \return 
 *     0 if there is nothing any more to read (EOF) 
 *    -1 in case of any error 
 * 
 *  \note Side-effect: Returns length of start-code in bytes.  
 * 
 * \note 
 *   GetAnnexbNALU expects start codes at byte aligned positions in the file 
 * 
 ************************************************************************ 
 */ 
 
int GetAnnexbNALU (NALU_t *nalu) 
{ 
  int info2, info3, pos = 0; 
  int StartCodeFound, rewind; 
  char *Buf; 
     
  if ((Buf = (char*)calloc (nalu->max_size , sizeof(char))) == NULL) no_mem_exit("GetAnnexbNALU: Buf"); 
 
  nalu->startcodeprefix_len=3; 
 
  info2 = 0; 
  info3 = 0; 
   
  if (3 != fread (Buf, 1, 3, bits)) 
  { 
    free(Buf); 
    return 0; 
  } 
 
  info2 = FindStartCode (Buf, 2); 
  if(info2 != 1) { 
    if(1 != fread(Buf+3, 1, 1, bits)) 
    { 
      free(Buf); 
      return 0; 
    } 
    info3 = FindStartCode (Buf, 3); 
  } 
 
  if (info2 != 1 && info3 != 1) 
  { 
    printf ("GetAnnexbNALU: no Start Code at the begin of the NALU, return -1\n"); 
    free(Buf); 
    return -1; 
  } 
 
  if( info2 == 1) { 
    nalu->startcodeprefix_len = 3; 
    pos = 3; 
  } 
  else if(info3 ==1 ) { 
    pos = 4; 
    nalu->startcodeprefix_len = 4; 
  } 
  else 
    printf( " Panic: Error \n"); 
 
  StartCodeFound = 0; 
  info2 = 0; 
  info3 = 0; 
 
  while (!StartCodeFound) 
  { 
    if (feof (bits)) 
    { 
      nalu->len = (pos-1)-nalu->startcodeprefix_len; 
      memcpy (nalu->buf, &Buf[nalu->startcodeprefix_len], nalu->len);      
      nalu->forbidden_bit = (nalu->buf[0]>>7) & 1; 
      nalu->nal_reference_idc = (nalu->buf[0]>>5) & 3; 
      nalu->nal_unit_type = (nalu->buf[0]) & 0x1f; 
 
// 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); 
 
#if TRACE 
  fprintf (p_trace, "\n\nLast NALU in File\n\n"); 
  fprintf (p_trace, "Annex B NALU w/ %s startcode, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d\n\n", 
    nalu->startcodeprefix_len == 4?"long":"short", nalu->len, nalu->forbidden_bit, nalu->nal_reference_idc, nalu->nal_unit_type); 
  fflush (p_trace); 
#endif 
      free(Buf); 
      return pos-1; 
    } 
    Buf[pos++] = fgetc (bits); 
    info3 = FindStartCode(&Buf[pos-4], 3); 
    if(info3 != 1) 
      info2 = FindStartCode(&Buf[pos-3], 2); 
    StartCodeFound = (info2 == 1 || info3 == 1); 
  } 
 
  
  // Here, we have found another start code (and read length of startcode bytes more than we should 
  // have.  Hence, go back in the file 
  rewind = 0; 
  if(info3 == 1) 
    rewind = -4; 
  else if (info2 == 1) 
    rewind = -3; 
  else 
    printf(" Panic: Error in next start code search \n"); 
 
  if (0 != fseek (bits, rewind, SEEK_CUR)) 
  { 
    snprintf (errortext, ET_SIZE, "GetAnnexbNALU: Cannot fseek %d in the bit stream file", rewind); 
    free(Buf); 
    error(errortext, 600); 
  } 
 
  // Here the Start code, the complete NALU, and the next start code is in the Buf.   
  // The size of Buf is pos, pos+rewind are the number of bytes excluding the next 
  // start code, and (pos+rewind)-startcodeprefix_len is the size of the NALU 
 
  nalu->len = (pos+rewind)-nalu->startcodeprefix_len; 
  memcpy (nalu->buf, &Buf[nalu->startcodeprefix_len], nalu->len); 
  nalu->forbidden_bit = (nalu->buf[0]>>7) & 1; 
  nalu->nal_reference_idc = (nalu->buf[0]>>5) & 3; 
  nalu->nal_unit_type = (nalu->buf[0]) & 0x1f; 
 
 
//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); 
#if TRACE 
  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", 
    nalu->startcodeprefix_len == 4?"long":"short", nalu->len, nalu->forbidden_bit, nalu->nal_reference_idc, nalu->nal_unit_type); 
  fflush (p_trace); 
#endif 
   
  free(Buf); 
  
  return (pos+rewind); 
} 
 
 
 
 
/*! 
 ************************************************************************ 
 * \brief 
 *    Opens the bit stream file named fn 
 * \return 
 *    none 
 ************************************************************************ 
 */ 
void OpenBitstreamFile (char *fn) 
{ 
  if (NULL == (bits=fopen(fn, "rb"))) 
  { 
    snprintf (errortext, ET_SIZE, "Cannot open Annex B ByteStream file '%s'", input->infile); 
    error(errortext,500); 
  } 
} 
 
 
/*! 
 ************************************************************************ 
 * \brief 
 *    Closes the bit stream file 
 ************************************************************************ 
 */ 
void CloseBitstreamFile() 
{ 
  fclose (bits); 
} 
 
 
/*! 
 ************************************************************************ 
 * \brief 
 *    returns if new start code is found at byte aligned position buf. 
 *    new-startcode is of form N 0x00 bytes, followed by a 0x01 byte. 
 * 
 *  \return 
 *     1 if start-code is found or                      \n 
 *     0, indicating that there is no start code 
 * 
 *  \param Buf 
 *     pointer to byte-stream 
 *  \param zeros_in_startcode 
 *     indicates number of 0x00 bytes in start-code. 
 ************************************************************************ 
 */ 
static int FindStartCode (unsigned char *Buf, int zeros_in_startcode) 
{ 
  int info; 
  int i; 
 
  info = 1; 
  for (i = 0; i < zeros_in_startcode; i++) 
    if(Buf[i] != 0) 
      info = 0; 
 
  if(Buf[i] != 1) 
    info = 0; 
  return info; 
}