视频解码 (VDEC)
概述
VDEC 模块,为提供视频硬件解码的接⼝。
使用流程
对一段视频流执行解码生成 yuv 数据的操作流程如下。
- VDEC 设备初始化, 调用 ZH_MPI_VDEC_CreateChn 创建一路解码通道。
- 调用 ZH_MPI_VDEC_StartRecvStream,表示解码通道可以接受码流输入。
- 调用 ZH_MPI_VDEC_SendStream 将数据流发送给解码通道进行解码。
- 通过 ZH_MPI_VDEC_GetFd 获取到解码通道 fd,使用 poll 的方式等待有输出的解码帧可读。
- 使用 ZH_MPI_VDEC_GetFrame 获取到解码帧。
- 使用完整后,调用 ZH_MPI_VDEC_ReleaseFrame 释放掉解码帧。
重要概念
-
码流发送模式
解码器码流发送模式包括以下两种。
-
流式发送(VIDEO_MODE_STREAM)
⽤⼾每次可发送任意⻓度码流到解码器,由解码器内部完成码流分帧,解码器需要在收到下⼀帧码流才能识别当前帧码流的结束,因此在该发送模式下,⽆法⽴即输出当前帧解码图像。
-
按帧发送(VIDEO_MODE_FRAME)
⽤⼾每次发送完整⼀帧码流到解码器,解码器认为该帧码流包含⼀帧完整的图像码流,内部不再做分帧,开始解码图像,因此需保证每次调⽤发送接⼝发送的码流必须为⼀帧,否则会出现解码错误。通过该发送⽅式可以达到快速解码的⽬的。
说明:
码流发送模式配置⽅法: 码流发送模式可通过接⼝ ZH_MPI_VDEC_CreateChn 配置通道属性 VDEC_CHN_ATTR_S enMode 来配置。
-
-
码流包创建⽅式
通过码流发送接⼝发送码流时,承载码流数据的数据类型统⼀为 MB_BLK 类型的内存块,该内存块的创建⽅式包括:
-
基于⽤⼾已有的虚拟内存构建
通过接⼝
ZH_MPI_SYS_CreateMB创建内存块,需配置MB_EXT_CONFIG_S参数。若外部码流在读取或解析后,已经存放于⼀块虚拟内存,可直接基于该虚拟内存地址构建⼀块 MB 内存块,内部仅做数据结构类型封装,不做拷⻉。- 若该虚拟内存在外部需要循环使⽤时,则不需要配置释放回调⽅法 pFreeCB,并在发送码流时以通过拷⻉模式发送。
- 若该 虚拟内存是动态分配的,可通过配置释放回调⽅法,交由解码器管理,并在使⽤完成后调⽤回调释放该虚拟内存。
-
基于⽤⼾已有的 DMA-BUF 构建
若⽤于已通过其他⽅式创建了 DMA Buffer,并将码流存放在该 Buffer 内,可通过基于虚拟内存相同的构建⽅法,创建 MB 内存块。每个 DMA Buffer 均有对应的访问句柄 FD,在配置
MB_EXT_CONFIG_S参数时需填写对应的句柄 FD。 -
从内存池申请
通过接⼝
ZH_MPI_MB_CreatePool先创建内存池,然后通过ZH_MPI_MB_GetMB获取⼀个内存块,在使⽤完成后调⽤ZH_MPI_MB_ReleaseMB释放回内存池。 -
直接申请
直接调⽤ SYS 模块提供的接⼝申请 MB 内存块,然后将码流数据拷⻉到申请的内存块。通过接⼝
ZH_MPI_SYS_Malloc申请虚拟内存,通过接⼝ZH_MPI_SYS_MmzAlloc申请物理内存。
-
-
解码器码流接收模式
⽤⼾通过码流发送接⼝发送码流给解码器时,解码器以直通模式接收码流。通过码流发送接⼝送⼊的码流数据会在解码器内部不做拷⻉,只是对
VDEC_STREAM_S->pMbBlk增加⼀次引⽤,在处理完成后释放该引⽤。- 若该 pMbBlk 是通过
ZH_MPI_SYS_CreateMB构建的外部内存块,在释放 pMbBlk 时,会同时调⽤⽤⼾构建 pMbBlk 时设置的释放回调 pFreeCB 释放相关内存。 - 若该 pMbBlk 是通过
ZH_MPI_MB_GetMB构建的内存块,则会释放回 MB 内存池,循环使⽤。
- 若该 pMbBlk 是通过
-
帧存分配⽅式
解码帧存是存放解码后的图像数据内存,VDEC 模块⽀持私有池(MB_SOURCE_PRIVATE)解码内存池分配。
私有池是指由 VDEC 模块内部按通道创建并被该通道独占的 MB 内存池,可从该内存池申请 MB 作为该通道的图像 Buffer。⽤⼾可以在创建通道接⼝
ZH_MPI_VDEC_CreateChn中设置私有 MB 内存池的个数 u32FrameBufCnt, 不支持 u32FrameBufSize 配置,由内部根据配置的宽⾼计算所需的图像 Buffer ⼤⼩。
-
显示时间戳处理
- 按帧模式(VIDEO_MODE_FRAME)发送码流时,解码输出的图像显示时间戳 PTS 为发送码流接口(ZH_MPI_VDEC_SendStream)中用户送入的 PTS,解码器不会更改此值,但可能会更改输出顺序。比如码流存在 B 帧时,输出图像 PTS 与输入的码流 PTS 不一致。如果用户送入的 PTS 值为 -1,则表示此图像不会被视频输出模块(VO)显示。若用户配置的 PTS 值为 0,则表示用户不进行帧率控制,而是由视频输出模块 VO 进行帧率控制;
- 按流式模式(VIDEO_MODE_STREAM)发送码流时,解码输出图像的 PTS 应统一设为 0,用户不进行帧率控制,而是由视频输出模块 VO 进行帧率控制。
-
用户图片插入支持
用户可直接向 VDEC 模块插入图片数据,VDEC 模块不对该图片做任何处理,在绑定模式下,直接送往下一级。在码流源端出现某种异常时,用户可通过该方法插入图片提示。比如当网络异常断开,前端没有再继续送码流,用户可通过设置插入图片,并输出显示到 VO 模块,以提示当前网络异常或没有码流可解码。
VDEC 模块插入用户图片方式为立即插入图片。即 VDEC 模块会先清空解码器内部的码流和图像,然后插入用户图片。
说明:
用户图片插入方法如下。
- 通过接口 ZH_MPI_VDEC_SetUserPic 设置需要插入的 用户图片。
- 通过接口 ZH_MPI_VDEC_EnableUserPic 使能插入的用户图片。
API 参考
该功能模块为用户提供以下 API:
- ZH_MPI_VDEC_CreateChn:创建视频解码通道。
- ZH_MPI_VDEC_DestroyChn:销毁视频解码通道。
- ZH_MPI_VDEC_ResetChn:复位解码通道。
- ZH_MPI_VDEC_GetChnAttr:获取视频解码通道属性。
- ZH_MPI_VDEC_SetChnAttr:设置视频解码通道属性。
- ZH_MPI_VDEC_StartRecvStream:解码器开始接收⽤⼾发送的码流。
- ZH_MPI_VDEC_StopRecvStream:解码器停⽌接收⽤⼾发送的码流。
- ZH_MPI_VDEC_QueryStatus:查询解码通道状态。
- ZH_MPI_VDEC_SendStream:向视频解码通道发送码流数据。
- ZH_MPI_VDEC_GetFrame:获取视频解码通道的解码图像。
- ZH_MPI_VDEC_ReleaseFrame:释放视频解码通道的解码图像。
- ZH_MPI_VDEC_GetFd:获取视频解码通道的设备⽂件句柄。
- ZH_MPI_VDEC_CloseFd:关闭视频解码的设备⽂件句柄。
- ZH_MPI_VDEC_SetChnParam:设置解码通道参数。
- ZH_MPI_VDEC_GetChnParam:获取解码通道参数。
- ZH_MPI_VDEC_SetUserPic: 设置用户图片属性。
- ZH_MPI_VDEC_EnableUserPic:使能插入用户图片。
- ZH_MPI_VDEC_DisableUserPic:禁止使能插入用户图片。
- ZH_MPI_VDEC_SetRotation:设置解码图像旋转角度。
- ZH_MPI_VDEC_GetRotation:获取解码图像旋转角度。
- ZH_MPI_VDEC_SetDisplayMode:设置显示模式。
- ZH_MPI_VDEC_GetDisplayMode:获取显示模式。
ZH_MPI_VDEC_CreateChn
描述
创建视频解码通道。
语法
ZH_S32 ZH_MPI_VDEC_CreateChn(VDEC_CHN VdChn, const VDEC_CHN_ATTR_S *pstAttr)
参数
| 参数名 | 数据类型 | 描述 | 输入/输出 |
|---|---|---|---|
| VdChn | VDEC_CHN | 视频解码通道号。 取值范围:[0, VDEC_MAX_CHN_NUM)。 | 输入 |
| pstAttr | const VDEC_CHN_ATTR_S* | 解码通道属性指针。 | 输⼊ |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功。 |
| 非 0 | 失败,请参见 VDEC 错误码。 |
需求
头文件:zh_mpi_vdec.h,zh_comm_vdec.h。
注意事项
- 通道号必须合法,不能超出最⼤通道号
VDEC_MAX_CHN_NUM。 - 参数 pstAttr 不能为空,否则将返回空指针错误
ZH_ERR_VDEC_NULL_PTR。 - 在创建视频解码通道之前必须保证通道未创建(或者已经销毁),否则将返回通道已存在错误
ZH_ERR_VDEC_EXIST。 - 通道属性 pstAttr 中的宽⾼必须⼤于 0,否则将返回⾮法参数错误
ZH_ERR_VDEC_ILLEGAL_PARAM。 - 通道属性 pstAttr 中的宽⾼不能超硬件解码能⼒限制,否则解码通道会初始化失败。
- 解码帧存分配⽅式只支持私有池⽅式,则⽤⼾需要根据解码码流配置解码所需的内存块个数 u32FrameBufCnt, 建议 u32FrameBufCnt 根据码流情况以及系统内存情况配置,根据个数创建相应的 MB 私有池。
相关主题
ZH_MPI_VDEC_DestroyChn
描述
销毁视频解码通道。
语法
ZH_S32 ZH_MPI_VDEC_DestroyChn(VDEC_CHN VdChn)
参数
| 参数名 | 数据类型 | 描述 | 输入/输出 |
|---|---|---|---|
| VdChn | VDEC_CHN | 视频解码通道号。 取值范围:[0, VDEC_MAX_CHN_NUM)。 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功。 |
| 非 0 | 失败,请参见 VDEC 错误码。 |
需求
头文件: zh_mpi_vdec.h,zh_comm_vdec.h。
注意事项
通道必须已创建,否则会返回通道不存在的错误 ZH_ERR_VDEC_UNEXIST。
相关主题
ZH_MPI_VDEC_ResetChn
描述
复位视频解码通道,将清除解码通道缓存数据。
语法
ZH_S32 ZH_MPI_VDEC_ResetChn(VDEC_CHN VdChn)
参数
| 参数名 | 数据类型 | 描述 | 输入/输出 |
|---|---|---|---|
| VdChn | VDEC_CHN | 视频解码通道号。 取值范围:[0, VDEC_MAX_CHN_NUM)。 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功。 |
| 非 0 | 失败,请参见 VDEC 错误码。 |
需求
头文件:zh_mpi_vdec.h,zh_comm_vdec.h。
注意事项
通道必须已创建,否则会返回通道不存在的错误 ZH_ERR_VDEC_UNEXIST。
ZH_MPI_VDEC_GetChnAttr
描述
获取视频解码通道属性。
语法
ZH_S32 ZH_MPI_VDEC_GetChnAttr(VDEC_CHN VdChn, VDEC_CHN_ATTR_S *pstAttr)
参数
| 参数名 | 数据类型 | 描述 | 输入/输出 |
|---|---|---|---|
| VdChn | VDEC_CHN | 视频解码通道号。 取值范围:[0, VDEC_MAX_CHN_NUM)。 | 输入 |
| pstAttr | VDEC_CHN_ATTR_S* | 解码通道属性指针。 | 输出 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功。 |
| 非 0 | 失败,请参见 VDEC 错误码。 |
需求
头文件:zh_mpi_vdec.h,zh_comm_vdec.h。
注意事项
- 通道必须已创建,否则会返回通道不存在的错误
ZH_ERR_VDEC_UNEXIST。 - 传⼊的 pstAttr 不能为空,否则会返回空指针错误
ZH_ERR_VDEC_NULL_PTR。
ZH_MPI_VDEC_SetChnAttr
描述
设置视频解码通道属性。
语法
ZH_S32 ZH_MPI_VDEC_SetChnAttr(VDEC_CHN VdChn, const VDEC_CHN_ATTR_S *pstAttr)
参数
| 参数名 | 数据类型 | 描述 | 输入/输出 |
|---|---|---|---|
| VdChn | VDEC_CHN | 视频解码通道号。 取值范围:[0, VDEC_MAX_CHN_NUM)。 | 输入 |
| pstAttr | const VDEC_CHN_ATTR_S* | 解码通道属性指针。 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功。 |
| 非 0 | 失败,请参见 VDEC 错误码。 |
需求
头文件:zh_mpi_vdec.h,zh_comm_vdec.h。
注意事项
- 通道必须已创建,否则会返回通道不存在的错误
ZH_ERR_VDEC_UNEXIST。 - 必须在调⽤ ZH_MPI_VDEC_StartRecvStream 之前设置,不⽀持动态切换属性。
- 切换通道属性之前必须先停⽌接收码流,再次启动接收码流⽅可⽣效。
- 解码器改变属性之后,再次启动接收码流会⾃动复位解码通道。
相关主题
ZH_MPI_VDEC_StartRecvStream
描述
解码器开始接收⽤⼾发送的码流。
语法
ZH_S32 ZH_MPI_VDEC_StartRecvStream(VDEC_CHN VdChn)
参数
| 参数名 | 数据类型 | 描述 | 输入/输出 |
|---|---|---|---|
| VdChn | VDEC_CHN | 视频解码通道号。 取值范围:[0, VDEC_MAX_CHN_NUM)。 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功。 |
| 非 0 | 失败,请参见 VDEC 错误码。 |
需求
头文件:zh_mpi_vdec.h,zh_comm_vdec.h。
注意事项
- 通道必须已创建,否则会返回通道不存在的错误
ZH_ERR_VDEC_UNEXIST。 - 启动接收码流之后,才能调⽤ ZH_MPI_VDEC_SendStream 发送码流成功。
- 重复调⽤启动接收码流接⼝时,返回成功。
相关主题
ZH_MPI_VDEC_StopRecvStream
描述