Gstreamer- QoS

服务质量

服务质量是关于测量和调整pipeline的实时性能。

实时性能总是相对于pipeline时钟进行度量,并且通常发生在sink与时钟同步缓冲区时。

测量会导致QOS事件,这些事件旨在调整一个或多个上游element中的数据速率。可进行两种调整:

  • 基于sinks的最新观察结果的短期“紧急”修正。
  • 基于sinks中观察到的趋势进行的长期速率修正。

应用程序也可以人为地在同步缓冲区之间引入延迟,这称为节流。例如,它可以用来降低帧率。

服务质量问题的来源

  • CPU负载高
  • 网络问题
  • 其他资源问题,如磁盘负载、内存瓶颈等。
  • 应用级限制

服务质量事件

QoS 事件由与时钟同步的element生成。它向上游传播并包含以下字段:

  • type:GST_TYPE_QOS_TYPE:QoS事件的类型,我们有以下几种类型,默认类型是GST_QOS_TYPE_UNDERFLOW:
    • GST_QOS_TYPE_OVERFLOW:element接收缓冲区的速度太快,处理速度无法跟上它们。上游应降低速率。
    • GST_QOS_TYPE_UNDERFLOW:element接收缓冲区的速度太慢,必须删除它们,因为它们太晚了。上游应提高处理率。
    • GST_QOS_TYPE_THROTTLE:应用程序要求在缓冲区之间添加额外的延迟,允许上游丢弃缓冲区
  • timestamp:G_TYPE_UINT64:生成 QoS 事件的缓冲区上的时间戳。这些时间戳在接收器中以总 running_time 表示,因此该值会不断增加。
  • jitter:G_TYPE_INT64:时间戳与当前时钟时间的差值。负值表示时间戳是准时的。正值表示时间戳的延迟时间。当及时接收缓冲区且没有启用节流(throttling)时,QoS类型字段设置为OVERFLOW。当节流时,抖动包含由应用程序添加的节流延迟,类型设置为THROTTLE。
  • proportion: G_TYPE_DOUBLE:理想速率相对于正常速率的长期预测以获得最佳质量

本文档的其余部分涉及如何在sink中计算这些值以及其他element如何使用这些值来调整其操作。

服务质量消息

每当element决定执行以下操作时,都会在总线上发布 QOS 消息:

  • 由于 QoS 原因删除缓冲区
  • 由于 QoS 原因(质量)改变其处理策略

应该期望创建和发布QoS消息是相当快的,不会对QoS问题造成显著影响。禁用此特性的选项也可以显示在element上。

此消息可以由执行时钟同步(live)的sink/src发布,也可以由执行 QoS 的上游element发布,因为从下游element (!live) 接收到 QOS 事件。

GST_MESSAGE_QOS 至少包含以下信息:

  • live:G_TYPE_BOOLEAN:如果 QoS 消息被live element(例如sink或live source)丢弃。如果 live 属性为 FALSE,则 QoS 消息是作为对非 live element中的 QoS 事件的响应而生成的。
  • running-time:G_TYPE_UINT64:生成 QoS 消息的缓冲区的运行时间。
  • stream-time: G_TYPE_UINT64: 生成 QoS 消息的缓冲区的 stream_time。
  • timestamp:G_TYPE_UINT64:生成 QoS 消息的缓冲区的时间戳。
  • duration:G_TYPE_UINT64:生成 QoS 消息的缓冲区的持续时间。
  • jitter:G_TYPE_INT64:运行时间与截止时间的差值。负值表示时间戳准时。正值表示时间戳的延迟时间。截止时间可以是实时 running_time 或估计的 running_time。
  • proportion: G_TYPE_DOUBLE:理想速率相对于正常速率的长期预测以获得最佳质量。
  • quality:G_TYPE_INT:element相关整数值,指定element的当前质量级别。默认最大质量为 1000000。
  • format:GST_TYPE_FORMAT 处理和删除字段的单位。Video sinks 和 video filters将使用 GST_FORMAT_BUFFERS(帧)。Audio sinks和 audio filters 可能会使用 GST_FORMAT_DEFAULT(采样)。
  • processed:G_TYPE_UINT64:自上次状态更改为 READY 或刷新操作以来正确处理的单元总数。
  • dropped:G_TYPE_UINT64:自上次状态更改为 READY 或刷新操作以来丢弃的单位总数。

running-time processed 字段可用于估计平均处理速率(视频的帧速率)。

element可能会在相关element或基类中记录的消息中添加其他字段。

收集统计数据

