Hello World

日常工作中的设计:解耦和封装

2020-06-18
coderhuo

本文介绍日常工作中模块间解耦,并抽象封装的一个例子。

一、问题提出

在一个嵌入式设备中,视频相关业务流程如下,DSP采集编码后,生成H264数据,然后对H264数据分别进行MP4、RTP、PS封装,封装后形成的数据进入对应的缓存队列。缓存队列是DSP和APP共享的,DSP写入,APP读取。

业务层(APP层)的录像模块(包括循环录像、事件录像等)从mp4数据包缓存队列中读取数据进行存储,实时预览模块从RTP数据包缓存队列中读取数据发送给客户端,平台接入模块从PS数据包缓存队列中读取数据发送给平台。

优化前的业务框图

我们先停下来想想,这种业务流程存在哪些问题?

  1. 录像存储是设备的主动行为,所以开机就要进行MP4封装,这个没问题;但是,实时预览和平台接入都是被动行为,RTP、PS封装是一直工作还是有任务的时候再工作?
    • 如果一直工作,很多时候是在做无用功,白白浪费了资源;
    • 如果外界触发的时候再工作,需要在APP和DSP之间增加控制指令,增加了交互的复杂性。
  2. 如果业务扩展,需要增加一个视频流类型怎么办?比如,对接一个新的客户端,视频流是TS流,需要修改以下几点:
    • DSP层增加一个H264转TS的视频封装模块
    • 增加一个TS流的共享缓存队列
    • APP层增加TS业务处理流程
  3. 多个缓存队列,对内存资源是个挑战
  4. 录像、预览、平台接入等业务模块都是直接操作缓存队列,如果缓存队列的实现机制发生变化,缓存队列的所有使用者都需要修改。
  5. 我们不妨从团队分工协作的角度考虑一下(一般情况下DSP和APP是不同的团队),录像、预览、平台接入这些业务功能和DSP有关系吗?好像没有。那这些码流封装逻辑放在DSP会带来其他的好处吗,比如性能提升等?好像也没有。这样做只会导致业务的协作链特别长,带来的问题就是开发效率低,容易出问题,出了问题比较难定位

二、优化方案

下图是优化后的流程图,变更点如下(绿色方框中的为主要变更内容):

  1. MP4、RTP、PS等码流封装模块从DSP层上移到APP层
  2. DSP和APP之间只有一个共享的H264数据缓存队列
  3. 抽象出一个帧读取器对象,APP层的录像、预览、平台接入等模块不再直接操作缓存队列,而是通过帧读取器获取帧数据。

优化后的业务框图

那么,这样做的好处在哪里?

  1. MP4封装、RTP封装、PS封装等任务由业务层按需启停,现在控制方便
  2. 如果业务扩展,DSP层不需要参与,只需要APP层修改以下几点:
    • APP层增加一个H264转TS的视频封装模块
    • APP层增加TS业务处理流程
  3. DSP和APP之间只有一个共享缓存队列,节省了内存资源
  4. 帧读取器对象封装了缓存队列的操作流程,如果缓存队列的实现机制变更,只需修改帧读取器对象即可。(这里类似设计模式中的策略模式

  5. 从团队分工协作的角度考虑:
    • DSP只负责出H264数据流,APP层负责业务的多样性,二者都更加聚焦;
    • 类似业务扩展不再需要DSP参与,协作链变短了,开发效率变高,出问题的几率变小,出了问题也比较好定位

Comments

Content

我的公众号:coderhuo
我的公众号