Fuchsia.media

新增:7

通訊協定

ActivityReporter

定義於 fuchsia.media/activity_reporter.fidl

用於監控 AudioRenderer 和 AudioCapturer 使用活動的通訊協定。

WatchCaptureActivity

每當一組有效的 AudioCaptureUsages 發生變更時,系統就會通知用戶端。第一次呼叫時,會立即傳回。

已移除:31 已淘汰:26

要求

<EMPTY>

回應

名稱類型
active_usages vector<AudioCaptureUsage>:4

WatchCaptureActivity2

每當一組有效的 AudioCaptureUsages 發生變更時,系統就會通知用戶端。第一次呼叫時,會立即傳回。

要求

<EMPTY>

回應

名稱類型
payload ActivityReporter_WatchCaptureActivity2_Result

WatchRenderActivity

每當一組使用中的 AudioRenderUsage 有所變更時,系統就會通知用戶端。第一次呼叫時,會立即傳回。

已移除:31 已淘汰:26

要求

<EMPTY>

回應

名稱類型
active_usages vector<AudioRenderUsage>:5

WatchRenderActivity2

每當一組使用中的 AudioRenderUsage 有所變更時,系統就會通知用戶端。第一次呼叫時,會立即傳回。

要求

<EMPTY>

回應

名稱類型
payload ActivityReporter_WatchRenderActivity2_Result

音訊

定義於 fuchsia.media/audio.fidl

CreateAudioCapturer

建立 AudioCapturer,從目前的預設音訊輸入裝置擷取音訊,或根據傳遞給回送旗標的值,從目前的預設音訊輸出裝置回送音訊。

要求

名稱類型
audio_capturer_request server_end:AudioCapturer
loopback bool

CreateAudioRenderer

要求

名稱類型
audio_renderer_request server_end:AudioRenderer

AudioCapturer

定義於 fuchsia.media/audio_capturer.fidl

AudioCapturer

AudioCapturer 是從 fuchsia.media.Audio 的 CreateAudioCapturer 方法傳回的介面,用戶端可使用這個介面,從目前的預設音訊輸入裝置或目前的預設音訊輸出裝置擷取音訊,具體取決於建立期間傳遞的標記。

**支援格式**

請參閱下方的 (Get|Set)StreamType。根據預設,擷取的串流類型一開始會由 AudioCapturer 在建立時繫結的來源目前設定的串流類型決定。使用者可以使用 GetStreamType 擷取這種類型,也可以選擇呼叫 SetStreamType,將媒體重新取樣或轉換為所選類型。注意:只有在系統未執行時,才能設定串流類型,也就是說,沒有待處理的擷取區域 (使用 CaptureAt 指定),且系統目前未在「async」擷取模式下執行。

**緩衝區和記憶體管理**

在 AddPayloadBuffer 呼叫期間,音訊資料會擷取至使用者提供給 AudioCapturer 的共用記憶體緩衝區 (VMO)。請注意下列與酬載緩衝區管理相關的規定。

  • 必須先提供酬載緩衝區,才能開始任何擷取作業。在建立酬載緩衝區之前,任何嘗試啟動擷取 (透過 CaptureAt 或 StartAsyncCapture) 的行為都會發生錯誤。
  • 有任何擷取作業待處理時,不得變更酬載緩衝區。
  • 設定酬載緩衝區後,可能無法變更串流類型。
  • 酬載緩衝區必須是音訊影格大小的整數 (以位元組為單位)
  • 在「async」模式下執行時 (請參閱下文),酬載緩衝區的大小至少必須是 StartAsyncCapture 期間指定的 frames_per_packet 大小的兩倍。
  • 使用者提供的酬載緩衝區控制代碼必須可讀取、可寫入、可對應及可轉移。
  • 使用者應一律將酬載緩衝區視為唯讀。

**同步與非同步擷取模式**

AudioCapturer 介面可透過兩種互斥模式使用:同步和非同步。以下說明各個模式和其優缺點。

**同步模式**

根據預設,AudioCapturer 執行個體會以「同步」模式執行。只有在使用者使用 CaptureAt 方法提供至少一個要擷取的區域時,才會擷取資料。系統會按照接收順序填入以這種方式提供的區域,並透過 CaptureAt 方法的傳回值,以 StreamPackets 的形式傳回用戶端。如果 AudioCapturer 執行個體有要擷取的資料,但沒有地方可放置 (因為沒有更多待處理區域可填入),則產生的下一個酬載會透過在下一個產生的 StreamPacket 上設定 Discontinuity 旗標,指出其已溢位。同步模式不得與非同步模式搭配使用。如果系統仍有 CaptureAt 提供的區域等待填入,嘗試呼叫 StartAsyncCapture 會發生錯誤。

如果使用者先前曾提供要由 AudioCapturer 執行個體填入的區域,但希望回收這些區域,可以使用 DiscardAllPackets 方法。呼叫 DiscardAllPackets 方法會導致所有待處理區域傳回,但 StreamPacket 的 PTS 為 NO_TIMESTAMP。如要瞭解時間戳記和不連續標記,請參閱下方的「時間和溢位」一節。執行 DiscardAllPackets 作業後,系統會產生 OnEndOfStream 事件。雖然 AudioCapturer 在傳回已完成的區域後,絕不會覆寫酬載緩衝區的任何區域,但可能會覆寫部分填滿的緩衝區中未填滿的部分,而該緩衝區是因 DiscardAllPackets 作業而傳回。

非同步模式

在「async」模式下執行時,用戶端不需要明確提供共用緩衝區區域,供 AudioCapturer 執行個體填入。用戶端會呼叫 StartAsyncCapture,並提供回呼介面和每次回呼要擷取的影格數,進入「非同步」模式。在非同步模式下執行時,AudioCapturer 例項會識別要擷取至哪些酬載緩衝區區域、擷取指定數量的影格,然後使用 OnPacketCapture FIDL 事件,將這些影格做為 StreamPacket 傳送。使用者可以停止擷取,並使用 StopAsyncCapture 方法將 AudioCapturer 執行個體傳回「同步」模式。

嘗試執行下列任一作業都會視為錯誤。

  • 在未建立酬載緩衝區時,嘗試進入「async」擷取模式。
  • 指定每個酬載要擷取的影格數量,不允許在已建立的共用酬載緩衝區中,同時存在至少兩個連續擷取酬載。
  • 在 AudioCapturer 執行個體以「async」模式執行時,使用 CaptureAt 方法傳送要擷取的區域。
  • 在 AudioCapturer 執行個體以「async」模式執行時,嘗試呼叫 DiscardAllPackets。
  • 嘗試重新啟動「async」模式擷取,而不先停止。
  • 在停止過程中嘗試執行 SetGain 以外的任何作業。

與 StopAsyncCapture 作業同步

停止非同步擷取模式並返回同步擷取模式,需要一些時間。呼叫 StopAsyncCapture 後,使用者不得在 AudioCapturer 介面上呼叫 SetGain 以外的任何其他方法 (包括再次呼叫 StopAsyncCapture),直到停止作業完成為止。因此,使用者必須能夠與停止作業同步。系統提供兩種機制。

第一種是使用 StopAsyncCapture (而非 NoReply 變體)。當使用者的回呼被呼叫時,他們可以確定停止操作已完成,且 AudioCapturer 執行個體已返回同步操作模式。

第二種判斷停止作業是否完成的方法,是使用封包上的旗標。呼叫 StopAsyncCapture 後,這些封包會透過使用者提供的 AudioCapturerCallback 介面傳送。當系統要求停止時,任何部分填滿的封包都會傳回給使用者,且傳回的最終封包一律會設定串流結束標記 (kFlagsEos),表示這是序列中的最終影格。如果沒有部分填滿的封包可傳回,AudioCapturer 會合成一個沒有時間戳記的空白封包,並將偏移/長度設為零,以便傳送已設定串流結尾標記的封包。使用者在呼叫 stop 後看到串流結束標記,表示 AudioCapturer 已完成停止作業,並返回同步操作模式。

**時間點和餘額累計**

AudioCapturer 執行個體產生的所有媒體封包,都會在 PTS 欄位中填入音訊擷取時間,並以參考時鐘時間軸提供的時間戳記表示。注意:這個時間戳記實際上是擷取時間戳記,而非顯示時間戳記 (更像是 CTS 而非 PTS),代表基礎系統對第一個音訊影格擷取時間的最佳估計值,包括所有外部和硬體引入的緩衝延遲。因此,AudioCapturer 產生的所有時間戳記,都應預期為相對於串流參考時鐘時間軸上的「現在」過去的時間。

「所有項目都有明確時間戳記」規則的唯一例外狀況,是在同步模式下運作時捨棄提交的區域。捨棄的封包不含任何資料,但 FIDL 要求執行所有待處理的方法傳回值回呼。因此,系統會將區域傳回給使用者,但時間戳記會設為 NO_TIMESTAMP,酬載大小則會設為零。任何部分填入的酬載都會有有效的時間戳記,但酬載大小會小於原本要求的大小。最後一個捨棄的酬載 (如有) 後面會接著 OnEndOfStream 事件。

如果第二個封包中包含的第一個音訊影格,是在第一個封包中最後一個音訊影格之後,剛好一個標稱影格時間擷取,則 AudioCapturer 執行個體傳送的兩個 StreamPacket 為「連續」。如果這項關係不成立,第二個 StreamPacket 的 flags 欄位會設定 STREAM_PACKET_FLAG_DISCONTINUITY 位元。

雖然每個產生的 StreamPacket 都會提供明確的時間戳記,但如果使用者對時間有非常精確的要求,建議一律透過計算自上次不連續以來傳送的影格來推論時間,而不是直接使用原始擷取時間戳記。這是因為連續封包上寫入的明確時間戳記,可能會根據擷取時間軸參考時鐘的單位是否可被所選音訊影格速率整除,而產生少量四捨五入誤差。

使用者應一律預期 AudioCapturer 產生的第一個 StreamPacket 會設定不連續標記 (因為沒有前一個封包可連續)。同樣地,在 DiscardAllPackets 或 Stop/Start 週期後,第一個 StreamPacket 一律會不連續。之後,StreamPacket 只有在以下兩種情況下才會不連續:

  1. 使用者在同步模式下操作,且未及時提供要填入的區域。如果下一個連續資料框架在需要從來源緩衝區清除時尚未擷取,就會發生溢位,AudioCapturer 會將下一個擷取的區域標示為不連續。
  2. 使用者在非同步模式下操作,但發生內部錯誤,導致 AudioCapturer 執行個體無法連續擷取下一個音訊影格。這可能是系統負載過高或硬體錯誤,但一般來說,這種情況不應該發生。不過,在實際操作中,如果發生這種情況,下一個產生的封包會標記為不連續。

**同步與非同步的權衡**

使用者可自行選擇以同步或非同步模式運作,視使用者需求而定,每種選擇各有優缺點。

同步模式只需要一個 Zircon 管道,因此可以節省一些資源。此外,使用者可以完全控管緩衝區管理。使用者可以指定音訊擷取位置和順序。因此,如果使用者不需要持續擷取,可以輕鬆停止擷取,並在稍後重新啟動 (只要停止提供封包,然後在稍後恢復即可)。酬載的大小也不必一致,用戶端可以指定任何適當精細程度的酬載。

在同步模式下運作的主要缺點是,每個要擷取的封包都必須傳送兩則訊息。一個用於通知 AudioCapturer 要擷取至哪個例項,另一個用於通知使用者封包已擷取。這可能會增加負擔,並使用戶端設計變得複雜。

非同步模式的優點是只需要 1/2 的訊息,但在「非同步」模式下運作時,AudioCapturer 執行個體無法得知使用者是否及時處理傳送的 StreamPacket,也無法自動偵測溢位狀況。「async」模式的使用者應謹慎使用足夠大的緩衝區,確保能在 AudioCapturer 被迫覆寫資料前處理資料。

AddPayloadBuffer

將酬載緩衝區新增至與連線相關聯的目前緩衝區組合。StreamPacket 結構體會使用 StreamPacket.payload_buffer_id 欄位,依 ID 參照目前集合中的酬載緩衝區。

叫用這個方法時,ID 為 id 的緩衝區不得位於目前集合中,否則服務會關閉連線。

要求

名稱類型
id uint32
payload_buffer handle<vmo>

BindGainControl

繫結至這個 AudioCapturer 的增益控制項。

要求

名稱類型
gain_control_request server_end:fuchsia.media.audio/GainControl

CaptureAt

明確指定共用酬載緩衝區的區域,用於擷取音訊輸入。

要求

名稱類型
payload_buffer_id uint32
payload_offset uint32
frames uint32

回應

名稱類型
captured_packet StreamPacket

DiscardAllPackets

要求

<EMPTY>

回應

<EMPTY>

DiscardAllPacketsNoReply

要求

<EMPTY>

GetReferenceClock

擷取串流的參考時鐘。傳回的控制代碼將具有 READ、DUPLICATE 和 TRANSFER 權限,並參照 MONOTONIC 和 CONTINUOUS 的 zx::clock。

要求

<EMPTY>

回應

名稱類型
reference_clock handle<clock>

GetStreamType

取得目前設定的串流類型。注意:如果 AudioCapturer 剛建立,且尚未明確設定串流類型,這會擷取 AudioCapturer 建立時,AudioCapturer 繫結來源 (輸入或迴圈輸出) 的串流類型。即使這符合用戶端所需的格式,仍須呼叫 SetPcmStreamType。

要求

<EMPTY>

回應

名稱類型
stream_type StreamType

OnEndOfStream

表示串流已結束。

回應

<EMPTY>

OnPacketProduced

傳送服務產生的封包。用戶端處理完酬載記憶體後,必須呼叫 ReleasePacket 釋放酬載記憶體。

回應

名稱類型
packet StreamPacket

ReleasePacket

釋出與先前透過 OnPacketProduced 傳送的封包相關聯的酬載記憶體。

要求

名稱類型
packet StreamPacket

RemovePayloadBuffer

從與連線相關聯的目前緩衝區組合中移除酬載緩衝區。

叫用這個方法時,目前集合中必須存在 ID 為 id 的緩衝區,否則服務會關閉連線。

要求

名稱類型
id uint32

SetPcmStreamType

設定要傳送的串流類型。視需要重新格式化/重新取樣來源資料,以產生要求的串流類型。必須在建立酬載緩衝區前呼叫。

要求

名稱類型
stream_type AudioStreamType

SetReferenceClock

設定參考時鐘,控制這個擷取器的播放速率。如果輸入參數是有效的 zx::clock,則必須具備 READ、DUPLICATE、TRANSFER 權限,且參照的時鐘必須是 MONOTONIC 和 CONTINUOUS。如果傳遞的是無效時鐘 (例如未初始化的 zx::clock()),則表示串流會使用 AudioCore 產生的「彈性」時鐘,追蹤音訊裝置。

新增擷取器酬載緩衝區後,無法呼叫 SetReferenceClock。也無法再次呼叫 (即使在擷取前也一樣)。如果用戶端需要一開始為 CLOCK_MONOTONIC,但之後可能會有差異的參考時鐘,應建立單調時鐘的複製版本,並將其設為串流的參考時鐘,然後視需要調整速率。

要求

名稱類型
reference_clock handle<clock>?

SetUsage

設定擷取串流的用途。這項設定可即時變更,但傳輸中的封包可能會受到影響。根據預設,擷取器會以 FOREGROUND 用途建立。

已淘汰 :請使用 SetUsage2 和 AudioCaptureUsage2

要求

名稱類型
usage AudioCaptureUsage

SetUsage2

設定擷取串流的用途。這項設定可即時變更,但可能會影響傳輸中的封包。根據預設,擷取器會以 FOREGROUND 用途建立。

要求

名稱類型
usage AudioCaptureUsage2

StartAsyncCapture

將 AudioCapturer 設為「async」擷取模式,並開始產生封包,每個封包的影格數剛好為「frames_per_packet」。系統會使用 StreamSink 的 OnPacketProduced 事件,通知用戶端已產生封包。

要求

名稱類型
frames_per_packet uint32

StopAsyncCapture

停止在「async」擷取模式下擷取,並 (視需要) 傳送回呼,供用戶端在需要明確同步處理時使用。

要求

<EMPTY>

回應

<EMPTY>

StopAsyncCaptureNoReply

要求

<EMPTY>

AudioConsumer

定義於 fuchsia.media/audio_consumer.fidl

用於播放及控制音訊的介面。

BindVolumeControl

繫結至這個 AudioConsumer 音量控制項,以便控制和接收通知。

要求

名稱類型
volume_control_request server_end:fuchsia.media.audio/VolumeControl

CreateStreamSink

為具有指定屬性的消費者建立 StreamSink。

您可以使用這個方法取得多個串流接收器,但這些接收器應依序使用,而非同時使用。使用這個方法建立的第一個串流接收器,會做為傳入邏輯消費者的封包唯一來源,直到該串流接收器關閉,或在該接收器上呼叫 EndOfStream 方法為止。屆時,系統會使用第二個串流接收器,以此類推。

如果提供不支援的壓縮類型,stream_sink_request 要求會關閉,並顯示 ZX_ERR_INVALID_ARGS 的 epitaph 值。

要求

名稱類型
buffers vector<handle<vmo>>:16
stream_type AudioStreamType
compression Compression?
stream_sink_request server_end:StreamSink

OnEndOfStream

表示串流結束前的最後一個封包已算繪。

回應

<EMPTY>

SetRate

要求變更轉譯器的播放速率。1.0 表示正常播放。不支援負費率。更新後的狀態會反映新費率。任何新建立的 StreamSink 預設費率為 1.0。

要求

名稱類型
rate float32

開始

開始算繪,如 flags 所示。

media_time 表示與 reference_time 對應的封包時間戳記。通常是第一個要算繪的封包時間戳記。如果提供的封包沒有時間戳記,這個值應為 NO_TIMESTAMP。傳遞 NO_TIMESTAMP 的 media_time 值會選擇預設媒體時間,建立方式如下:1. 首次啟動時,預設媒體時間是傳送至串流接收器的第一個封包的時間戳記。2. 停止後繼續播放時,預設媒體時間是串流停止時的媒體時間。

reference_time 是應開始算繪的單調系統時間。如果是供應端驅動的來源,這必須是第一個封包傳送 (或將傳送) 的時間加上前置時間,且必須在 AudioConsumerStatus 指出的範圍內。如果是需求導向來源,用戶端必須確保在開始時間符合前置時間規定。如果為 reference_time 傳遞預設值 0,取用端會根據封包可用性、前置時間需求,以及是否指定 LOW_LATENCY,選擇開始時間。

實際開始時間會反映在更新後的狀態中。

要求

名稱類型
flags AudioConsumerStartFlags
reference_time zx/Time
media_time int64

停止

呼叫這個方法後,系統會盡快停止算繪。實際停止時間會反映在更新後的狀態中。

要求

<EMPTY>

WatchStatus

使用長 GET 模式取得消費者的目前狀態。當狀態變更時,消費者會回應這個方法,一開始是根據初始狀態值,之後則是根據先前報告的狀態值。

要求

<EMPTY>

回應

名稱類型
status AudioConsumerStatus

AudioCore

定義於 fuchsia.media/audio_core.fidl

BindUsageVolumeControl

繫結至指定用途的音量控制通訊協定。

已淘汰 - 請使用 BindUsageVolumeControl2 和 AudioRenderUsage2

要求

名稱類型
usage Usage
volume_control server_end:fuchsia.media.audio/VolumeControl

BindUsageVolumeControl2

繫結至指定用途的音量控制通訊協定。

要求

名稱類型
usage Usage2
volume_control server_end:fuchsia.media.audio/VolumeControl

CreateAudioCapturer

建立 AudioCapturer,從目前的預設音訊輸入裝置擷取音訊,或根據傳遞給回送旗標的值,從目前的預設音訊輸出裝置回送音訊。

要求

名稱類型
loopback bool
audio_in_request server_end:AudioCapturer

CreateAudioCapturerWithConfiguration

根據指定需求建立 AudioCapturer。

pcm_stream_type 會設定要傳送的串流類型。如有需要,系統會重新格式化/重新取樣來源資料,以產生要求的串流類型。

Fuchsia 會使用 usage 做出使用者體驗相關決策。詳情請參閱 AudioCaptureUsage。

configuration 必須初始化為變化版本,否則無法建立擷取器。

要求

名稱類型
stream_type AudioStreamType
configuration AudioCapturerConfiguration
audio_capturer_request server_end:AudioCapturer

CreateAudioRenderer

建立 AudioRenderer,將音訊輸出至預設裝置。

要求

名稱類型
audio_out_request server_end:AudioRenderer

GetDbFromVolume

查詢特定 usage 的分貝值,該值會對應到音量百分比 [0, 1]。這與 BindUsageVolumeControl 的 VolumeControl 使用的對應關係相同。

已淘汰 :請使用 GetDbFromVolume2 和 AudioRenderUsage2

要求

名稱類型
usage Usage
volume float32

回應

名稱類型
gain_db float32

GetDbFromVolume2

查詢特定 usage 的分貝值,該值會對應到音量百分比 [0, 1]。這與 BindUsageVolumeControl 的 VolumeControl 使用的對應關係相同。

要求

名稱類型
usage Usage2
volume float32

回應

名稱類型
payload AudioCore_GetDbFromVolume2_Result

GetVolumeFromDb

查詢對應至特定 usage 的 gain_db 值的音量百分比 [0, 1]。這與 BindUsageVolumeControl 的 VolumeControl 使用的對應關係相同。

已淘汰 :請使用 GetVolumeFromDb2 和 AudioRenderUsage2

要求

名稱類型
usage Usage
gain_db float32

回應

名稱類型
volume float32

GetVolumeFromDb2

查詢對應至特定 usage 的 gain_db 值的音量百分比 [0, 1]。這與 BindUsageVolumeControl 的 VolumeControl 使用的對應關係相同。

要求

名稱類型
usage Usage2
gain_db float32

回應

名稱類型
payload AudioCore_GetVolumeFromDb2_Result

LoadDefaults

重新載入平台政策設定。如果平台未提供設定,則會改用預設設定。

要求

<EMPTY>

ResetInteractions

重新初始化目前控管 audio_core 中串流互動的一組規則。預設行為是「NONE」。

要求

<EMPTY>

SetCaptureUsageGain

設定這個擷取用途的增益。根據預設,所有擷取用途都會設為 Unity (0 db)。

已淘汰 :請改用 SetCaptureUsageGain2 和 AudioCaptureUsage2

要求

名稱類型
usage AudioCaptureUsage
gain_db float32

SetCaptureUsageGain2

設定這個擷取用途的增益。根據預設,所有擷取用途都會設為 Unity (0 db)。

要求

名稱類型
usage AudioCaptureUsage2
gain_db float32

SetInteraction

設定 audio_core 如何同時處理多個有效串流的互動。如果用途 active 的串流正在處理音訊,而用途 affected 的串流也正在處理音訊,則指定的行為會套用至用途 affected 的串流。

已淘汰 :請改用 SetInteraction2 和 AudioRenderUsage2

要求

名稱類型
active Usage
affected Usage
behavior Behavior

SetInteraction2

設定 audio_core 如何同時處理多個有效串流的互動。如果用途 active 的串流正在處理音訊,而用途 affected 的串流也正在處理音訊,則指定的行為會套用至用途 affected 的串流。

要求

名稱類型
active Usage2
affected Usage2
behavior Behavior

SetRenderUsageGain

設定這個轉譯用途的增益。根據預設,所有轉譯用途都會設為 Unity (0 db)。

已淘汰 :請改用 SetRenderUsageGain2 和 AudioRenderUsage2

要求

名稱類型
usage AudioRenderUsage
gain_db float32

SetRenderUsageGain2

設定這個轉譯用途的增益。根據預設,所有轉譯用途都會設為 Unity (0 db)。

要求

名稱類型
usage AudioRenderUsage2
gain_db float32

AudioDeviceEnumerator

定義於 fuchsia.media/audio_device_enumerator.fidl

AddDeviceByChannel

淘汰

StreamConfig 已不再支援,請改用音訊複合,詳情請參閱音訊驅動程式架構

已淘汰

要求

名稱類型
device_name string:256
is_input bool
channel client_end:fuchsia.hardware.audio/StreamConfig

GetDeviceGain

增益/靜音/AGC 控制

請注意,每項作業都需要 device_token,才能指定正確的輸入/輸出。

Get 指令會傳回回報收益的裝置 device_token,如果要求的 device_token 無效,或裝置在 Get 指令處理前已從系統中移除,則會傳回 ZX_KOID_INVALID。

