建设网站需要设备,网站建设后需要交费吗,网站开发有哪些方向,寮步网站建设哪家好文章目录 一、前言二、示例源码【1】目录结构【2】Makefile源码【3】h264parser.c源码【4】编译运行【5】源码下载地址 声明#xff1a;此篇示例源码非原创#xff0c;原作者雷霄骅。雷霄骅#xff0c;中国传媒大学通信与信息系统专业博士生#xff0c;在此向雷霄骅雷神致敬… 文章目录 一、前言二、示例源码【1】目录结构【2】Makefile源码【3】h264parser.c源码【4】编译运行【5】源码下载地址 声明此篇示例源码非原创原作者雷霄骅。雷霄骅中国传媒大学通信与信息系统专业博士生在此向雷霄骅雷神致敬。 代码原文地址视音频数据处理入门H.264视频码流解析
一、前言
示例源码是一个H.264码流解析程序。该程序可以从H.264码流中分析得到它的基本单元NALU分离出NALU然后再分析NALU的各个字段。
关于NALU的相关内容可参考文章【H.264】H.264详解一—— 一文看懂H.264协议
二、示例源码
【1】目录结构
project/
├── Makefile
├── h264parser.c
├── sintel.h264【2】Makefile源码
app:h264parser.cgcc -o app h264parser.c
clean:rm -f app【3】h264parser.c源码
#include stdio.h
#include stdlib.h
#include string.htypedef enum {NALU_TYPE_SLICE 1,NALU_TYPE_DPA 2,NALU_TYPE_DPB 3,NALU_TYPE_DPC 4,NALU_TYPE_IDR 5,NALU_TYPE_SEI 6,NALU_TYPE_SPS 7,NALU_TYPE_PPS 8,NALU_TYPE_AUD 9,NALU_TYPE_EOSEQ 10,NALU_TYPE_EOSTREAM 11,NALU_TYPE_FILL 12,
} NaluType;typedef enum {NALU_PRIORITY_DISPOSABLE 0,NALU_PRIRITY_LOW 1,NALU_PRIORITY_HIGH 2,NALU_PRIORITY_HIGHEST 3
} NaluPriority;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 sizeint forbidden_bit; //! should be always FALSEint nal_reference_idc; //! NALU_PRIORITY_xxxxint nal_unit_type; //! NALU_TYPE_xxxx char *buf; //! contains the first byte followed by the EBSP
} NALU_t;FILE *h264bitstream NULL; //! the bit stream fileint info20, info30;static int FindStartCode2 (unsigned char *Buf){if(Buf[0]!0 || Buf[1]!0 || Buf[2] !1) return 0; //0x000001?else return 1;
}static int FindStartCode3 (unsigned char *Buf){if(Buf[0]!0 || Buf[1]!0 || Buf[2] !0 || Buf[3] !1) return 0;//0x00000001?else return 1;
}int GetAnnexbNALU (NALU_t *nalu){int pos 0;int StartCodeFound, rewind;unsigned char *Buf;if ((Buf (unsigned char*)calloc (nalu-max_size , sizeof(char))) NULL) printf (GetAnnexbNALU: Could not allocate Buf memory\n);nalu-startcodeprefix_len3;if (3 ! fread (Buf, 1, 3, h264bitstream)){free(Buf);return 0;}info2 FindStartCode2 (Buf);if(info2 ! 1) {if(1 ! fread(Buf3, 1, 1, h264bitstream)){free(Buf);return 0;}info3 FindStartCode3 (Buf);if (info3 ! 1){ free(Buf);return -1;}else {pos 4;nalu-startcodeprefix_len 4;}}else{nalu-startcodeprefix_len 3;pos 3;}StartCodeFound 0;info2 0;info3 0;while (!StartCodeFound){if (feof (h264bitstream)){nalu-len (pos-1)-nalu-startcodeprefix_len;memcpy (nalu-buf, Buf[nalu-startcodeprefix_len], nalu-len); nalu-forbidden_bit nalu-buf[0] 0x80; //1 bitnalu-nal_reference_idc nalu-buf[0] 0x60; // 2 bitnalu-nal_unit_type (nalu-buf[0]) 0x1f;// 5 bitfree(Buf);return pos-1;}Buf[pos] fgetc (h264bitstream);info3 FindStartCode3(Buf[pos-4]);if(info3 ! 1)info2 FindStartCode2(Buf[pos-3]);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 filerewind (info3 1)? -4 : -3;if (0 ! fseek (h264bitstream, rewind, SEEK_CUR)){free(Buf);printf(GetAnnexbNALU: Cannot fseek in the bit stream file);}// Here the Start code, the complete NALU, and the next start code is in the Buf. // The size of Buf is pos, posrewind are the number of bytes excluding the next// start code, and (posrewind)-startcodeprefix_len is the size of the NALU excluding the start codenalu-len (posrewind)-nalu-startcodeprefix_len;memcpy (nalu-buf, Buf[nalu-startcodeprefix_len], nalu-len);//nalu-forbidden_bit nalu-buf[0] 0x80; //1 bitnalu-nal_reference_idc nalu-buf[0] 0x60; // 2 bitnalu-nal_unit_type (nalu-buf[0]) 0x1f;// 5 bitfree(Buf);return (posrewind);
}/*** Analysis H.264 Bitstream* param url Location of input H.264 bitstream file.*/
int simplest_h264_parser(char *url){NALU_t *n NULL;int buffersize100000;//FILE *myoutfopen(output_log.txt,wb);FILE *myoutstdout;h264bitstreamfopen(url, rb);if (h264bitstreamNULL){printf(Open file error\n);return 0;}n (NALU_t*)calloc (1, sizeof(NALU_t));if (n NULL){printf(Alloc NALU Error\n);return 0;}n-max_sizebuffersize;n-buf (char*)calloc (buffersize, sizeof(char));if (n-buf NULL){free (n);printf (AllocNALU: n-buf);return 0;}int data_offset0;int nal_num0;printf(------------- NALU Table ---------------\n);printf( NUM | POS | IDC | TYPE | LEN |\n);printf(--------------------------------------\n);while(!feof(h264bitstream)){int data_lenth;data_lenthGetAnnexbNALU(n);char type_str[20]{0};switch(n-nal_unit_type){case NALU_TYPE_SLICE:sprintf(type_str,SLICE);break;case NALU_TYPE_DPA:sprintf(type_str,DPA);break;case NALU_TYPE_DPB:sprintf(type_str,DPB);break;case NALU_TYPE_DPC:sprintf(type_str,DPC);break;case NALU_TYPE_IDR:sprintf(type_str,IDR);break;case NALU_TYPE_SEI:sprintf(type_str,SEI);break;case NALU_TYPE_SPS:sprintf(type_str,SPS);break;case NALU_TYPE_PPS:sprintf(type_str,PPS);break;case NALU_TYPE_AUD:sprintf(type_str,AUD);break;case NALU_TYPE_EOSEQ:sprintf(type_str,EOSEQ);break;case NALU_TYPE_EOSTREAM:sprintf(type_str,EOSTREAM);break;case NALU_TYPE_FILL:sprintf(type_str,FILL);break;}char idc_str[20]{0};switch(n-nal_reference_idc5){case NALU_PRIORITY_DISPOSABLE:sprintf(idc_str,DISPOS);break;case NALU_PRIRITY_LOW:sprintf(idc_str,LOW);break;case NALU_PRIORITY_HIGH:sprintf(idc_str,HIGH);break;case NALU_PRIORITY_HIGHEST:sprintf(idc_str,HIGHEST);break;}fprintf(myout,%5d| %8d| %7s| %6s| %8d|\n,nal_num,data_offset,idc_str,type_str,n-len);data_offsetdata_offsetdata_lenth;nal_num;}//Freeif (n){if (n-buf){free(n-buf);n-bufNULL;}free (n);}return 0;
}int main(int argc, char* argv[]){simplest_h264_parser(sintel.h264);return 0;
}【4】编译运行 【5】源码下载地址
H.264详解二- H264视频码流解析示例源码