NAL分析器程序源代码

    技术2022-05-13  26

     

    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;} 


    最新回复(0)