測試服務器需要一個h264流,從h264文件讀取流的函數實現: c語言版本
注意需要h264文件開頭即爲00 00 00 01
/***
***20190828 canok
*** output: complete frames
**/
#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
#include <string.h>
typedef unsigned char uint8_t; //無符號8位數
#define CACH_LEN (1024*500)//緩衝區不能設置太小,如果出現比某一幀比緩衝區大,會被覆蓋掉一部分
static uint8_t *g_cach[2] = {NULL,NULL};
static FILE* fp_inH264 = NULL;
static int icach = 0;
static int ioffset = 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 )<CACH_LEN)
{
printf("intpufile too short [%d%s]\n",__LINE__,__FUNCTION__);
return -1;
}
return 0;
}
int deinit()
{
if(g_cach[0])
{
free(g_cach[0]);
g_cach[0] = NULL;
}
if(g_cach[1])
{
free(g_cach[1]);
g_cach[1] = NULL;
}
if(fp_inH264)
{
fclose(fp_inH264);
fp_inH264 = NULL;
}
}
int checkHead(uint8_t *buffer, int offset)
{
static uint8_t mMark[4] = {0x00,0x00,0x00,0x01};
return !memcmp(buffer+offset,mMark,4);
}
//獲取一幀數據到 buf, bufLen表示緩衝區最大可以容納的數據
//返回實際的幀數據長度
int getOneFrame(uint8_t *buf, int bufLen)
{
int i =0;
int startpoint = ioffset;
int endpoint = ioffset;
for (i = ioffset+4; i <= CACH_LEN - 4; i++) {
if (checkHead(g_cach[icach], i)){
startpoint = ioffset;
endpoint = i;
}
}
if(endpoint - startpoint > 0)
{
memcpy(buf,g_cach[icach]+startpoint, (endpoint - startpoint));
ioffset = endpoint;
return endpoint - startpoint;
}
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 <CACH_LEN -(oldLen) )
{
return -1;
}
ioffset = 0;
icach = (icach+1)%2;
return getOneFrame(buf,bufLen);
}
}
int main()
{
if(init())
{
return -1;
}
uint8_t *buffer = (uint8_t*)malloc(CACH_LEN);
int len =0;
FILE *fp_out = fopen("out.h264","w+");
while((len = getOneFrame(buffer,CACH_LEN) )> 0)
{
printf("get a fram :%d\n",len);
fwrite(buffer,1,len,fp_out);
}
fclose(fp_out);
free(buffer);
deinit();
}