没有蜡笔的小鑫

没有蜡笔的小鑫

0个粉丝

2

问答

0

专栏

0

资料

没有蜡笔的小鑫  发布于  2021-11-16 19:38:57
采纳率 0%
2个问答
1864

Hi3536 VDEC 按帧发送模式的疑问

   

海思Hi3536解码sample中VDEC部分有流式发送和按帧发送两种模式

「流式发送」即直接将H.265码流发送给VDEC模块即可

「按帧发送」则需要对H.265码流进行分析,每次送给VDEC的码流必须为一帧。

这两种发送方式详见《HiMPP V3.0 媒体处理软件开发参考》第10章视频解码部分

海思的vdec sample中也给出了这两种发送方式的代码,流式发送很好理解,但按帧发送部分我有一些疑惑,下面放一下sample中按帧发送的代码

else if (pstVdecThreadParam->s32StreamMode==VIDEO_MODE_FRAME && pstVdecThreadParam->enType == PT_H265)    // 如果是按帧发送模式且为H.265解码协议

        {

            HI_BOOL  bNewPic = HI_FALSE;

            bFindStart = HI_FALSE;

            bFindEnd   = HI_FALSE;

            fseek(fpStrm, s32UsedBytes, SEEK_SET);

            s32ReadLen = fread(pu8Buf, 1, pstVdecThreadParam->s32MinBufSize, fpStrm);    // 从文件中读取H.265码流



            if (s32ReadLen == 0)

            {

                if (pstVdecThreadParam->bLoopSend == HI_TRUE)    // 循环读取文件

                {

                    s32UsedBytes = 0;

                    fseek(fpStrm, 0, SEEK_SET);

                    s32ReadLen = fread(pu8Buf, 1, pstVdecThreadParam->s32MinBufSize, fpStrm);

                }

                else

                {

                    break;

                }

            }



            for (i=0; i<s32ReadLen-6; i++)    // 查找H.265码流中的帧,0x00 0x00 0x01 是Start Code,Start Code后两字节为NALU Header

            {

                bNewPic = (pu8Buf[i+0] == 0 && pu8Buf[i+1] == 0 && pu8Buf[i+2] == 1

                    &&(((pu8Buf[i+3]&0x7D) >= 0x0 && (pu8Buf[i+3]&0x7D) <= 0x2A) || (pu8Buf[i+3]&0x1F) == 0x1)

                    &&((pu8Buf[i+5]&0x80) == 0x80));//first slice segment



                if (bNewPic)

                {

                    bFindStart = HI_TRUE;

                    i += 4;

                    break;

                }

            }



            for (; i<s32ReadLen-6; i++)    // 判断剩余部分码流有没有新的帧

            {

                bNewPic = (pu8Buf[i+0] == 0 && pu8Buf[i+1] == 0 && pu8Buf[i+2] == 1

                    &&(((pu8Buf[i+3]&0x7D) >= 0x0 && (pu8Buf[i+3]&0x7D) <= 0x2A) || (pu8Buf[i+3]&0x1F) == 0x1)

                    &&((pu8Buf[i+5]&0x80) == 0x80));//first slice segment



                if (  pu8Buf[i  ] == 0 && pu8Buf[i+1] == 0 && pu8Buf[i+2] == 1

                    &&(((pu8Buf[i+3]&0x7D) == 0x40) || ((pu8Buf[i+3]&0x7D) == 0x42) || ((pu8Buf[i+3]&0x7D) == 0x44)|| bNewPic)

                   )

                {

                    bFindEnd = HI_TRUE;

                    break;

                }

            }



            s32ReadLen = i;



            if (bFindStart == HI_FALSE)

            {

                printf("hevc can not find start code! %d s32ReadLen 0x%x +++++++++++++\n", pstVdecThreadParam->s32ChnId,s32ReadLen);

            }

            else if (bFindEnd == HI_FALSE)

            {

                s32ReadLen = i+6;

            }



        }

疑问点:

在寻找H.265新帧的时候,对NALU Header的判断为什么使用 pu8Buf[i+3] & 0x7D 呢,我查了关于H.265码流的格式资料,获取 NALU Header中的nal_unit_type 应该使用『int type = (code & 0x7E)>>1』吧。

我自己重写了这部分找帧模块,只以Start Code(0x00 0x00 0x01)作为帧与帧之间的区分,程序能够正常执行,可以跑通视频,但是随着程序运行时间的增加,解码的时延也逐渐增大,我推测应该是这部分找帧模块的问题。想直接用海思这部分的找帧模块,但没弄明白海思这段代码。

有没有大佬能解答一下

我来回答
回答2个
时间排序
认可量排序

CST-视觉光源方案

0个粉丝

3

问答

51

专栏

3

资料

CST-视觉光源方案 2021-11-18 17:35:53
认可0

帧模式 是会延迟的。一般设置解码缓存一帧,看看会不会有改善

没有蜡笔的小鑫

0个粉丝

2

问答

0

专栏

0

资料

没有蜡笔的小鑫 2021-11-22 10:32:34
认可0

更新
我自己一开始写的找帧模式仅对 Start Code做区分,VPS SPS PPS SEI 与 IDR帧给分开了,修改程序把 VPS SPS PPS SEI 与 IDR帧 统一为一帧后,延迟随时间增大的问题解决了。

或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区