服務品質
服務品質是關于測量和調整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 消息。