前言
后面由于业务需求有rockit编解码的功能开发,这里我是第一次接触编解码,所以后续有些概念表述可能不太清楚,请各位多多包涵。
先来说一下解码模块的使用,rockit中的解码模块是VDEC,如果想要开发rockit的vdec可能需要开发者了解一些视频编解码的基本知识,这些基础知识在网上有很多文章,这里就不多赘述了,想了解可以点击这里。
我们可以从rk提供的demo以及mpi文档入手,我先来了解一些概念
基本概念:
VDEC——提供驱动视频解码硬件工作的 MPI 接口,实现视频解码功能。
重要概念:
码流发送模式
解码器码流发送模式包括以下两种:
流式发送(VIDEO_MODE_STREAM)
用户每次可发送任意长度码流到解码器,由解码器内部完成码流分帧,解码器需要在收到下一帧码流才能识别当前帧码流的结束,因此在该发送模式下,无法立即输出当前帧解码图像。
按帧发送(VIDEO_MODE_FRAME)
用户每次发送完整一帧码流到解码器,解码器认为该帧码流包含一帧完整的图像码流,内部不再做分帧,开始解码图像,因此需保证每次调用发送接口发送的码流必须为一帧,否则会出现解码错误。通过该发送方式可以达到快速解码的目的。
解码器码流接收模式
用户通过码流发送接口发送码流给解码器时,解码器接收码流方式包括以下两种:
拷贝模式
通过码流发送接口送入的码流数据会在解码器内部做拷贝,解码器内外部码流 Buffer 已无关联,用户可根据需要自行管理 VDEC_STREAM_S->pMbBlk 相关的内存块。
直通模式
通过码流发送接口送入的码流数据会在解码器内部不做拷贝,只是对 VDEC_STREAM_S->pMbBlk 增加一次引用,在处理完成后释放该引用。若该 pMbBlk 是通过 RK_MPI_SYS_CreateMB 构建的外部内存块,在释放pMbBlk 时,会同时调用用户构建pMbBlk时设置的释放回调 pFreeCB 释放相关内存。若该 pMbBlk 是通过RK_MPI_MB_GetMB 构建的内存块,则会释放回 MB 内存池,循环使用。
还有一些其他的概念具体可以去rk提供的MPI文档中查看。
接下来是vdec的大致流程:初始化->启动vdec接收码流->发送码流数据到vdec
初始化
RK_MPI_VDEC_SetModParam
这个函数用于设置解码通道参数。
通过接口 RK_MPI_VDEC_SetModParam
配置模块参数 VDEC_MOD_PARAM_S 可以设置内存池分配方式, 分配方式有3种: 私有池,用户池, 模块内存池, 可以根据不同的需求设置不同类型的内存池便于对存放解码后的图像数据内存进行管理,如未配置,默认为MB_SOURCE_MODULE模式,一般不进行配置就行了。
RK_MPI_VDEC_CreateChn
该函数用于创建视频解码通道,通过配置VDEC_CHN_ATTR_S结构体来设置各种通道属性。
结构体成员如下:
enType:解码协议设置(264,265)
enMode:码流发送方式(流式,帧式)
u32PicWidth:必须大于0
u32PicHeig:必须大于0
u32FrameBufSize:该参数在RK_MPI_VDEC_SetModParam
函数中配置成私用池(PrivateMB)才有效
u32FrameBufCnt:该参数在RK_MPI_VDEC_SetModParam
函数中配置成私用池(PrivateMB)才有效
u32StreamBufCnt:该参数用于存放缓冲帧
RK_MPI_VDEC_SetChnParam
该函数用于设置通道参数,可以配置解码图像输出方式。
RK_MPI_VDEC_AttachMbPool
用于将解码通道绑定到某个视频缓存 MB 池中。
这个函数如果前没有设置解码后的帧放入到私有池或者用户池,就不需要调用,如果有调用参考rk提供的demo有部分前置条件设置和具体的使用方式。
RK_MPI_VDEC_StartRecvStream
该函数用于解码器开始接收用户发送的码流。这个函数的成功调用表明了rockit内部的vdec已经做好准备接收编码流了。
RK_MPI_VDEC_SendStream
该函数用于将未解码的码流发送到rockit内部的vdec模块中解码。
其中码流各项数据存放在VDEC_STREAM_S结构体指针所指向的地址中,其中码流的数据内容需要使用RK_MPI_SYS_CreateMB
创建缓冲块来存放,具体可以参考demo中的使用方式。该函数被调用时会将码流根据先前设置好的模块属性将其送进不同通道进行解码,如果不报错的以及码流数据没问题的话,解码完毕后会将帧存放到我们前面说的重要概念中的内存池中,可以通过RK_MPI_VDEC_GetFrame
函数来获取,也可以通过绑定的方式RK_MPI_SYS_Bind
来直接输出到后级。
RK_MPI_VDEC_GetFrame
该函数可以从通道获取解码完的图像。
通过该函数可以获取图像的数据,以便用户后续处理。
RK_MPI_VDEC_ReleaseFrame
该函数释放视频解码通道的图像,需要与RK_MPI_VDEC_GetFrame
配套使用。
对于VDEC模块的基本使用大致就是上述的步骤,具体代码可以参考demo中的使用,同时需要注意的是,不同业务场景下可能需要对vdec模块的通道参数或者模块参数进行调整,比如内存池的选择,以及码流接收模式等等。