静帧放大流程


1. 概述

静帧放大过程主要依赖于Vdec 模块实现,基本原理是在静止暂停的状态下,在解码器始终保留一帧待解数据,通过重复刷新解码该帧实现后端pipeline的数据更新。下面将从暂停、多画面与单画面切换、单帧步和抓图这几个场景进行简述。

2. 静帧暂停过程

代码实现:

bool bPause = false;
bool Flag = false;
main()
{
    while(true)
    {
        if( bPause == true )
        {
            if( Flag == true )
            {
                MI_VDEC_SendStream
                MI_VDEC_RefreshChn
                Flag = false
            }
            else
            {
                continue
            }
        }
        else
        {
            MI_VDEC_SendStream
        }
    }
}

UI flow:
do
{
    if(bPause == false)
    {
        bPause = true
        MI_VDEC_PauseChn
        Flag = true
    }
    else if(bPause == true)
    {
        bPause = false
        MI_VDEC_ResumeChn
        Flag = false
    }
}
while

暂停时,通过cat proc 信息可以确认是否成功:LeftCnt 在MI_VDEC_RefreshChn 调用后始终维持为1,而DecFrmCnt 会逐渐递增,说明解码器已经进入了重复解码同一帧的工作状态。

1、用户点击暂停时,会调用到MI_VDEC_PauseChn 接口,SDK解码暂停并且APP进入送流暂停状态,同时标记各个在播通道的是否需要多一帧

2、APP送流线程通过暂停状态进入轮询,会读取该通道标记,如果标记置起来了,就从磁盘中再读取一帧数据送下去。

3、MI_VDEC_SendStream 接口送完之后,需要调一次MI_VDEC_RefreshChn接口,以刷新循环解码的一帧,如果不调的话,可能就会导致画面还是暂停再前一帧状态,待下次MI_VDEC_RefreshChn的时候,如果画面内容刚好有变则可能会看到不一样的画面。

3. 多画面和单画面切换过程

代码实现:

do
{
    if(bPause == false)
    {
        unbind vdec disp
        MI_DISP_DisableInputPort
        MI_VDEC_StopChn
        MI_VDEC_DestroyChn
        MI_VDEC_CreateChn
        MI_VDEC_StartChn
        bind vdec disp
        MI_DISP_SetInputPortAttr
        MI_DISP_EnableInputPort
    }
    else if(bPause == true)
    {
        MI_DISP_DisableInputPort
        MI_VDEC_SetOutputPortAttr
        MI_DISP_SetInputPortAttr
        MI_VDEC_RefreshChn
        MI_DISP_EnableInputPort
    }
}
while

多画面和单画面互相切换的情景下,需要在调整VDEC和DISP 相关宽高参数后调MI_VDEC_RefreshChn解码一次,即可重复解码当前帧率,达到不失真播放。

4. 单帧步进

1、当前未处于暂停状态的时候,点击单帧播放按钮需要执行暂停过程(见第二点),令解码器进入暂停状态。

2、如果目前已处于暂停状态,则再往解码器送下一帧待解数据,最后执行一次MI_VDEC_StepChn。

5. 抓图

在播放暂停的情况下,在读取VENC模块编码数据之前需要调用一次MI_VDEC_RefreshChn,以便VENC模块能拿到视频数据。如果不调用的话,VENC将没法抓到图。