如果設定指令的裝置權杖無效,系統會忽略該指令,不會執行任何動作。此外,使用者不必在每次通話時,控制音訊裝置的所有增益設定。只有在 set_flags 參數中設定對應旗標的設定會受到影響。舉例來說,傳遞 SetAudioGainFlag_MuteValid 會導致 SetDeviceGain 呼叫只關注 gain_info 結構中的靜音設定,而傳遞 (SetAudioGainFlag_GainValid | SetAudioGainFlag_MuteValid) 則會導致靜音和增益狀態同時變更。

要求

名稱類型
device_token uint64

回應

名稱類型
device_token uint64
gain_info AudioGainInfo

GetDevices

取得目前使用中的音訊裝置清單。

要求

<EMPTY>

回應

名稱類型
devices vector<AudioDeviceInfo>

OnDefaultDeviceChanged

已淘汰

回應

名稱類型
old_default_token uint64
new_default_token uint64

OnDeviceAdded

新增或移除裝置,或裝置屬性變更時傳送的事件。

回應

名稱類型
device AudioDeviceInfo

OnDeviceGainChanged

回應

名稱類型
device_token uint64
gain_info AudioGainInfo

OnDeviceRemoved

回應

名稱類型
device_token uint64

SetDeviceGain

要求

名稱類型
device_token uint64
gain_info AudioGainInfo
valid_flags AudioGainValidFlags

AudioRenderer

定義於 fuchsia.media/audio_renderer.fidl

AudioRenderer 隨時可能處於兩種狀態之一:可設定或可操作。只要有封包排入佇列等待轉譯,轉譯器就會視為運作中;否則,轉譯器會處於「可設定」狀態。AudioRenderer 進入運作狀態後,就無法呼叫「設定」方法,否則音訊服務會中斷用戶端的連線。以下是設定方法:AddPayloadBuffer、SetPcmStreamType、SetStreamType、SetPtsUnits、SetPtsContinuityThreshold。

如果必須重新設定 AudioRenderer,用戶端必須確保在呼叫這些「設定」方法時,沒有任何封包仍在佇列中。因此,最佳做法是在重新設定轉譯器之前,先在 AudioRenderer 上呼叫 DiscardAllPackets (最好在 DiscardAllPackets 之前呼叫 Stop)。

AddPayloadBuffer

將酬載緩衝區新增至與連線相關聯的目前緩衝區組合。StreamPacket 結構體會使用 StreamPacket.payload_buffer_id 欄位,依 ID 參照目前集合中的酬載緩衝區。

叫用這個方法時,ID 為 id 的緩衝區不得位於目前集合中,否則服務會關閉連線。

要求

名稱類型
id uint32
payload_buffer handle<vmo>

BindGainControl

繫結至這個 AudioRenderer 的增益控制項。

要求

名稱類型
gain_control_request server_end:fuchsia.media.audio/GainControl

DiscardAllPackets

捨棄先前透過 SendPacket 或 SendPacketNoReply 傳送且尚未釋出的封包。所有封包都釋出後,系統就會傳送回應。

要求

<EMPTY>

回應

<EMPTY>

DiscardAllPacketsNoReply

捨棄先前透過 SendPacket 或 SendPacketNoReply 傳送且尚未釋出的封包。

要求

<EMPTY>

EnableMinLeadTimeEvents

啟用或停用通知,以便在這個 AudioRenderer 的最小時鐘前置時間 (以奈秒為單位) 變更時收到通知。呼叫這個方法並將「enabled」設為 true,會立即觸發 OnMinLeadTimeChanged 事件,並提供 AudioRenderer 目前的最短前置時間。如果值有所變更,系統會引發 OnMinLeadTimeChanged 事件,並提供新值。這種行為會持續到使用者呼叫 EnableMinLeadTimeEvents(false) 為止。

時鐘前置時間下限是指封包必須在參考時鐘的「現在」時間之前抵達的時間 (相對於播放時鐘轉換),混音器才能混合封包。例如...

  • 假設封包 X 的 PTS 為 P(X)
  • 假設將 PTS 轉換為 RefClock 的函式為 R(p) (這個函式是由對 Play(...) 的呼叫決定)
  • 假設最短前置時間為 MLT

如果 R(P(X)) < RefClock.Now() + MLT 則封包延遲,且必須略過封包的部分 (或全部) 酬載,才能在排定的時間顯示封包。

min_lead_time_nsec = 0 是特殊值,表示 AudioRenderer 尚未轉送至輸出裝置。如果在 AudioRenderer 轉送前呼叫 Play,系統會捨棄所有播放的封包。客戶應等到 min_lead_time_nsec > 0,再呼叫 Play。

要求

名稱類型
enabled bool

EndOfStream

表示直播已結束。這個方法的精確語意由繼承介面決定。

要求

<EMPTY>

GetMinLeadTime

雖然可以在 SetPcmStreamType 之前呼叫 GetMinLeadTime,但這麼做沒有太大意義。這是因為前置時間是格式/速率的函式,因此前置時間會在 SetPcmStreamType 之後重新計算。如果在 SetPcmStreamType 之前啟用最短前置時間事件 (使用 EnableMinLeadTimeEvents(true)),系統會產生事件來回應 SetPcmStreamType。

要求

<EMPTY>

回應

名稱類型
min_lead_time_nsec int64

GetReferenceClock

擷取串流的參考時鐘。傳回的控制代碼將具有 READ、DUPLICATE 和 TRANSFER 權限,並參照 MONOTONIC 和 CONTINUOUS 的 zx::clock。

要求

<EMPTY>

回應

名稱類型
reference_clock handle<clock>

OnMinLeadTimeChanged

回應

名稱類型
min_lead_time_nsec int64

暫停

立即將 AudioRenderer 設為暫停狀態,然後回報媒體與參考時間軸之間的關係 (如有要求)。

如果 AudioRenderer 在呼叫時已處於暫停狀態,系統會傳回先前建立的時間軸值 (如有要求)。

要求

<EMPTY>

回應

名稱類型
reference_time int64
media_time int64

PauseNoReply

要求

<EMPTY>

播放

立即將 AudioRenderer 設為播放狀態。使用呼叫端提供的特定值 (如未指定,則使用預設值),開始推進媒體時間軸。在選用的回呼中,傳回最終使用的時間戳記值,這些值會設定媒體和參考時間軸之間的持續關係 (即如何在簡報時間戳記的網域和本機系統時間的領域之間進行轉譯)。

本機系統時間以奈秒為單位;media_time 則以使用者在 SetPtsUnits 函式中定義的單位為準,如果未呼叫 SetPtsUnits,則以奈秒為單位。

將 AudioRenderer 設為播放狀態,會在 1) 使用者為這個特定 AudioRenderer 定義的媒體 (或簡報) 時間軸,以及 2) 實際系統參考時間軸之間建立關係。為了說明如何在時間軸之間轉譯,Play() 回呼會在每個時間網域中提供等效的時間戳記。第一個值 ('reference_time') 是以這個轉譯器的參考時鐘表示;第二個值 ('media_time') 則是與該本機時間完全對應的媒體時間。換句話說,音訊串流中「media_time」的影格應根據參考時鐘在「reference_time」顯示。

注意:呼叫這個 API 時,media_time 會立即開始推進。呼叫端有可能 (雖然不常見) 指定很久以前或很久以後的系統時間。這項資訊和指定的媒體時間,只是用來判斷哪個媒體時間對應到「現在」,然後將「該」媒體時間與已提交封包的呈現時間戳記交集,判斷接下來應呈現哪些媒體影格。

使用者可以利用對應的 reference_time 和 media_time 值,將任意時間值從一個時間軸轉換到另一個時間軸。呼叫 SetPtsUnits(pts_per_sec_numerator, pts_per_sec_denominator) 並取得 Play 的「ref_start」和「media_start」值後,對於任何「ref_time」:

media_time = ( (ref_time - ref_start) / 1e9 * (pts_per_sec_numerator / pts_per_sec_denominator) ) + media_start

相反地,對於任何顯示時間戳記「media_time」:

ref_time = ( (media_time - media_start) * (pts_per_sec_denominator / pts_per_sec_numerator) * 1e9 ) + ref_start

使用者可以視用途選擇不指定其中一個或兩個時間戳記。如要省略時間戳記,請提供特殊值「NO_TIMESTAMP」。AudioRenderer 會使用下列規則,自動推論任何省略的時間戳記值:

參考時間 如果省略「reference_time」,AudioRenderer 會根據目前繫結至這個 AudioRenderer 的輸出裝置最短前置時間,選取「安全」的參考時間開始播放。舉例來說,如果 AudioRenderer 繫結至內部音訊輸出,且需要至少 3 毫秒的前置時間,而 HDMI 輸出需要至少 75 毫秒的前置時間,則 AudioRenderer 可能會 (如果省略「reference_time」) 選取從現在起 80 毫秒的參考時間。

媒體時間 如果省略 media_time,AudioRenderer 會選取兩個值之一。

  • 如果 AudioRenderer 從暫停狀態恢復,且封包在暫停後未遭捨棄,AudioRenderer 會使用與播放暫停時對應的 media_time。
  • 如果 AudioRenderer 在啟動或「捨棄封包」作業後首次進入播放狀態,初始 media_time 會設為待處理封包佇列中第一個酬載的 PTS。如果待處理佇列為空,初始 media_time 會設為零。

傳回值 收到要求時,AudioRenderer 會傳回在播放呼叫的傳回值中選取及使用的「reference_time」和「media_time」(無論是否明確指定)。

範例

  1. 使用者已使用 SendPacket 將部分音訊排入佇列,並希望盡快開始播放。使用者可以呼叫 Play,而不提供明確的時間戳記 -- Play(NO_TIMESTAMP, NO_TIMESTAMP)。

  2. 使用者已使用 SendPacket 將部分音訊排入佇列,並希望在指定的「reference_time」開始播放,與其他媒體串流同步,無論是最初或捨棄封包後。使用者會呼叫 Play(reference_time, NO_TIMESTAMP)。

  3. 使用者已使用 SendPacket 將部分音訊排入佇列。其中第一個封包的 PTS 為零,使用者希望盡快開始播放,但希望略過 PTS 0 和 PTS「media_time」之間的所有音訊內容。使用者會呼叫 Play(NO_TIMESTAMP, media_time)。

  4. 使用者已使用 SendPacket 將部分音訊排入佇列,並想在其他裝置上與另一個播放器同步播放這項媒體。分散式播放器群組的協調者會向每位播放器傳送明確訊息,指示他們在 PTS「media_time」和時間 (根據群組的共用參考時鐘)「reference_time」開始播放音訊。使用者會呼叫 Play(reference_time, media_time)。

要求

名稱類型
reference_time int64
media_time int64

回應

名稱類型
reference_time int64
media_time int64

PlayNoReply

要求

名稱類型
reference_time int64
media_time int64

RemovePayloadBuffer

從與連線相關聯的目前緩衝區組合中移除酬載緩衝區。

叫用這個方法時,目前集合中必須存在 ID 為 id 的緩衝區,否則服務會關閉連線。

要求

名稱類型
id uint32

SendPacket

將封包傳送至服務。服務處理完相關聯的酬載記憶體後,就會傳送回應。

packet 必須對目前的緩衝區組合有效,否則服務會關閉連線。

要求

名稱類型
packet StreamPacket

回應

<EMPTY>

SendPacketNoReply

將封包傳送至服務。這個介面並未定義用戶端如何得知接收器何時完成相關聯的酬載記憶體。繼承介面必須定義該屬性。

packet 必須對目前的緩衝區組合有效,否則服務會關閉連線。

要求

名稱類型
packet StreamPacket

SetPcmStreamType

設定用戶端要傳送的串流類型。使用這個方法代表串流編碼為 AUDIO_ENCODING_LPCM。

必須在 Play 或 PlayNoReply 之前呼叫。呼叫 SetPcmStreamType 後,用戶端必須傳送 AddPayloadBuffer 要求,然後傳送各種 StreamSink 方法,例如 SendPacket/SendPacketNoReply。

要求

名稱類型
type AudioStreamType

SetPtsContinuityThreshold

設定使用者明確提供的 PTS 與預期 PTS (使用內插法決定) 之間的最大門檻 (以秒為單位)。超過這個門檻後,轉譯器就不會再將串流視為「連續」。

預設為半個 PTS「刻度」的間隔,使用目前定義的 PTS 單位。大多數使用者不需要變更這個值的預設設定。

範例:使用者正在播放容器中的 48KHz 音訊,該容器也包含影片,且需要與音訊同步。時間戳記由容器明確提供,並以毫秒為單位。這表示媒體時間軸的一個刻度 (1 毫秒) 剛好代表 48 個音訊影格。在這個情境中,應用程式會將音訊封包傳送至 AudioRenderer,每個封包都包含 470 個音訊影格,且每個封包都有明確的時間戳記,設定為最能代表播放時間的值 (根據這個媒體時鐘的解析度)。因此,從零開始,時間戳記會是…

[ 0, 10, 20, 29, 39, 49, 59, 69, 78, 88, ... ]

在這個範例中,如果嘗試使用顯示時間計算封包中音訊的起始影格編號,大多數情況下都會出錯。第一個時間戳記是正確的 (根據定義),但要經過 24 個封包,時間戳記和影格編號才會重新對齊 (第 24 個封包會從第 11280 個音訊影格開始,PTS 剛好是 235)。

如要修正這個問題,可以將串流的 PTS 連續性門檻 (以下簡稱 CT) 設為媒體時鐘單一刻度內所含影格數所需時間的 1/2,並無條件進位。在這個情境中,這會是 24.0 個音訊影格,或 500 微秒。如果封包的預期 PTS 落在明確提供的 PTS +/-CT 影格範圍內,系統會將其視為前一個音訊影格的延續。在這個範例中,呼叫「SetPtsContinuityThreshold(0.0005)」即可解決問題。

其他可能用途: 如果使用者明確排定音訊時間,且該時間與未設為參考時鐘的時鐘相關,則可使用這個值控制可接受的最大同步處理錯誤,避免發生不連續的情況。舉例來說,如果使用者根據復原的通用媒體時鐘排定音訊,且未將該時鐘發布為參考時鐘,並將 CT 設為 20 毫秒,則在 AudioRenderer 刻意插入呈現不連續性以考量錯誤之前,最多可累積 20 毫秒的漂移錯誤。

如果使用者需要處理的容器時間戳記可能比 +/- 1/2 PTS 刻度更不準確,可以將這個值設得更大。如果已知容器時間戳記的不準確程度,這應是最大值。如果無法做到,則可設為在明確遵守絕對時間戳記之前,可容忍的最大漂移誤差。最後,使用者可以將這個數字設為非常大的值 (例如 86400.0 秒),這樣就能有效忽略第一個時間戳記之後的「所有」時間戳記,進而將所有音訊視為與先前傳送的封包連續。相反地,如果使用者希望「一律」明確排定音訊封包,可以將 CT 指定為 0。

注意:明確指定高頻率 PTS 單位會相應降低預設連續性門檻。在內部,這個門檻會儲存為 1/8192 子影格的整數。預設門檻的計算方式如下: RoundUp((AudioFPS/PTSTicksPerSec) * 4096) / (AudioFPS * 8192) 因此,如果指定的 PTS 單位頻率大於影格率的 8192 倍 (或未呼叫 SetPtsUnits,接受預設 PTS 單位 1 奈秒),預設連續性門檻就會是零。

要求

名稱類型
threshold_seconds float32

SetPtsUnits

設定呈現 (媒體) 時間軸使用的單位。根據預設,PTS 單位為奈秒 (如同呼叫時分子為 1e9,分母為 1)。這個比率必須介於 1/60 (每分鐘 1 個 tick) 和 1e9/1 (每 tick 1 奈秒) 之間。

要求

名稱類型
tick_per_second_numerator uint32
tick_per_second_denominator uint32

SetReferenceClock

設定參考時鐘,控制這個轉譯器的播放速率。如果輸入參數是有效的 zx::clock,則必須具備 READ、DUPLICATE、TRANSFER 權限,且參照的時鐘必須是 MONOTONIC 和 CONTINUOUS。如果傳遞的是無效時鐘 (例如未初始化的 zx::clock()),則表示串流會使用 AudioCore 產生的「彈性」時鐘,追蹤音訊裝置。

呼叫 SetPcmStreamType 後,就無法呼叫 SetReferenceClock。此外,也無法再次呼叫 (即使尚未設定轉譯器格式)。如果用戶端想要一個一開始為 CLOCK_MONOTONIC,但之後可能會發散的參考時鐘,應建立單調時鐘的複製版本,並將其設為串流的參考時鐘,然後視需要調整速率。

要求

名稱類型
reference_clock handle<clock>?

SetUsage

設定轉譯串流的用途。呼叫 SetPcmStreamType 後,可能無法呼叫這個方法。預設用量為 MEDIA。

已淘汰 :請使用 SetUsage2 和 AudioRenderUsage2

要求

名稱類型
usage AudioRenderUsage

SetUsage2

設定轉譯串流的用途。呼叫 SetPcmStreamType 後,可能無法呼叫這個方法。預設用量為 MEDIA。

要求

名稱類型
usage2 AudioRenderUsage2

ProfileProvider

定義於 fuchsia.media/profile_provider.fidl

RegisterHandlerWithCapacity

將執行緒註冊為媒體執行緒。這會通知媒體子系統,這個執行緒應套用較高的排程設定檔,以符合音訊或影片期限。

name 是系統排程角色的名稱,會套用至 thread_handle 指定的執行緒。不同產品可能會根據要求的角色,自訂基礎排程策略。建議排定的間隔為 period。如果執行緒沒有偏好的排程間隔,period 可能為零。capacity 是執行緒需要執行的排程間隔比例,以達到良好效能或符合 period 定義的排程期限。如果工作負載沒有固定的執行階段需求,capacity 可能為零。請注意,capacity 應根據執行緒在每個週期所需的最差執行階段,進行善意估算。如果要求過多容量,可能會遭到拒絕,或導致其他執行緒的效能降低,以符合資源限制。

容量、執行時間上限和週期之間的關係如下:

容量 = 執行階段上限 / 週期

其中:

0 <= 執行時間上限 <= 週期,且 0 <= 容量 <= 1

如果是異質系統,則應根據系統中效能最高的處理器來規劃 / 衡量容量。系統會自動調整有效容量,以因應較慢的處理器和作業點,並避免處理器和作業點過慢,無法滿足要求的排程參數 (前提是這些參數合理)。

傳回套用的週期和容量 (實際最大執行階段),其中任一值可能為零,表示不適用。

要求

名稱類型
thread_handle handle<thread>
name string:64
period zx/Duration
capacity float32

回應

名稱類型
period zx/Duration
capacity zx/Duration

RegisterMemoryRange

將記憶體範圍註冊為用於媒體處理。這會通知媒體子系統,這個記憶體應套用較高的記憶體設定檔,以符合音訊或影片期限。

name 是系統記憶體角色的名稱,要套用至 vmar_handle 提供的記憶體。不同產品可能會根據要求的角色,自訂基礎記憶體策略。

要求

名稱類型
vmar_handle handle<vmar>
name string:64

回應

<EMPTY>

UnregisterHandler

將執行緒的排程設定檔重設為預設值。

要求

名稱類型
thread_handle handle<thread>
name string:64

回應

<EMPTY>

UnregisterMemoryRange

重設記憶體範圍的記憶體分析器。

要求

名稱類型
vmar_handle handle<vmar>

回應

<EMPTY>

SessionAudioConsumerFactory

定義於 fuchsia.media/audio_consumer.fidl

用於建立繫結至工作階段的音訊取用者的介面。

CreateAudioConsumer

建立 AudioConsumer,這是用於播放音訊的介面,繫結至特定工作階段。session_id 是要轉譯音訊的媒體工作階段 ID。

要求

名稱類型
session_id uint64
audio_consumer_request server_end:AudioConsumer

SimpleStreamSink

定義於 fuchsia.media/stream.fidl

使用 StreamBufferSet 管理緩衝區的 StreamSink。

AddPayloadBuffer

將酬載緩衝區新增至與連線相關聯的目前緩衝區組合。StreamPacket 結構體會使用 StreamPacket.payload_buffer_id 欄位,依 ID 參照目前集合中的酬載緩衝區。

叫用這個方法時,ID 為 id 的緩衝區不得位於目前集合中,否則服務會關閉連線。

要求

名稱類型
id uint32
payload_buffer handle<vmo>

DiscardAllPackets

捨棄先前透過 SendPacket 或 SendPacketNoReply 傳送且尚未釋出的封包。所有封包都釋出後,系統就會傳送回應。

要求

<EMPTY>

回應

<EMPTY>

DiscardAllPacketsNoReply

捨棄先前透過 SendPacket 或 SendPacketNoReply 傳送且尚未釋出的封包。

要求

<EMPTY>

EndOfStream

表示直播已結束。這個方法的精確語意由繼承介面決定。

要求

<EMPTY>

RemovePayloadBuffer

從與連線相關聯的目前緩衝區組合中移除酬載緩衝區。

叫用這個方法時,目前集合中必須存在 ID 為 id 的緩衝區,否則服務會關閉連線。

要求

名稱類型
id uint32

SendPacket

將封包傳送至服務。服務處理完相關聯的酬載記憶體後,就會傳送回應。

packet 必須對目前的緩衝區組合有效,否則服務會關閉連線。

要求

名稱類型
packet StreamPacket

回應

<EMPTY>

SendPacketNoReply

將封包傳送至服務。這個介面並未定義用戶端如何得知接收器何時完成相關聯的酬載記憶體。繼承介面必須定義該屬性。

packet 必須對目前的緩衝區組合有效,否則服務會關閉連線。

要求

名稱類型
packet StreamPacket

StreamBufferSet

定義於 fuchsia.media/stream.fidl

管理串流的一組酬載緩衝區。這個介面通常會與 StreamSink 或 StreamSource 一起繼承,以便在用戶端和服務之間傳輸基本串流。

AddPayloadBuffer

將酬載緩衝區新增至與連線相關聯的目前緩衝區組合。StreamPacket 結構體會使用 StreamPacket.payload_buffer_id 欄位,依 ID 參照目前集合中的酬載緩衝區。

叫用這個方法時,ID 為 id 的緩衝區不得位於目前集合中,否則服務會關閉連線。

要求

名稱類型
id uint32
payload_buffer handle<vmo>

RemovePayloadBuffer

從與連線相關聯的目前緩衝區組合中移除酬載緩衝區。

叫用這個方法時,目前集合中必須存在 ID 為 id 的緩衝區,否則服務會關閉連線。

要求

名稱類型
id uint32

StreamProcessor

定義於 fuchsia.media/stream_processor.fidl

作業總覽:

  1. 建立
  • 透過 CodecFactory 建立 - 請參閱 CodecFactory
  • 透過 LicenseSession 建立 - 請參閱 LicenseSession
  1. 取得輸入限制
  • OnInputConstraints():串流處理器建立後不久,由串流處理器主動傳送。
  1. 提供輸入緩衝區 ()
  • SetInputBufferPartialSettings()
  • 或 AddBuffer (如果 StreamProcessor 透過 CodecFactory 回報支援動態緩衝區,在這種情況下,QueueInputFormatDetails 和 QueueInputEndOfStream 不需要事先呼叫 AddBuffer,但 QueueInputPacket 仍需要)。
  1. 提供輸入資料
  • QueueInputPacket() + OnFreeInputPacket(),直到所有輸入封包都重複處理完畢,
  1. 取得輸出限制和格式
  • OnOutputConstraints()
  • 即使 StreamProcessor 背後的基礎處理器基本上不需要任何輸入資料來判斷輸出限制,也必須等到用戶端傳送至少一則 QueueInput* 訊息後,才會傳送這則訊息。這種伺服器行為可防止用戶端在輸入內容傳送前,對顯示的輸出限制產生錯誤的依賴關係。* 用戶端必須容許此訊息在大量輸入資料傳送後才送達,包括透過 OnFreeInputPacket() 回收的大量輸入封包。 * 此訊息可能會在第一筆輸出資料前多次送達。
  1. 提供輸出緩衝區 * SetOutputBufferPartialSettings() / CompleteOutputBufferPartialSettings()
  2. 資料流程,可選用 EndOfStream * OnOutputPacket() / RecycleOutputPacket() / QueueInputPacket() / OnFreeInputPacket() / QueueInputEndOfStream() / OnOutputEndOfStream()

半信任 StreamProcessor 伺服器:軟體解碼器會在隔離環境中執行 (功能極少),以防解碼軟體有漏洞,可能遭人利用來接管 StreamProcessor 伺服器。與其他介面相比,使用解碼器和處理獨立安全性內容串流的串流處理器介面用戶端,更需要防範無效的伺服器行為,例如重複釋放 packet_index 和任何其他無效的伺服器行為。輸入單一安全性內容的壓縮資料後,請勿過度信任單一 StreamProcessor 執行個體,以免 StreamProcessor 伺服器曾接收到的任何緩衝區資料混淆。請改為建立個別的 StreamProcessor 執行個體,供安全性獨立的用戶端情境使用。雖然硬體解碼器的情況略有不同,且超出本段落的討論範圍,但用戶端應一律使用獨立的 StreamProcessor 執行個體,以確保用戶端內容的安全性。