时间戳为 B1 的缓冲区在时间 T1 到达sink。然后缓冲区时间戳与时钟同步,从时钟产生抖动 J1 返回值。抖动 J1 简单地计算为

J1 = CT - B1

其中CT为条目(entry)到达sink时的时钟时间。这个值是在执行gst_clock_id_wait()时在时钟内部计算的。

如果jitter为负,则条目及时到达,等待时钟到达时间B1(也是 CT - J1 )后可以渲染。

然而,如果抖动是正的,则条目到达sink的时间太晚,因此应该被丢弃。 J1 是条目延迟的时间量。

任何到达sink的缓冲区都应在上游生成 QoS 事件。

使用抖动,我们可以计算缓冲区到达sink的时间:

  T1 = B1 + J1.                                (1)

同步后缓冲区离开sink的时间测量值为:

T2 = B1 + (J1 < 0 ? 0 : J1)                  (2)

对于及时到达的缓冲区 (J1 < 0),缓冲区在同步后离开,正好是 B1。 延迟缓冲区 (J1 >= 0) 在到达时离开sink,没有任何同步,即 T2 = T1 = B1 + J1。

使用之前的 T0 和新的 T1,我们可以计算上游生成时间戳为 B1 的缓冲区所花费的时间。

   PT1 = T1 - T0                                (3)

我们称 PT1 为生成时间戳为 B1 的缓冲区所需的处理时间。

此外,给定缓冲区 D1 的持续时间,上游element的当前数据速率 (DR1) 为:

      PT1   T1 - T0
DR1 = --- = -------                           (4)
      D1      D1

对于 0.0 < DR1 <= 1.0 的值,上游element的生产速度比实时的要快。如果 DR1 正好为 1.0,则element以完美的速度运行。

值 DR1 > 1.0 意味着上游element无法实时生成持续时间为 D1 的缓冲区。正是 DR1 告诉我们需要从上游获得多少加速才能重新获得实时性能。

未接收到足够数据的element称为下溢(underflowed)。

Element 测量

除了测量上游element的数据速率外,典型element还必须测量其自身的性能。当element接收到太多无法及时处理的数据时,全局pipeline性能问题确实也可能由element本身引起。然后称该element已溢出。

短期修正

时间戳和抖动用作上游element的短期校正信息。实际上,给定 (1) 中给出的到达时间 T1,我们可以确定时间戳 B2 < T1 的缓冲区在sink中为时已晚。

因此,在正抖动的情况下,我们可以发送带有时间戳 B1、抖动 J1 和 (4)中给出的比例的 QoS 事件。

这允许上游element不生成任何时间戳为 B2 < T1 的数据,其中element可以将 T1 导出为 B1 + J1。

这将有效地导致丢帧。

该element甚至可以更好地估计它应该输出的下一个有效时间戳。

事实上,给定element生成了一个时间戳为 B0 的缓冲区,该缓冲区及时到达sink,但随后收到一个 QoS 事件,说明 B1 到达 J1 太晚了。这意味着生成 B1 需要 (B1 + J1) - B0 = T1 - T0 = PT1,如(3)中给出的。鉴于缓冲区 B1 的持续时间为 D1,并假设生成新缓冲区 B2 将花费相同的处理时间,则对 B2 的更好估计将是:

 B2 = T1 + D2 * DR1

扩展后:

  B2 = (B1 + J1) + D2 * (B1 + J1 - B0)
                          --------------
                               D1

假设帧的持续时间相等,因此D1 = D2:

    B2 = (B1 + J1) + (B1 + J1 - B0)

    B2 =  2 * (B1 + J1) - B0

同样:

 B0 = B1 - D1

所以:

 B2 =  2 * (B1 + J1) - (B1 - D1)

它产生下一个缓冲区的更准确预测,如下所示:

  B2 =  B1 + 2 * J1 + D1                          (5)

长期修正

用于计算(5)短期预测的数据是基于单一观测。通过在多个数据量观测中创建运行平均值,可以获得更准确的数据量。

这个平均值不太容易受到突变的影响,因为突变只会在很短的时间内影响数据量。

在(4)中给出的观测值上计算运行平均值,并作为上行发送的QoS事件中的proportion 成员。

QoS 事件的接收者应按照比例成员的规定永久降低其数据速率。不这样做肯定会导致更多的丢帧和更差的 QoS。

节流

在节流模式下,缓冲区之间的时间距离保持在可配置的节流间隔内。这意味着实际上缓冲速率被限制为每个节流间隔 1 个缓冲。例如,这可用于限制帧速率。

