h264测试文件--从h.264文件读取单独帧模拟视频流

测试服务器需要一个h264流,从h264文件读取流的函数实现: c语言版本

注意需要h264文件开头即为00 00 00 01

/***

***20190828 canok

*** output: complete frames

**/

#include
#include	
#include 
#include 
#define MIN(a,b) ((a)<(b)?(a):(b))

typedef unsigned char   uint8_t;     //无符号8位数

#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 CACH_LEN (1024*1024)//缓冲区不能设置太小,如果出现比某一帧比缓冲区大,会被覆盖掉一部分
static uint8_t *g_cach[2] = {NULL,NULL};
static FILE* fp_inH264 = NULL;
static int icach = 0;
static int ioffset = 0;
static int bLoop = 0;
int init()
{	
	if(g_cach[0] == NULL)
	{
		g_cach[0] = (uint8_t*)malloc(CACH_LEN);
	}
	if(g_cach[1] == NULL)
	{
		g_cach[1] = (uint8_t*)malloc(CACH_LEN);
	}
	
	if(fp_inH264 == NULL)
	{
		fp_inH264 = fopen("./test.h264","r");
		if(fp_inH264 == NULL)
		{
			printf("fope erro [%d%s]\n",__LINE__,__FUNCTION__);
			return -1;
		}
	}
	
	if(fread(g_cach[icach], 1,CACH_LEN,fp_inH264 ) 0)
	{
		int dataLen = endpoint -startpoint;
		if(bufLen < dataLen)
		{
			printf("recive buffer too short , need %d byte!\n",dataLen);
		}
		memcpy(buf,g_cach[icach]+startpoint, MIN(dataLen,bufLen));
		ioffset = endpoint;
		
		return MIN(dataLen,bufLen);
	}
	else
	{
		int oldLen =CACH_LEN -startpoint;
		memcpy(g_cach[(icach+1)%2],g_cach[icach]+startpoint, oldLen );
		
		int newLen = 0;
		newLen = fread(g_cach[(icach+1)%2]+oldLen, 1,CACH_LEN -(oldLen),fp_inH264);
		if(newLen  0)
	{
		printf("get a Nal len:%8d-----",len);
		checkNal(buffer[4]);
		fwrite(buffer,1,len,fp_out);
	}
	fclose(fp_out);
	free(buffer);
	deinit();

	printf("All_count %d\n",All_count);
	printf("I_count %d\n",I_count);
	printf("PB_count %d\n",PB_count);
	printf("AUD_count %d\n",AUD_count);
	printf("SPS_count %d\n",SPS_count);
	printf("PPS_count %d\n",PPS_count);
}

注:上述代码中,I_count  PB_cout 并不能完全表示 有I_cout 个关键帧/非关键帧。 h264的NAL单元,用 00 00 00 01 或者 00 00 01 来分割,一个NAL单元中如果携带视频数据的话,就是携带一个slice 片, 这里统计的就是这个slice的个数。 一般情况下一帧视频数据 会存储在一个slice中,这个时候slice数量就和帧数量相等。 但是有时候视频压缩率低,比如高质量的宣传片等,一帧数据被分割成几个slice存储,这种情况下slice数量就比 帧数要大了。

你可能感兴趣的:(h264,vlc)