NAL分析器程序源代碼

 

NAL分析器程序源代碼

 

#include "stdio.h"
#include "stdlib.h"

#include "nalucommon.h"

//#####################################
//#本程序檢查一個緩衝區裏面有幾個NALU #
//#輸出每個NALU的類型到輸出文件    #
//#輸入爲一個帶有標記/NALU+標記/的文件#
//#####################################

 

void main(void)
{
 FILE *pSrc;
 FILE *pRep;
 
 
 if((pSrc=fopen("H264.rec","r+b"))==NULL)
  exit(-1);
 else printf("open src file succeed/n");
 if((pRep=fopen("H264.rep","w+t"))==NULL)
  exit(-1);
 else printf("open report file succeed/n");
 ReportNalu(pSrc,pRep);
 fclose(pSrc);
 fclose(pRep);
}


/*! **************************************************************************************
 * /file
 *    nalucommon.h.h
 * /brief
 *    NALU handling common to encoder and decoder
***************************************************************************************
 */
#include <memory.h>


#ifndef _NALUCOMMON_H_
#define _NALUCOMMON_H_

typedef struct
{
 int startcodeprefix_len;      //! 4 for parameter sets and first slice in picture, 3 for everything else (suggested)
 unsigned len;                 //! Length of the NAL unit (Excluding the start code, which does not belong to the NALU)
 unsigned max_size;            //! Nal Unit Buffer size
 int nal_unit_type;            //! NALU_TYPE_xxxx
 int nal_reference_idc;        //! NALU_PRIORITY_xxxx
 int forbidden_bit;            //! should be always FALSE
 unsigned char *buf;        //! conjtains the first byte followed by the EBSP
} NALU_t;

#define MAXRBSPSIZE 64000

#define NALU_TYPE_SLICE    1
#define NALU_TYPE_DPA      2
#define NALU_TYPE_DPB      3
#define NALU_TYPE_DPC      4
#define NALU_TYPE_IDR      5
#define NALU_TYPE_SEI      6
#define NALU_TYPE_SPS      7
#define NALU_TYPE_PPS      8
#define NALU_TYPE_AUD      9
#define NALU_TYPE_EOSEQ    10
#define NALU_TYPE_EOSTREAM 11
#define NALU_TYPE_FILL     12

#define NALU_PRIORITY_HIGHEST     3
#define NALU_PRIORITY_HIGH        2
#define NALU_PRIRITY_LOW          1
#define NALU_PRIORITY_DISPOSABLE  0


#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

#ifndef BOOL
#define BOOL unsigned int
#endif

void ReportNalu(FILE* src,FILE* rep);
void ParseRecBuf(unsigned char *p,int bufsize,FILE* pReport);
int ShowBits (unsigned char buffer[],int totbitoffset,int bytecount, int numbits);
BOOL next_bits(unsigned char *p,int bufpos,int bs,int id );
static int FindStartCode (unsigned char *Buf, int bufpos,  int bufsize, int next_start_pos, BOOL fIRFD);
BOOL gETNALandPROC(unsigned char *p,int bufpos,int bufsize, BOOL fisrtfd,NALU_t *mNal,int inc_SIZE,FILE *pReport);
#endif


//############################################################
//#       src 文件格式如下  
//#        #-#-#-#-#-B-INT32LEN-T264DST  - #-#-#-#-B-INT32LEN #
//#    1 1 1 1 1 1     4   INT32LEN                           #
//############################################################

void ReportNalu(FILE* src,FILE* rep)
{
 unsigned char tempbuf[1];
 unsigned char *pBuf;
 int *dstlen;
    int fpos=0;
 int fstart=0;
 int FileSize=0;
 int BufSize;
 int dstpacketid=0;
 unsigned int  SymState=0;
 fseek(src,0,SEEK_END);
 FileSize=ftell(src);
 printf("the src file size is %d /n",FileSize);
 fseek(src,0,SEEK_SET);
 do {
 
  while (fread(tempbuf,sizeof(unsigned char),1,src))
  {
   if(tempbuf=="#") SymState++;
   else
   {
    fpos=fstart+1;
    SymState=0;
    fseek(src,fpos,SEEK_SET);
   }
   if(SymState==4)
   {fpos+=4;break;}
  }
 
  fread(tempbuf,sizeof(unsigned char),1,src);
 
  if(tempbuf=="B")
  {
   SymState++;
   fpos+=1;
  }
  else
  {
   fpos=fstart+1;
   fseek(src,fpos,SEEK_SET);
  }
 
  if(SymState==5)  
  {  
   dstpacketid++;
   fprintf(rep,"the %d dstpacket/n",dstpacketid);
   dstlen=(int*)malloc(sizeof(int));
   fread(dstlen,sizeof(unsigned char),4,src);
   BufSize=(int*)dstlen;
   pBuf=(unsigned char*)malloc(sizeof(unsigned char)*BufSize);
   fpos+=4;
   fread(pBuf,sizeof(unsigned char),BufSize,src);
   ParseRecBuf(pBuf,BufSize,rep);
   fstart=fpos;
   free(dstlen);
   free(pBuf);
  }
 
 } while(fpos!=FileSize);//
 
}


