Edit online

Frame manager

Frame manager 负责管理图像 buffer。Frame manager 内部通过两个链表来管理图像 buffer:empty list 和 render list。 其中,empty list 存放可以给解码输出使用的图像 buffer,render list 存放解码完成但还未显示的图像 buffer。 在运行过程中,正在显示的图像 buffer 和用于参考的图像 buffer 可能不在这两个 list 中。

  1. 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 不进入任何队列,等待解码器还参考帧;

      ../../images/frame_status1.png
      1. frame 状态迁移
  • frame manager 调用流程

    对于 JPEG、PNG 这类没有参考帧概念的编码格式,每一帧的状态是唯一的,解码后的数据帧可直接送 render list

    ../../images/frame_manager_jpeg1.png
    2. frame manager 调用流程(JPEG/PNG)

    但对于 H264 这类有参考帧的编码格式,解码后的视频帧可能既被显示占用也会被解码器用作参考帧,并且由于双向参考帧的存在, 视频帧需要重排序后才能送显示。 不同于 JPG,H264 解码库内部存在一个 delay list 用于为显示帧重排序。

    ../../images/frame_manager_2641.png
    3. frame manager 调用流程(H264)