本通訊協定方法採取的動作和事物狀態說明,是以串流處理器伺服器同步執行方法為前提,但實際上,如同 FIDL 介面的典型情況,訊息處理是非同步的。除非另有說明,否則所述狀態應視為用戶端觀點的狀態。從伺服器傳回的事件當然會以非同步方式傳送,而每個 StreamProcessor 執行個體處理多個串流的用戶端,則需要注意特定事件是來自目前串流,還是來自即將消失的舊串流。

Sync() 方法的主要用途是讓用戶端能有效防止系統同時分配新舊緩衝區,因為媒體緩衝區可能非常大。Sync() 方法會等到先前對 StreamProcessor 通訊協定的所有呼叫,在 StreamControl 排序網域中實際生效後,才傳送回應,藉此達成上述目的。如果用戶端可能大幅領先 StreamProcessor 伺服器 (例如連續要求建立大量串流),Sync() 也能用於等待串流處理器伺服器趕上。您也可以在偵錯期間使用這項功能,確保串流處理器伺服器未卡住。呼叫 Sync() 完全是選用性質,不一定要呼叫才能確保正確性,只有在需要避免資源使用重疊時才可能需要呼叫。

您可以將 StreamProcessor 執行個體重複用於其他串流,有時這樣做可以略過重新分配緩衝區的步驟。在某些情況下,這項功能非常實用,例如跳轉至新位置,在 StreamProcessor 介面中,這可能看起來像切換至新串流。

AddBuffer

新增先前透過 ParticipateInBufferAllocation 建立的緩衝區。

對於輸入緩衝區,用戶端可以在任何 AddBuffer 訊息之前傳送 QueueInputFormatDetails 或 QueueInputEndOfStream。必須先新增至少一個輸入緩衝區,才能傳送有效的 QueueInputPacket。大多數用戶端會希望繼續快速新增緩衝區,直到至少達到 buffer_count_for_server_current,以免轉碼器可能停滯,且通常會超過該數量,以維持管道順暢運作。第一個 QueueInputPacket 之後,可以新增第一個輸入緩衝區以外的輸入緩衝區。

即使 buffer_constraints_version_ordinal 是最新版本,如果緩衝區與目前的 buffer_constraints_version_ordinal 不一致 (根據 sysmem GetVmoInfo 提供的 StreamProcessor 限制),伺服器也不得關閉管道。伺服器必須改為傳送新的 OnOutputConstraints。這可簡化某些用戶端的極端案例,尤其是當用戶端無法可靠地偵測到,新取得的緩衝區是否確實是在 buffer_constraints_version_ordinal 變更後分配,或可能先前已快取。

用戶端可以隨時使用這則訊息,在同一個通訊埠和 buffer_lifetime_ordinal 中新增其他緩衝區。如果 buffer_lifetime_ordinal 不再是最新版本,系統會忽略訊息、捨棄緩衝區的控制代碼,並立即完成與相同緩衝區相關的任何後續 RemoveBuffer 訊息。

如果所有 AddBuffer 呼叫 (具有相同的 buffer_lifetime_ordinal) 新增的緩衝區總和超過 dynamic_buffers_input_max 或 dynamic_buffers_output_max,伺服器可能會關閉管道。如果新增過多緩衝區會導致效能降低或未經測試的行為,伺服器必須在這種情況下關閉管道。

切換至新的 buffer_lifetime_ordinal 會開始移除與舊 buffer_lifetime_ordinal 相關聯的緩衝區。不過,在移除作業完成前,轉碼器仍可照常使用這些緩衝區。另請參閱 RemoveBuffer,無論 RemoveBuffer 是否啟動移除作業 (包括不使用動態緩衝區時),都可用於偵測移除作業何時完成。

緩衝區會保留,直到移除作業完成。緩衝區會保持新增狀態,並可能多次重複使用。用戶端可以使用 RemoveBuffer 啟動 (和/或確認/隔離) 移除作業。轉碼器伺服器可以單方面啟動緩衝區移除作業;如果伺服器執行這項操作,則必須傳送新的 buffer_constraints_version_ordinal,並將 action_required 設為 true。其他一些用戶端啟動的訊息也可以開始移除緩衝區,例如 CloseCurrentStream 搭配 release_input_buffers 和/或 release_output_buffers。如果用戶端關閉 StreamProcessor client_end,或伺服器關閉 StreamProcessor server_end,緩衝區也會自動移除並釋出。

如果通訊埠上仍有任何緩衝區處於有效狀態,則不得混合使用 AddBuffer 和 SetInputBufferPartialSettings/SetOutputBufferPartialSettings。如要成功切換通訊埠模式,大多數用戶端會選擇直接建立新的 StreamProcessor 執行個體。如要確保這項操作可靠,請先確認通訊埠下新增至「目前」的所有緩衝區 (包括 buffer_lifetime_ordinal 較舊的緩衝區) 都已完成 RemoveBuffer 要求。只有在這種情況下,才能在同一個 StreamProcessor 下切換該通訊埠的模式。大多數用戶端只會使用其中一種方式新增緩衝區,而且不需要切換到另一種方式,尤其是在同一個 StreamProcessor 中。

如果用戶端可能「濫用」建立許多新的 buffer_lifetime_ordinal 值,而緩衝區在期間未實際使用,用戶端應考慮每隔幾個 buffer_lifetime_ordinal 啟動同步處理,以隔離舊 buffer_lifetime_ordinal 值的清除作業,並避免超過 16 個 buffer_lifetime_ordinal 值,以免同步處理完成。否則,如果新的 buffer_lifetime_ordinal 累積過多,導致舊的 buffer_lifetime_ordinal 無法及時關閉,管道可能會關閉。16 的門檻遠低於違規處置門檻。如果用戶端不會傳送新的 buffer_lifetime_ordinal 值,或新增的緩衝區在再次替換前,至少會有一些實際用量可供用戶端查看,則用戶端不需要同步。

相同通訊埠和 buffer_lifetime_ordinal 的所有緩衝區都必須共用相同的 [fuchsia.sysmem2/SingleBufferSetttings]。用戶端可以透過多種方式確保這一點。其中一種方法是先使用 ParticipateInBufferAllocation,然後為至少第一個緩衝區使用 AddBuffer,再為後續緩衝區使用 ParticipateInBufferAllocation。另一種方法是在傳送 AddBuffer 之前觀察 SingleBufferSettings 中的不相符情形,並將 AddBuffer 的 buffer_lifetime_ordinal 值提高至下一個奇數。

新增:32

要求

名稱類型
payload StreamProcessorAddBufferRequest

CloseCurrentStream

這會「關閉」目前的串流,因此不會有任何串流。此外,這則訊息可以選擇釋出 (和取消註冊) 輸入緩衝區或輸出緩衝區。

如果從未有任何有效串流,stream_lifetime_ordinal 必須為零,否則伺服器會關閉管道。如果曾有過有效串流,stream_lifetime_ordinal 必須是最近的有效串流,無論該串流是否仍有效。否則伺服器會關閉管道。

如果有多個這類訊息,且中間沒有任何新的有效串流,則不視為錯誤,用戶端可以使用這類訊息關閉目前的串流,避免在使用者不再關心的串流上浪費處理能力,然後決定釋出緩衝區,並再次傳送這類訊息,並將 release_input_buffers 和/或 release_output_buffers 設為 true,以釋出緩衝區,如果用戶端想要避免舊緩衝區和新緩衝區之間的資源使用重疊 (並非所有用戶端都如此)。

另請參閱 Sync()。

要求

名稱類型
stream_lifetime_ordinal uint64
release_input_buffers bool
release_output_buffers bool

CompleteOutputBufferPartialSettings

在 SetOutputBufferPartialSettings() 之後,伺服器不會傳送 OnOutputConstraints()、OnOutputFormat()、OnOutputPacket() 或 OnOutputEndOfStream(),直到用戶端傳送 CompleteOutputBufferPartialSettings() 為止。

AddBuffer 後不允許傳送這則訊息。使用動態緩衝區時,伺服器可以在第一個 QueueInputPacket 之後,隨時傳送 OnOutputConstraints、OnOutputFormat、OnOutputPacket 或 OnOutputEndOfStream。如果是 OnOutputPacket,則必須至少有一個已新增但尚未完全移除的輸出緩衝區 (RemoveBuffer 尚未完成)。

部分用戶端可能可以在 SetOutputBufferPartialSettings() 之後立即傳送 CompleteOutputBufferPartialSettings(),在這種情況下,用戶端必須準備好接收輸出內容,而不知道緩衝區數量或封包數量,這類用戶端可能會在內部延遲處理收到的輸出內容,直到用戶端收到 sysmem 的訊息 (用戶端會得知緩衝區數量和封包數量)。

其他用戶端可能會先等待 sysmem 分配、準備接收輸出,然後傳送 CompleteOutputBufferPartialSettings()。

要求

名稱類型
buffer_lifetime_ordinal uint64

EnableForceOutputBuffersFixedImageSize

如果是影片解碼器,當圖片大小需要變更時,這會強制重新分配輸出緩衝區。這會造成浪費,因為一般影片位元率控制策略 (適用於串流和 RTC) 涉及在邏輯影片/串流播放時反覆上下移動圖片尺寸,有時甚至在網路條件相當穩定的情況下,也會強制重新分配額外的緩衝區。無論是在單一 StreamProcessor 串流中切換維度,還是使用新的 StreamProcessor 串流切換新維度,都會產生這項額外的緩衝區重新分配成本。

除非用戶端確實必須在每次輸出圖片大小變更時,強制重新分配輸出緩衝區,否則不應傳送這則訊息。

如果多次傳送這則訊息,系統會關閉管道。如果傳送這則訊息,則必須在傳送任何 SetInputBufferPartialSettings、SetOutputBufferPartialSettings、ParticipateInBufferAllocation 或 AddBuffer 之前傳送。

只有在這個 StreamProcessor 是影片解碼器時,才允許傳送這則訊息。

只有在 [fuchsia.mediacodec/CodecFactory.DetailedCodecDescription.supports_dynamic_buffers] 為 true 時,才允許傳送這則訊息。

新增:32

要求

<EMPTY>

EnableOldOutputBuffers

這會通知 StreamProcessor,用戶端已準備好處理輸出封包,這些封包指定的緩衝區 buffer_lifetime_ordinal 比最新的 buffer_lifetime_ordinal 舊。

如果用戶端未傳送這則訊息,StreamProcessor 會省略任何這類輸出內容,即使 DetailedCodecDescription.supports_dynamic_buffers 為 true 也是如此。對於 VP9 解碼器等相關解碼器,如果不傳送這則訊息,可能會導致輸出內容不符合位元串流規格,且輸出內容在視覺上可能與位元串流預期的不同。

這類串流僅適用於部分位元串流格式 (例如 VP9),雖然不常見,但仍可能發生,且根據位元串流規格,這類串流可能有效。舉例來說,VP9 位元串流可以使用 show_existing_frame 指定這類串流,在輸出新維度緩衝區後,輸出舊維度緩衝區。

大多數傳送這則訊息的用戶端也會想使用 RemoveBuffer,瞭解何時可以安全地停止追蹤舊緩衝區。

大多數情況下,這不會造成任何差異,因為大多數位元串流實際上不會發出舊緩衝區,即使位元串流規格允許也是如此。舊輸出緩衝區在 RTC 串流中特別罕見,因為這類串流通常不會重新排序影格。

在大多數使用維度切換做為位元率控制策略一部分的影片串流情境中 (根據我觀察到的情況),在 StreamProcessor 層,新維度是新串流的一部分,而不是與舊串流拼接在一起。不過,繼續使用舊串流也是實作維度切換的完全有效方式。在維度切換期間,如果發生串流切換,系統不會保留解碼器狀態,也不會在新的緩衝區之後發出任何舊的緩衝區,因為新的串流對舊串流填入的舊緩衝區一無所知。

如果用戶端尚未測試處理舊輸出緩衝區的能力,則不應傳送這則訊息。如果用戶端解碼 VP9 等位元串流是為了測試解碼器是否符合規範,則應傳送這則訊息 (並使用 DetailedCodecDescrption.supports_dynamic_buffers 為 true 的 VP9 解碼器)。如果用戶端必須支援舊的輸出影格,和/或完全符合相關位元串流規格,則應/必須傳送這則訊息,並應使用測試串流進行測試,該串流會輸出參照舊輸出緩衝區的封包。

如果多次傳送這則訊息,系統會關閉管道。如要傳送這則訊息,必須在用戶端建立第一個輸出 buffer_lifetime_ordinal 之前傳送。這項規定可避免舊 buffer_lifetime_ordinal 封包的閒置/忙碌狀態不明確,因為當用戶端未傳送這則訊息時,伺服器可以代表用戶端自動回收具有舊 buffer_lifetime_ordinal 的封包。

只有在 [fuchsia.mediacodec/CodecFactory.DetailedCodecDescription.supports_dynamic_buffers] 為 true 時,才允許傳送這則訊息。

新增:32

要求

<EMPTY>

EnableOnStreamFailed

允許伺服器使用 OnStreamFailed(),而不是在串流失敗時直接關閉整個 StreamProcessor 管道。

如果伺服器在串流失敗前未收到這則訊息,就會關閉 StreamProcessor 管道,而不是傳送 OnStreamFailed()。

要求

<EMPTY>

EnableSameOutputBufferConcurrentlyInFlight

這會通知 StreamProcessor,用戶端已準備好處理輸出封包,這些封包指定的緩衝區與同時傳送至用戶端的另一個封包相同 (尚未回收)。

大多數位元串流格式都不會這樣做。在可執行這項操作的格式 (例如 VP9) 中,大多數實際位元串流都不會執行這項操作。

舉例來說,在 VP9 中,串流可能會在同一個 VP9 參考/保留影格槽上多次使用 show_existing_frame,而未在該槽中解碼新影格,導致另一個發出的輸出封包/影格使用相同的輸出緩衝區。

如果用戶端需要完全符合這類位元串流格式的位元串流規格,就必須傳送這則訊息。

如果這則訊息未生效,伺服器會省略任何這類輸出內容,這可能會導致輸出內容不符合相關位元串流規格,且可能與預期的串流在視覺上有所不同。

如果多次傳送這則訊息,系統會關閉管道。如要傳送,必須在用戶端建立第一個輸出 buffer_lifetime_ordinal 之前傳送。

只有在 [fuchsia.mediacodec/CodecFactory.DetailedCodecDescription.supports_dynamic_buffers] 為 true 時,才允許傳送這則訊息。

新增:32

要求

<EMPTY>

FlushEndOfStreamAndCloseStream

這則訊息為選用,用戶端不一定要傳送。

術語附註:在這個訊息名稱中,「flush」是指沖洗,有時稱為「drain」。這則訊息不會捨棄。如要捨棄,只要使用新的 stream_lifetime_ordinal 執行 QueueInputPacket 即可,不必先等待舊串流的 OnOutputEndOfStream,也不必傳送 FlushEndOfStreamAndCloseStream。

目前除了用戶端關閉 StreamProcessor 管道外,無法取消這則訊息的清除效果。

只有在 QueueInputEndOfStream() 處理完這個串流後,這則訊息才有效。stream_lifetime_ordinal 輸入參數必須與 QueueInputEndOfStream() 的 stream_lifetime_ordinal 相符,否則伺服器會關閉管道。

用戶端可以使用這則訊息,清除 (排空,而非捨棄) 串流的最後一筆輸入資料,讓串流處理器伺服器在移至下一個串流之前,為所有輸入資料產生對應的輸出資料,而用戶端不必等待 OnOutputEndOfStream(),即可將另一個串流的資料排入佇列。

QueueInputEndOfStream() 和 FlushEndOfStreamAndCloseStream() 的差異:QueueInputEndOfStream() 是用戶端承諾不會再有串流的輸入資料 (部分串流處理器需要這項資訊,才能發出最後一筆輸出資料)。即使已傳送 QueueInputEndOfStream(),用戶端仍可關閉目前串流 (無論是否切換串流),完全捨棄目前串流的其餘部分。相較之下,FlushEndOfStreamAndCloseStream() 是用戶端提出的要求,要求處理所有先前排入佇列的輸入資料,包括邏輯「EndOfStream」,在轉移至任何新串流之前,顯示為 OnOutputEndOfStream() (成功案例) - 這基本上會將關閉串流處理從捨棄變更為僅針對此串流進行清除。

使用這則訊息的用戶端可以開始為新串流提供輸入資料,而不會導致舊串流資料遭到捨棄。這就是這則訊息的目的:允許用戶端清除 (而非捨棄) 舊串流的最後一筆資料 (而非關閉或切換串流時的預設行為,即捨棄)。

由於舊串流尚未處理完畢,且舊串流的資料並未捨棄,因此用戶端必須準備好繼續處理 OnOutputConstraints() 訊息,直到 stream_lifetime_ordinal 完成為止。當 OnOutputEndOfStream()、OnStreamFailed() 或 StreamProcessor 管道關閉時,用戶端就會知道 stream_lifetime_ordinal 已完成。

要求

名稱類型
stream_lifetime_ordinal uint64

OnFreeInputPacket

串流處理器讀取完這個封包中的資料後,伺服器就會傳送這則訊息 (但不一定會處理完自己的資料副本)。無論 stream_lifetime_ordinal、串流關閉、buffer_lifetime_ordinal 變更 (支援時) 等是否有任何變更,系統都會傳送這則訊息。

建立新的輸入 buffer_lifetime_ordinal 時,所有輸入封包都會從用戶端開始,且沒有初始 OnFreeInputPacket。

收到這個事件後,用戶端可以根據用戶端維護的 packet_index 到 buffer_index 對應關係,判斷哪個輸入緩衝區可供重複使用。這項對應關係可以是固定或動態,視用戶端偏好而定。

如果是影片解碼器,則可依賴 OnFreeInputPacket,指出所有先前的封包也已從輸入緩衝區讀取完畢。不過,用戶端不需要追蹤這項資訊,因為所有 OnFreeInputPacket 都會由伺服器傳送 (即使是影片解碼器,也不一定會按照 QueueInputPacket 的順序傳送)。

一般來說,重複使用輸入緩衝區 buffer_index 值與重複使用輸入封包 packet_index 值無關,但部分用戶端可能會選擇一律將 packet_index 設為與 buffer_index 相同的值。

OnFreeInputPacket() 不代表輸入封包中的資料已成功處理,或已嘗試處理輸入位元組,僅代表 StreamProcessor 不再需要相關聯輸入緩衝區中的輸入資料。如果用戶端需要知道哪些輸入資料產生了對應的輸出內容,建議使用 timestamp_ish 值。

OnFreeInputPacket 的順序不保證與 QueueInputPacket 的順序相同,且 OnFreeInputPacket 可能會在 OnStreamFailed 之後發生。

回應

名稱類型
free_input_packet PacketHeader

OnInputConstraints

伺服器會在 StreamProcessor 建立後不久傳送此訊息,指出輸入緩衝區限制。「min」和「max」輸入限制在 StreamProcessor 的生命週期內不會變更。

緩衝區空間和數量的「最大」值,足以支援伺服器在輸入時支援的最嚴苛格式。「建議」值應可與建立 StreamProcessor 時傳送的輸入 FormatDetails 搭配使用。如果用戶端使用 QueueInputFormatDetails() 變更輸入格式,則「建議」值不一定適用。在這種情況下,用戶端必須自行決定合適的值,方法是建立新的 StreamProcessor 執行個體,或是在這個通訊協定範圍外找出合適的值。

請參閱 StreamBufferConstraints 的註解。

在 StreamProcessor 建立期間或建立後不久,系統一定會主動將這則訊息傳送至 StreamProcessor 用戶端。用戶端不應假設這是第一個抵達用戶端的訊息。

「min」和「max」輸入限制條件保證不會因特定 StreamProcessor 執行個體而變更。當伺服器處理 QueueInputFormatDetails() 時,「建議」值可能會有效變更。在通訊協定中,除了為用戶端建立新的 StreamProcessor 執行個體,沒有其他方法可以取得這些新的「建議」值。

伺服器 (用於輸入) 的第一個 buffer_constraints_version_ordinal 一律為 1。

回應

名稱類型
input_constraints StreamBufferConstraints

OnOutputConstraints

這個事件會通知用戶端新的輸出限制。

這則訊息會與其他輸出內容 (例如輸出封包、輸出格式、輸出串流結尾) 一起排序。

在串流的第一個 OnOutputPacket() 之前,伺服器保證會傳送至少一個 OnOutputConstraints() 和一個 OnOutputFormat()。用戶端必須在第一個輸出封包前,容許出現多個 OnOutputConstraints() (和 1 個 OnOutputFormat() 訊息)。只要用戶端未移至新串流,伺服器就不會傳送另一個 OnOutputConstraints(),直到用戶端設定輸出緩衝區為止。

當伺服器需要新的輸出緩衝區時,可以在串流中途傳送這則訊息。在用戶端透過 SetOutputBufferPartialSettings 或 AddBuffer 新增輸出緩衝區之前,伺服器不會產生更多輸出內容。

在用戶端設定/重新設定輸出緩衝區之前,伺服器不會為這個串流傳送任何 OnOutputPacket()。

所有用戶端 (即使是不想支援任何中串流輸出緩衝區重新設定或中串流 OnOutputFormat() 的用戶端) 都必須在第一個輸出封包前處理 1..多個 OnOutputConstraints() 訊息,並在第一個輸出封包前處理一個 OnOutputFormat() 訊息。

回應

名稱類型
output_config StreamOutputConstraints

OnOutputEndOfStream

StreamProcessor 用戶端傳送 QueueInputEndOfStream() 後,StreamProcessor 伺服器會在合理時間內傳送對應的 OnOutputEndOfStream()。與 QueueInputEndOfStream() 類似,每個串流最多會傳送一次 OnOutputEndOfStream()。

這則訊息之後,系統不會再傳送這個串流的資料。這個串流的所有輸入資料都已處理完畢。

雖然 StreamProcessor 用戶端不需要 QueueInputEndOfStream() (除非用戶端想使用 FlushEndOfStreamAndCloseStream()),但如果 StreamProcessor 伺服器收到 QueueInputEndOfStream(),且用戶端未關閉串流,StreamProcessor 伺服器必須在沒有發生錯誤的情況下產生對應的 OnOutputEndOfStream(),或必須傳送 OnStreamFailed(),或必須關閉 StreamProcessor 管道的伺服器端。理想的 StreamProcessor 伺服器會透過 error_ 旗標處理及回報串流錯誤,並完成串流處理,而不傳送 OnStreamFailed(),但無論如何,上述選項是 QueueInputEndOfStream() 後不會發生 OnOutputEndOfStream() 的唯一方式。

在這個訊息之後,這個 stream_lifetime_ordinal 將不會再有 OnOutputPacket() 或 OnOutputConstraints() 訊息。如果伺服器不遵守這項規則,用戶端應關閉 StreamProcessor 管道。

error_detected_before bool 的語意與 OnOutputPacket() 中的 error_detected_before bool 相同。

回應

名稱類型
stream_lifetime_ordinal uint64
error_detected_before bool

OnOutputFormat

伺服器會在任何串流的第一個輸出封包之前傳送這則訊息,也可能在串流的輸出封包之間傳送,並依輸出封包和 OnOutputConstraints() 排序。

伺服器保證每個串流的第一個封包都會在 OnOutputFormat() 之前。

伺服器保證在 OnOutputConstraints() 和 OnOutputPacket() 之間會有 OnOutputFormat()。換句話說,用戶端基本上可以忘記任何 OnOutputConstraints() 上的輸出格式,因為伺服器承諾在任何 OnOutputPacket() 之前會有後續的 OnOutputFormat()。

在用戶端重新設定輸出緩衝區之前,伺服器不會傳送 OnOutputFormat() (因此也不會傳送 OnOutputPacket())。

伺服器可以在兩個輸出封包之間,傳送 OnOutputFormat() 中間串流。

伺服器不會在沒有任何輸出封包的情況下,傳送兩個相鄰的 OnOutputFormat 訊息。不過,OnOutputFormat 訊息不保證後續會有封包,因為伺服器可能會改為傳送 OnOutputEndOfStream 或 OnStreamFailed,或者用戶端可能會移至新串流,而伺服器可能不會從舊串流傳送封包,即使已傳送 OnOutputFormat 也是如此。

如果用戶端不希望順暢處理串流中輸出格式變更,應確保用戶端處理的串流不會有任何串流中格式變更,或確保任何重試處理作業都會在舊格式結束和新格式開始的邏輯點或之後開始新的嘗試,否則用戶端可能會再次遇到相同的串流中格式變更。

