动态视频流切换的处理策略

问题背景

动态视频流切换是指在视频播放过程中,将输入动态地从一个视频流切换到另一个视频流。具体场景包括:

  • 切换播放画质
  • 插播广告(有多个广告打包插播)
  • 电视剧连续播放
  • 多个点播节目拼接为虚拟直播频道
  • 用户切换播放节目

动态切换播放视频流,需要做到无缓冲、不闪黑屏,声音连续。

方案设计

因为存在插播,直观上需要通过树形结构来描述视频流的关系,但是这样做的复杂度很高,需要寻找简单的模型。

所以我们将流切换任务用线性链表结构来表示,对于插播,需要有两个切换任务:进入插播和退出插播。

流切换任务包含“切换目标流的URL”和“切换类型”。切换类型有下列5种:

  • 平滑切换(时间点接续,用户看到的内容连续)
  • 开始插播(可以递归插播)
  • 退出插播(退出一层插播,对应任务没有URL)
  • 直接切换(前后流没有关联)
  • 追加切换(在末尾接续播放)

使用线性链表结构是方案的关键,有了链表结构,我们可以很容易的实现任务的取消。要取消中间一部分任务,简单的列表删除就可以了。

流切换实现在视频解封装(demux)阶段,用一个MultipleDemuxer管理多个实际的demuxer。

增加一个切换任务,就创建一个新的具体的demuxer(退出插播除外),新的任务在切换前需要准备好(demuxer完成初始化,如mp4流已经获取到头部索引并完成解析),准备过程是异步的。提前准备可以消除切换引起的播放缓冲。

准备完成后,切换任务被顺序处理。根据不同的切换类型,切换处理是不一样的,下面具体分析。

1、平滑切换

平滑切换中,新老视频流需要满足时间戳一致,即同一个时间点对应在音视频内容是一样的(分辨率可以不同,广义分辨率包括视频宽高、颜色深度;音频采样率、声道数,采样深度);不需要编码同步帧位置一致。

根据当前播放流的播放位置,在新的流中寻找该位置的下一个同步帧(一般只需要处理视频,音频每一个帧都是同步帧),以同步帧的时间点(音视频取小者)为切换时间点,设置老流的截止位置。

当前流处理到截止位置时,执行切换,老的流被关闭丢弃。

2、开始插播

根据当前播放流的播放位置,计算下一个同步帧时间点,设置老流的截止位置。

当前流处理到截止位置时,执行切换,老的流不关闭,在插播栈中保存(push);退出插播时,从插播栈取出(pop)恢复处理。

3、退出插播

当前流处理结束后,从插播栈取出插播前的流,恢复处理。

4、直接切换

直接执行切换,老的流被关闭丢弃,新的流从头开始处理。

5、追加切换

当前流处理结束后,执行切换,老的流被丢弃,新的流从头开始处理。

-------------------------------------------------------------------------------------

流切换还需要decode阶段的配合处理,decode阶段需要根据demux阶段给出的切换提示,重新创建解码器。根据不同的切换类型,对老流的音视频数据也有不同的处理策略,比如decode前后有队列缓存,对于“直接切换”需要清空。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting Horse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值