//####################################################
//# unsigned char *p  --T264 encode的一個dst長度爲len#
//# int bufsize   --buffer的大小     #
//##FILE* pReport     --文件指針,存放NAL的分析結果  #
//####################################################

void ParseRecBuf(unsigned char *p,int bufsize,FILE* pReport)
{

 
 int bufpos=0;
 int bUFSTART=0;
    struct NALU_t *mNal;
 BOOL isfirst;
 BOOL starcode_ex;
 BOOL zero_ex;
 BOOL trail_ex;
 int nALSIZE=0;
 int nal_id=0;
 BOOL firstfd=FALSE;
 
 while (bufpos<bufsize)
 {
  if( !next_bits(p,bufpos,bufsize, 24 )  &&
   !next_bits(p,bufpos,bufsize,32 )  &&
   next_bits( p,bufpos,bufsize,8 ))
  {bufpos+=8;isfirst=TRUE;firstfd=TRUE;}// leading_zero_8bits /* equal to 0x00 */ //f(8)
  else{ isfirst=FALSE; }
 
  if(!next_bits( p,bufpos,bufsize,24 )  &&   
   next_bits( p,bufpos,bufsize,8 )
   ) 
  {   
   bufpos+=8;//zero_byte /* equal to 0x00 */ f(8)
   zero_ex=TRUE;
   if( bufpos<bufsize &&
    next_bits(p,bufpos,bufsize, 24 ) )
   {     
    bufpos+=24; // start_code_prefix_one_3bytes /* equal to 0x000001 */ f(24)
    starcode_ex=TRUE;
    mNal=(struct NALU_t* )malloc(sizeof( NALU_t));
   if(gETNALandPROC(p,bufpos,bufsize,firstfd,mNal,nALSIZE,pReport))  

 
   { 
   
    nal_id++;
       fprintf(pReport," id of the nal packet above is %d/n",nal_id);
    bufpos+=(nALSIZE>>3);
    if(( bufpos<bufsize)  &&
     (!next_bits(p,bufpos,bufsize, 24 )) && 
     (!next_bits(p,bufpos,bufsize, 32 ) ) &&
     (next_bits(p,bufpos, bufsize,8 )))
    {
     bufpos+=8; trail_ex=TRUE ;/*  trailing_zero_8bitsequal to 0x00 */
    }
    else trail_ex=FALSE;
    free(mNal);
   }
   else printf("cannot get any nal units/n");
   }
   else{starcode_ex=FALSE;}     
  }
  else
  { zero_ex=FALSE; }
 
  if (!zero_ex || !starcode_ex)
   bufpos=bUFSTART+1;
  else bUFSTART=bufpos;
 }
}

 

 

 

//############################################
//#unsigned char *p =--buffer containing NALU#
//#int bufpos--current buffer position   #
//#int bs---buffersize                   #
//#int id                                #
//#  id=24   ----0x000001----FALSE   #
//#     id=32   ----0x00000001---FALSE   #
//#     id=8 ----0x00------TRUE    #
//############################################
BOOL next_bits(unsigned char *p,int bufpos,int bs,int id )
{
 BOOL rERULT;
 switch(id) {
 case 8:  
  if(ShowBits(p,bufpos,bs,8)==0x00) rERULT=TRUE ;
  else rERULT=FALSE;
  break;
 case 24:
  if(ShowBits(p,bufpos,bs,24)!=0x000001) rERULT=FALSE;
  else rERULT=TRUE;
  break;
 case 32 :
  if(ShowBits(p,bufpos,bs,32)!=0x00000001) rERULT=FALSE;
  else rERULT=TRUE;
  break;
 default:
  break;
 }
 return rERULT;
}

 

//##############################################
// # /brief         #
// #  Reads bits from the bitstream buffer     #
// # /param buffer        #
// #    buffer containing VLC-coded data bits  #
// # /param totbitoffset      #
// #    bit offset from start of partition     #
// # /param bytecount                          #
// #    total bytes in bitstream               #
// # /param numbits                            #
// #    number of bits to read                 #
// #############################################
int ShowBits (unsigned char buffer[],int totbitoffset,int bytecount, int numbits)
{
 
 register int inf;
 long byteoffset;      // byte from start of buffer
 int bitoffset;      // bit from start of byte
 
 byteoffset= totbitoffset/8;
 bitoffset= 7-(totbitoffset%8);
 
 inf=0;
 while (numbits)
 {
  inf <<=1;
  inf |= (buffer[byteoffset] & (0x01<<bitoffset))>>bitoffset;
  numbits--;
  bitoffset--;
  if (bitoffset < 0)
  {
   byteoffset++;
   bitoffset += 8;
   if (byteoffset > bytecount)
   {
    return -1;
   }
  }
 }
 
 return inf;   // return absolute offset in bit from start of frame
}   


