正文
如读取B3视频数据成功,合成之后还要备份B3的视频数据到指定位置,用于下次读取失败时复用上一帧;当B3主播停止连麦或较长时间卡顿后,还需要清除该数据缓存,避免引起歧义。
接下来拷贝B3、B2之间间隔部分,即A的视频数据到VidoeMixer中,1行。
循环5-9步过程,把B2、B2与B1间隔(A的1行)的视频数据拷贝到VidoeMixer中;再循环一次,把B1、B1下部(A的100行)的视频数据拷贝到VidoeMixer中。
使用上述流程,就完成了“A+B1+B2+B3”视频图像合成,合成结果已存储在VidoeMixer中。
生成“A+B1+B2+B3”视频图像后,UpServer需要把该视频数据流编码、打包,并发送给DeliveryServer,用于移动直播用户观看连麦视频。
A主播也需要观看其他B主播的视频,但是否使用“A+B1+B2+B3”的视频图像需要讨论,方法不同复杂度也不尽相同,具体将在A主播视频合成小节中说明。每个B主播也要显示A主播和其他B主播视频,个人认为使用“A+B1+B2+B3”的视频数据流就可以满足需求,具体细节在B主播视频合成小节中讲述。
A主播的视频数据处理分为发送、接收、显示三个部分,发送环节包括采集、编码、打包、发送,接收环节包括接收、按时间戳同步、解包、解码,显示环节包括本地视频图像和远端视频图像的合成及显示。
发送部分,由UpServer负责合成视频时,A主播需要把采集到的本地视频编码,并按指定封装格式打包,然后发送给UpServer,流程结构如图1所示。该部分与直播连麦关系不大,与单一主播直播时流程一致。
A主播接收部分,如图2所示,先接收UpServer推送的B主播视频数据,然后按时间戳同步读取、解包、解码。UpServer为A主播推送的视频数据内容可以有以下三种,若数据内容不同,合成显示部分的处理流程也不同。
图2 UpServer合成,A主播接收视频结构图
-
第一种,UpServer推送合成好的所有视频数据“A+B1+B2+B3”,与推送给普通观众的视频相同;
-
第二种,B1/B2/B3视频数据流独立推送,即UpServer直接转发各B主播的视频给A主播;
-
第三种,UpServer把B1/B2/B3视频按尺寸和显示位置合成为一路视频数据流,并把该路视频数据流推送给A主播。
下面分享A主播的合成显示部分,结合上面讲到的A主播接收的3种视频数据流形式,分别描述和比较它们的优劣。
先简单介绍个人不建议的形式,由UpServer按视频尺寸和显示位置把多个B主播的视频合成一路视频流,该方式的缺点是UpServer的压力显著增加。UpServer已为每个连麦进行了视频合成工作,再为A主播另外合成一路,在视频合成和编码发送方面,承担了更多的压力,本身Server端合成最大的瓶颈就是UpServer服务器的处理能力,故任何增加其负担的行为都应该被摒弃。同时,该方式下A主播自身的解码、合成流程也没有什么变化,CPU使用基本未减少,故不建议采用。
接着介绍UpServer推送合成好的所有视频“A+B1+B2+B3”给A主播的形式,此时UpServer仅增加了一路数据流推送,而没有更多的消耗,属于可以接受的方式。但该方式对A主播的图像合成压力比较大,为保证本地视频的实时性,底图的A视频图像必须使用刚刚采集的,所以合成图像前需要先抠图。具体步骤如下:
最后UpServer直接转发各B主播视频给A主播的方式,该方法的问题是推送三路数据流时,A主播的网络丢包(接收丢包)、时间戳同步控制更麻烦,但在解码、合成方面则问题不大,且UpServer服务器增加的压力也非常微小。具体实现流程可以参考第一节的视频图像合成介绍。
总结,在UpServer推送B主播视频数据时,比较后建议选择第一种或第二种方法,特别是UpServer直接转发各B主播视频给A主播的方式(第二种),原因是第一种推送合成好的所有视频“A+B1+B2+B3”给A主播的形式有个瑕疵——如B2主播连麦一段时间后停止了,UpServer和A主播收到该消息的时间是有先后差异的,会出现两种情况:
以上两种情况,是由于消息接收和处理时间差异造成的,故会非常短暂,仅属于瑕疵。使用UpServer直接转发各B主播视频给A主播的方式,由于每路数据流是独立的,故不存在该瑕疵。