硬编码支持情况(一)

                                                              硬编码支持情况(一)

图片信息原文链接:http://trac.ffmpeg.org/wiki/HWAccelIntro

截个图:

注:

(一):Intel 平台

1:Intel 平台的Quick Sync Video(qsv)是对于音视频编解码的框架具体对外接口则为上面图中的LIBMFX,可以理解为Quick Sync Video(qsv)是对外宣称的技术ffmpeg对外设备TYPE选择也是这个,但如果不用ffmpeg直接用intel自身api则操作的是LIBMFX库提供的对外API接口。

2:SDK下载地址:https://github.com/Intel-Media-SDK/MediaSDK,需要安装。

3:samples下载地址:https://github.com/Intel-Media-SDK/samples/tree/4293f965b42310c043bc49d23c6f9f5d3d587dd8,里面有编码和解码的samples。

4:【Intel(R)_Media_SDK】官方文档翻译摘要:https://blog.csdn.net/zhuweigangzwg/article/details/83861644

5:如果开发程序需要添加的lib库如下:

//用intel的mfx的media库command工程中引用如下才能编译成功生成lib库。
//本项目再引用此lib库。
/*
..\include;
$(INTELMEDIASDKROOT);               //intelmediasdk
..\include\vm;
*/
/*
本工程添加的头文件目录
..\INTEL_MFX\include;
$(INTELMEDIASDKROOT)\include;       //intelmediasdk
添加的lib库目录:..\Debug; ..\Release; 即上面command生成的lib库。
添加lib库目录:$(INTELMEDIASDKROOT)\lib\$(Platform)    //intelmediasdk
*/

//添加command库
#pragma comment(lib,"libmfx_vs2015.lib")  
#pragma comment(lib,"dxva2.lib") 
#pragma comment(lib,"d3d9.lib") 
#pragma comment(lib,"d3d11.lib") 
#pragma comment(lib,"dwmapi.lib") 
#pragma comment(lib,"comsuppw.lib") 
#pragma comment(lib,"dxgi.lib") 

//目录C:\Program Files (x86)\IntelSWTools\Intel(R) Media SDK 2018 R2\Software Development Kit\lib

#pragma comment(lib,"libmfx.lib")           

//目录C:\Program Files (x86)\IntelSWTools\Intel(R) Media SDK 2018 R2\Software Development Kit\lib             
#pragma comment(lib,"libmfx_vs2015.lib")  
#pragma comment(lib,"command.lib")  

6:CBuffering::m_pSurfaces内存管理的类,由于此类中的一些函数或变量是protected的,
只有用c++继承方式,但这里是c语言,需要修改源码protected为public,文件是mfx_buffering.h,函数和变量都修改为public。

7:mfx解码时候的5个surface,输入两个在(1)中说明,输出两个在(2)中说明,(3)中是个临时变量为解决解码参数问题。

如果输出的surface不用直接将(3)的解码后的surface用于输出也可以。

(1)CurrentFreeSurface是空闲的surface,传入解码器,用于解码,如果在解码途中则需要转给m_UsedSurfacesPool队列。
即这段数据正在解码被锁住则传入正在使用的surface队列中
m_FreeSurfacesPool队列中取出的m_pCurrentFreeInSurface和m_UsedSurfacesPool都是用于存放对H264处理的surface.都是输入surface。current字段是防止和系统的变量名称冲突。

(2)CurrentFreeOutputSurface是空闲的输出surface,传入解码器,用于接收解码之后的yuv数据,接收之后传给m_OutputSurfacesPool队列。GetFreeOutputSurface中取出的m_pCurrentFreeOutputSurface和m_OutputSurfacesPool都是用于存放解码后的yuv数据surface,都是输出队列。

(3)引入m_pOutSurface这个变量只是为了适应DecodeFrameAsync这个函数传入**指针的操作,如果可以用m_pCurrentFreeOutputSurface也可以。

8:这里一定要注意有个大坑:

mfxBitstream * pBitstream 这个变量中就是存放一帧要解码数据的结构体其中,MaxLength:申请的内存大小,DataLength:解码前是传入的数据大小,解码后是剩余的数据大小。DataOffset:解码前为0,解码后实际解码了多少数据。

解码后的状态码MFX_ERR_MORE_DATA == sts时pBitstream->DataLength一定等于0这时候再读取一帧数据没问题。
如果MFX_ERR_NONE == sts时分为两种情况,1:pBitstream->DataLength == 0,这时再去读取一帧数据。
如果MFX_ERR_NONE == sts时分为两种情况,2:pBitstream->DataLength != 0,这时一定不能读取新的数据,要继续用剩下的数据去解码.否则会有帧减少产生图像花屏绿屏情况。

也就是说解码传进去一帧数据有可能返回的时候剩余一些字段,需要将这些字段再传给解码器做解码,而不是再读取一帧用于解码这个值就是pBitstream->DataLength。

9:mfxEncodeCtrl encCtrl;   //编码的帧类型和一些扩展信息存储结构体。只是扩展用填写为NULL也可以如果没有扩展。

 //编码时这个值必须清零否则EncodeFrameAsync会失败返回-15.
 MSDK_ZERO_MEMORY(encCtrl);

编码后需要做异步同步操作。//同步操作,输出数据到m_mfxBS中
sts = m_mfxSession.SyncOperation(UserSyncp, MSDK_WAIT_INTERVAL);

10:mfx 填写qp时,unsigned short UserRateControlMethod = MFX_RATECONTROL_CQP;  //CBR,ABR,CQP

m_mfxEncParams.mfx.RateControlMethod = UserRateControlMethod;  //CBR,ABR,CQP  

 if (UserRateControlMethod == MFX_RATECONTROL_CQP)
    {
        m_mfxEncParams.mfx.QPI = 24;
        m_mfxEncParams.mfx.QPP = 34;
        m_mfxEncParams.mfx.QPB = 34;
    }

其他值RateControlMethod 则一旦填写QP初始化会失败。

11:    //解决实时编码问题(传入空数据)。
    do 
    {
        sts = m_pmfxENC->EncodeFrameAsync(&encCtrl, pSurf, &m_mfxBS, &UserSyncp);
        pSurf = NULL;
        Sleep(1);
    } while (sts == MFX_ERR_MORE_DATA);

12://解决实时解码问题(传入空数据)。

    do
    {
        sts = m_pmfxDEC->DecodeFrameAsync(NULL, &(m_pCurrentFreeSurface->frame), &m_pOutSurface, &usersyncp);

        if (sts == MFX_ERR_MORE_DATA)
        {
            Sleep(1);
        }

    } while (MFX_ERR_MORE_DATA== sts);

13:  //解决实时解码问题(传入空数据)。

    //错误处理
    if (sts == MFX_ERR_DEVICE_LOST ||
        sts == MFX_ERR_INCOMPATIBLE_VIDEO_PARAM ||
        sts == MFX_ERR_INVALID_VIDEO_PARAM ||
        sts == MFX_ERR_UNDEFINED_BEHAVIOR ||
        sts == MFX_ERR_DEVICE_FAILED)
    {
        DISPATCHER_LOG_INFO((("CMfxDecoder::DecodeFrameAsync = %d."), sts)

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值