在串流中途傳送這則訊息的例子,是影片解碼器輸出的影片影格尺寸在串流中途變更。

並非所有伺服器都支援順暢處理格式變更。如果支援順暢處理格式變更,可能需要格式變更,也不需要重新設定輸出緩衝區,才能順暢處理。請參閱 OnOutputConstraints() 的註解區塊,進一步瞭解伺服器和用戶端應如何運作,特別是無法順暢處理輸出限制變更和/或輸出格式變更時。

如果伺服器未在串流開始時傳送這則訊息,最常見的原因是用戶端尚未處理 OnOutputConstraints() (使用 SetOutputBufferPartialSettings 或 AddBuffer 設定輸出緩衝區)。

回應

名稱類型
output_format StreamOutputFormat

OnOutputPacket

串流處理器會透過這種方式,將輸出封包傳送至串流處理器用戶端。

順序很重要。

用戶端最終應呼叫 RecycleOutputPacket() (可能在多次切換串流後),除非 buffer_lifetime_ordinal 已變更。串流變更不會改變哪些封包忙於用戶端,哪些封包在伺服器上可用。

相關緩衝區一律是封包 buffer_index 欄位中指定的緩衝區。

對於支援低階緩衝區類型的 StreamProcessor,在低階緩衝區實際有任何可用資料之前,StreamProcessor 可以自由發出輸出封包,並透過與 OnOutputPacket() 訊息分開的機制,發出資料存在的信號。對於這類低階緩衝區類型,從發出封包中下游的資料消費者必須參與低階緩衝區信號機制,才能知道何時可以安全地使用資料。使用影片解碼器和 gralloc 樣式緩衝區時,最有可能需要考量這點。

error_ bool 允許 (但非必要) StreamProcessor 伺服器回報 AU 期間或 AU 之間發生的錯誤。

error_detected_before 的範圍從這個串流上最後一個傳送的輸出封包結束時開始,如果這個串流上沒有先前的輸出封包,則從串流開始時開始。範圍會在 output_packet 的開頭結束。

error_detected_before bool 是獨立的,因此可以與目前封包是否損壞分開表示不連續性。

error_detected_during 的範圍是從這個 output_packet 的開頭到結尾。

回應

名稱類型
output_packet Packet
error_detected_before bool
error_detected_during bool

OnOutputTimestampHasNoOutput

大多數用戶端都可以忽略 OnOutputTimestampHasNoOutput 訊息。

OnOutputTimestampHasNoOutput 僅由 StreamProcessor 伺服器傳送,且 supports_dynamic_buffers 為 true。

如果伺服器判定先前具有指定 timestamp_ish 值的輸入封包不會產生任何輸出內容,就會傳送這則訊息,並附上 timestamp_ish 值。

當伺服器最終判定時間戳記不會產生任何輸出內容時,這則訊息可視為 OnOutputPacket 的替代訊息,這也是名稱開頭為「OnOutput」的原因。與表示輸出的訊息類似,當有進行中的串流驅動輸出重新設定時 (從 OnOutputConstraints 開始),伺服器不會傳送這則訊息。

雖然伺服器應在允許、可行和實際的情況下盡快傳送這則訊息,但無法保證伺服器傳送這則訊息的具體時間。對於某些不會產生任何輸出的輸入封包,伺服器可能會在取用對應的輸入封包後,很快就傳送這則訊息。對於其他不會產生任何輸出的輸入封包,伺服器可能不會傳送這則訊息,直到伺服器能證明對應的輸入封包不會透過延遲方式產生任何輸出,例如涉及 max_num_reorder_frames 的邏輯,或任何相關的位元串流格式特定邏輯。伺服器可以不傳送這則訊息,直到伺服器接收並處理更多輸入內容為止。用戶端不得在傳送更多輸入內容前,嘗試等待接收這則訊息,因為這可能會造成死結。

傳送時,這則訊息會在對應輸入封包 (具有相同 timestamp_ish 值) 的 OnFreeInputPacket 訊息之後傳送。用戶端不得延遲重複使用輸入緩衝區,直到收到 OnOutputTimestampHasNoOutput 為止,因為這可能會造成死結。

傳送時,這則訊息會先於 stream_lifetime_ordinal 串流的 OnOutputEndOfStream 訊息傳送。伺服器不一定要先為所有未解析 (輸出是/否) 的輸入 timestamp_ish 值傳送 OnOutputTimestampHasNoOutput,再傳送 OnOutputEndOfStream,且 OnOutputEndOfStream 會明確解析用戶端追蹤的任何剩餘輸入 timestamp_ish 值的 (輸出是/否) 狀態。

伺服器不得在後續的 OnOutputPacket 中輸出指定的 timestamp_ish 值,除非用戶端未確保 timestamp_ish 值不重複,且用戶端在另一個輸入封包中重複使用 timestamp_ish 值。伺服器端機制可透過位元串流格式和轉碼器實作,實現這項功能。

如果輸入封包未產生輸出內容的原因,是用戶端切換至新串流,但未執行 FlushEndOfStreamAndCloseStream、串流失敗或轉碼器失敗,伺服器就不必傳送這則訊息。

如果用戶端確保所有具有指定 stream_lifetime_ordinal 的輸入封包都具有不重複的 timestamp_ish 值,則用戶端可以使用這則訊息來判斷哪些輸入封包永遠不會產生任何輸出內容。

如果用戶端無法確保所有輸入封包都有不重複的 timestamp_ish 值,則用戶端應一律忽略這則訊息,因為在這種情況下,通訊協定不會對這則訊息做出任何特定保證 (任何這類用戶端可能都無法區分所指的輸入封包,伺服器傳送這則訊息的次數可能不會與具有相同 timestamp_ish 值的輸入封包一樣多,伺服器可能在發現任何非不重複的 timestamp_ish 值後完全不傳送這則訊息等)。

如要有效且穩健地使用這則訊息,用戶端可能需要將 timestamp_ish 值指派為依序的無正負號 64 位元數字,並在用戶端本機保留任何對應的實際時間戳記。

如果用戶端沒有任何特定原因需要注意這個事件,則應忽略這個事件。大多數用戶端都可以完全忽略這個事件,不會造成任何負面影響。

新增:32

回應

名稱類型
payload StreamProcessorOnOutputTimestampHasNoOutputRequest

OnStreamFailed

串流失敗,但 StreamProcessor 執行個體仍可用於新串流。

只有在用戶端先前傳送 EnableOnStreamFailed() 時,伺服器才會傳送這則訊息。如果用戶端未傳送 EnableOnStreamFailed(),伺服器會改為關閉 StreamProcessor 管道。

建議 StreamProcessor 伺服器實作項目處理串流錯誤 (最好也透過 OnOutputPacket() 和 OnOutputEndOfStream() 的 error_ bools 回報錯誤),而不中斷整個串流。不過,如果串流處理器伺服器無法這麼做,但仍能完全避免失敗影響串流,則串流處理器伺服器可以 (假設已呼叫 EnableOnStreamFailed()) 使用 OnStreamFailed() 向用戶端指出串流失敗,而不關閉 StreamProcessor 管道。

理想的 StreamProcessor 伺服器會處理輸入資料的問題,而不會傳送這則訊息。不過,如果 StreamProcessor 伺服器能 100% 可靠地將串流失敗限制在串流中,且不會對後續串流造成任何負面影響,則建議傳送這則訊息,而非關閉 StreamProcessor 管道的伺服器端。

伺服器不會再傳送有關失敗串流的訊息。這包括用戶端原本預期的任何 OnOutputEndOfStream()。

回應

名稱類型
stream_lifetime_ordinal uint64
error StreamError

ParticipateInBufferAllocation

除非 supports_dynamic_buffers 設為 true,否則這則訊息會導致管道關閉。

這會參與緩衝區分配,以便日後與 AddBuffer 搭配使用。用戶端也可以使用自己的相關 sysmem 權杖 (與同一個邏輯緩衝區集合相關聯),參與 sysmem 分配,取得這些緩衝區的 VMO 控制代碼。用戶端可視需要,使用自己的相關 sysmem 權杖 (如有) 另行設定任何限制。

部分用戶端可能偏好使用 SetInputBufferPartialSettings 和/或 SetOutputBufferPartialSettings。伺服器必須支援這些訊息。

處理這則訊息時,如果 allow_single_buffer 設為 true,伺服器不得限制分配的緩衝區數量。伺服器必須將 min_buffer_count 設為 1,並將 max_buffer_count 留空或設為 0xFFFFFFFF,且所有 min_buffer_count_* 欄位都必須留空。如果傳送端想要分配特定數量的緩衝區,可以將 min_buffer_count 和 max_buffer_count 設為相同的值。如果未設定 allow_single_buffer 或設為 false,伺服器會向 sysmem 指出所需的緩衝區數量。

伺服器的 BufferCollection 管道 (從傳入的 sysmem2_token 建立) 可能隨時會看到 ZX_CHANNEL_PEER_CLOSED,但伺服器不應預期 BufferCollection 管道在傳送 SetConstraints 後,仍會與 sysmem 保持連線。因此,伺服器可能無法呼叫 WaitForAllBuffersAllocated 或類似函式,所以伺服器應傳送 SetConstraints、Close,然後關閉伺服器的 BufferCollection client_end。這表示伺服器在處理這則訊息時,一般不應嘗試取得這些緩衝區的 VMO 控制代碼。

伺服器不應假設這些緩衝區一定會透過 AddBuffer 新增至這個 StreamProcessor 執行個體,或任何其他 StreamProcessor 執行個體 (無論是否由伺服器擁有)。這些緩衝區可能會遭到捨棄,或是在較不常見的情況下,新增至由不同伺服器實作提供的不同轉碼器,而該伺服器實作也參與了相同的 sysmem 緩衝區集合分配。

對於輸入緩衝區,將已分配緩衝區的 AddBuffer 新增至相同轉碼器 (每個 CodecFactory 相同) 的不同 StreamProcessor 執行個體,可能可以運作,但建議盡可能使用相同的 StreamProcessor 執行個體。

相較之下,對於輸出緩衝區,將已分配緩衝區的 AddBuffer 新增至相同轉碼器 (每個 CodecFactory 相同) 的不同 StreamProcessor 例項,通常無法 (在合理範圍內) 運作,尤其是視訊解碼器。因此,對於輸出緩衝區,此訊息和 AddBuffer 必須使用相同的 StreamProcessor 執行個體。雖然用戶端目前可能可以針對這則訊息使用不同的 StreamProcessor 執行個體,並針對某些轉碼器的輸出緩衝區使用 AddBuffer,但這可能會隨時中斷,且不會被視為伺服器端錯誤。

之後可以使用 AddBuffer (逐一) 新增已分配的緩衝區,並使用 RemoveBuffer (逐一) 移除。

多個不同的 ParticipateInBufferAllocation 訊息,稍後可以使用相同的 buffer_lifetime_ordinal,將其緩衝區新增至同一個 StreamProcessor 執行個體。如果用戶端想逐步分配緩衝區,或動態調整緩衝區數量 (可能在主動處理時),這個方法就很有用。另請參閱這則訊息的 buffer_lifetime_ordinal 欄位。

伺服器實作項目可能會使用 sysmem,在稍後透過 AddBuffer 新增緩衝區時,協助驗證緩衝區相容性。

新增:32

要求

名稱類型
payload StreamProcessorParticipateInBufferAllocationRequest

QueueInputEndOfStream

通知伺服器,這個串流的所有 QueueInputPacket() 訊息都已傳送。

如果串流未先關閉 (由用戶端、OnStreamFailed() 或 StreamProcessor 管道關閉),稍後會出現對應的 OnOutputEndOfStream()。

只有在伺服器發現用戶端關閉串流 (例如啟動新串流) 前,就完成處理串流,才會產生對應的 OnOutputEndOfStream() 訊息。如要強制伺服器在關閉前完成串流,請在 QueueInputEndOfStream() 之後、任何新串流之前,使用 FlushEndOfStreamAndCloseStream()。另一種強制伺服器在關閉前完成串流的方法,是等待 OnOutputEndOfStream() 執行,再採取任何關閉串流的動作。

除了做為「EndOfStream」標記,讓用戶端在所有輸入資料處理完畢時能清楚得知,如果用戶端從未傳送 QueueInputEndOfStream,無論等待多久,都不一定會將所有輸入資料處理到輸出。部分串流處理器會有一些內部延遲的資料,這些資料只能透過額外的輸入資料「或」這個 EndOfStream 標記來排出 (推送)。從這個角度來看,這則訊息可視為 InputData 網域層級的耗盡,但只有在串流處理器在串流於 StreamControl 網域層級關閉之前,甚至達到該程度時,耗盡才會生效。單憑這則訊息,不足以在 StreamControl 層級全面排除。如要這麼做,請先傳送這則訊息,然後傳送 FlushEndOfStreamAndCloseStream (此時可以將新串流的輸入資料排入佇列,而不會導致這個舊串流的資料遭到捨棄)。或者,用戶端可以等待 OnOutputEndOfStream,再關閉目前的串流。

用戶端傳送串流的 QueueInputEndOfStream 後,如果又傳送同一個串流的 QueueInputPacket、QueueInputFormatDetails、QueueInputEndOfStream,伺服器就會關閉 StreamProcessor 管道。

要求

名稱類型
stream_lifetime_ordinal uint64

QueueInputFormatDetails

如果輸入格式詳細資料仍與建立 StreamProcessor 時指定的資料相同,則不需要傳送這則訊息。

如果串流不存在,這則訊息會建立串流。

用戶端至少傳送一則 QueueInput* 訊息後,伺服器才會傳送 OnOutputConstraints()。

只要 StreamProcessor 執行個體支援新格式,所有伺服器都必須允許在串流開始時執行 QueueInputFormatDetails(),且不得失敗。技術上來說,這可讓伺服器僅支援 StreamProcessor 建立期間設定的確切輸入格式,這是設計使然。如果用戶端嘗試切換格式,但 StreamProcessor 管道失敗,應使用 CodecFactory 建立新的 StreamProcessor 執行個體,並在建立期間使用新的輸入格式,然後再試一次。

這些格式詳細資料會覆寫建立串流處理器時指定的格式詳細資料,但僅適用於這個串流。下一個串流會預設為建立串流處理器時設定的格式詳細資料。

這則訊息可在第一個串流開始時傳送 (就像在任何串流開始時一樣)。指定的格式不一定要與建立串流處理器時指定的格式相符,但如果不相符,StreamProcessor 管道可能會關閉,如上所述。

要求

名稱類型
stream_lifetime_ordinal uint64
format_details FormatDetails

QueueInputPacket

這則訊息會將輸入資料排入串流處理器的佇列,以便處理。

如果串流不存在,這則訊息會建立新串流。

用戶端至少傳送一則 QueueInput* 訊息後,伺服器才會傳送 OnOutputConstraints()。

使用動態緩衝區時,伺服器可在第一個 QueueInputPacket 之後,隨時傳送 OnOutputConstraints、OnOutputFormat、OnOutputPacket 或 OnOutputEndOfStream。如果是 OnOutputPacket,則必須至少有一個已新增但尚未完全移除的輸出緩衝區 (RemoveBuffer 尚未完成)。

即使串流處理器尚未產生第一個 OnOutputConstraints,且 StreamProcessor 正在為先前排入佇列的輸入封包產生 OnFreeInputPacket,用戶端仍須繼續透過這則訊息傳送輸入資料。只要有可用封包,輸入資料就必須繼續,以確保伺服器會產生第一個 OnOutputConstraints。

如果這個封包參照舊的 buffer_lifetime_ordinal,伺服器會關閉管道。如果用戶端需要將不同尺寸的輸入圖片傳送至影片編碼器,可以 (a) 分配足夠大的緩衝區,以容納所需圖片大小範圍,並使用這些緩衝區傳送所有輸入圖片;(b) 保留自己的緩衝區組合,用於不同圖片尺寸,並使用 AddBuffer 重新新增舊緩衝區,每次圖片尺寸變更時,都移至新的 buffer_lifetime_ordinal;或 (c) 每次圖片尺寸變更時,都分配新的緩衝區。如果用戶端可以彈性地將不同尺寸的圖片儲存在單一緩衝區中,建議選擇 (a) 選項。如果用戶端要求每個緩衝區只能有一種圖片大小,則可使用選項 (b) 或 (c)。

要求

名稱類型
packet Packet

RecycleOutputPacket

用戶端處理完輸出封包後,必須使用這則訊息,告知串流處理器該輸出封包可重複用於更多輸出內容。

您不得回收串流處理器伺服器已釋出的輸出封包。

如果用戶端使用 EnableOldOutputBuffers,則必須在處理完所有封包後回收,即使是舊 buffer_lifetime_ordinal 的封包也一樣。所有用戶端也允許這項行為。

如果用戶端未使用 EnableOldOutputBuffers,則可選擇省略這個訊息,用於 buffer_lifetime_ordinal 舊的封包。換句話說,如果用戶端未使用且不會使用 EnableOldOutputBuffers,則在明確或隱含輸出緩衝區取消設定之前,不需要回收封包。

要求

名稱類型
available_output_packet PacketHeader

RemoveBuffer

使用動態緩衝區時,只要緩衝區可以移除,且不會對任何進行中的處理作業或參照緩衝區的傳輸中輸出封包造成負面影響,這項呼叫就會移除緩衝區。

如果用戶端想移除緩衝區,但有傳輸中的輸出封包參照該緩衝區,則用戶端必須先對該傳輸中的輸出封包執行 RecycleOutputPacket,才能完成 RemoveBuffer。

使用 SetInputBufferPartialSettings/SetOutputBufferPartialSettings 時,這項呼叫不會啟動緩衝區移除作業。當緩衝區因其他原因 (例如新的 buffer_lifetime_ordinal 啟動) 而移除時,這項呼叫就會完成。

在 RemoveBuffer 完成前,轉碼器仍可傳送參照緩衝區的 OnOutputPacket 訊息,且轉碼器可能仍有開啟緩衝區的 VMO 控制代碼。RemoveBuffer 完成後,轉碼器會保證後續的輸出封包不會參照緩衝區,且伺服器不會保留緩衝區的 VMO 控制代碼。

用戶端可能需要回收輸出封包,才能完成 RemoveBuffer 呼叫。用戶端應避免在 RemoveBuffer 要求進行期間封鎖封包回收,否則可能會造成死結。

伺服器必須在完成這項呼叫前,關閉緩衝區的所有 VMO 控制代碼,用戶端才能避免記憶體用量暴增。

如果用戶端未提供任何輸入內容,因而「暫停」處理,則用戶端可能需要先傳送 CloseCurrentStream,RemoveBuffer 才會完成。使用動態緩衝區時,不需要將 release_input_buffers 或 release_output_buffers 設為 true;RemoveBuffer 會明確指示轉碼器釋出特定緩衝區。如果不使用動態緩衝區,用戶端必須將 release_input_buffers 或 release_output_buffers 設為 true,因為在不使用動態緩衝區時,單獨使用 RemoveBuffer 不會啟動移除作業。目前「暫停」的串流必須停止,因為影格可以保留為參考影格,且轉碼器一律不需要複製輸出資料。

如果移除任何影片解碼器輸出緩衝區時,有進行中的串流 (無論是否輸入),用戶端最好假設移除影片解碼器輸出緩衝區可能需要很長的時間。這是因為位元串流 (尤其是非標準相容位元串流,但在某些情況下,甚至可能是標準相容位元串流) 可以無限期地將影片解碼器輸出緩衝區保留在有效參考框架 (又稱為 DPB) 集合中。伺服器不需注意串流是否符合這方面的位元串流標準。

在 h.264 解碼的情況下,符合標準的位元串流會將重新排序延遲限制在不超過最大 DPB 占用量。不過,伺服器不一定要偵測或拒絕不符合規範的串流,這類串流可能會將影格保留在 DPB 中較長的時間。

HEVC 的情況與 h.264 (IIUC) 類似。

如果是 VP9,位元串流規格中沒有任何限制重新排序延遲 (IIUC) 的規定,也就是說,影格可能會無限期留在 VP9 的 8 個參考影格 (又稱 DPB) 組合中。伺服器不一定要偵測或緩解這種情況。

在呼叫完成前,伺服器可能仍會使用緩衝區。對於輸出緩衝區,伺服器仍可傳送參照這個緩衝區的 OnOutputPacket 訊息,但僅限於伺服器傳送 RemoveBuffer 完成訊息之前。用戶端必須繼續對參照緩衝區的封包執行 RecycleOutputPacket,直到 RemoveBuffer 完成為止。

使用動態緩衝區時,伺服器收到這則訊息後,就不會再選取緩衝區用於任何新用途 (也就是將緩衝區從「可用」移至「不可用」的任何用途)。即使伺服器沒有其他可用的緩衝區 (也就是沒有其他「可用」緩衝區),也適用這項規定。緩衝區的任何現有使用情形不會僅因這個呼叫而提早結束。

如果不使用動態緩衝區,伺服器收到這則訊息時,只會記住要在緩衝區因其他原因完成移除後不久,完成這項呼叫 (移除並非由這項呼叫觸發/引起)。

使用動態緩衝區時,影片解碼器用戶端通常應避免移除過多輸出緩衝區,才能繼續解碼。如果發生這種情況,解碼器會等待用戶端使用 AddBuffer 新增另一個輸出緩衝區。如果用戶端從未傳送 AddBuffer,就可能發生死結。由於 DPB 機制和影格重新排序,傳送單一 AddBuffer 不一定能保證另一個 OnOutputPacket,因為伺服器可能需要額外的輸出緩衝區,才能傳送 OnOutputPacket。

無論時間是否重疊,用戶端都不得對同一個緩衝區多次呼叫 RemoveBuffer。如果伺服器不強制執行這項限制,就必須追蹤其他並行要求,因此伺服器應強制執行這項限制。如果強制執行會耗用更多伺服器記憶體,則伺服器不一定要強制執行。

如果 buffer_lifetime_ordinal 和 buffer_index 組合從未是實際緩衝區,伺服器可以快速完成這項要求,並傳回成功結果,但如果用戶端尚未啟動 buffer_lifetime_ordinal,則必須關閉管道 (不移除潛在的未來緩衝區)。

使用動態緩衝區時,buffer_lifetime_ordinal 和 buffer_index 組合可能會在 RemoveBuffer 完成後重複使用,但前提是 buffer_lifetime_ordinal 是目前的 buffer_lifetime_ordinal。換句話說,請勿在舊的 buffer_lifetime_ordinal 下新增緩衝區。

假設指定了有效的歷來緩衝區,成功完成這項呼叫表示伺服器已完全釋出緩衝區,且不會在任何後續的 OnOutputPacket 中參照。

新增:32

要求

名稱類型
payload StreamProcessorRemoveBufferRequest

回應

名稱類型
payload StreamProcessor_RemoveBuffer_Result

SetInputBufferPartialSettings

如果用戶端未使用動態緩衝區,單一 SetInputBufferPartialSettings() 會為 StreamProcessor 提供用戶端指定的輸入設定,以及 StreamProcessor 用來將限制傳送至 sysmem 的 BufferCollectionToken。用戶端和 StreamProcessor 都會透過 BufferCollection 管道 (而非 StreamProcessor 管道),直接由 sysmem 收到已分配緩衝區的通知。

sysmem 通知用戶端緩衝區分配已成功完成後,用戶端才能 QueueInput...()。

伺服器應準備好在收到 sysmem 緩衝區分配通知前,先看到 QueueInput...()。伺服器必須容許任一順序,因為 QueueInput...() 和 sysmem 分配完成通知會透過不同管道送達,因此用戶端收到分配完成通知,不代表伺服器也知道分配已完成。不過,伺服器可以預期分配作業實際上已完成,並在向 sysmem 要求資訊時,立即從 sysmem 取得分配資訊。

如果通訊埠上仍有任何緩衝區處於啟用狀態,則不得混用 AddBuffer 和 SetInputBufferPartialSettings。如要成功切換通訊埠模式,大多數用戶端會選擇直接建立新的 StreamProcessor 執行個體。如要確保這項操作可靠,請先確認通訊埠下新增至「目前」的所有緩衝區 (包括 buffer_lifetime_ordinal 較舊的緩衝區) 都已完成 RemoveBuffer 要求。只有在這種情況下,才能在同一個 StreamProcessor 下切換該通訊埠的模式。大多數用戶端只會使用其中一種方式新增緩衝區,而且不需要切換到另一種方式,尤其是在同一個 StreamProcessor 中。

要求

名稱類型
input_settings StreamBufferPartialSettings

SetOutputBufferPartialSettings

這會取代 SetOutputBufferSettings()。

