H.264 模块
H.264 解码引擎包含了时序控制、熵解码、反量化、反变换、重构、帧内预测、帧间预测、deblock、后处理等模块,每个模块的处理的基本单元是 Macroblock (MB)。
下图呈现了 H.264 解码引擎的功能模块以及外部接口示意。
- 熵解码从外部 DRAM 读取原始码流,并分别解码出 MB 信息与块系数信息,其中 MB 信息会传递给帧内或帧间预测模块、Deblock 模块,块系数信息会传递给反量化模块。
- 反量化模块根据接收到的块系数以及反量化参数进行反量化,并将反量化后的结果传递给反变换模块。
- 反变换模块根据当前宏块信息选择正确的反变换方式进行反变换,将反变换后的残差系数传递给重构模块。
- 帧内和帧间模块根据收到的 MB 信息从参考帧中计算出当前块的预测值。
- 重构模块将收到的残差系数与预测值进行相加,得到当前的块的像素值。
- Deblock 模块根据当前的 MB 信息将当前块边沿像素值进行平滑滤波,输出最终的解码图像。
- 时序控制根据图像标准与 MB 类型对各个子模块进行调度,确保解码过程的正确性与高效率,为了提高解码效率,各子模块之间采取并行的方式进行。
解码辅助功能
- Startcode 检测
VE 引擎还具有 startcode 检索、错误检测等功能。当 VE 引擎检测到下一个非 slice startcode,VE 引擎会将检测到的 startcode 之前的所有数据送给解码器,并将码流读取指针停留在 startcode 之前。
- 错误处理
当所有数据解码完成后,无论当前帧解码是否完整,都视为解码完成。主 CPU 需要根据已经解码出的 MB 个数判断当前解码是否正确。当解码遇到错误时(超越规定的范围值),VE 引擎会停止解码,并将码流读取指针停留在当前位置。在发出解码完成中断通知的同时产生解码错误的中断,主 CPU 需要根据当前的错误情况进行容错处理。
- 写保护
VE 引擎还具有外部 SDRAM 写保护功能。主 CPU 可设置一个允许 VE 引擎可改写的 SDRAM 地址范围,当 VE 引擎尝试改写该地址范围之外的地址空间时,写保护功能将阻止对 SDRAM 的改写,并触发错误中断。
原始码流配置功能
- 主 CPU 将 VE 解码所需要的原始码流写入原始码流缓冲区 (Bitstream Buffer) ,以便 VE 解码引擎读取。
- VE 引擎启动解码之前,主 CPU 需要通知 VE
引擎该缓冲区的开始地址、结束地址、有效码流的偏移位置和有效码流长度等信息。
原始码流缓冲区是一个环形 Buffer,当 VE 引擎读取到结束地址后自动返回到开始地址继续读取,因此 VE 引擎启动解码之前需要知道上述信息。
当主 CPU 向原始码流缓冲区写入数据时,如果中间通过 Cache,必须确保数据真正写入 SDRAM 后才能启动 VE 解码。
- VE 引擎从外部 SDRAM 中的原始码流缓冲器中读取有效数据,并放入内部的小缓冲区。
熵解码基于该小缓冲区进行解码。尽管熵解码没有直接基于 SDRAM 中的码流缓冲区进行解码,VE 引擎会将有效消耗的数据位偏移量正确映射到码流缓冲区上。
- VE 引擎在读取过程中通过寄存器实时给出当前的读取偏移量,主 CPU 会根据 VE 读取的偏移量继续有效填写数据,避免数据溢出 (overflow)。
- VE 引擎完成当前解码。如果 VE 引擎将配置的有效数据解码消耗完成后,还无法完成当前解码,则表示当前解码数据不够,此时有两种情况:
- 如果主 CPU 已经配置 last 位,表示当前解码所需的数据都已经写入,则表示当前解码出错,VE 引擎将结束当前解码任务
- 如果主 CPU 没有配置 last 位,则表示当前解码所需的数据还只是部分写入,则 VE 引擎仅产生解码中断,保持当前所有状态,等待主 CPU 将下笔数据写入并启动 VE 引擎,然后继续当前的解码任务。
为了保证数据读取的高效率以及降低数据读取延迟 (latency) 的敏感度,VE 引擎内部还有一个小的缓冲区:
H.264 文件解码流程
H264 视频文件解码包括文件解析、视频原始码流分离、视频序列头数据解析、视频帧/场头数据解析、视频 slice 头数据解析、MB 数据解析与解码等过程。
VE 引擎仅仅对运算量要求比较大的 Slice 级以及 MB 级数据进行处理,对于 Slice 和/ 或 MB 之上的数据处理仍然需要主 CPU 进行处理。
H.264 格式启动一次解码仅完成一个 slice 数据解码,一个 slice 可以是完整的一帧图像,也可以是部分图像。H.264 格式解码流程如下: