[GStreamer] multiqueue

前言:

gstreamer 提供了 multiqueue 用来同步多路数据。element 包含多个 queue,每个 queue 都可以自定义容量和阈值等一系列信息,通过这些信息,multiqueue 可以实现对每个 queue 的单独控制,这种控制包括但不限于 是否从上游拉数据,是否把数据推给下游 等等。

在多媒体领域里,常常用在 demuxer 之后,用来确保送给 audio 和 video decoder 的数据不会存在过大的 pts 时间差,变相提供一种偏软的音画同步机制。




官网:

multiqueue




机制:

机制1) 写入数据时,超过阈值会阻塞写入线程,知道有可用空间以供写入

原文:

Data is queued until one of the limits specified by the max-size-buffersmax-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)
}

### GStreamer 中的 Queue 元素 Queue 是一种用于管理缓冲区的元素,在复杂的多媒体处理管线中起到至关重要的作用。当多个线程并行工作时,队列能够有效地协调不同组件之间的数据流动,防止生产者消费者问题的发生[^1]。 #### 创建和配置 Queue 元素 为了创建一个新的 `queue` 对象,可以在命令行工具 gst-launch 或编程接口中指定该名称作为 bin 的一部分: ```bash gst-launch-1.0 fakesrc num-buffers=10 ! queue max-size-buffers=5 leaky=no ! fakesink ``` 上述实例展示了如何设置最大缓存数量 (`max-size-buffers`) 并控制溢出行为(`leaky`)。这里设置了最多允许存储五个缓冲区;如果超过此限制,则会依据泄露模式决定丢弃旧的数据还是阻止新的输入进入队列[^2]。 #### 使用场景举例 在一个典型的音频播放器应用里,可能会遇到这样的情况:解码后的原始 PCM 数据需要被传递给声音硬件设备完成最终渲染过程。然而由于 CPU 负载波动等原因可能导致某些时刻生成速度高于消费速率,这时就可以通过插入适当大小的 queue 来缓解压力,确保整个流程平稳运行而不至于崩溃或卡顿[^3]。 另一个实际案例是在视频转码过程中加入 tee 分支节点之后连接两个不同的输出目的地之前放置 queues ,从而使得每条路径都能独立运作而互不影响[^4]。 ```python import gi gi.require_version('Gst', '1.0') from gi.repository import Gst def create_pipeline(): pipeline = Gst.Pipeline.new("test-pipe") source = Gst.ElementFactory.make("fakesrc", "source") queue = Gst.ElementFactory.make("queue", "queue-element") sink = Gst.ElementFactory.make("fakesink", "sink") if not (pipeline and source and queue and sink): print("Failed to create elements.") exit(-1) # Set properties on the queue element here as needed. pipeline.add(source, queue, sink) source.link(queue).link(sink) return pipeline if __name__ == "__main__": p = create_pipeline() p.set_state(Gst.State.PLAYING) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值