如果用戶端使用 sysmem 分配緩衝區,系統會使用這則訊息,而非 SetOutputBufferSettings()+AddOutputBuffer()。相反地,單一 SetOutputBufferPartialSettings() 會為 StreamProcessor 提供用戶端指定的輸出設定,以及 StreamProcessor 用來將限制傳送至 sysmem 的 BufferCollectionToken。用戶端和 StreamProcessor 都會透過 BufferCollection 管道 (而非 StreamProcessor 管道),直接由 sysmem 收到分配緩衝區的通知。

用戶端收到 OnOutputConstraints(),且 buffer_constraints_action_required 為 true,stream_lifetime_ordinal 等於用戶端目前的 stream_lifetime_ordinal (即使有使用中的串流) 時,必須設定輸出緩衝區。如果目前沒有串流,則允許隨時設定。

關閉目前串流的作業會在 StreamControl 排序網域上進行,因此在 CloseCurrentStream() 或 FlushEndOfStreamAndCloseStream() 之後,用戶端必須收到後續的 Sync() 完成通知,才能得知目前已無串流。

如果通訊埠上仍有任何緩衝區處於啟用狀態,則不得混用 AddBuffer 和 SetOutputBufferPartialSettings。如要成功切換通訊埠模式,大多數用戶端會選擇直接建立新的 StreamProcessor 執行個體。如要確保這項操作可靠,請先確認通訊埠下新增至「目前」的所有緩衝區 (包括 buffer_lifetime_ordinal 較舊的緩衝區) 都已完成 RemoveBuffer 要求。只有在這種情況下,才能在同一個 StreamProcessor 下切換該通訊埠的模式。大多數用戶端只會使用其中一種方式新增緩衝區,而且不需要切換到另一種方式,尤其是在同一個 StreamProcessor 執行個體中。

另請參閱 CompleteOutputBufferPartialSettings()。

要求

名稱類型
output_settings StreamBufferPartialSettings

同步

完成後,所有先前的 StreamProcessor 呼叫都已在伺服器端完成其工作,但不包括處理使用 QueueInputPacket() 排入佇列的資料。

這項呼叫的主要目的是讓用戶端等待 CloseCurrentStream() (release_input_buffers 和/或 release_output_buffers 設為 true) 生效,然後用戶端才會分配新的緩衝區,並重新設定輸入和/或輸出緩衝區。這種資源使用去重疊的做法,對於媒體緩衝區來說可能很有價值,因為媒體緩衝區可以消耗資源類型,而這些資源類型的整體集區不一定比消耗的資源大。尤其是用戶端多次重新設定緩衝區時。

請注意,在分配新的媒體緩衝區之前,單靠 Sync() 不足以避免整個系統的媒體緩衝區資源用量重疊,但這可以做為達成此目標的實用方法。

Sync() 會傳輸 Output 排序網域和 StreamControl 排序網域,但不會傳輸 InputData 排序網域。

這項要求可用於避免達到 kMaxInFlightStreams (目前為 10)。如果用戶端維持 <= 8 個進行中的串流,就能輕鬆保持在 10 個的限制內。雖然通訊協定允許重複 SetInputBufferSettings() 等,但如果用戶端向管道傳送垃圾內容,且伺服器或管道本身落後太多,管道就會關閉。

要求

<EMPTY>

回應

<EMPTY>

StreamSink

定義於 fuchsia.media/stream.fidl

取用封包串流。這個介面通常會與 StreamBufferSet 一起繼承,以便將基本串流從用戶端傳輸到服務。

DiscardAllPackets

捨棄先前透過 SendPacket 或 SendPacketNoReply 傳送且尚未釋出的封包。所有封包都釋出後,系統就會傳送回應。

要求

<EMPTY>

回應

<EMPTY>

DiscardAllPacketsNoReply

捨棄先前透過 SendPacket 或 SendPacketNoReply 傳送且尚未釋出的封包。

要求

<EMPTY>

EndOfStream

表示直播已結束。這個方法的精確語意由繼承介面決定。

要求

<EMPTY>

SendPacket

將封包傳送至服務。服務處理完相關聯的酬載記憶體後,就會傳送回應。

packet 必須對目前的緩衝區組合有效,否則服務會關閉連線。

要求

名稱類型
packet StreamPacket

回應

<EMPTY>

SendPacketNoReply

將封包傳送至服務。這個介面並未定義用戶端如何得知接收器何時完成相關聯的酬載記憶體。繼承介面必須定義該屬性。

packet 必須對目前的緩衝區組合有效,否則服務會關閉連線。

要求

名稱類型
packet StreamPacket

StreamSource

定義於 fuchsia.media/stream.fidl

產生封包串流。這個介面通常會與 StreamBufferSet 一起繼承,以便將基本串流從服務傳輸至用戶端。

DiscardAllPackets

要求

<EMPTY>

回應

<EMPTY>

DiscardAllPacketsNoReply

要求

<EMPTY>

OnEndOfStream

表示串流已結束。

回應

<EMPTY>

OnPacketProduced

傳送服務產生的封包。用戶端處理完酬載記憶體後,必須呼叫 ReleasePacket 釋放酬載記憶體。

回應

名稱類型
packet StreamPacket

ReleasePacket

釋出與先前透過 OnPacketProduced 傳送的封包相關聯的酬載記憶體。

要求

名稱類型
packet StreamPacket

Usage2AudioConsumerFactory

定義於 fuchsia.media/audio_consumer.fidl

用於建立音訊消費者,以便在本機轉譯。

CreateAudioConsumer

建立 AudioConsumer,這是用於播放音訊的介面,並提供使用值。提交至這類消費者的音訊一律會在本機轉譯。

要求

名稱類型
usage AudioRenderUsage2
audio_consumer_request server_end:AudioConsumer

UsageAudioConsumerFactory

定義於 fuchsia.media/audio_consumer.fidl

用於建立音訊消費者,以便在本機轉譯。

已移除:31 已淘汰:26

CreateAudioConsumer

要求

名稱類型
usage AudioRenderUsage
audio_consumer_request server_end:AudioConsumer

UsageGainListener

定義於 fuchsia.media/usage_reporter.fidl

用於監控用量增益設定變更的通訊協定。

如果裝置不在,管道就會關閉。

OnGainMuteChanged

連線後立即呼叫,之後每次用量增益設定變更時也會呼叫。

用戶端必須回應,確認收到事件。如果用戶端未確認事件,最終會中斷連線。

注意:這個 API 未導入隱藏回報功能;muted 一律為 false。

要求

名稱類型
muted bool
gain_dbfs float32

回應

<EMPTY>

UsageGainReporter

定義於 fuchsia.media/usage_reporter.fidl

用於設定用量增加監控器的通訊協定。

RegisterListener

將監聽器連結至 device_token 裝置上 usage 的使用增益設定變更串流。使用增益並非由任何用戶端直接設定,而是每個裝置的使用音量設定,加上有效靜音/閃避增益調整後的總和。

裝置可能會將相同的音量等級對應至不同的 dbfs,因此需要 device_unique_id 來識別裝置。

如果用戶端需要在執行階段選取 ID,AudioDeviceEnumerator 可讓您以程式輔助方式存取裝置及其專屬 ID。

已淘汰 - 請使用 RegisterListener2 和 Usage2

要求

名稱類型
device_unique_id string:36
usage Usage
usage_gain_listener client_end:UsageGainListener

RegisterListener2

將監聽器連結至 device_token 識別裝置上 usage 的使用增益設定變更串流。使用增益並非由任何用戶端直接設定,而是每個裝置的使用音量設定,加上主動靜音/降低音量增益調整後的總和。

裝置可能會將相同的音量等級對應至不同的 dbfs,因此需要 device_unique_id 來識別裝置。

如果用戶端需要在執行階段選取 ID,AudioDeviceEnumerator 可讓您以程式輔助方式存取裝置及其專屬 ID。

要求

名稱類型
device_unique_id string:36
usage Usage2
usage_gain_listener client_end:UsageGainListener

UsageReporter

定義於 fuchsia.media/usage_reporter.fidl

用於設定音訊使用情況監控器的通訊協定。

智慧手錶

已淘汰 - 請使用 Watch2、Usage2 和 UsageWatcher2

要求

名稱類型
usage Usage
usage_watcher client_end:UsageWatcher

Watch2

要求

名稱類型
usage Usage2
usage_watcher client_end:UsageWatcher2

UsageWatcher

定義於 fuchsia.media/usage_reporter.fidl

用於監聽音訊使用政策狀態變更的通訊協定。

使用者動作 (例如調低音量或將串流靜音) 不會反映在這個 API 中。

已淘汰 - 請使用 Watch2、Usage2 和 UsageWatcher2

OnStateChanged

在首次連線和監控的使用量變更時呼叫。提供的用途一律為繫結用途,因此這個通訊協定的實作項目可能會繫結至多個用途。

用戶端必須回應,確認收到事件。如果用戶端未確認事件,最終會中斷連線。

要求

名稱類型
usage Usage
state UsageState

回應

<EMPTY>

UsageWatcher2

定義於 fuchsia.media/usage_reporter.fidl

OnStateChanged

在首次連線和監控的使用量變更時呼叫。提供的用途一律為繫結用途,因此這個通訊協定的實作項目可能會繫結至多個用途。

用戶端必須回應,確認收到事件。如果用戶端未確認事件,最終會中斷連線。

要求

名稱類型
usage Usage2
state UsageState

回應

<EMPTY>

STRUCTS

AacConstantBitRate

定義於 fuchsia.media/stream_common.fidl

欄位類型說明預設
bit_rate uint32

每秒位元數

無預設值

AacEncoderSettings

定義於 fuchsia.media/stream_common.fidl

欄位類型說明預設
transport AacTransport 無預設值
channel_mode AacChannelMode 無預設值
bit_rate AacBitRate 無預設值
aot AacAudioObjectType 無預設值

AacTransportAdts

定義於 fuchsia.media/stream_common.fidl

ADTS 內的 AAC

<EMPTY>

AacTransportLatm

定義於 fuchsia.media/stream_common.fidl

LATM 內的 AAC

欄位類型說明預設
mux_config_present bool

是否含有 MuxConfiguration 串流元素

無預設值

AacTransportRaw

定義於 fuchsia.media/stream_common.fidl

原始 AAC 存取單位。

<EMPTY>

ActivityReporter_WatchCaptureActivity2_Response

定義於 fuchsia.media/activity_reporter.fidl

欄位類型說明預設
active_usages vector<AudioCaptureUsage2>:8 無預設值

ActivityReporter_WatchRenderActivity2_Response

定義於 fuchsia.media/activity_reporter.fidl

欄位類型說明預設
active_usages vector<AudioRenderUsage2>:8 無預設值

AudioCompressedFormatAac

定義於 fuchsia.media/stream_common.fidl

<EMPTY>

AudioCompressedFormatSbc

定義於 fuchsia.media/stream_common.fidl

<EMPTY>

AudioCore_GetDbFromVolume2_Response

定義於 fuchsia.media/audio_core.fidl

欄位類型說明預設
gain_db float32 無預設值

AudioCore_GetVolumeFromDb2_Response

定義於 fuchsia.media/audio_core.fidl

欄位類型說明預設
volume float32 無預設值

AudioDeviceInfo

定義於 fuchsia.media/audio_device_enumerator.fidl

欄位類型說明預設
name string 無預設值
unique_id string 無預設值
token_id uint64 無預設值
is_input bool 無預設值
gain_info AudioGainInfo 無預設值
is_default bool 無預設值

AudioGainInfo

定義於 fuchsia.media/audio_device_enumerator.fidl

欄位類型說明預設
gain_db float32 無預設值
flags AudioGainInfoFlags 無預設值

AudioStreamType

定義於 fuchsia.media/stream_type.fidl

說明音訊基本串流的類型。

欄位類型說明預設
sample_format AudioSampleFormat 無預設值
channels uint32 無預設值
frames_per_second uint32 無預設值

壓縮

定義於 fuchsia.media/stream_type.fidl

說明套用至串流的壓縮方式。這個類型可與 AudioStreamType 或 VideoStreamType 搭配使用,代表特定媒體的壓縮類型。

欄位類型說明預設
type CompressionType

套用至串流的壓縮類型。這通常是 ENCODING 值之一,但不得使用 AUDIO_ENCODING_LPCM 和 VIDEO_ENCODING_UNCOMPRESSED,因為這些編碼會視為未壓縮。

無預設值
parameters vector<uint8>:8192?

描述串流壓縮方式的類型專屬不透明「頻外」參數。

無預設值

EncryptionPattern

定義於 fuchsia.media/stream_common.fidl

EncryptionPattern

模式加密會使用加密和明文 16 位元組區塊的模式,涵蓋子樣本的受保護範圍 (SubsampleEntry 的 encrypted_bytes)。這個結構會指定加密資料區塊的數量,後面接著明文資料區塊的數量。

欄位類型說明預設
clear_blocks uint32 無預設值
encrypted_blocks uint32 無預設值

中繼資料

定義於 fuchsia.media/metadata.fidl

欄位類型說明預設
properties vector<Property> 無預設值

參數

定義於 fuchsia.media/stream_common.fidl

參數

一般參數。

我們希望盡可能以原生方式定義串流專屬參數語意,盡量減少使用這種一般「參數」結構。

欄位類型說明預設
scope string 無預設值
name string 無預設值
value Value 無預設值

PcmFormat

定義於 fuchsia.media/stream_common.fidl

PcmFormat

PCM 音訊格式詳細資料。

欄位類型說明預設
pcm_mode AudioPcmMode 無預設值
bits_per_sample uint32 無預設值
frames_per_second uint32 無預設值
channel_map vector<AudioChannelId>:16 無預設值

屬性

定義於 fuchsia.media/metadata.fidl

欄位類型說明預設
label string 無預設值
value string 無預設值

SbcEncoderSettings

定義於 fuchsia.media/stream_common.fidl

SBC 編碼器的設定。

SBC 編碼器會採用帶正負號的小端序 16 位元線性 PCM 樣本,並傳回編碼的 SBC 影格。SBC 編碼器會以 sub_bands * block_count 個 PCM 影格為一批,這個編碼器會接受任意影格邊界的 PCM 資料,但 EOS 排入佇列時排出的輸出內容可能會以零填補,以建立完整的編碼批次。

欄位類型說明預設
sub_bands SbcSubBands SbcSubBands.SUB_BANDS_8
allocation SbcAllocation SbcAllocation.ALLOC_LOUDNESS
block_count SbcBlockCount SbcBlockCount.BLOCK_COUNT_4
channel_mode SbcChannelMode 無預設值
bit_pool uint64

SBC 位元集區值。

無預設值

StreamPacket

定義於 fuchsia.media/stream.fidl

說明 StreamSink 消耗或 StreamSource 產生的封包。

欄位類型說明預設
pts int64

根據呈現時鐘,封包的呈現時間。

NO_TIMESTAMP
payload_buffer_id uint32

這個封包使用的酬載緩衝區 ID。

如果這個結構與 StreamBufferSet 搭配使用,這個欄位就是透過 StreamBufferSet.AddPayloadBuffer 提供的酬載緩衝區 ID。在這種情況下,這個值必須識別目前集合中的酬載緩衝區。其他介面可能會為這個欄位定義不同的語意。

無預設值
payload_offset uint64

封包酬載在酬載緩衝區中的偏移量。

這個值加上 payload_size 值,必須小於或等於參照酬載緩衝區的大小。

無預設值
payload_size uint64

酬載大小 (以位元組為單位)。

這個值加上 payload_offest 值,必須小於或等於參照酬載緩衝區的大小。

無預設值
flags uint32

一組位元 OR 運算旗標 (請參閱下方常數),用於描述這個封包的屬性。

0
buffer_config uint64

與這個封包相關聯的緩衝區設定。這個欄位的語意取決於使用這個結構體的介面。在許多情況下,這個欄位不會用到。這個欄位適用於明確識別緩衝區設定 (即酬載緩衝區組合) 的情況。在這種情況下,payload_buffer_id 是指這個欄位所識別緩衝區設定中的酬載緩衝區。

0
stream_segment_id uint64

與這個封包相關聯的串流片段。這個欄位的語意取決於使用這個結構體的介面。在許多情況下,這個欄位不會使用。這個欄位用於區分串流的連續區隔,其中串流屬性 (例如編碼) 可能因區隔而異。

0

StreamProcessor_RemoveBuffer_Response

定義於 fuchsia.media/stream_processor.fidl

<EMPTY>

StreamType

定義於 fuchsia.media/stream_type.fidl

說明基本串流的類型。

欄位類型說明預設
medium_specific MediumSpecificStreamType

媒體專屬類型資訊。

無預設值
encoding string:255

編碼 (請參閱下方的常數)。這個值會以字串表示,因此可以導入新的編碼,而不必修改這個檔案。

無預設值
encoding_parameters vector<uint8>?

編碼專屬參數,有時稱為「頻外資料」。這類資料通常與壓縮串流相關聯,並提供解壓縮串流所需的參數。除了串流的生產者和消費者外,這項資料通常對所有各方都不透明。

無預設值

SubpictureStreamType

定義於 fuchsia.media/stream_type.fidl

說明子畫面基本串流的類型。

<EMPTY>

SubsampleEntry

定義於 fuchsia.media/stream_common.fidl

SubsampleEntry

子樣本是樣本中的位元組範圍,由明文位元組範圍和加密位元組範圍組成。這個結構會指定子樣本中每個範圍的大小。

欄位類型說明預設
clear_bytes uint32 無預設值
encrypted_bytes uint32 無預設值

TextStreamType

定義於 fuchsia.media/stream_type.fidl

說明文字基本串流的類型。

<EMPTY>

TimelineFunction

定義於 fuchsia.media/timeline_function.fidl

TimelineFunction 代表主體時間軸與參考時間軸之間的線性關係。

舉例來說,假設常見用途中的參考時間是系統的單調時鐘,而主體時間是某些媒體 (例如影片) 的預定播放時間。

reference_time 是播放開始時單調時鐘的值。如果媒體從頭開始播放,subject_time 為 0。接著,我們選擇 reference_delta 和 subject_delta,讓 subject_delta / reference_delta 代表所需的播放速率,例如 0/1 代表暫停,1/1 代表正常播放。

公式

透過函式,我們可以使用以下公式 (其中 reference_delta > 0),根據參考時間軸值 r 判斷主體時間軸值 s:

s = (r - reference_time) * (subject_delta / reference_delta) + subject_time

同樣地,我們可以使用這個公式 (其中 subject_delta > 0),根據主體時間軸值 s 找出參考時間軸值 r:

r = (s - subject_time) * (reference_delta / subject_delta) + referenc_time

選擇時間值

時間值可以任意指定,線性關係當然也會相同,但我們可以使用這些值,表示分段線性關係中各段的界限。

舉例來說,如果使用者執行略過章節,我們可能會想用 TimelineFunction 來描述,其中 subject_time 是要略過的時間,reference_time 是現在加上一些 epsilon,而 delta 比率是 1/1,表示正常播放速率。

欄位類型說明預設
subject_time int64
新增:31
無預設值
reference_time int64
新增:31
無預設值
subject_delta uint32
新增:31
無預設值
reference_delta uint32
新增:31
無預設值

VideoStreamType

定義於 fuchsia.media/stream_type.fidl

說明影片基礎串流的類型。

欄位類型說明預設
pixel_format fuchsia.images/PixelFormat
已淘汰:13
無預設值
color_space ColorSpace 無預設值
width uint32

影片影格的尺寸 (以像素為單位)。

無預設值
height uint32 無預設值
coded_width uint32

影片影格的尺寸 (以像素為單位)。這些值必須等於或大於各自的寬度/高度值。

無預設值
coded_height uint32 無預設值
pixel_aspect_ratio_width uint32

影格顯示時單一像素的顯示比例。

無預設值
pixel_aspect_ratio_height uint32 無預設值
stride uint32

主要影片平面中每個「編碼」資料列的位元組數。

無預設值

VideoUncompressedFormat

定義於 fuchsia.media/stream_common.fidl

VideoUncompressedFormat

未壓縮影片格式詳細資料。

欄位類型說明預設
image_format fuchsia.sysmem/ImageFormat_2 無預設值
fourcc uint32 無預設值
primary_width_pixels uint32 無預設值
primary_height_pixels uint32 無預設值
secondary_width_pixels uint32 無預設值
secondary_height_pixels uint32 無預設值
planar bool 無預設值
swizzled bool 無預設值
primary_line_stride_bytes uint32 無預設值
secondary_line_stride_bytes uint32 無預設值
primary_start_offset uint32 無預設值
secondary_start_offset uint32 無預設值
tertiary_start_offset uint32 無預設值
primary_pixel_stride uint32 無預設值
secondary_pixel_stride uint32 無預設值
primary_display_width_pixels uint32 無預設值
primary_display_height_pixels uint32 無預設值
has_pixel_aspect_ratio bool 否
pixel_aspect_ratio_width uint32 1
pixel_aspect_ratio_height uint32 1

無效

定義於 fuchsia.media/audio_consumer.fidl

<EMPTY>

列舉

AacAudioObjectType strict

類型:uint32

定義於 fuchsia.media/stream_common.fidl

名稱值說明
0

MPEG-2 Low Complexity

1

MPEG-4 Low Complexity

strict AacChannelMode

類型:uint32

定義於 fuchsia.media/stream_common.fidl

名稱值說明
0
2

strict AacVariableBitRate

類型:uint32

定義於 fuchsia.media/stream_common.fidl

可變位元率模式。實際產生的位元率會因輸入訊號和其他編碼設定而異。

請參閱 https://wiki.hydrogenaud.io/index.php?title=Fraunhofer_FDK_AAC#Bitrate_Modes

名稱值說明
1
2
3
4
5

AudioBitrateMode strict

類型:uint32

定義於 fuchsia.media/stream_common.fidl

名稱值說明
0
1
2

AudioCaptureUsage strict

類型:uint32

定義於 fuchsia.media/audio_core.fidl

用途,用於註解擷取音訊的串流用途。音訊政策會使用 AudioCaptureUsage,決定音訊串流之間的互動方式。

名稱值說明
0

Stream 用於在背景擷取音訊。這些串流可能隨時處於啟用狀態,且視為具有特殊權限。範例:偵測啟動字詞

1

Stream 適用於一般擷取功能。如果串流建立者位於前景,且串流用於擷取音訊,則應使用這個屬性。範例:語音錄音工具

2

Stream 則用於與系統代理互動。只有在使用者表明有意與感興趣的對象互動時,才應使用這個方法。範例:Google 助理、Siri、Alexa

3

Stream 適用於使用者之間的即時通訊。語音/視訊通訊應使用此功能。

AudioCaptureUsage2 彈性

類型:uint32

定義於 fuchsia.media/audio_core.fidl

用途,用於註解擷取音訊的串流用途。音訊政策會使用 AudioCaptureUsage,決定音訊串流之間的互動方式。

名稱值說明
0

Stream 用於在背景擷取音訊。這些串流可能隨時處於啟用狀態,且視為具有特殊權限。範例:偵測啟動字詞

1

Stream 適用於一般擷取功能。如果串流建立者在前景執行時,串流用於擷取音訊,則應使用此屬性。範例:語音錄音工具

2

Stream 則用於與系統代理互動。只有在使用者表示有意與感興趣的對象互動時,才應使用這個方法。範例:Google 助理、Siri、Alexa

3

Stream 適用於某種形式的使用者即時通訊。語音/視訊通訊應使用此功能。

AudioChannelId strict

類型:uint32

定義於 fuchsia.media/stream_common.fidl

AudioChannelId

用於指定哪個音訊管道對應哪個揚聲器位置 / 類型。

TODO(b/529511595):我們是否需要/想要更多管道 ID?

名稱值說明
0
1
2
3
4
5
6
7
8
9
10
1862270976
2147483647

AudioOutputRoutingPolicy strict

類型:uint32

定義於 fuchsia.media/audio_core.fidl

已淘汰

名稱值說明
0
1

AudioPcmMode strict

類型:uint32

定義於 fuchsia.media/stream_common.fidl

名稱值說明
0
1
2

AudioRenderUsage strict

類型:uint32

定義於 fuchsia.media/audio_core.fidl

用途,用於註解用來轉譯音訊的串流用途。AudioRenderer 的用途建立後即無法變更。音訊政策會使用 AudioRenderUsage,決定音訊串流之間的互動方式。

名稱值說明
0

Stream 適用於環境或背景音效。如果串流可以中斷且不會造成任何後果,則應使用此值。

1

Stream 適用於一般功能。屬於正常功能的串流應使用此功能。

2

串流會中斷裝置目前執行的任何功能。用於通知等中斷情形的串流應使用此設定。

3

Stream 則用於與系統代理互動。這項功能應在使用者觸發時使用。

4

Stream 適用於使用者之間的即時通訊。語音/視訊通訊應使用此功能。

AudioRenderUsage2 彈性

類型:uint32

定義於 fuchsia.media/audio_core.fidl

