Frame manager
Frame manager 负责管理图像 buffer。Frame manager 内部通过两个链表来管理图像 buffer:empty list 和 render list。 其中,empty list 存放可以给解码输出使用的图像 buffer,render list 存放解码完成但还未显示的图像 buffer。 在运行过程中,正在显示的图像 buffer 和用于参考的图像 buffer 可能不在这两个 list 中。
-
frame 状态迁移
初始化时,该模块申请指定个数的图像 buffer(个数可由外部配置),每个图像 buffer 的信息存放在内部数组中。 每个图像 buffer 有 4 种状态:
-
Decoding: 该帧正在被解码器使用(用于解码输出或作为参考帧)
-
wait_render: 该帧在 render list 中,等待显示
-
Rendering: 该帧正在被显示占用
-
IDLE: 该帧处于空闲状态(既没有被显示占用,也没有被解码器用作参考帧)
其状态转移如下图所示:
-
初始化时,所有图像 buffer 都在 empty list 中,此时处于 IDLE 状态;
-
解码模块从 empty list 链表头部获取一个空图像 buffer,此时 buffer 被解码模块占用,从 IDLE 状态变为 Decoding 状态;
-
解码完成后,解码模块还图像数据。此时分两种情况:
-
如果当前帧还未被显示,该帧加入 render list 链表尾部,从 Decoding 状态变为 wait render 状态;
-
该帧不再用做参考帧且已显示完成,此时该帧加入 empty list 链表尾部,由 Decoding 状态进入 IDLE 状态;
-
-
显示模块从 render list 链表头部取一帧图像,此时当前帧由 wait render 状态进入 Rendering 状态;
-
显示模块还图像 buffer,分两种情况:
-
如果当前帧不用于参考,此时由 Rendering 状态回到 IDLE 状态,该帧加入 empty list 链表尾部;
-
如果当前帧用于参考,此时由 Rendering 状态进入 Decoding 状态,该图像 buffer 不进入任何队列,等待解码器还参考帧;
图 1. frame 状态迁移
-
-
frame manager 调用流程
对于 JPEG、PNG 这类没有参考帧概念的编码格式,每一帧的状态是唯一的,解码后的数据帧可直接送 render list
图 2. frame manager 调用流程(JPEG/PNG) 但对于 H264 这类有参考帧的编码格式,解码后的视频帧可能既被显示占用也会被解码器用作参考帧,并且由于双向参考帧的存在, 视频帧需要重排序后才能送显示。 不同于 JPG,H264 解码库内部存在一个 delay list 用于为显示帧重排序。
图 3. frame manager 调用流程(H264)