前言:
gstreamer 提供了 multiqueue 用来同步多路数据。element 包含多个 queue,每个 queue 都可以自定义容量和阈值等一系列信息,通过这些信息,multiqueue 可以实现对每个 queue 的单独控制,这种控制包括但不限于 是否从上游拉数据,是否把数据推给下游 等等。
在多媒体领域里,常常用在 demuxer 之后,用来确保送给 audio 和 video decoder 的数据不会存在过大的 pts 时间差,变相提供一种偏软的音画同步机制。
官网:
机制:
机制1) 写入数据时,超过阈值会阻塞写入线程,知道有可用空间以供写入
原文:
Data is queued until one of the limits specified by the max-size-buffers, max-size-bytes and/or max-size-time properties has been reached. Any attempt to push more buffers into the queue will block the pushing thread until more space becomes available. extra-size-buffers,extra-size-bytes and extra-size-time are currently unused.
这一点很重要,因为他会阻塞上游element里的写入线程,所以如果上游element的写入线程还在做其他什么工作,那么那些工作将会被阻塞。这很危险。
机制2) 上限阈值取最低原则,触发overrun
原文:
The default queue size limits are 5 buffers, 10MB of data, or two second worth of data, whichever is reached first. Note that the number of buffers will dynamically grow depending on the fill level of other queues.
The overrun signal is emitted when one of the queues is filled.
默认情况下阈值配置是 5个buffer/10M数据/2秒数据,这三者任何一个触及都会认为触及了阈值,也就是说这三个阈值是 或 的关系。触及阈值会触发 overrun 信号。代码表示为
if(queue0.currentBuffer >=5 || queue0.currentBytes >= 10M || queue0.currentDuration >= 2s
||queue1.currentBuffer >=5 || queue1.currentBytes >= 10M || queue1.currentDuration >= 2s)
{
signal(overrun)
}
机制3) 下限阈值全空原则,触发underrun
原文:
The underrun signal is emitted when all of the queues are empty.
当且仅当所有队列都为空的时候才会触发 underrun,代码表示为
if( queue0.isempty() && queue1.isempty())
{
signal(underrun)
}