265编码——帧长度解析
从海思MPP示例代码里拷贝出来的,做个记录。
读取文件,将265编码的长度写入csv文件中,便于excel进行分析。
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef enum hiVIDEO_MODE_E {
VIDEO_MODE_STREAM = 0, /* send by stream */
VIDEO_MODE_FRAME, /* send by frame */
VIDEO_MODE_COMPAT, /* One frame supports multiple packets sending. */
/* The current frame is considered to end when bEndOfFrame is equal to 1 */
VIDEO_MODE_BUTT
} VIDEO_MODE_E;
/* We just coyp this value of payload type from RTP/RTSP definition */
typedef enum {
PT_JPEG = 26,
PT_H264 = 96,
PT_H265 = 265,
/* add by hisilicon */
PT_MJPEG = 1002,
PT_BUTT
} PAYLOAD_TYPE_E;
int writ_length_to_excel(char *filename,int length)
{
static FILE *fp = NULL;
if(fp == NULL)
{
fp=fopen(filename,"wb"); // fp指针指向文件头部
if(fp == NULL)
{
perror("fopen");
return 0;
}
}
fprintf(fp,"%d\n",length);
}
int main(int argc, char **argv)
{
int bEndOfStream = 0;
int s32UsedBytes = 0, s32ReadLen = 0;
FILE *fpStrm=NULL;
unsigned char *pu8Buf = NULL;
int bFindStart, bFindEnd;
uint32_t u32Len, u32Start;
int s32Ret, i;
char cFileName[256]="1080P.h265";
int s32MinBufSize = 1024*1024*10;
int s32StreamMode = VIDEO_MODE_FRAME;
int enType = PT_H265;
if(argc == 2)
{
strcpy(cFileName,argv[1]);
}
if(cFileName != 0)
{
fpStrm = fopen(cFileName, "rb");
if(fpStrm == NULL)
{
printf("can't open file %s in send stream thread!\n", cFileName);
return (-1);
}
}
printf("\n \033[0;36m stream file:%s, userbufsize: %d \033[0;39m\n",
cFileName, s32MinBufSize);
char cCSVFileName[256] = {0};
char* cFileFix = ".csv";
snprintf(cCSVFileName,sizeof(cCSVFileName),"%s%s", cFileName, cFileFix);
printf("cCSVFileName %s\n",cCSVFileName);
pu8Buf = malloc(s32MinBufSize);
if(pu8Buf == NULL)
{
printf("can't alloc %d in send stream thread!\n", s32MinBufSize);
fclose(fpStrm);
return (-1);
}
fflush(stdout);
while (1)
{
bEndOfStream = 0;
bFindStart = 0;
bFindEnd = 0;
u32Start = 0;
fseek(fpStrm, s32UsedBytes, SEEK_SET);
s32ReadLen = fread(pu8Buf, 1, s32MinBufSize, fpStrm);
if (s32ReadLen == 0)
{
int bCircleSend = 0;
if (bCircleSend == 1)
{
s32UsedBytes = 0;
fseek(fpStrm, 0, SEEK_SET);
s32ReadLen = fread(pu8Buf, 1, s32MinBufSize, fpStrm);
}
else
{
break;
}
}
if (s32StreamMode==VIDEO_MODE_FRAME && enType == PT_H264)
{
for (i=0; i<s32ReadLen-8; i++)
{
int tmp = pu8Buf[i+3] & 0x1F;
if ( pu8Buf[i ] == 0 && pu8Buf[i+1] == 0 && pu8Buf[i+2] == 1 &&
(
((tmp == 0x5 || tmp == 0x1) && ((pu8Buf[i+4]&0x80) == 0x80)) ||
(tmp == 20 && (pu8Buf[i+7]&0x80) == 0x80)
)
)
{
bFindStart = 1;
i += 8;
break;
}
}
for (; i<s32ReadLen-8; i++)
{
int tmp = pu8Buf[i+3] & 0x1F;
if ( pu8Buf[i ] == 0 && pu8Buf[i+1] == 0 && pu8Buf[i+2] == 1 &&
(
tmp == 15 || tmp == 7 || tmp == 8 || tmp == 6 ||
((tmp == 5 || tmp == 1) && ((pu8Buf[i+4]&0x80) == 0x80)) ||
(tmp == 20 && (pu8Buf[i+7]&0x80) == 0x80)
)
)
{
bFindEnd = 1;
break;
}
}
if(i>0)s32ReadLen = i;
if (bFindStart == 0)
{
printf("can not find H264 start code!s32ReadLen %d, s32UsedBytes %d.!\n",
s32ReadLen, s32UsedBytes);
}
if (bFindEnd == 0)
{
s32ReadLen = i+8;
}
}
else if (s32StreamMode==VIDEO_MODE_FRAME
&& enType == PT_H265)
{
int bNewPic = 0;
for (i=0; i<s32ReadLen-6; i++)
{
uint32_t tmp = (pu8Buf[i+3]&0x7E)>>1;
bNewPic = ( pu8Buf[i+0] == 0 && pu8Buf[i+1] == 0 && pu8Buf[i+2] == 1
&& (tmp >= 0 && tmp <= 21) && ((pu8Buf[i+5]&0x80) == 0x80) );
if (bNewPic)
{
bFindStart = 1;
i += 6;
break;
}
}
for (; i<s32ReadLen-6; i++)
{
uint32_t tmp = (pu8Buf[i+3]&0x7E)>>1;
bNewPic = (pu8Buf[i+0] == 0 && pu8Buf[i+1] == 0 && pu8Buf[i+2] == 1
&&( tmp == 32 || tmp == 33 || tmp == 34 || tmp == 39 || tmp == 40 || ((tmp >= 0 && tmp <= 21) && (pu8Buf[i+5]&0x80) == 0x80) )
);
if (bNewPic)
{
bFindEnd = 1;
break;
}
}
if(i>0)s32ReadLen = i;
if (bFindStart == 0)
{
printf("can not find H265 start code!s32ReadLen %d, s32UsedBytes %d.!\n",
s32ReadLen, s32UsedBytes);
}
if (bFindEnd == 0)
{
s32ReadLen = i+6;
}
}
else if (enType == PT_MJPEG || enType == PT_JPEG)
{
for (i=0; i<s32ReadLen-1; i++)
{
if (pu8Buf[i] == 0xFF && pu8Buf[i+1] == 0xD8)
{
u32Start = i;
bFindStart = 1;
i = i + 2;
break;
}
}
for (; i<s32ReadLen-3; i++)
{
if ((pu8Buf[i] == 0xFF) && (pu8Buf[i+1]& 0xF0) == 0xE0)
{
u32Len = (pu8Buf[i+2]<<8) + pu8Buf[i+3];
i += 1 + u32Len;
}
else
{
break;
}
}
for (; i<s32ReadLen-1; i++)
{
if (pu8Buf[i] == 0xFF && pu8Buf[i+1] == 0xD9)
{
bFindEnd = 1;
break;
}
}
s32ReadLen = i+2;
if (bFindStart == 0)
{
printf("can not find JPEG start code!s32ReadLen %d, s32UsedBytes %d.!\n",
s32ReadLen, s32UsedBytes);
}
}
else
{
if((s32ReadLen != 0) && (s32ReadLen < s32MinBufSize))
{
bEndOfStream = 1;
}
}
printf("%d\n", s32ReadLen);
writ_length_to_excel(cCSVFileName,s32ReadLen);
s32UsedBytes = s32UsedBytes +s32ReadLen + u32Start;
}
printf("\033[0;35m send steam thread return ... \033[0;39m\n");
fflush(stdout);
if (pu8Buf != NULL)
{
free(pu8Buf);
}
fclose(fpStrm);
return 0;
}