265编码——帧长度解析

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值