//#########################################################################
// # /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   bufpos                                             #
// #     indicates current bufpos.
//#     /bufsize
//  #   indicates   total buffer size                          #
//  #  /param      next_star_pos                                           #
//  #      indicates the next_start_code pos                               #
//  #  /param      fIRFD
//  #    is firs nal already found
// ########################################################################
static int FindStartCode (unsigned char *Buf, int bufpos,  int bufsize, int next_start_pos, BOOL fIRFD)
{
 int info;
 int tPOS;
 int tSTART=bufpos;
 BOOL sTARFOUND=FALSE;
 info = 1;
 while (!sTARFOUND && tSTART<bufsize) {
  for (tPOS = 0; tPOS < 3; tPOS++)
   if(Buf[tSTART+tPOS] != 0)
    info = 0;   
   if(Buf[tSTART+tPOS] != 1)
    info = 0;
   if (info==0)    tSTART++;   
   else sTARFOUND=TRUE;
 }
 if (fIRFD && sTARFOUND)
 { 
  if(Buf[tSTART-1]==0 &&
   Buf[tSTART-2]==0)
  { info=2;//trailing zero found
  next_start_pos=tSTART-2;}
  else {info=1;
  next_start_pos=tSTART;}  
 }
 return info;
}

 


//#####################################
//# unsigned char *p      #
//# int bufpos                    #
//# NALU_t *mNal          #
//# int n_SIZE       #
//#           #
//#           #
//#####################################
BOOL gETNALandPROC(unsigned char *p,
       int bufpos,
       int bufsize,
       BOOL fisrtfd,
       NALU_t *mNal,
       int inc_SIZE,
       FILE *pReport)

 BOOL getNfailed=FALSE;
    int nal_BUFSIZE=0;
 int next_start_point=0;
 int mNal_size=0;
 int b_bufpos=bufpos/8;
 unsigned int finresult;
 BOOL info=TRUE;
 finresult=FindStartCode (p,b_bufpos,bufsize,next_start_point,fisrtfd);
 if (finresult==1 || finresult==2) {  
  nal_BUFSIZE=next_start_point-b_bufpos-1;
  inc_SIZE=nal_BUFSIZE;
  mNal->buf=(unsigned char *)malloc(sizeof(unsigned char)*nal_BUFSIZE);
  mNal->len=nal_BUFSIZE;
  memcpy (mNal->buf, &p[b_bufpos+1], mNal->len);
  mNal->forbidden_bit = (mNal->buf[0]>>7) & 1;
  mNal->nal_reference_idc = (mNal->buf[0]>>5) & 3;
  mNal->nal_unit_type = (mNal->buf[0]) & 0x1f;
  fprintf(pReport,"#########################################################################/n");
  fprintf(pReport,"nal len is %d/n",mNal->len);
  fprintf(pReport,"fobidden bit is % d/n",mNal->forbidden_bit);
  fprintf(pReport,"nal_reference_idc is d%/n",mNal->nal_reference_idc);
  switch(mNal->nal_unit_type) {
  case NALU_TYPE_SLICE :
   fprintf(pReport," nal type is  * NALU_TYPE_SLICE/n");
   break;
  case NALU_TYPE_DPA:
   fprintf(pReport,"nal type is *  NALU_TYPE_DPA/n");
   break;
  case NALU_TYPE_DPB :
   fprintf(pReport,"nal type is  * NALU_TYPE_DPB/n");
   break;
  case NALU_TYPE_DPC:
   fprintf(pReport,"nal type is  * NALU_TYPE_DPC/n");
   break;
  case NALU_TYPE_IDR:
   fprintf(pReport,"nal type is  * NALU_TYPE_IDR/n");
   break;
  case NALU_TYPE_SEI:
   fprintf(pReport,"nal type is  * NALU_TYPE_SEI/n");
   break;
  case NALU_TYPE_SPS:
   fprintf(pReport,"nal type is  * NALU_TYPE_SPS/n");
   break;
  case NALU_TYPE_PPS:
   fprintf(pReport,"nal type is  * NALU_TYPE_PPS/n");
   break;
  case NALU_TYPE_AUD:
   fprintf(pReport,"nal type is  * NALU_TYPE_AUD/n");
   break;
  case NALU_TYPE_EOSEQ:
   fprintf(pReport,"nal type is  * NALU_TYPE_EOSEQ/n");
   break;
  case NALU_TYPE_EOSTREAM:
   fprintf(pReport,"nal type is  * NALU_TYPE_EOSTREAM/n");
   break;
  case NALU_TYPE_FILL  :
   fprintf(pReport,"nal type is  * NALU_TYPE_FILL/n");
   break;
  default:
   break;
  }
  fprintf(pReport,"nal start code len is %d/n",mNal->startcodeprefix_len);
  fprintf(pReport,"#########################################################################/n");
  free(mNal->buf);
  mNal->buf=NULL;
  }
 else info=FALSE;
 return info;
}
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章