Gstreamer- 事件(Events)

事件

事件是与缓冲区数据流并行传递的对象,以通知element各种事件。

使用事件函数在pad上接收事件。一些事件应该与数据流交错,因此它们需要采用 STREAM_LOCK,而另一些则不需要。

存在不同类型的事件来实现各种功能。

  • GST_EVENT_FLUSH_START:数据将被丢弃
  • GST_EVENT_FLUSH_STOP:再次允许数据
  • GST_EVENT_CAPS:关于随后的缓冲区的格式信息
  • GST_EVENT_SEGMENT:关于随后的缓冲区的时序信息
  • GST_EVENT_TAG:关于流的元数据信息。
  • GST_EVENT_BUFFERSIZE:缓冲区大小要求。目前还没有使用。
  • GST_EVENT_SINK_MESSAGE:事件被接sink转化为消息
  • GST_EVENT_EOS:pad上不会出现更多数据。
  • GST_EVENT_QOS:流服务质量的通知
  • GST_EVENT_SEEK:应该定位到流的新位置
  • GST_EVENT_NAVIGATION:导航事件。
  • GST_EVENT_LATENCY:配置pipeline的延迟
  • GST_EVENT_STEP:步进事件
  • GST_EVENT_RECONFIGURE:流重新配置事件

源垫(source pad)

srcpad 上的 gst_pad_push_event() 将首先将粘性事件存储在粘性数组中,然后再将事件发送到peer pad。如果没有peer pad并且事件没有存储在粘性数组中,则返回 FALSE。

Flushing pads将拒绝事件并且不会存储粘性事件。

接收垫(sink pad)

在sinkpad 上调用 gst_pad_send_event() 将调用 pad 上的事件函数。如果事件函数返回成功,则粘滞事件存储在粘滞事件数组中,并将该事件标记为更新。

当pad 冲洗时,gst_pad_send_event() 函数立即返回 FALSE。

当下一个数据项被推送时,挂起的事件被首先推送。

这确保了永远不会为flushing pads调用事件函数,并且粘性数组仅包含事件函数返回成功的事件。

垫链接(pad link)

链接 pads 时,srcpad 粘性事件在与 sinkpad 事件不同时被标记为更新。下一次缓冲区推送会将事件推送到sink。

FLUSH_START/STOP

向下游和上游发送flush事件以清除pipeline中的任何挂起数据。当正常数据流被例如seek事件中断时,这可能需要使图像更具响应性。

Flushing 发生在两个阶段。

  1. source element将 FLUSH_START 事件发送到下游peer element。下游element开始拒绝来自上游element的缓冲区。它向下游进一步发送flush 事件,并尽快丢弃它持有的任何缓冲区并从链函数返回。这确保所有上游element都被取消阻塞。此事件与 STREAM_LOCK 不保持同步,可以在应用程序线程中完成。

  2. source element发送 FLUSH_STOP 事件以指示下游element可以再次接收缓冲区。下游element将flush 事件发送到其peer element。在此步骤之后,数据流继续。 FLUSH_STOP 调用与 STREAM_LOCK 保持同步,因此如果需要,链函数使用的任何数据都可以在这里安全地释放。任何未决的EOS事件也应该被丢弃。

flush 完成第二阶段后,数据再次在pipeline中流动,并且所有缓冲区都比刷新之前的缓冲区更新。

对于使用 pullrange 函数的element,它们以相同的方式将两个flush 事件发送到上游 pads,以确保 pullrange 函数解锁并清除上游element中的任何挂起缓冲区。

FLUSH_START 可以指示pipeline将新的 base_time 分配给element,以便将 running_time 重置为 0。(参见时钟和同步)。

流结束(EOS)

EOS 事件只能在sink上发送。它通常在source element完成发送数据时发出。此事件主要在流线程中发送,但也可以从应用程序线程中发送。

下游element应将 EOS 事件转发到其下游peer element。这样,事件最终将到达sink,然后sink应在PLAYING状态时在总线上发布 EOS 消息。

在向下游转发 EOS 事件之前,element可能希望flush其内部排队的数据。这种flush可以在与处理 EOS 事件的线程相同的线程中完成。

对于具有多个sinkpad的element,可能在转发事件之前等待所有pad上的EOS。

EOS 事件应始终与数据流交错,因此 GStreamer core将采用 STREAM_LOCK。

有时 EOS 事件是由另一个element而不是source element生成的,例如,demuxer element可以在source element之前生成 EOS 事件。这不是问题,demuxer 不会向上游element发送 EOS 事件,而是返回 GST_FLOW_EOS,导致source element停止发送数据。

在pad上发送 EOS 的element应停止在该pad上发送数据。为此,source element通常会 pause() 其任务。

默认情况下,GstBin在将EOS消息发送给它的父对象之前,会从它所有的sink中收集所有的EOS消息。