用途:註解用於轉譯音訊的串流用途。AudioRenderer 的用途在建立後即無法變更。音訊政策會使用 AudioRenderUsage2 值,決定音訊串流之間的互動方式。這個列舉會以額外的串流類型,擴充原始 (嚴格) 列舉 |AudioRenderUsage|。

名稱值說明
0

Stream 適用於環境或背景音效。如果串流可以中斷且不會造成任何後果,則應使用此值。

1

Stream 適用於一般功能。屬於正常功能的串流應使用此功能。

2

串流會中斷裝置目前執行的任何功能。用於通知等中斷情形的串流應使用此設定。

3

Stream 則用於與系統代理互動。這項功能應在使用者觸發時使用。

4

Stream 適用於使用者之間的即時通訊。語音/視訊通訊應使用此功能。

5

Stream 適用於無障礙功能或其他非系統代理語音輸出,例如螢幕閱讀器 TTS。

AudioSampleFormat strict

類型:uint32

定義於 fuchsia.media/stream_type.fidl

列舉支援的音訊取樣格式。

名稱值說明
1

8 位元無符號樣本,樣本大小為 1 位元組。

2

16 位元帶正負號樣本,主機端序,樣本大小 2 位元組。

3

32 位元、主機位元組序、樣本大小 4 位元組的 24 位元帶正負號樣本。

4

32 位元浮點樣本,樣本大小為 4 位元組。

行為彈性

類型:uint32

定義於 fuchsia.media/audio_core.fidl

多個串流處於啟用狀態時,套用至串流的行為。

名稱值說明
0

混合串流。

1

套用增益,降低其中一個串流的音量。(-14.0db)

2

套用增益,將其中一個串流設為靜音。(-160.0db)

CodecProfile 彈性

類型:uint32

定義於 fuchsia.media/stream_common.fidl

允許的轉碼器設定檔清單。這份清單應保持彈性,因為日後可能會新增轉碼器。如有需要,這項設定可同時包含影片和音訊設定檔。

名稱值說明
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

ColorSpace strict

類型:uint32

定義於 fuchsia.media/stream_type.fidl

名稱值說明
0
1
2
3
4

Lc3FrameDuration 彈性

類型:uint32

定義於 fuchsia.media/stream_common.fidl

新增:HEAD

名稱值說明
1
2

彈性攜碼轉移

類型:uint32

定義於 fuchsia.media/stream_processor.fidl

這個列舉值代表 StreamProcessor 輸入或輸出。這會用於可套用至輸入或輸出的訊息。舉例來說,StreamProcessor.ParticipateInBufferAllocation 訊息包含 port 欄位。

新增:32

名稱值說明
0
1
2

SbcAllocation strict

類型:uint32

定義於 fuchsia.media/stream_common.fidl

名稱值說明
0
1

SbcBlockCount strict

類型:uint32

定義於 fuchsia.media/stream_common.fidl

名稱值說明
4
8
12
16

strict

類型:uint32

定義於 fuchsia.media/stream_common.fidl

名稱值說明
0
1
2
3

SbcSubBands strict

類型:uint32

定義於 fuchsia.media/stream_common.fidl

名稱值說明
4
8

StreamError strict

類型:uint32

定義於 fuchsia.media/stream_common.fidl

StreamError

這個錯誤代碼封裝了 StreamProcessor 伺服器可能發生的各種錯誤。這項資訊可以透過 OnStreamFailed 事件傳送,也可以做為管道的墓誌銘。

名稱值說明
1

發生內部錯誤,原因不明。

2

用戶端提供的輸入格式詳細資料無效。

3

伺服器收到的緩衝區不適合執行作業。舉例來說,如果解碼器收到的輸出緩衝區太小,無法將影格解碼至其中,就會發生這種情況。

4

無法處理輸入 EOS (串流結束),因此串流失敗。目前,如果核心轉碼器監控程式在處理 EOS 時觸發,就可能發生這種情況。

16777217

內部解碼器錯誤,原因不明。

16777218

無法剖析的輸入資料。只有部分剖析問題/錯誤會以這種方式回報。損毀的輸入資料可能會回報為其他 StreamError,也可能不會造成 StreamError。

33554433

內部編碼器錯誤,原因不明。

50331649

解密器發生內部錯誤,原因不明。

50331650

解密器無法使用要求的 KeyId。如果該金鑰可用,用戶端可以稍後再試。

VideoColorSpace strict

類型:uint32

定義於 fuchsia.media/stream_common.fidl

已淘汰:32 已新增:7

名稱值說明
0

TABLES

AudioCompressedFormatCvsd

定義於 fuchsia.media/stream_common.fidl

AudioCompressedFormatCvsd 目前不含任何欄位,因為我們會使用 Bluetooth Core Spec v5.3 第 9.2 節建議的參數值。

新增:HEAD

序數欄位類型說明

AudioCompressedFormatLc3

定義於 fuchsia.media/stream_common.fidl

AudioCompressedFormatLc3 不含任何欄位。設定解碼器所需的參數會嵌入為 FormatDetails.oob_bytes 中的 Codec_Specific_Configuration (Assigned Numbers 第 6.12.5 節)。

新增:HEAD

序數欄位類型說明

AudioConsumerStatus

定義於 fuchsia.media/audio_consumer.fidl

代表消費者的狀態。在初始狀態下,error 和 presentation_timeline 不存在。前置時間欄位一律會顯示。

序數欄位類型說明
error AudioConsumerError

如果存在,表示目前生效的錯誤條件。如果沒有錯誤,則不會顯示。

presentation_timeline TimelineFunction

如果存在,則表示顯示時間軸與本機單調時鐘之間的目前關係,兩者皆以奈秒為單位。如果不存在,則表示沒有關係。一開始不存在。

「Presentation timeline」是指封包上的 pts (顯示時間戳記) 值。這項時間軸函式可用於根據封包的 pts 值,判斷封包顯示的本機單調時鐘時間。

min_lead_time uint64

指出這個 AudioConsumer 支援的最短前置時間 (以奈秒為單位)。換句話說,提供給 AudioConsumer.Start 的 media_time 與第一個封包的 PTS 之間的差距可以有多小。超出這個範圍的值會遭到裁剪。

max_lead_time uint64

指出這個 AudioConsumer 支援的前置時間上限 (以奈秒為單位)。換句話說,提供給 AudioConsumer.Start 的 media_time 與第一個封包的 pts 之間,可以有多大的差距。超出這個範圍的值會遭到裁剪。

CvsdEncoderSettings

定義於 fuchsia.media/stream_common.fidl

CVSD 編碼器的設定。目前不含任何欄位,因為我們會使用 Bluetooth Core Spec v5.3 第 9.2 節建議的參數值。

新增:HEAD

序數欄位類型說明

DecryptedFormat

定義於 fuchsia.media/stream_common.fidl

DecryptedFormat

這會說明解密內容的格式。StreamProcessor 伺服器必須先傳送這個封包,才能傳送輸出封包。目前沒有解密輸出內容的其他格式詳細資料。

序數欄位類型說明
ignore_this_field bool

EncryptedFormat

定義於 fuchsia.media/stream_common.fidl

EncryptedFormat

解密串流處理器的串流格式詳細資料酬載。這個資料表中的資料稀疏,用於指定資料串流以外的解密必要參數。只有在欄位變更時才需要更新,但如果重複相同的值,也不會發生錯誤。

序數欄位類型說明
init_vector InitVector

init_vector 會與金鑰和內容區塊搭配使用,在鏈結中建立第一個密碼區塊,並在密碼區塊鏈中衍生後續的密碼區塊。使用方式:

  • 必須先設定,才能將輸入封包傳送至解密器。
  • 在資料串流期間,這項設定可能會變更數次。
subsamples vector<SubsampleEntry>

subsamples 用於識別子樣本的明文和加密部分。使用方式:

  • 如要加密整個樣本,請勿傳送這個參數。
  • 在資料串流期間,這項設定可能會變更多次。
pattern EncryptionPattern

pattern 用於識別模式型加密的明文和加密區塊。使用方式:

  • CENC 和 CBC1 不允許使用這個屬性,CENS 和 CBCS 則必須使用。
  • 如有需要,必須先設定這個屬性,再將輸入封包傳送至解密器。
  • 在資料串流期間,這項設定可能會變更數次。
scheme string

scheme 指定要使用的加密配置,例如 fuchsia.media.ENCRYPTION_SCHEME_CENC。使用方式:

  • 必須在傳送輸入封包前設定。
  • 只有在某些情況下,才允許在串流中途變更配置。 為串流選取加密配置後,該配置只能設為 fuchsia.media.ENCRYPTION_SCHEME_UNENCRYPTED 或相同的初始加密配置。配置隨時可以設為 fuchsia.media.ENCRYPTION_SCHEME_UNENCRYPTED。
key_id KeyId

key_id 會識別應用於解密後續資料的金鑰。使用方式:

  • 必須先設定這項屬性,才能將輸入封包傳送至解密器。
  • 在資料串流期間,這項設定可能會變更數次。

FormatDetails

定義於 fuchsia.media/stream_common.fidl

FormatDetails

這會說明/詳述 StreamProcessor 輸入或輸出的格式 (輸入和輸出為不同執行個體)。

序數欄位類型說明
format_details_version_ordinal uint64

FormatDetails 的特定例項會設定這個欄位,讓接收器更容易判斷格式的任何部分是否與上次收到的相同內容 FormatDetails 相比有所變更。

StreamProcessor 輸入:建立 StreamProcessor 時,系統會提供初始輸入 FormatDetails,並附上初始 format_details_version_ordinal (通常為 0,如果省略,CodecImpl 預設為 0,但用戶端應設定)。在特定串流中,每個 QueueInputFormatDetails 的 format_details_version_ordinal 必須大於或等於該串流先前的輸入 format_details_version_ordinal,且如果 FormatDetails 的任何部分與該串流先前的輸入 FormatDetails 相比有所變更,則必須嚴格增加 format_details_version_ordinal。啟動新串流時,串流的初始輸入 FormatDetails (及其 format_details_version_ordinal) 會預設回 StreamProcessor 建立時指定的初始 FormatDetails,因此序數可能會在串流切換時降至較低的數字。

StreamProcessor 輸出:在特定串流中,每當輸出 FormatDetails 變更時,OnOutputFormat 的 format_details_version_ordinal 就會增加。在串流切換期間,伺服器 (例如 CodecImpl) 可能會繼續增加輸出 format_details_version_ordinal,而不是依串流重設 (這是允許的序列),或是在串流切換期間降低至較低的數字 (OnOutputFormat 一律會在新的串流第一個輸出封包之前傳送)。

mime_type string
oob_bytes vector<uint8>
domain DomainFormat
pass_through_parameters vector<Parameter>
encoder_settings EncoderSettings

指示編碼器如何編碼原始資料。

解碼器可能會忽略這個欄位,但有權拒絕設定這個欄位的要求,因為這不合理。

timebase uint64

輸入封包 timestamp_ish 值的時基每秒刻度數。

只有在輸入時間戳記 (適用於輸入封包有效部分的位元組 0) 未直接對應至任何輸出封包有效部分的位元組 0 時,時基才會用於 timestamp_ish 值的選用外推。

如果不需要時間戳記外推,請保持未設定狀態,原因可能是輸入內容缺少時間戳記,或輸入內容是以編碼器輸入區塊大小的增量提供 (根據編碼器設定,並由用戶端獨立計算)。如果已知需要時間戳記外推,或已知用戶端可接受,請設定。

profile CodecProfile

指定編碼器或解碼器的轉碼器設定檔。

編碼器:這個值完全是選填。基於通訊協定相容性 (例如 WebRTC),用戶端可能需要指定轉碼器設定檔。不過,如果未設定值,編碼器可以自由選擇任何支援的轉碼器設定檔。

解碼器:這個值為選用,但建議提供 (至少針對未加密串流)。容器格式包含編碼設定檔,應提供給解碼器。某些格式 (例如 VP9 和 AV1) 會在基本位元串流中加入編碼設定檔,因此這些解碼器可以找出串流編碼的設定檔。無論如何,用戶端應盡可能提供編碼設定檔。

H264EncoderSettings

定義於 fuchsia.media/stream_common.fidl

H264 編碼器的設定。

序數欄位類型說明
bit_rate uint32

編碼串流的目標每秒位元數。如果省略,則視為 200,000。

frame_rate uint32

編碼串流的目標每秒影格數。如果省略,則解讀為 30。

gop_size uint32

每個主影格的圖片數量。如果設為 0,系統會停用關鍵影格編碼,除非 force_key_frame 設為 true。如果省略,則解讀為 8。

variable_frame_rate bool

是否啟用影格率調整功能,以達到目標位元率。如果省略,則視為 false。

min_frame_rate uint32

啟用 variable_frame_rate 時允許的最低影格率。如果省略,則解讀為 10。

force_key_frame bool

如果為 true,下一個編碼的影格會是關鍵影格。如果省略,則解讀為 false。

quantization_params H264QuantizationParameters

允許自訂編碼的量化參數。設定完成後,系統會使用新值提交每個影格。如果省略,則不會變更編碼器預設值。

H264QuantizationParameters

定義於 fuchsia.media/stream_common.fidl

自訂巨集區塊量化的 h264 編碼器參數。值介於 0 到 51 之間,數字越低,代表品質/位元率越高。雖然編碼器應盡可能支援這些欄位,但部分編碼器可能會忽略這些欄位。您可以不設定這個表格,或不設定表格中的部分欄位,因為編碼器可以自行決定預設值。如果無法以指定值達到目標位元率,使用者應預期產生的編碼串流位元率會與要求的位元率不同。

序數欄位類型說明
i_base uint32

關鍵影格量化的起始值。

i_min uint32

關鍵影格量化的最小值。

i_max uint32

關鍵影格量化的最大允許值。

p_base uint32

預測影格量化的起始值。

p_min uint32

預測影格量化的最小值。

p_max uint32

預測影格量化的最大允許值。

HevcEncoderSettings

定義於 fuchsia.media/stream_common.fidl

HEVC/H265 編碼器的設定。

序數欄位類型說明
bit_rate uint32

編碼串流的目標每秒位元數。如省略,則預設為 200,000。

frame_rate uint32

編碼串流的目標每秒影格數。如省略,預設為 30。

gop_size uint32

每個主畫面格的圖片數量。如省略,預設為 8。

InputAudioCapturerConfiguration

定義於 fuchsia.media/audio_capturer.fidl

擷取器的設定,用於接收輸入裝置的串流。

序數欄位類型說明
usage AudioCaptureUsage

已淘汰 :請使用 usage2 和 AudioCaptureUsage2

usage2 AudioCaptureUsage2

Lc3EncoderSettings

定義於 fuchsia.media/stream_common.fidl

LC3 編碼器的設定。包含 LC3 規格 1.0 版中說明的參數。包含 PcmFormat 未表示的欄位。

新增:HEAD

序數欄位類型說明
nbytes uint16

用於音訊影格編碼的外部位元組計數值。根據 LC3 規格 v1.0,每個音訊管道可能會有不同的輸出位元組大小值,但 Fuchsia 的用途是為所有通道使用相同的 nbytes 值。

frame_duration Lc3FrameDuration

影格時間長度會與取樣頻率搭配使用,以決定影格大小。

LoopbackAudioCapturerConfiguration

定義於 fuchsia.media/audio_capturer.fidl

擷取器的設定,會接收系統輸出的回送串流。

序數欄位類型說明

MSbcEncoderSettings

定義於 fuchsia.media/stream_common.fidl

mSBC 編碼器的設定。mSBC 編碼器會使用 HFP 規格第 1.8 版所需的值,因此沒有任何設定。

新增:HEAD

序數欄位類型說明

封包

定義於 fuchsia.media/stream_processor.fidl

封包代表串流處理器輸入或輸出的資料區塊。

串流處理器輸出內容:

當封包透過 OnOutputPacket() 傳送至用戶端時,串流處理器會避免修改參照的輸出資料。用戶端呼叫 RecycleOutputPacket(packet_index) 後,串流處理器會收到通知,得知用戶端再次同意變更參照資料。

串流處理器輸入:

用戶端一開始會提供所有可填入的 packet_index,之後會透過 OnFreeInputPacket() 再次取得可填入的 packet_index。用戶端不得在 QueueInputPacket() 和 OnFreeInputPacket() 之間修改參照資料。

序數欄位類型說明
header PacketHeader
buffer_index uint32

這個封包參照的緩衝區。封包的指定傳輸中時間間隔是指使用 buffer_lifetime_ordinal (在 PacketHeader 中) 和 buffer_index 的特定緩衝區。

用戶端應準備好處理參照舊 buffer_lifetime_ordinal 的輸出封包 (buffer_index 範圍限定為舊 buffer_lifetime_ordinal)。(根據作者目前的經驗) 這種串流並不常見。部分用戶端可能偏好忽略 buffer_lifetime_ordinal 舊的輸出封包,或注意到 buffer_lifetime_ordinal 舊,並在用戶端端失敗串流。如果用戶端想要完整處理這類串流 (適用於一開始就能執行這項操作的位元串流格式),可以使用 RemoveBuffer 完成作業,偵測舊 buffer_lifetime_ordinal 的每個緩衝區何時不會再於任何後續輸出封包中參照。如果舊緩衝區中的影格尺寸與先前的輸出影格不同,系統會在輸出封包之間傳送 OnOutputFormat (如往常)。

用戶端應準備好處理 (即「不當機」) 兩個或多個輸出封包參照相同緩衝區的情況,而第一個輸出封包尚未回收至 StreamProcessor。我們刻意不保證與用戶端傳輸中的封包都會參照不重複的緩衝區,至少在 VP9 show_existing_frame 方面是如此,其他位元串流格式中的類似編碼工具可能也是如此。直接用戶端上方的某些層可能不支援這項功能,在這種情況下,如果用戶端不需要支援解碼執行這項操作的串流,則在用戶端失敗串流可能是可接受的。在這種情況下,更複雜的翻譯策略不在本文件的討論範圍內。如果用戶端打算處理受 DRM 保護的串流,請注意,可能無法使用 CPU 複製影格內容。明確來說,本文作者從未看過受 DRM 保護的串流會這樣做,而唯一看過這樣做的非 DRM 保護串流是測試串流。不過,用戶端作者仍應注意,「野外」的串流可能會發生這種情況。

無論是否使用動態緩衝區,都支援 RemoveBuffer。搭配非動態緩衝區使用 RemoveBuffer 時,不需要使用 AddBuffer,因為 SetInputBufferPartialSettings 或 SetOutputBufferPartialSettings 已用於新增 buffer_lifetime_ordinal 的所有緩衝區。不過,如果是非動態緩衝區,RemoveBuffer 實際上不會開始移除緩衝區。但緩衝區完全移除後,就會完成。

只有在封包傳輸期間,封包才會有相關聯的 buffer_lifetime_ordinal 和 buffer_index,封包閒置時則沒有。

如果不使用動態緩衝區,這個值會與 sysmem buffer_index 相同。

使用動態緩衝區時,這個值與 sysmem buffer_index 不同 (除非是偶然),也不保證是小數字。

根據預設,對於輸出緩衝區,這個 buffer_index 值保證在目前與用戶端進行中的相同 buffer_lifetime_ordinal 緩衝區中是唯一的。解碼位元串流格式時,如果多個封包同時位於輸出佇列中 (可能具有不同的 timestamp_ish 值),則可輸出支援不同輸出封包的相同緩衝區。在這種情況下,用戶端可以傳送 EnableSameOutputBufferConcurrentlyInFlight,表示用戶端已準備好同時處理多個參照相同輸出緩衝區的輸出封包。除了位元串流格式測試外,很少有串流會因此產生差異。

stream_lifetime_ordinal uint64

1 是建立串流處理器後允許的最低值。用戶端傳送的值必須是奇數。值只能增加。

stream_lifetime_ordinal 代表串流的生命週期。所有特定串流的訊息都有 stream_lifetime_ordinal 值,且與特定串流相關的所有訊息都有相同的值。

start_offset uint32

這個封包使用的是相關緩衝區的哪個部分。這些設定適用於傳輸至串流處理器的輸入資料,以及串流處理器的輸出資料。

對於壓縮格式和未壓縮音訊,[start_offset, start_offset + valid_length_bytes) 中的資料是這個封包參照的連續有效資料。

對於未壓縮的影片影格,FormatDetails 是判斷哪些位元組相關的主要方法。FormatDetails 中的偏移量是相對於此處的 start_offset。valid_length_bytes 必須夠大,才能包含像素資料的完整最後一行,包括最後一行的完整行步幅 (不只是最後一行的像素寬度)。

雖然這些緩衝區已填滿,但部分未壓縮的影片緩衝區類型無法由 CPU 讀取。這些欄位存在並不代表 CPU 有辦法讀取未壓縮的影格。

valid_length_bytes uint32

這個值必須大於 0。

每個封包的有效資料語意會因資料類型而異,如下所示。

未壓縮影片:影片影格無法分割成多個封包。每個封包都是一個影片影格。

未壓縮音訊:無論是浮點或整數、線性或 uLaw,還是聲道數量,封包都必須包含非負數的完整音訊影格,其中單一音訊影格包含相同時間點的所有聲道資料。任何與串流處理器相關的內部詳細資料,例如 LFE 管道的較低取樣率等,都應由 StreamProcessor 伺服器實作隱藏。

compressed data input - A packet must contain at least one byte of data. 另請參閱 stream_input_bytes_min。允許在任意位元組邊界分割 AU,包括 AU 標頭中的邊界。

壓縮資料輸出:串流處理器不需要完全填滿每個輸出封包的緩衝區。

timestamp_ish uint64

嚴格來說,這個值並非時間戳記。這是一個任意的無正負號 64 位元數字,在某些情況下,串流處理器會將其從輸入封包未經修改地傳遞至完全對應的輸出封包。

如要將 timestamp_ish 值從輸入傳播到輸出,必須符合下列條件:

  • promise_separate_access_units_on_input 必須為 true
  • 指定輸入封包的 has_timestamp_ish 必須為 true,該 timestamp_ish 值才可能傳播至輸出封包
  • StreamProcessor 執行個體本身會決定 (非同步) 輸入封包是否會產生輸出封包。如果特定輸入封包從未產生輸出封包,則輸入封包上的 timestamp_ish 值就不會出現在任何輸出封包上。視輸入和輸出格式的特性,以及解碼器是否願意加入中途串流等因素而定,這種情況發生的可能性或多或少,但用戶端應編寫為可容納輸入封包中提供但從未出現在輸出封包中的 timestamp_ish 值,至少在合理程度上 (不當機、不視為錯誤)。
start_access_unit bool

如果 promise_separate_access_units_on_input (TODO(dustingreen):或任何類似的輸出模式) 為 true,則必須根據位元組 0「是」或「不是」存取單元的開頭,適當設定這個 bool。用戶端必須知道並正確設定這個布林值。如果這個布林值為 false,伺服器可以推斷位元組 0 是先前啟動的 AU 延續的第一個位元組。(start_offset 的位元組為「位元組 0」)。

如果 promise_separate_access_units_on_input 為 false,系統會忽略這個布林值。

known_end_access_unit bool

用戶端不一定要將這個布林值設為 true。

如果 promise_separate_access_units_on_input 為 true,則對於輸入資料,如果這個封包不包含此封包中包含或部分包含的最多一個 AU 的最後一個位元組,則此布林值必須為 false,且如果最多一個 AU 的最後一個位元組在此封包中,則此布林值可能為 true。如果用戶端一次傳送一個 AU,且希望透過解碼器盡可能降低延遲時間,則應在可設為 true 時,將這個布林值設為 true。

如果 promise_separate_access_units_on_input 為 false,系統會忽略這個布林值。

部分位元串流格式具有存取單位分隔符或類似概念。如果用戶端希望達到低延遲,可以選擇在每個存取單元後插入格式正確的存取單元分隔符 (或類似符號),做為向解碼器發出存取單元已結束信號的替代方式。不過,我們仍建議這類用戶端盡可能將這個欄位設為 true,確保解碼器的所有層級都能收到通知。如果設為 true (解碼器正常運作),則可以插入存取單位分隔符,但並非必要 (為了縮短延遲時間)。用戶端不需移除串流中可能已存在的任何存取單位分隔符,這個欄位的設定不一定要與任何存取單位分隔符的存在/不存在相符。

key_frame bool

用於壓縮影片封包。如果未提供,則應視為未知。如果為 false,表示封包不屬於關鍵影格。如果為 true,表示封包是關鍵影格的一部分。

PacketHeader

定義於 fuchsia.media/stream_processor.fidl

PacketHeader

提及可用封包時,我們會單獨使用 PacketHeader,而非 Packet,因為可用封包實際上沒有有意義的偏移或長度等。

已填入資料的 Packet 也會有 PacketHeader。

序數欄位類型說明
buffer_lifetime_ordinal uint64

這個標頭是指緩衝區設定生命週期。