当一个element被配置为节流模式(这通常只在sink上实现)时,它应该在上游产生 QoS 事件,并将抖动字段设置为节流间隔。这应该指示上游element在配置的节流间隔中跳过或删除剩余的缓冲区。

比例字段被设置为所需的期望减速,以获得期望的节流间隔。实现可以使用QoS Throttle type、proportion 和jitter成员来调优它们的实现。

服务质量策略

存在多种减少可能影响实时性能的处理延迟的策略。

  • 降低质量
  • 丢帧(减少 CPU/带宽使用)
  • 切换到较低的解码/编码质量(降低算法复杂度)
  • 切换到较低质量的源(减少网络使用)
  • 增加线程优先级
  • 切换到实时调度
  • 为关键pipeline部件分配更多 CPU 周期
  • 为关键pipeline部分分配更多 CPU

QoS 实施

下面简要概述如何在一系列不同类型的element中实现 QoS。

GstBaseSink

QoS的主要实现是GstBaseSink。它将计算以下值:

  • 流时间中处理时间 (5) 的上游运行平均值。
  • 缓冲持续时间的运行平均值。
  • 渲染时间的运行平均值(系统时间)
  • 渲染/丢弃的缓冲区

处理时间和平均缓冲持续时间将用于计算比例。

将系统时间中的处理时间与渲染时间进行比较,以确定大部分时间是花费在上游还是在sink本身中。该值用于决定上溢或下溢。

渲染和丢弃的缓冲区的数量用于查询sink上的统计信息。

对于sink接收到的每个缓冲区,将向上游发送具有最新值的 QoS 事件。

通常仅对视频pipeline启用 QoS。原因是音频丢失比视频帧丢失更令人不安。此外,视频通常比音频需要更多的处理。

通常,当缓冲区在video sink中被丢弃时有一个阈值。迟到 20 毫秒的帧仍然会被渲染,因为它对人眼来说是不明显的。

当一个(部分)缓冲区被丢弃时,一个QoS消息就被发布。

在节流模式下,sink向上游发送 QoS 事件,时间戳设置为最新缓冲区的 running_time,抖动设置为节流间隔。如果节流缓冲区延迟,则从节流间隔中减去延迟时间以保持所需的节流间隔。

GstBaseTransform

转换element可以完全跳过基于最近 QoS 事件的时间戳和抖动值的转换,因为这些缓冲区肯定会太晚到达。

对于任何中间element,该element应衡量其性能,以确定它是否对质量问题或任何上游/下游element负责。

一些转换可以降低其算法的复杂性。根据算法的不同,质量的变化可能会产生令人不安的视觉或听觉效果,应该避免。

当帧丢失或过滤器质量降低时,应发布 QoS 消息。 QOS 消息中的质量成员应反映过滤器的质量设置。

视频解码器

视频解码器可以根据所使用的编解码器决定不解码中间帧。一个典型的编解码器可以跳过b帧的解码来减少CPU的使用和帧率。

如果每帧都是独立解码的,则可以根据最新QoS事件的时间戳和抖动值跳过任何帧。此外,可以使用比例成员永久跳过帧。

建议根据预期的丢帧数(跳过 B 和/或 P 帧)调整 QoS 消息的质量字段。这取决于流中 B 和 P 帧的特定间距。如果质量控制会导致一半的帧被丢弃(典型的 B 帧跳过),则质量字段将设置为 1000000 * 1/2 = 500000。如果使用典型的I帧间距为18帧,则跳过B和P帧将导致17个丢弃帧或每18帧1个解码帧。质量成员应设置为 1000000 * 1/18 = 55555。

  • 跳过 B 帧:质量 = 500000
  • 跳过P/B帧:质量=55555(对于18帧的I帧间距)

分流器

除了当延迟 QoS 事件到达source pad时跳帧到下一个关键帧之外,解复用器通常不能对 QoS 做很多事情。

然而,分路器可以测量性能问题是上游还是下游,并将更新的 QoS 事件向上转发。

大多数具有多个输出pad的分流器可能需要组合所有pad上的 QoS 事件,并为上游element导出聚合的 QoS 事件。

源(Sources)

QoS 事件仅适用于基于推送的源,因为基于拉的源完全由另一个下游element控制。

源可以接收溢出或下溢事件,可用于切换到要求较低的源。在网络流的情况下,可以切换到较低或较高质量的流,或者可以使用或忽略额外的增强层。

当处理element推出的数据时间过长时,实时源会自动删除数据。

数据丢失时,实时源应发布 QoS 消息。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值