EOS 仅由处于 PLAYING 状态的sink element发布到总线上。如果在 PAUSED 状态下接收到 EOS 事件,它会进入等候队列直到element进入 PLAYING状态。

element上的 FLUSH_STOP 事件会刷新 EOS 状态和所有挂起(pending) EOS 消息。

段(SEGMENT)

segment 事件由element向下游发送,以指示以下缓冲区组在指定位置开始和结束。newsegment 事件还包含流的播放速度和使用的速率(the applied rate of the stream)。

由于流时间总是在start和seek之后被设置为0,所有下一个缓冲区的时间戳的0点必须使用SEGMENT事件通过pipeline传播。

在发送缓冲区之前,element必须发送 SEGMENT 事件。如果缓冲区之前没有 SEGMENT 事件,则element可以自由的拒绝缓冲区。

与时钟同步的element应存储 SEGMENT 开始和结束值,并在将其与流时间进行比较之前从缓冲区时间戳中减去开始值(请参阅时钟)。

允许element发送已经从时间戳中减去 SEGMENT 开始时间的缓冲区。如果它这样做,它需要向下游发送一个校正的SEGMENT ,即起始时间为0的segment。

SEGMENT 事件应在pipeline中尽快生成,通常由demuxer 或source生成。该事件在推送第一个缓冲区之前和seek之后,就在推送新缓冲区之前生成。

SEGMENT 事件应该从流线程发送并且应该与缓冲区序列化。

缓冲区应该在由newsegment 事件开始和停止值指示的范围内裁剪。sink必须丢弃时间戳超出指定段范围的缓冲区。

标签(tag)

当element在媒体文件中发现元数据tag时,tag事件被发送到下游。编码器可以使用此事件来调整其tagging 系统。tag与缓冲区序列化。

缓冲大小(BUFFERSIZE)

注意 此事件尚未实现。

element可以提议下游element的缓冲区大小。这通常由在多个source pad上生成数据的element完成,例如demuxers。

服务质量(QOS)

QOS或quality of service消息在element中生成以向上游element报告关于当前流的实时性能的质量。这通常由sink完成测量丢帧量。 (见qos)

(定位)seek

应用程序发出seek事件以配置流的播放范围。它从应用程序线程中调用并向上游传输。

seek事件包含执行seek后播放的新开始和停止位置。可以选择将停止位置保留为 -1 以继续播放到流的末尾。 seek 事件还包含流的新播放速率,1.0 是正常播放,2.0 倍速和负值表示向后播放。

seek通常会刷新图像以最小化查找后的延迟。此行为是通过在seek事件上使用 SEEK_FLUSH 标志来触发的。

seek事件通常从sink element开始,并从element到element向上游传播,直到到达可以执行seek的element。不允许任何中间element假设会发生对该位置的seek。如果需要,允许修改开始和停止时间。这种典型的情况是seek请求的是一个非时间的位置。

实际的seek是在应用程序线程中执行的,因此可以将成功或失败报告为seek事件的返回值。因此,在执行seek之前,element获取STREAM_LOCK,以便流线程和seek被序列化,这一点很重要。

使用 FLUSH 执行seek的一般流程如下:

  1. 解除阻塞流线程,它们可以在链函数中被阻塞。这是通过在所有 srcpad 上发送 FLUSH_START 或暂停流任务来完成的,具体取决于seek 的 FLUSH 标志。flush 将确保所有下游element解锁,并且该控制将返回到此element的chain/loop函数。在执行此操作之前我们不能锁定 STREAM_LOCK,因为它可能会导致死锁。

  2. 获取 STREAM_LOCK。这是没有问题的,因为 chain/loop 函数在步骤 1) 中被unlocked/paused。

  3. 执行seek。由于持有STREAM_LOCK,流线程将等待seek完成。最可能的情况是,流线程将暂停,因为peer element正在刷新。

  4. 向所有peer element发送 FLUSH_STOP 事件以再次允许流传输。

  5. 创建一个 SEGMENT 事件来通知新的缓冲区时间戳基准时间。此事件必须排队等待以便由流线程发送。

  6. 启动停止的任务并解锁 STREAM_LOCK,数据流将从新位置继续。

有关不同seek类型的更多信息可以在seek中找到。

导航 (NAVIGATION)

导航事件由sink element生成,以向导航事件的element发出信号,例如鼠标移动或按钮单击。导航事件向上游传播。

延迟(LATENCY)

延迟事件用于配置pipeline中的特定延迟。它包含具有所需延迟的单个 GstClockTime。延迟值由pipeline计算并在设置为 PLAYING 之前分配给所有sink element。sink 会将配置的延迟值添加到缓冲区的时间戳中,以延迟它们的渲染。 (另见延迟)。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值