請參閱 [fuchsia.mediacodec/StreamBufferPartialSettings.buffer_lifetime_ordinal]。

對於 QueueInputPacket(),如果伺服器收到的 buffer_lifetime_ordinal 不是目前的輸入 buffer_lifetime_ordinal,就會關閉管道。

如果是輸出封包,只有在用戶端傳送 EnableOldOutputBuffers 時,才能使用舊的 buffer_lifetime_ordinal。另請參閱 RemoveBuffer,判斷何時可以安全停止追蹤舊的輸出緩衝區 (僅與部分影片位元串流格式 (例如 VP9) 相關,且僅與解碼器相關)。除了位元串流格式測試串流外,很少有串流會發出舊的輸出緩衝區。

packet_index uint32

使用 SetInputBufferPartialSettings 或 SetOutputBufferPartialSettings 分配緩衝區時,packet_index 的有效範圍為 0..buffer_count-1,其中 buffer_count 是 [fuchsia.sysmem2/BufferCollectionInfo.buffers] 的長度,輸入和輸出會分開考量。

使用 ParticipateInBufferAllocation 和 AddBuffer 分配及新增緩衝區時,packet_index 的有效範圍不受限制 (任何 uint32 值)。用戶端和伺服器仍須確保 packet_index 值不會重複使用,直到另一端指出 packet_index 值再次可用且可重複使用。

每個通訊埠 (輸入與輸出) 和 buffer_lifetime_ordinal 的並行傳輸中 packet_index 值數量有限。如果用戶端從不使用多個輸入封包同時傳送相同的輸入緩衝區,這本質上可確保用戶端符合這項限制。大多數用戶端可以放心忽略伺服器輸出的這項限制。限制如下: * 傳送封包時,傳送端必須確保通訊埠 (輸入或輸出) 和 buffer_lifetime_ordinal 下同時傳輸中的 packet_index 值數量,不超過伺服器目前在 buffer_lifetime_ordinal 下同時存在的緩衝區高水位標記數量。使用 SetInputBufferPartialSettings 時,這就是上述的 buffer_count。

  • 使用 AddBuffer 時,輸入和輸出的高水位值決定方式略有不同。
    • 對於輸入,這個高水位值是目前為止的最大值,低於 buffer_lifetime_ordinal 的 AddBuffer 訊息總數 (關於 buffer_lifetime_ordinal) 減去 RemoveBuffer 訊息總數 (關於 buffer_lifetime_ordinal)。
      • 如果用戶端從不使用多個不同的輸入 packet_index 值,同時將輸入緩衝區傳送超過一次,則用戶端本質上會保持在輸入限制之下。
    • 如果是輸出,這個高水位值是目前 buffer_lifetime_ordinal 下的最大值,計算方式是 AddBuffer 訊息總數減去 buffer_lifetime_ordinal 下已完成的緩衝區移除總數。buffer_lifetime_ordinal無論緩衝區移除作業是否有對應的 RemoveBuffer 完成作業,都是如此。
      • 如果用戶端希望 (選擇性) 驗證這項伺服器行為,可以依賴伺服器在伺服器端完成緩衝區移除後,才完成 RemoveBuffer (否則伺服器無法符合 RemoveBuffer 語意或無法符合這項限制)。

對於輸入,用戶端在傳送含有 QueueInputPacket 的輸入封包時,會任意選擇可用的 packet_index 值,且在伺服器傳送含有該 packet_index 值的 OnFreeInputPacket 之前,用戶端不會重複使用該值。

對於輸出,伺服器在傳送含有 OnOutputPacket 的輸出封包時,會任意選擇可用的 packet_index 值 (在所有 uint32 值中),且在用戶端傳送含有該 packet_index 值的 RecycleOutputPacket 之前,不會重複使用該值。

可用的 packet_index 值可以任意順序排入佇列。

用戶端和伺服器都應根據已知繫結 (如有,請參閱上文) 驗證 packet_index,如果超出繫結範圍,則中斷連線。

packet_index 值不代表封包的使用順序。用戶端不應預期順序會隨著時間保持不變,串流處理器可以保留輸入或輸出封包一段時間,在此期間,某些 packet_index 值可能會重複使用多次。

對於正常運作的指定 StreamProcessor 執行個體,輸出 packet_index 值在同時未完成的封包中會是唯一的。

伺服器應驗證用戶端是否重複使用封包,用戶端也應以類似方式驗證伺服器的 packet_index 值。

StreamBufferConstraints

定義於 fuchsia.media/stream_processor.fidl

這個結構體會傳達 buffer_constraints_version_ordinal。

這個表格過去包含的欄位比現在多,但這些欄位都已淘汰,改用 sysmem。

這個結構體有不同的執行個體,分別用於串流輸入和串流輸出。

欄位注意事項:

對於未壓縮的影片,一律必須在不同的緩衝區中提供獨立且完整的影格 (每封包緩衝區模式)。

序數欄位類型說明
buffer_constraints_version_ordinal uint64

這是伺服器在限制上設定的版本號碼,可讓伺服器判斷用戶端何時已趕上伺服器傳送的最新限制。用戶端必須先設定輸出設定和緩衝區,且 buffer_constraints_version_ordinal >= buffer_constraints_action_required 為 true 的最新 buffer_constraints_version_ordinal,伺服器才會發出輸出資料。詳情請參閱 buffer_constraints_action_required 註解。

為簡化初始狀態處理,不允許 buffer_constraints_version_ordinal 為 0。除了 0 以外,奇數和偶數版本序數都允許 (與 stream_lifetime_ordinal 相反,用戶端和伺服器都沒有理由認為最新版本已過時,因此不允許偶數值沒有任何好處)。

default_settings StreamBufferSettings

已淘汰 :請忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints()

per_packet_buffer_bytes_min uint32

已淘汰 :請忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints()

per_packet_buffer_bytes_max uint32

已淘汰 :請忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints()

packet_count_for_server_min uint32

已淘汰 :請忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints()

packet_count_for_server_max uint32

已淘汰 :請忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints()

packet_count_for_client_min uint32

已淘汰 :請忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints()

packet_count_for_client_max uint32

已淘汰 :請忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints()

single_buffer_mode_allowed bool

已淘汰 :請忽略。已淘汰。

is_physically_contiguous_required bool

已淘汰 :請忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints()

buffer_count_for_server_current uint32

如果轉碼器的 [fuchsia.mediacodec/DetailedCodecDescription.supports_dynamic_buffers] 設為 true,伺服器必須設定這個欄位,且該欄位會是伺服器需要同時使用 (或繼續使用) 的輸入或輸出緩衝區數量下限,以確保向前進度。如果是影片解碼器,這個數字假設串流符合位元串流標準。只要伺服器沒有這麼多緩衝區可供伺服器同時使用 (DPB 大小 + 1),處理作業可能會暫停,但不會失敗。在這種情況下,用戶端可以使用 AddBuffers 新增更多緩衝區,重新啟動處理作業。當 DPB 需要參照更多圖片時,回收輸出緩衝區不一定會重新開始處理,因為圖片可能仍在 DPB 中,因此即使緩衝區已由用戶端回收,也無法重複使用。

對於輸入,轉碼器可能需要這麼多緩衝區,才能處理任何輸入。目前,輸入的這個值在每個 StreamProcessor 執行個體中都是靜態的。在新增這麼多輸入緩衝區之前,用戶端可以傳送 QueueInput...() 訊息,但至少要新增這麼多輸入緩衝區,才能預期有任何輸出。這也適用於任何 QueueInputPacket 之前的 QueueInputFormatDetails 和 QueueInputEndOfStream,適用於新啟動的串流,因此在目前仍未新增輸入緩衝區的情況下,可以傳送前兩個。如果轉碼器只需要一個輸入緩衝區就能繼續執行 (非連續、非流暢的執行也算),則應將這個值設為 1。大多數用戶端會希望新增少量額外緩衝區,讓管道順暢運作,避免在 OnFreeInputPacket 從轉碼器傳送至用戶端時,處理作業停滯。將輸入資料複製到獨立串流緩衝區 (有時視為循環) 的解碼器,通常只需要一個輸入緩衝區,就能向前推進,但大多數用戶端仍會想要新增少量額外的輸入緩衝區,以便更順暢地排程執行緒,即使這類解碼器核心可能在單一輸入緩衝區中以 100% 的使用率執行。

對於影片解碼器輸出,如果用戶端整體只 AddBuffers 這麼多緩衝區,則每次發生 OnOutputPacket 時,解碼器可能會停滯,直到伺服器收到 RecycleOutputPacket 為止。因此,大多數用戶端會偏好分配更多緩衝區,考量到管道的其他部分 (無論是否位於用戶端本機) 也可能需要「暫存」緩衝區,原因與影片解碼無關,也可能需要少量額外緩衝區,以維持管道順暢運作,避免在可用緩衝區即將回收或類似情況時,解碼作業停滯。

如果是影片解碼器輸出,設定後,這個值一律會小於或等於 [fuchsia.mediacodec/DetailedCodecDescription.dynamic_buffers_video_decoder_output_safe]。

伺服器傳送新的 OnOutputConstraints (action_required 為 false) 時,可以更新這個值。不過,即使「action_required」為 false,用戶端仍須確保目前可供轉碼器同時使用的緩衝區數量至少達到這個值。

如果用戶端使用動態緩衝區搭配影片解碼器,但不想注意這個欄位,則仍應注意 [fuchsia.mediacodec/DetailedCodecDescription.dynamic_buffers_video_decoder_output_safe]。或者,用戶端也可以改用 SetInputBufferPartialSettings/SetOutputBufferPartialSettings,這在整體緩衝區數量方面 (假設管道運作正常) 的效果大致相同 (可能會有負面影響)。雖然這些較不複雜的用戶端實作選項一開始可能看起來會浪費一些記憶體,但只有在串流具有所需選用欄位且值小於最大 DPB 大小時,注意 buffer_count_for_server_current (相較於僅 dynamic_buffers_video_decoder_output_safe) 才能節省記憶體,但很遺憾,這無法保證。特別是,在 vui_parameters (或任何其他地方) 未設定 max_num_reorder_frames 或 max_dec_frame_buffering 的 h.264 串流似乎比不設定更常見 (對作者來說,在目前觀察到的串流中),不過這可能很大程度上取決於用戶端想要解碼的特定串流組合。用戶端實作者可能需要先檢查一些相關串流,確認是否有相關位元串流標頭欄位,再考慮這個欄位以及這個欄位傳達的值對影片解碼器的動態變更。此外,用戶端實作者可以自由使用其他策略來節省記憶體,例如減少緩衝區數量,但如果轉碼器似乎需要緩衝區 (例如下游佇列輸出緩衝區開始不足),則動態且快速地新增緩衝區。這類策略由客戶決定,如果客戶採用這類策略,就必須掌握正確時機 (要完美正確 / 調整並不容易)。平台不保證額外緩衝區的分配速度,因此如果用戶端嘗試以低於 dynamic_buffers_video_decoder_output_safe 的數量執行,可能會遇到串流轉譯卡頓或類似問題,包括在串流中途發生。平台不保證在這種情況下能避免卡頓,例如有中串流標頭增加這個輸出值 (不常見)。

建議上層允許將較小的圖片儲存在較大的緩衝區中,這樣一來,中串流維度變更就不需要重新分配緩衝區。在這種情況下,幾乎一律建議繼續使用現有的大型緩衝區,避免因分配緩衝區的速度不一定符合預期,加上輸出緩衝區數量不一定有足夠的額外緩衝區,無法及時吸收緩衝區重新分配,而導致轉譯卡頓。不過,如果上層確實必須在圖片大小變更時重新分配緩衝區,且保留圖片所需的緩衝區空間減少,則這類用戶端必須設定傳遞至 CreateDecoder 的 force_new_buffers_for_new_dimensions。否則,影片解碼器可以開始將較小的圖片放入現有較大的緩衝區,並顯示 OnOutputFormat 訊息。

新增:32
size fuchsia.math/SizeU

用戶端可以忽略這個欄位。

只有在 [fuchsia.mediacodec/DetailedCodecDescription.supports_dynamic_buffers] 為 true,且指示通訊埠輸出未壓縮影片時,才會設定這個欄位。

這個欄位僅供參考,適用於可能想瞭解這項資訊的用戶端。不過,即使用戶端未讀取這個欄位,StreamProcessor 和 sysmem 通訊協定仍可正常運作。

這是必要的編碼大小,不會裁剪成顯示大小。

如果用戶端直接以 sysmem 參與者的身分參與,則不應設定與此大小不相容的限制,否則分配會失敗。請勿將這個欄位解讀為特定緩衝區只能使用單一圖片大小。一般來說,這種說法並不正確。而是表示 StreamProcessor sysmem 參與者使用傳遞至 SetInputBufferPartialSettings、SetOutputBufferPartialSettings 或 ParticipateInBufferAllocation 的權杖,設定 required_min_size 和 required_max_size 所涵蓋的大小。

雖然這個大小表示特定寬度和高度,但分配的緩衝區可能允許一系列圖片大小 (用於影片解碼器輸出或影片編碼器輸入)。

新增:32
pixel_format fuchsia.images2/PixelFormat

用戶端可以忽略這個欄位。

只有在 [fuchsia.mediacodec/DetailedCodecDescription.supports_dynamic_buffers] 為 true,且指示通訊埠傳送未壓縮的影片時,才會設定這個欄位。

這個欄位僅供參考,適用於可能想瞭解這項資訊的用戶端。不過,即使用戶端未讀取這個欄位,StreamProcessor 和 sysmem 通訊協定仍可正常運作。

在 StreamProcessor 伺服器支援的像素格式中,有些可承載圖片的完整位元深度,有些則廣泛支援承載所需位元深度的圖片。假設 pixel_format_modifier 為線性,則這是單獨考量 StreamProcessor 時,效能最高的像素格式。如果多個合格格式的效能基本上相同,則應選擇最常見的格式 (或在常見程度大致相同的格式中任意選擇)。大多數 StreamProcessor 伺服器都會硬式編碼特定格式,並在每個支援的位元深度中填入這個欄位。

目前預期不需要在這裡列出清單,但如果遇到非測試情境,且只能透過在這裡列出清單 (或透過 ParticipateInBufferAllocation 嘗試多個測試分配,或新增 sysmem 功能) 解決,請與我們聯絡。

一般來說,sysmem 不保證會選取這個像素格式,因為這取決於 StreamProcessor 執行個體和其他 sysmem 參與者支援的完整像素格式組合。如果只有用戶端和 StreamProcessor 是 sysmem 參與者 (例如在某些測試中),且用戶端需要這個像素格式,緩衝區分配仍可成功。一般非測試用戶端不需要也不會想限制 sysmem 分配,只允許這種像素格式,因為與讓 sysmem 挑選所有參與者共同支援的格式相比,這種做法更有可能導致分配失敗。

新增:32

StreamBufferPartialSettings 資源

定義於 fuchsia.media/stream_processor.fidl

序數欄位類型說明
buffer_lifetime_ordinal uint64

每個緩衝區都與 buffer_lifetime_ordinal 值相關聯。

輸入和輸出有不同的 buffer_lifetime_ordinal。

值必須是奇數。值只能增加 (允許增加超過 2)。

使用 SetInputBufferPartialSettings 或 SetOutputBufferPartialSettings 時,新訊息不得重複使用相同的值 (輸入和輸出分開考量)。使用這些訊息時,系統會將特定 buffer_lifetime_ordinal 值的所有緩衝區,分配為一個 sysmem 緩衝區集合。

新的 buffer_lifetime_ordinal 啟動時,也會自動開始取消註冊及釋出與先前 buffer_lifetime_ordinal 值相關聯的任何緩衝區,但如果轉碼器仍使用這些緩衝區做為參考,則不會強制完成取消註冊 (或釋出) (VP9 可在串流中維度切換時執行這項操作)。在取消註冊完成前,伺服器仍可輸出緩衝區 (如輸出封包所示)。

如果用戶端希望伺服器快速捨棄所有緩衝區,可以傳送 CloseCurrentStream,並設定 release_input_buffers 和/或 release_output_buffers。這當然也會停止解碼目前的串流。另一個選項是關閉 StreamProcessor 用戶端。

buffer_constraints_version_ordinal uint64

這個值代表用戶端目前/先前知道的限制版本。

對於輸入,這必須一律為 0,因為輸入的限制不會變更 (設定可以變更,但輸入沒有設定與目前限制同步的問題)。

對於輸出,這可讓伺服器在產生更多輸出之前,知道用戶端何時已充分趕上。

如果沒有任何進行中的串流,用戶端可以使用相同的 buffer_constraints_version_ordinal 重新設定緩衝區。

single_buffer_mode bool
已淘汰:23

已淘汰 :請忽略。已淘汰。

packet_count_for_server uint32
已淘汰:23

已淘汰 :請忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints()

packet_count_for_client uint32
已淘汰:23

已淘汰 :請忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints()

sysmem_token client_end:fuchsia.sysmem/BufferCollectionToken
已淘汰:23
sysmem2_token client_end:fuchsia.sysmem2/BufferCollectionToken

BufferCollectionToken 管道的用戶端,StreamProcessor 會使用這個管道將限制傳送至 sysmem,並瞭解 sysmem 分配的緩衝區。

用戶端保證 sysmem 已知權杖 (透過 BufferCollectionToken.Sync()、BufferCollection.Sync() 或 BufferCollectionEvents.OnDuplicatedTokensKnownByServer())。

新增:23

StreamBufferSettings

定義於 fuchsia.media/stream_processor.fidl

已淘汰。請改用 SetStreamBufferPartialSettings() 和 StreamBufferPartialSettings。

已淘汰 :請忽略。請改用 SetStreamBufferPartialSettings。

序數欄位類型說明
buffer_lifetime_ordinal uint64

已淘汰 :請忽略。請改用 SetStreamBufferPartialSettings。

buffer_constraints_version_ordinal uint64

已淘汰 :請忽略。請改用 SetStreamBufferPartialSettings。

packet_count_for_server uint32

已淘汰 :請忽略。請改用 SetStreamBufferPartialSettings。

packet_count_for_client uint32

已淘汰 :請忽略。請改用 SetStreamBufferPartialSettings。

per_packet_buffer_bytes uint32

已淘汰 :請忽略。請改用 SetStreamBufferPartialSettings。

single_buffer_mode bool

已淘汰 :請忽略。請改用 SetStreamBufferPartialSettings。

StreamOutputConstraints

定義於 fuchsia.media/stream_processor.fidl

串流處理器控制的輸出設定,包括輸出的 StreamBufferConstraints 和輸出的 FormatDetails。

序數欄位類型說明
stream_lifetime_ordinal uint64

如果用戶端在收到 OnOutputConstraints() 且 buffer_constraints_action_required 為 true 時,一律會立即重新設定輸出緩衝區,則可放心忽略這個欄位。

如果用戶端知道伺服器已收到指示,要捨棄具有相同 stream_lifetime_ordinal 的串流其餘部分,或這個 stream_lifetime_ordinal 欄位設為 0,則即使 buffer_constraints_action_required 為 true,用戶端仍可忽略 OnOutputConstraints() 訊息。如果最近完成的伺服器端輸出設定不是伺服器想要/需要的新串流,伺服器必須透過 OnOutputConstraints() 重新傳送所需的輸出設定,並將新的 stream_lifetime_ordinal 和 buffer_constraints_action_required 設為 true。

buffer_constraints_action_required bool

緩衝區限制傳送後,會指出是否需要採取行動。如果此處的值為 false,則可傳送較新的限制,而不必強制重新設定緩衝區。如果這個值為 false,用戶端就無法假設可以立即安全地重新設定輸出緩衝區。如果為 true,用戶端可以假設立即設定輸出緩衝區一次是安全的。

不使用動態緩衝區時,false 值已淘汰,且不會由任何已知伺服器傳送。

使用動態緩衝區時,伺服器可能會傳送 false 值來更新 buffer_count_for_server_current,但該值一律會小於或等於 dynamic_buffers_video_decoder_output_safe。如果 buffer_constraints_action_required 為 false,偏好只使用 dynamic_buffers_video_decoder_output_safe 的用戶端可以忽略新的 StreamOutputConstraints (假設用戶端沒有其他理由需要注意該訊息)。如果用戶端使用 buffer_count_for_server_current,可能為明確允許的串流保留一些緩衝區 (可惜的是,據我所知,指定較低 DPB 大小的串流相當罕見),則用戶端必須注意 buffer_count_for_server_current 的新值,即使 buffer_constraints_action_required 為 false 也一樣,並確保轉碼器有可用的緩衝區數量,且與新值一致。轉碼器不會根據目前可用 / 空閒 / 看似可供轉碼器使用的緩衝區數量,設定 true 或 false,因為轉碼器無法可靠地偵測到這一點,因為緩衝區可能會伺機交給轉碼器,但實際上會保留給下游管道 (或類似管道) 潛在使用 (以及潛在的「暫存」)。

如果 buffer_constraints_action_required 為 false,用戶端可以忽略緩衝區限制版本。伺服器不得將相同 buffer_constraints_version_ordinal 的 buffer_constraints_action_required 從 false 變更為 true。

對於每項設定,用戶端都必須使用新的緩衝區,不得使用先前用於其他用途的緩衝區,也不得使用先前用於任何其他 StreamProcessor 用途的緩衝區。這項規則有許多好處,與串流中變更和串流邊界變更有關。用戶端每次都應使用新的緩衝區。

如果這個值為 true,伺服器已盡可能取消參照低層級輸出緩衝區,同時仍能有效率地轉換至新緩衝區,並會盡快取消參照其餘緩衝區。在相關格式有效允許的範圍內,不需要使用 Sync() 即可避免資源使用重疊。

如果 buffer_constraints_action_required 為 true,伺服器在用戶端設定 (或重新設定) 輸出緩衝區之前,不得提供更多輸出資料。

buffer_constraints StreamBufferConstraints

StreamOutputFormat

定義於 fuchsia.media/stream_processor.fidl

序數欄位類型說明
stream_lifetime_ordinal uint64

如果用戶端知道伺服器已收到指示,要捨棄具有相同 stream_lifetime_ordinal 的其餘串流,或這個 stream_lifetime_ordinal 欄位設為 0,則即使 buffer_constraints_action_required 為 true,用戶端仍可忽略 OnOutputFormat() 訊息。如果最近完成的伺服器端輸出設定不是伺服器想要/需要的新串流,伺服器必須透過 OnOutputConstraints() 重新傳送所需的輸出設定,並將新的 stream_lifetime_ordinal 和 buffer_constraints_action_required 設為 true。

伺服器必須在串流的第一個輸出封包之前傳送 OnOutputFormat()。

format_details FormatDetails

如果 format_details.format_details_version_ordinal 變更,用戶端應檢查新的格式詳細資料,並判斷是否必須調整為新格式。伺服器保證,如果格式有所變更,format_details.format_details_version_ordinal 也會變更,但 format_details.format_details_version_ordinal 變更不保證格式詳細資料實際有所變更。強烈建議伺服器不要在串流的第一個輸出資料之前變更 format_details.format_details_version_ordinal,除非串流中確實有中串流格式變更。不必要的串流中格式變更,可能會導致不需要處理串流中格式變更的簡單用戶端直接關閉管道。在串流的第一個輸出資料之前變更格式,不屬於這裡所指的「串流中」變更,這類變更可用於偵測 / 設定串流格式。

請注意,如果輸出緩衝區在格式變更後不需要重新設定,建議伺服器在傳達新格式詳細資料的訊息中,將 buffer_constraints_action_required 設為 false,但這並非必要。較簡單的伺服器可能會將整個輸出情況視為一項重大事件,並在輸出情況發生任何變化時,要求重新設定輸出緩衝區。

用戶端不一定會處理 buffer_constraints_action_required 為 false 的新 buffer_constraints,但應一律追蹤最新的 format_details。

更新後的 format_details 會依據發出的輸出封包排序,並套用至所有後續封包,直到下一個具有較大 version_ordinal 的 format_details 為止。如果簡易用戶端不打算處理中途格式變更,仍應追蹤最近收到的 format_details,直到第一個輸出封包抵達為止,然後鎖定格式詳細資料、處理這些格式詳細資料,並驗證從伺服器收到的任何 format_details.format_details_version_ordinal 是否與鎖定的 format_details 相同,直到用戶端完成串流為止。即使是這類簡單的用戶端,也必須容許 format_details.format_details_version_ordinal 在串流 (任何串流,包括第一個串流或後續串流) 開始輸出資料前多次變更。這樣一來,串流處理器就能要求推測性設定輸出緩衝區和輸出格式,並在伺服器瞭解所有必要資訊,可完整建立初始輸出格式詳細資料後,由伺服器在串流首次輸出資料前,選擇性調整輸出設定。這可簡化串流處理器伺服器的實作,並讓智慧型串流處理器伺服器在任何輸入資料前,猜測其輸出設定,以降低延遲時間,同時在猜測錯誤時,仍能修正輸出設定 (包括格式詳細資料)。

