海思多媒体(MPP)开发(3)——视频输出(VO)与视频解码(VDEC)

前言:

    海思多媒体处理平台(MPP)分为:视频输入(VI),视频处理(VPSS),视频编码(VENC),视频解码(VDEC),视频输出(VO)、视频侦测分析(VDA),音频输入(AI),音频输出(AO),音频编码(AENC),音频解码(ADEC),区域管理(REGION)等模块. 这里介绍视频解码(VDEC)和视频输出模块(VO)。
    VO与自己的显示设备密切相关,在使用VO之前,应该了解自己的显示设备的接口方式及时序等信息。

说明:

测试使用开发板的配置:

  • Hisi:Hi3521A
  • AD :NVP6134C 一个
  • 摄像头:720P,1080P
  • 显示:HDMI总线,1080P屏。

Hi3521A VO:

  • 1个高清设备DHD0,视频层VHD0最多支持16画面。
  • 支持PIP(Picture In Picture)画面叠加,PIP 视频层最多支持 1 画面
  • 最大输出时序:1920x1080@60或者1600x1200@60

HDMI:

    海思设备的HDMI开发,可以参考官方提供的《HDMI 开发参考.pdf》,其基本内容有:
    HDMI 的音频不能单独输出,必须依赖于视频输出,且 HDMI 的时钟来源于 VO 的时钟,因此接口调用顺序上需要先使能 VO,再调用 HDMI 接口,然后配置音视频输出。此外 Hi35xx 芯片内置的 HDMI 不支持 HDCP、CEC 功能。
    
    正确加载驱动之后,直接调用SAMPLE_COMM_VO_HdmiStart 函数就可以启动HDMI接口。
    
    注意,在调试HDMI的时候,因为HDMI的引脚可以被复用成普通GPIO口,所以如果调试不通的时候,可以先检查一下HDMI引脚的配置。

视频解码:

    这里不关联视频输入VI,直接使用一个H264文件来模拟h264视频流,

(a)数据流

  • 一般的视频里面封装有视频和音频,现在主流使用的视频压缩格式有H264,H265,MGPEG等格式。我们这里只介绍H264格式。
  • 海思sample里面是用一个1080P的h264文件来产生h264数据流。
  • 模拟数据流主要的是要寻找到h264每一帧数据的开始位置和结束位置,然后将一帧完整的数据发送到解码器里面去。
  • 可以有两种方式的去找到一帧完整的数据

(2)一次读一个字节数据

    每次读取一个自己数据,找到帧的开始位置,然后再找到下一帧开始的位置,中间就是一帧完整的数据

  • 优点:可以不用预设一帧数据的大小
  •  缺点:读数据耗费的时间长。

(3)一次多一大包数据    

先根据视频文件的分辨率设置一帧数据的最大空间大小,将这个值作为最小空间一次从文件中读取出来。再从这包数据中找出帧的开始位置和结束位置,下次读取的时候按结束位置来读取,剩下的数据包不用处理。

  • 优点:读取文件速度快
  • 缺点:需要预先知道一帧数据最大空间

海思sample_vdec 中使用的就是方法2,代码如下:

else if ( (pstVdecThreadParam->s32StreamMode==VIDEO_MODE_FRAME) && (pstVdecThreadParam->enType == PT_H264) )
        {
            bFindStart = HI_FALSE;  
            bFindEnd   = HI_FALSE;
            /**每次偏移到下一帧开始的位置**/
            fseek(fpStrm, s32UsedBytes, SEEK_SET);
            s32ReadLen = fread(pu8Buf, 1, pstVdecThreadParam->s32MinBufSize, fpStrm);
            if (s32ReadLen == 0)
            {
                if (pstVdecThreadParam->bLoopSend)
                {
                    s32UsedBytes = 0;
                    fseek(fpStrm, 0, SEEK_SET);
                    s32ReadLen = fread(pu8Buf, 1, pstVdecThreadParam->s32MinBufSize, fpStrm);
                }
                else
                {
                    break;
                }
            }

            /**查找开始位置**/
            for (i=0; i<s32ReadLen-5; i++)
            {
                if (  pu8Buf[i] == 0 && pu8Buf[i+1] == 0 && pu8Buf[i+2] == 1 && 
                     ( (pu8Buf[i+3]&0x1F) == 0x5 || (pu8Buf[i+3]&0x1F) == 0x1 ) &&
                     ( (pu8Buf[i+4]&0x80) == 0x80)
                   )                 
                {
                    bFindStart = HI_TRUE;
                    i += 4;
                    break;
                }
            }

            /**查找结束位置,也就是下一个开始帧的标志**/
            for (; i<s32ReadLen-5; i++)
            {
                if (  pu8Buf[i  ] == 0 && pu8Buf[i+1] == 0 && pu8Buf[i+2] == 1 && 
                    ( ((pu8Buf[i+3]&0x1F) == 0x7) || ((pu8Buf[i+3]&0x1F) == 0x8) || ((pu8Buf[i+3]&0x1F) == 0x6)
                      || (((pu8Buf[i+3]&0x1F) == 0x5 || (pu8Buf[i+3]&0x1F) == 0x1) &&((pu8Buf[i+4]&0x80) == 0x80))
                    )
                   )
                {
                    bFindEnd = HI_TRUE;
                    break;
                }
            }

            if(i > 0) s32ReadLen = i;
            if (bFindStart == HI_FALSE)
            {
                printf("SAMPLE_TEST: chn %d can not find start code!s32ReadLen %d, s32UsedBytes %d. \n", 
                                            pstVdecThreadParam->s32ChnId, s32ReadLen, s32UsedBytes);
            }
            else if (bFindEnd == HI_FALSE)
            {
                s32ReadLen = i+5;
            }
            
        }    

解码显示:

    解码模块基本上参考手册上的接口说明就可以实现。
    这里将将4个h264文件模拟成数据流输入到解码模块, 将解码模块与输出模块绑定,在显示屏中以4分屏显示4路画面,效果如下:

在海思Hi3521A 设备上实时解码4路1080P@30fps 从画面上看不会出现卡顿问题,但是CPU占用率非常高。

本章频测工程可以从「目录与序言」提供的地址去获取

本专栏第一篇文章「目录与序言」列出了专栏的完整目录,按目录顺序阅读,有助于你的理解。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

li_wen01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值