format_details.format_details_version_ordinal 是否會在串流中途變更,取決於串流處理器和串流,此處的註解並未指定,且在大多數情況下,也取決於串流處理器輸入的格式是否變更。用戶端可能經常使用技術上支援中途變更格式的格式,但用戶端剛好知道,用戶端要處理的串流都不會中途變更格式。

StreamProcessorAddBufferRequest 資源

定義於 fuchsia.media/stream_processor.fidl

序數欄位類型說明
port Port

必須設定。緩衝區適用的通訊埠 (輸入或輸出)。

buffer_constraints_version_ordinal uint64

一般來說,這是用戶端根據 OnInputConstraints/OnOutputConstraints 得知的最新 buffer_constraints_version_ordinal。舊值不會影響正確性。

如果伺服器已建立較新的 buffer_constraints_version_ordinal 值,且 action_required 為 true,則伺服器會忽略這則訊息。如果伺服器忽略這則訊息,系統會快速完成這個緩衝區的後續 RemoveBuffer,且不會產生錯誤。

用戶端不需確保每次呼叫 AddBuffer 時,使用相同的 buffer_lifetime_ordinal 和 buffer_constraints_version_ordinal,但用戶端必須確保共用相同 buffer_lifetime_ordinal 的所有 buffer_constraints_version_ordinal 值,都在相同的 action_required true 間隔內。每個這類間隔都會以 action_required 為 true 的值開頭,並持續到下一個 action_required 為 true 的值 (不含),或持續到目前的值 (如果尚未有下一個 action_required 為 true 的值)。如果這會對伺服器造成問題,伺服器應將 action_required 設為 true,而非 false。

buffer_lifetime_ordinal uint64

這些值的範圍會分別限定為輸入/輸出。

用戶端傳送的第一則訊息含有新的 (較高) buffer_lifetime_ordinal 值,會開始移除相同通訊埠上 buffer_lifetime_ordinal 較低的所有緩衝區。不過,在移除完成之前,轉碼器仍可使用舊緩衝區。

AddBuffer 訊息會將緩衝區新增至這個 buffer_lifetime_ordinal。

buffer_index uint32

在 buffer_lifetime_ordinal 下,buffer_index 值在所有已新增但尚未完全移除的緩衝區中必須是唯一的。這個值一開始是由用戶端使用這個欄位分配/指定,然後用戶端和伺服器都會使用輸入與輸出、buffer_lifetime_ordinal 和 buffer_index,明確參照這個新增的緩衝區 (必須提供這三個部分,才能明確指定這個緩衝區)。

請參閱 RemoveBuffer 文件註解,瞭解如何安全地移除緩衝區,以及可能重複使用 buffer_index 值。

與使用 SetInputBufferPartialSettings/SetOutputBufferPartialSettings 相比,使用 AddBuffer 和 RemoveBuffer 時,StreamProcessor buffer_index 值與 sysmem buffer_index (在 sysmem buffer_collection_id 下) 無關。StreamProcessor buffer_index 是由這個欄位指定,而非使用 sysmem 的 buffer_index。這樣一來,StreamProcessor 訊息就能明確指定來自兩個 sysmem 集合、具有相同 sysmem buffer_index (位於不同的 buffer_collection_id) 的兩個緩衝區。

buffer handle<vmo>

這是 VMO 控制代碼,伺服器可使用這個控制代碼存取 sysmem 緩衝區。

這個 VMO 必須由 sysmem 提供,且必須與伺服器的 sysmem 限制相容。

系統會先檢查 buffer_constraints_version_ordinal,如果檢查失敗,則會忽略這則訊息的其餘部分,而不檢查緩衝區欄位 (緩衝區會直接捨棄)。

如果 buffer_constraints_version_ordinal 檢查通過,但 buffer 不是 sysmem 提供的 VMO,或與伺服器的 sysmem 限制不一致,伺服器會關閉 StreamProcessor server_end。用戶端可以按照下列方式分配緩衝區,避免觸發這項失敗案例。

如果是影片解碼器輸入緩衝區,用戶端可以使用 sysmem 分配緩衝區,並使用 ParticipateInBufferAllocation 搭配 Port.INPUT,讓這個或另一個相同轉碼器實作的執行個體參與。在這種情況下,不需要使用相同的 StreamProcessor 執行個體,只要使用相同的轉碼器實作即可。如果使用不同的 StreamProcessor 執行個體 (但仍來自相同的轉碼器實作),用戶端應注意建立兩個 StreamProcessor 執行個體,並指定與 CodecFactory 相同的需求 (例如以相同方式設定 secure_input_mode 和 secure_output_mode)。如果影片解碼器伺服器實作的 supports_dynamic_buffers 為 true,就必須支援使用一個 StreamProcessor 執行個體分配輸入緩衝區,然後搭配其他 StreamProcessor 執行個體使用 (相較之下,輸出緩衝區則不需要)。

如果是影片解碼器輸出緩衝區,可以使用 sysmem 分配緩衝區,並使用 ParticipateInBufferAllocation 搭配 Port.OUTPUT,讓同一個 StreamProcessor 執行個體參與,即可達成這個目的。

伺服器應驗證這個 VMO (a) 是由 sysmem 提供,且 (b) 符合伺服器目前的 sysmem 限制。伺服器在使用這個 VMO 之前,可以透過檢查 sysmem 的 CheckVmoConstraints 結果,驗證 (a) 和 (b)。如果檢查失敗,伺服器可以關閉 StreamProcessor server_end。

StreamProcessorOnOutputTimestampHasNoOutputRequest

定義於 fuchsia.media/stream_processor.fidl

序數欄位類型說明
stream_lifetime_ordinal uint64

所有伺服器都會設定這個欄位。這是輸入 Packet 的 stream_lifetime_ordinal 值,永遠不會產生任何輸出封包。

timestamp_ish uint64

所有伺服器都會設定這個欄位。這是輸入 Packet 的 timestamp_ish 值,在具有此 timestamp_ish 值的 stream_lifetime_ordinal 下,永遠不會產生任何輸出封包。

StreamProcessorParticipateInBufferAllocationRequest 資源

定義於 fuchsia.media/stream_processor.fidl

序數欄位類型說明
port Port

緩衝區用於哪個通訊埠 (輸入或輸出)。

必須設定。

buffer_constraints_version_ordinal uint64

輸入時,這個欄位必須設為 1 (至少目前是如此)。

如果是輸出,這個欄位必須設為用戶端已知的最新 buffer_constraints_version_ordinal 值 (來自伺服器)。如果這個值小於伺服器建立的最新 buffer_constraints_version_ordinal (且 action_reqiured 為 true),伺服器會設定一般 sysmem 限制 (僅限 min_buffer_count 1),否則會忽略這則訊息。這是為了讓分配成功 (讓某些用戶端能更簡單地處理用戶端錯誤);在這種情況下,新的 buffer_constraints_version_ordinal 會到達用戶端,而用戶端可以趕上最新版本。

如果這個值是未來值,伺服器會捨棄 sysmem2_token,導致分配失敗。

必須設定。

sysmem2_token client_end:fuchsia.sysmem2/BufferCollectionToken

伺服器會使用這個 sysmem 權杖,直接通知 sysmem 任何適用的緩衝區限制。這些限制可以 (在某些情況下必須) 視這個 StreamProcessor 執行個體的建立方式而定。舉例來說,在建立 StreamProcessor 時,secure_input_mode/secure_output_mode 會導致伺服器分別為輸入/輸出設定 secure_required (分別由 Port.INPUT 或 Port.OUTPUT 指定)。

必須設定。

buffer_lifetime_ordinal uint64

如果設定此值,且先前在同一個 StreamProcessor 執行個體上,至少傳送過一個具有此 buffer_lifetime_ordinal 的 AddBuffer,且該 AddBuffer 尚未在伺服器端移除,則新的緩衝區將使用相同的 SingleBufferSettings 進行分配,否則分配將失敗。如果未滿足本段落中的任何條件,效果就等同於未設定這個欄位。

如果未設定這個欄位,伺服器設定的 sysmem 限制會適用於新 buffer_lifetime_ordinal 的緩衝區,且新緩衝區的 SingleBufferSettings 可能與先前任何緩衝區的 SingleBufferSettings 不符。

如果伺服器有目前的串流,且 port 表示輸出通訊埠,則限制集會允許串流在切換至新的 buffer_lifetime_ordinal 時正確處理 (假設用戶端使用新的 buffer_lifetime_ordinal,並在之後新增緩衝區等)。如果通訊埠代表輸入通訊埠,則無論目前串流為何,限制組合都會是輸入通訊埠的一般限制。

如果不使用這項機制,用戶端仍須確保所有 AddBuffer 具有指定的 StreamProcessor 執行個體、通訊埠和 buffer_lifetime_ordinal,且具有相同的 SingleBufferSettings。其中一種做法是在單一 sysmem 緩衝區集合下,分配 buffer_lifetime_ordinal 的所有緩衝區。另一種方法是讓用戶端直接告知 sysmem,新的緩衝區集合必須與先前集合的 SingleBufferSettings 相符,方法是使用 [fuchsia.sysmem2/BufferCollectionConstraints.must_match_vmo] 用戶端。

不建議用戶端在沒有 sysmem 協助,且沒有 StreamProcessor 透過這個欄位協助的情況下,嘗試強制新集合的 SingleBufferSettings 與舊集合的 SingleBufferSettings 相符,因為 sysmem 刻意允許參與相同集合的用戶端使用不同版本的 sysmem 介面,因此用戶端可能沒有足夠的資訊,在不使用 must_match_vmo 的情況下成功強制 SingleBufferSettings 相符,例如用戶端不知道新的 SingleBufferSettings 欄位 (或類似欄位)。最常見的 StreamProcessor 伺服器實作 (CodecImpl) 會代表用戶端使用 must_match_vmo 處理這個欄位,只要伺服器中仍有至少一個 buffer_lifetime_ordinal 的緩衝區處於有效狀態即可。sysmem 可能會在某個時間點新增功能,動態地將更多緩衝區新增至現有的 sysmem 集合;這可讓用戶端以另一種方式確保 buffer_lifetime_ordinal 內有相同的 SingleBufferSettings,但前提是所有 sysmem 集合參與者都表示支援動態 sysmem 緩衝區集合。

如果是輸出,當用戶端使用新的/不同的 sysmem 緩衝區集合,將額外的輸出緩衝區新增至現有的 buffer_lifetime_ordinal 時,強烈建議設定這個欄位,且建議為所有輸出緩衝區分配設定這個欄位。

如果是輸入,當用戶端為這個訊息和 AddBuffer 使用相同的 StreamProcessor 執行個體時 (建議盡可能使用),建議針對這些輸入緩衝區使用這個欄位。

如要設定,這個值必須與稍後在 AddBuffer 中傳送的 buffer_lifetime_ordinal 相符。

用戶端應盡可能設定這項屬性,詳情請參閱上文。

allow_single_buffer bool

如果設為 true,伺服器在傳送 SetConstraints 至 sysmem 時,會將所有 buffer_count_* 欄位設為未設定,並將 min_buffer_count 設為 1。

如果未設定或設為 false,伺服器會根據 buffer_count_for_server_current 的目前值,在傳送 SetConstraints 至 sysmem 時填入緩衝區計數欄位,不會有任何額外緩衝。用戶端可以視需要,透過保留的權杖新增寬裕時間。

無論這個欄位是否設為 true,用戶端都必須AddBuffer至少 buffer_count_for_server_current 個緩衝區,處理作業才能繼續進行。

StreamProcessorRemoveBufferRequest 資源

定義於 fuchsia.media/stream_processor.fidl

序數欄位類型說明
port Port

必須設定。緩衝區適用的通訊埠 (輸入或輸出)。

buffer_lifetime_ordinal uint64

範圍限定為輸入或輸出,這是 buffer_index 有意義的 buffer_lifetime_ordinal。

buffer_index uint32

先前 (以及最近) 透過 AddBuffer 或 SetInputBufferPartialSettings / SetOutputBufferPartialSettings 建立的緩衝區 buffer_index。這個值的範圍位於輸入與輸出之下,以及 buffer_lifetime_ordinal 值之下。

使用動態緩衝區時,在 AddBuffer 啟動和 RemoveBuffer 完成之間的 buffer_index 值 (有效的 buffer_index 值),對於指定的 Port 值和 buffer_lifetime_ordinal 值必須是唯一的。

使用動態緩衝區的用戶端可能不希望在 RemoveBuffer 完成後立即重複使用 buffer_index 值,以便進行偵錯/診斷,但技術上來說,只要 RemoveBuffer 完成,後續的 AddBuffer 就可以重複使用 buffer_index (從 StreamProcessor 的角度來看,用戶端可能有自己的原因,不希望這麼快重複使用)。在舊的 (非目前) buffer_lifetime_ordinal 下,一律不允許 AddBuffer。

UsageStateDucked

定義於 fuchsia.media/usage_reporter.fidl

音訊用途的狀態,已做出政策裁決,暫時降低所有使用此用途的串流音量。

序數欄位類型說明

UsageStateMuted

定義於 fuchsia.media/usage_reporter.fidl

音訊用途的狀態,其中已做出政策裁決,暫時將具有此用途的所有串流音量靜音。

序數欄位類型說明

UsageStateUnadjusted

定義於 fuchsia.media/usage_reporter.fidl

音訊用途的狀態,不會對任何具有該用途的串流採取政策動作。

序數欄位類型說明

UNIONS

strict AacBitRate

定義於 fuchsia.media/stream_common.fidl

序數Variant類型說明
constant AacConstantBitRate
variable AacVariableBitRate

AacTransport 彈性

定義於 fuchsia.media/stream_common.fidl

序數Variant類型說明
raw AacTransportRaw
latm AacTransportLatm
adts AacTransportAdts

ActivityReporter_WatchCaptureActivity2_Result strict

定義於 fuchsia.media/activity_reporter.fidl

序數Variant類型說明
response ActivityReporter_WatchCaptureActivity2_Response
framework_err internal

ActivityReporter_WatchRenderActivity2_Result strict

定義於 fuchsia.media/activity_reporter.fidl

序數Variant類型說明
response ActivityReporter_WatchRenderActivity2_Response
framework_err internal

AudioCapturerConfiguration strict

定義於 fuchsia.media/audio_capturer.fidl

音訊擷取器的設定。

序數Variant類型說明
loopback LoopbackAudioCapturerConfiguration
input InputAudioCapturerConfiguration

AudioCompressedFormat 彈性

定義於 fuchsia.media/stream_common.fidl

序數Variant類型說明
aac AudioCompressedFormatAac
sbc AudioCompressedFormatSbc
cvsd AudioCompressedFormatCvsd
新增:HEAD
lc3 AudioCompressedFormatLc3
新增:HEAD

AudioConsumerError strict

定義於 fuchsia.media/audio_consumer.fidl

代表 AudioConsumer 錯誤狀況。

序數Variant類型說明
place_holder Void

AudioCore_GetDbFromVolume2_Result strict

定義於 fuchsia.media/audio_core.fidl

序數Variant類型說明
response AudioCore_GetDbFromVolume2_Response
framework_err internal

AudioCore_GetVolumeFromDb2_Result strict

定義於 fuchsia.media/audio_core.fidl

序數Variant類型說明
response AudioCore_GetVolumeFromDb2_Response
framework_err internal

AudioFormat strict

定義於 fuchsia.media/stream_common.fidl

AudioFormat

序數Variant類型說明
compressed AudioCompressedFormat
uncompressed AudioUncompressedFormat

AudioUncompressedFormat strict

定義於 fuchsia.media/stream_common.fidl

AudioUncompressedFormat

序數Variant類型說明
pcm PcmFormat

CryptoFormat flexible

定義於 fuchsia.media/stream_common.fidl

CryptoFormat

加密 (加密或解密) 格式詳細資料。

序數Variant類型說明
encrypted EncryptedFormat
decrypted DecryptedFormat

DomainFormat strict

定義於 fuchsia.media/stream_common.fidl

DomainFormat

序數Variant類型說明
audio AudioFormat
video VideoFormat
crypto CryptoFormat

EncoderSettings 彈性

定義於 fuchsia.media/stream_common.fidl

編碼器設定,用於指示編碼器如何編碼原始格式。

序數Variant類型說明
sbc SbcEncoderSettings
aac AacEncoderSettings
h264 H264EncoderSettings
hevc HevcEncoderSettings
cvsd CvsdEncoderSettings
新增:HEAD
lc3 Lc3EncoderSettings
新增:HEAD
msbc MSbcEncoderSettings
新增:HEAD

MediumSpecificStreamType strict

定義於 fuchsia.media/stream_type.fidl

所有媒體專屬串流類型結構體的聯集。

序數Variant類型說明
audio AudioStreamType
video VideoStreamType
text TextStreamType
subpicture SubpictureStreamType

StreamProcessor_RemoveBuffer_Result strict

定義於 fuchsia.media/stream_processor.fidl

序數Variant類型說明
response StreamProcessor_RemoveBuffer_Response
framework_err internal

使用 strict

定義於 fuchsia.media/audio_core.fidl

序數Variant類型說明
render_usage AudioRenderUsage
capture_usage AudioCaptureUsage

用量 2 彈性

定義於 fuchsia.media/audio_core.fidl

序數Variant類型說明
render_usage AudioRenderUsage2
capture_usage AudioCaptureUsage2

UsageState flexible

定義於 fuchsia.media/usage_reporter.fidl

串流或一組串流的音訊政策強制執行狀態。

序數Variant類型說明
unadjusted UsageStateUnadjusted
ducked UsageStateDucked
muted UsageStateMuted

值 strict

定義於 fuchsia.media/stream_common.fidl

值

用於一般「Parameter」結構的一般「value」。

序數Variant類型說明
bool_value bool
uint64_value uint64
int64_value int64
string_value string
bytes_value vector<uint8>

VideoCompressedFormat strict

定義於 fuchsia.media/stream_common.fidl

VideoCompressedFormat

壓縮影片格式詳細資料。

序數Variant類型說明
temp_field_todo_remove uint32

Temp field to make the compiler happy until we have at least one real field. 請勿在程式碼中參照這個欄位。

VideoFormat strict

定義於 fuchsia.media/stream_common.fidl

VideoFormat

影片 (壓縮或未壓縮) 格式詳細資料。在這種情況下,「未壓縮」可能包含區塊式圖片壓縮格式,但仍允許相當快速地隨機存取圖片資料。

序數Variant類型說明
compressed VideoCompressedFormat
uncompressed VideoUncompressedFormat

BITS

AudioConsumerStartFlags strict

類型:uint32

定義於 fuchsia.media/audio_consumer.fidl

傳遞至 AudioConsumer.Start 的旗標。

名稱值說明
1

表示應盡可能降低延遲時間。

2

表示封包傳送時間是由外部程序決定,而非依需求決定。設定這個旗標後,服務應預期封包到達率和呈現率不相符,導致下溢或溢位。如未設定這個旗標,封包會視需求送達。

AudioGainInfoFlags strict

類型:uint32

定義於 fuchsia.media/audio_device_enumerator.fidl

名稱值說明
1
2
4

AudioGainValidFlags strict

類型:uint32

定義於 fuchsia.media/audio_device_enumerator.fidl

名稱值說明
1
2
4

常數

名稱值類型說明
AUDIO_ENCODING_AAC fuchsia.media.aac String

音訊編碼。

AUDIO_ENCODING_AACLATM fuchsia.media.aaclatm String
AUDIO_ENCODING_AMRNB fuchsia.media.amrnb String
AUDIO_ENCODING_AMRWB fuchsia.media.amrwb String
AUDIO_ENCODING_APTX fuchsia.media.aptx String
AUDIO_ENCODING_FLAC fuchsia.media.flac String
AUDIO_ENCODING_GSMMS fuchsia.media.gsmms String
AUDIO_ENCODING_LPCM fuchsia.media.lpcm String
AUDIO_ENCODING_MP3 fuchsia.media.mp3 String
AUDIO_ENCODING_OPUS fuchsia.media.opus String
AUDIO_ENCODING_PCMALAW fuchsia.media.pcmalaw String
AUDIO_ENCODING_PCMMULAW fuchsia.media.pcmmulaw String
AUDIO_ENCODING_SBC fuchsia.media.sbc String
AUDIO_ENCODING_VORBIS fuchsia.media.vorbis String
BEHAVIOR_COUNT 3 uint8
新增:32
CAPTURE_USAGE2_COUNT 4 uint8
CAPTURE_USAGE_COUNT 4 uint8
ENCRYPTION_SCHEME_CBC1 cbc1 String
ENCRYPTION_SCHEME_CBCS cbcs String
ENCRYPTION_SCHEME_CENC cenc String
ENCRYPTION_SCHEME_CENS cens String
ENCRYPTION_SCHEME_UNENCRYPTED unencrypted String
MAX_ENCRYPTION_SCHEME_SIZE 100 uint32
MAX_FRAMES_PER_RENDERER_PACKET 262143 int64

單一 StreamPacket 可包含的影格數量上限。

MAX_INIT_VECTOR_SIZE 16 uint32
MAX_KEY_ID_SIZE 16 uint32
MAX_PCM_CHANNEL_COUNT 8 uint32
MAX_PCM_FRAMES_PER_SECOND 192000 uint32
MAX_USAGE_COUNT 8 uint8

算繪或擷取用量的合理上限。請在 FIDL API 中使用這個值 (例如用於向量大小上限),而非直接使用 RENDER_USAGE2_COUNT 或 CAPTURE_USAGE2_COUNT。這樣一來,這些常數增加時,就不會造成 ABI 破壞性變更。

METADATA_LABEL_ALBUM fuchsia.media.album String
METADATA_LABEL_ARTIST fuchsia.media.artist String
METADATA_LABEL_COMPOSER fuchsia.media.composer String
METADATA_LABEL_EPISODE fuchsia.media.episode String
METADATA_LABEL_GENRE fuchsia.media.genre String
METADATA_LABEL_PUBLISHER fuchsia.media.publisher String
METADATA_LABEL_RELEASE_DATE fuchsia.media.release_date String
METADATA_LABEL_SEASON fuchsia.media.season String
METADATA_LABEL_STUDIO fuchsia.media.studio String
METADATA_LABEL_SUBTITLE fuchsia.media.subtitle String
METADATA_LABEL_TITLE fuchsia.media.title String
METADATA_LABEL_TRACK_NUMBER fuchsia.media.track_number String
METADATA_SOURCE_TITLE fuchsia.media.source_title String

媒體來源的標題,例如播放器、影視串流服務或網站。

MIN_PCM_CHANNEL_COUNT 1 uint32

AudioRenderer 和 AudioCapturer 的允許範圍

MIN_PCM_FRAMES_PER_SECOND 1000 uint32
NO_TIMESTAMP 9223372036854775807 int64

當做 StreamPacket.pts 值使用時,表示封包沒有特定的顯示時間戳記。這類封包的有效顯示時間取決於 StreamPacket 的使用情境。

RENDER_USAGE2_COUNT 6 uint8
RENDER_USAGE_COUNT 5 uint8
STREAM_PACKET_FLAG_DISCONTINUITY 4 uint32

表示封包序列在時間上不連續。這個旗標的精確語意取決於使用 StreamPacket 的情境。

STREAM_PACKET_FLAG_DROPPABLE 2 uint32

表示串流中的所有其他封包都可解讀,不需參考這個封包。這通常用於壓縮串流,以識別包含可能捨棄的影格封包,而不會影響其他影格。

STREAM_PACKET_FLAG_KEY_FRAME 1 uint32

表示不需參考串流中的其他封包,即可解讀封包。這通常用於壓縮串流,以識別含有主要畫面格的封包。

VIDEO_ENCODING_H263 fuchsia.media.h263 String

影片編碼。

VIDEO_ENCODING_H264 fuchsia.media.h264 String
VIDEO_ENCODING_MPEG4 fuchsia.media.mpeg4 String
VIDEO_ENCODING_THEORA fuchsia.media.theora String
VIDEO_ENCODING_UNCOMPRESSED fuchsia.media.uncompressed_video String
VIDEO_ENCODING_VP3 fuchsia.media.vp3 String
VIDEO_ENCODING_VP8 fuchsia.media.vp8 String
VIDEO_ENCODING_VP9 fuchsia.media.vp9 String
kMaxOobBytesSize 8192 uint64

別名

名稱值說明
CompressionType string[256]

壓縮類型的 ID。

EncryptionScheme string[MAX_ENCRYPTION_SCHEME_SIZE]
InitVector vector[MAX_INIT_VECTOR_SIZE]
KeyId vector[MAX_KEY_ID_SIZE]