协议
ActivityReporter
在 fuchsia.media/activity_reporter.fidl 中定义
用于监控 AudioRenderer 和 AudioCapturer 使用情况活动的协议。
WatchCaptureActivity
每当一组活跃的 AudioCaptureUsage 发生变化时,通知客户端。 首次调用时,它会立即返回。
请求
<EMPTY>
响应
| 名称 | 类型 |
|---|---|
active_usages |
vector<AudioCaptureUsage>:4
|
WatchCaptureActivity2
每当一组活跃的 AudioCaptureUsage 发生变化时,通知客户端。 首次调用时,它会立即返回。
请求
<EMPTY>
响应
| 名称 | 类型 |
|---|---|
payload |
ActivityReporter_WatchCaptureActivity2_Result
|
WatchRenderActivity
每当活跃 AudioRenderUsage 集合发生变化时,通知客户端。 首次调用时,它会立即返回。
请求
<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 指定),并且系统当前未在“异步”捕获模式下运行。
**缓冲区和内存管理**
在 AddPayloadBuffer 调用期间,音频数据会被捕获到用户提供给 AudioCapturer 的共享内存缓冲区 (VMO) 中。请注意以下与载荷缓冲区管理相关的要求。
- 必须先提供载荷缓冲区,然后才能开始任何捕获操作。在建立载荷缓冲区之前尝试开始捕获(通过 CaptureAt 或 StartAsyncCapture)属于错误。
- 当有任何捕获操作处于待处理状态时,不得更改载荷缓冲区。
- 设置载荷缓冲区后,不得更改流类型。
- 载荷缓冲区必须是音频帧大小(以字节为单位)的整数倍
- 在“异步”模式下运行时(见下文),载荷缓冲区的大小必须至少是 StartAsyncCapture 期间指定的 frames_per_packet 大小的两倍。
- 用户提供的载荷缓冲区句柄必须可读、可写、可映射和可传输。
- 用户应始终将载荷缓冲区视为只读。
**同步与异步捕获模式**
AudioCapturer 接口可在以下两种互斥模式之一中使用:同步和异步。下面介绍了每种模式及其优缺点。
**同步模式**
默认情况下,AudioCapturer 实例在“同步”模式下运行。只有当用户使用 CaptureAt 方法提供至少一个要捕获到的区域时,它们才会捕获数据。以这种方式提供的区域将按照接收顺序进行填充,并通过 CaptureAt 方法的返回值作为 StreamPacket 返回给客户端。如果 AudioCapturer 实例有要捕获的数据,但没有地方放置(因为没有更多待填充的区域),则生成的下一个载荷将通过在下一个生成的 StreamPacket 上设置 Discontinuity 标志来指示已发生溢出。同步模式不得与异步模式结合使用。如果系统仍有 CaptureAt 提供的区域等待填充,则尝试调用 StartAsyncCapture 会出错。
如果用户过去曾提供要由 AudioCapturer 实例填充的区域,但希望回收这些区域,则可以使用 DiscardAllPackets 方法。调用 DiscardAllPackets 方法会导致返回所有待处理区域,但其 StreamPacket 的 PTS 为 NO_TIMESTAMP。如需了解时间戳和不连续性标志,请参阅下文中的“时间和溢出”。在 DiscardAllPackets 操作之后,系统会生成 OnEndOfStream 事件。虽然 AudioCapturer 在返回已完成的区域后绝不会覆盖载荷缓冲区的任何区域,但它可能会覆盖因 DiscardAllPackets 操作而返回的部分填充缓冲区中未填充的部分。
异步模式
在“异步”模式下运行时,客户端无需明确提供要由 AudioCapturer 实例填充的共享缓冲区区域。相反,客户端通过调用 StartAsyncCapture 并提供回调接口和每次回调要捕获的帧数来进入“异步”模式。在异步模式下运行后,AudioCapturer 实例将确定要捕获到哪些载荷缓冲区区域,捕获指定数量的帧,然后使用 OnPacketCapture FIDL 事件将这些帧作为 StreamPacket 传送。用户可以使用 StopAsyncCapture 方法停止捕获,并将 AudioCapturer 实例返回到“同步”模式。
尝试执行以下任何操作都会被视为错误。
- 尝试在未建立载荷缓冲区时进入“异步”捕获模式。
- 指定每个载荷要捕获的帧数,该帧数不允许在已建立的共享载荷缓冲区中同时存在至少两个连续的捕获载荷。
- 在 AudioCapturer 实例以“async”模式运行时,使用 CaptureAt 方法发送要捕获到的区域。
- 尝试在 AudioCapturer 实例以“异步”模式运行时调用 DiscardAllPackets。
- 尝试在未先停止的情况下重新启动“异步”模式捕获。
- 在停止过程中尝试执行除 SetGain 以外的任何操作。
与 StopAsyncCapture 操作同步
停止异步捕获模式并返回到同步捕获模式是一项耗时的操作。除了 SetGain 之外,用户在调用 StopAsyncCapture 之后(包括再次调用 StopAsyncCapture),在停止操作完成之前,不得调用 AudioCapturer 接口上的任何其他方法。因此,用户必须能够与停止操作同步。为此,我们提供了两种机制。
第一种是使用 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 只有在以下两种情况下才会不连续:
- 用户在同步模式下操作,并且没有足够快地提供要填充的区域。如果下一个连续数据帧在需要从源缓冲区中清除时仍未被捕获,则表示发生了溢出,AudioCapturer 会将下一个捕获区域标记为不连续。
- 用户在异步模式下操作,并且某些内部错误导致 AudioCapturer 实例无法以连续方式捕获下一帧音频。这可能是系统负载过高或硬件错误,但通常情况下,这种情况不应该发生。 不过,在实践中,如果发生这种情况,下一个生成的数据包将被标记为不连续。
**同步与异步的权衡**
选择在同步模式还是异步模式下运行取决于用户,并且根据用户的要求,每种选择都有一些优点和缺点。
同步模式在后台只需要一个 Zircon 通道,因此可以节省一些开销。此外,用户可以完全控制缓冲区管理。用户可以指定音频的确切捕获位置和顺序。因此,如果用户不需要始终进行捕获,则可以轻松停止捕获,并在稍后重新开始捕获(只需停止提供数据包,然后在稍后恢复即可)。载荷的大小也不需要统一,客户端可以指定任何适当粒度的载荷。
以同步模式运行的主要缺点是,需要为每个要捕获的数据包发送两条消息。一个用于通知 AudioCapturer 要捕获到的实例,另一个用于通知用户数据包已被捕获。这最终可能会增加开销,并可能使客户端设计复杂化。
异步模式的优势在于只需要 1/2 的消息,但在“异步”模式下运行时,AudioCapturer 实例无法知道用户是否及时处理了正在发送的 StreamPacket,也无法自动检测溢出情况。“异步”模式的用户应注意使用足够大的缓冲区,以确保他们能够在 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 权限,并引用单调且连续的 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
设置捕获流的用途。此设置可以随时更改,但传输中的数据包可能会受到影响。默认情况下,创建的 Capturer 具有 FOREGROUND 用途。
已弃用 - 请使用 SetUsage2 和 AudioCaptureUsage2
请求
| 名称 | 类型 |
|---|---|
usage |
AudioCaptureUsage
|
SetUsage2
设置捕获流的用途。这可以动态更改,但可能会影响传输中的数据包。默认情况下,创建的 Capturer 具有 FOREGROUND 用途。
请求
| 名称 | 类型 |
|---|---|
usage |
AudioCaptureUsage2
|
StartAsyncCapture
将 AudioCapturer 置于“异步”捕获模式,并开始生成每个数据包正好包含“frames_per_packet”个帧的数据包。OnPacketProduced 事件(StreamSink 的事件)将用于通知客户端已生成数据包。
请求
| 名称 | 类型 |
|---|---|
frames_per_packet |
uint32
|
StopAsyncCapture
停止在“异步”捕获模式下捕获,并(可选)提供一个回调,如果需要显式同步,客户端可以使用该回调。
请求
<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 请求将关闭,并显示 epitaph 值 ZX_ERR_INVALID_ARGS。
请求
| 名称 | 类型 |
|---|---|
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。如果传递的 media_time 值为 NO_TIMESTAMP,则会选择默认媒体时间,该时间按如下方式确定:
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 如何同时处理多个活跃音频流的互动。如果 Usage active 的音频流正在处理音频,而 Usage affected 的音频流也在处理音频,则指定的 Behavior 将应用于 Usage affected 的音频流。
已弃用 - 请改用 SetInteraction2 和 AudioRenderUsage2
请求
| 名称 | 类型 |
|---|---|
active |
Usage
|
affected |
Usage
|
behavior |
Behavior
|
SetInteraction2
设置 audio_core 如何同时处理多个活跃音频流的互动。如果 Usage active 的音频流正在处理音频,而 Usage affected 的音频流也在处理音频,则指定的 Behavior 将应用于 Usage 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
If R(P(X)) < RefClock.Now() + MLT Then the packet is late, and some (or all) of the packet's payload will need to be skipped in order to present the packet at the scheduled time.
值 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 权限,并引用单调且连续的 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 毫秒提前时间的内部音频输出,以及需要至少 75 毫秒提前时间的 HDMI 输出,则 AudioRenderer 可能会(如果省略“reference_time”)选择从现在起 80 毫秒的参考时间。
媒体时间 如果省略 media_time,AudioRenderer 将选择两个值之一。
- 如果 AudioRenderer 从暂停状态恢复,并且自暂停以来未丢弃任何数据包,则 AudioRenderer 将使用与呈现暂停时刻对应的 media_time。
- 如果 AudioRenderer 在启动或“舍弃数据包”操作后首次进入播放状态,则初始 media_time 将设置为待处理数据包队列中第一个载荷的 PTS。如果待处理队列为空,则初始 media_time 将设置为零。
返回值 当收到请求时,AudioRenderer 将返回在播放调用的返回值中选择和使用的“reference_time”和“media_time”(无论它们是否已明确指定)。
示例
-
用户已使用
SendPacket将一些音频加入队列,并希望这些音频尽快开始播放。用户可以在不提供明确时间戳的情况下调用 Play --Play(NO_TIMESTAMP, NO_TIMESTAMP)。 -
用户已使用
SendPacket将一些音频排入队列,并希望在指定的“reference_time”开始播放,以便与某些其他媒体流同步(无论是在初始阶段还是在丢弃数据包之后)。用户将调用Play(reference_time, NO_TIMESTAMP)。 -
用户已使用
SendPacket将一些音频加入队列。这些数据包中的第一个数据包的 PTS 为零,用户希望尽快开始播放,但希望跳过 PTS 0 和 PTS“media_time”之间的所有音频内容。用户将调用Play(NO_TIMESTAMP, media_time)。 -
用户已使用
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“tick”,使用当前定义的 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 毫秒的漂移误差。
如果用户需要处理时间戳可能比 PTS 刻度的 +/- 1/2 更不正确的容器,则可以将此值设置为更大的值。这应该是容器时间戳中存在的最大不准确度(如果已知)。如果无法做到这一点,则可以将其设置为在明确遵循绝对时间戳之前可容忍的最大漂移误差。最后,用户可以将此数字设置为一个非常大的值(例如 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 是要为其渲染音频的媒体会话的标识符。
请求
| 名称 | 类型 |
|---|---|
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 中定义
操作概览:
- 创建
- 通过 CodecFactory 创建 - 请参阅 CodecFactory
- 通过 LicenseSession 创建 - 请参阅 LicenseSession
- 获取输入限制
- OnInputConstraints() - 在创建流处理器后不久由流处理器主动发送。
- 提供输入缓冲区 ()
- SetInputBufferPartialSettings()
- 或 AddBuffer(如果 StreamProcessor 通过 CodecFactory 报告了对动态缓冲区的支持,在这种情况下,QueueInputFormatDetails 和 QueueInputEndOfStream 不需要事先调用 AddBuffer,但 QueueInputPacket 仍然需要)。
- 提交输入数据
- QueueInputPacket() + OnFreeInputPacket(),只要需要,就一直运行,可能会在以下情况发生之前反复处理所有输入数据包…
- 获取输出限制和格式
- OnOutputConstraints()
- 在客户端发送至少一条 QueueInput* 消息之前,系统不会发送此消息,即使 StreamProcessor 背后的底层处理器根本不需要任何输入数据来确定其输出限制也是如此。这种服务器行为可防止客户端在输入传递之前对输出限制条件产生不正确的依赖。* 客户端必须能够容忍此消息在大量输入数据(包括通过 OnFreeInputPacket() 回收的大量输入数据包)传送之后才到达。 * 此消息可能会在第一个输出数据之前到达多次。
- 提供输出缓冲区 * SetOutputBufferPartialSettings() / CompleteOutputBufferPartialSettings()
- 数据流,可选择是否包含 EndOfStream * OnOutputPacket() / RecycleOutputPacket() / QueueInputPacket() / OnFreeInputPacket() / QueueInputEndOfStream() / OnOutputEndOfStream()
半可信 StreamProcessor 服务器 - 软件解码器在隔离区(功能非常有限)中运行,以防解码软件存在可能被用来接管 StreamProcessor 服务器的漏洞。与某些其他接口相比,使用解码器和处理单独安全上下文流的流处理器接口客户端更需要保护自身免受无效服务器行为(例如 packet_index 的双重释放和任何其他无效服务器行为)的影响。在输入一个安全上下文的压缩数据后,请勿过度信任单个 StreamProcessor 实例,以免 StreamProcessor 服务器曾经获知的任何缓冲区中的数据发生混淆。而是应创建单独的 StreamProcessor 实例,供安全隔离的客户端上下文使用。 虽然基于硬件的解码器的情况略有不同,且不在本段讨论范围内,但客户端应始终为安全隔离的客户端上下文使用单独的 StreamProcessor 实例。
此协议的方法所执行的操作以及事物状态的描述,就好像这些方法是由流处理器服务器同步执行的一样,但实际上,与 FIDL 接口的典型情况一样,消息处理是异步的。除非另有说明,否则所述状态应解读为从客户端角度看到的状态。从服务器返回的事件当然是异步传递的,每个 StreamProcessor 实例处理多个数据流的客户端需要注意给定事件是来自当前数据流还是来自一些即将消失的旧数据流。
Sync() 方法的主要用途是使客户端能够可靠地防止在系统中同时分配旧缓冲区和新缓冲区,因为媒体缓冲区可能非常大。Sync() 方法通过仅在 StreamControl 排序网域中对 StreamProcessor 协议的所有先前调用实际生效时才提供其响应来实现此目的。如果客户端可能比 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 消息都会立即完成。
如果所有具有相同 buffer_lifetime_ordinal 的 AddBuffer 调用添加的缓冲区总和超过 dynamic_buffers_input_max 或 dynamic_buffers_output_max,服务器可能会关闭通道。在这种情况下,如果添加过多缓冲区会导致性能下降或未经测试的行为,则服务器必须关闭通道。
切换到新的 buffer_lifetime_ordinal 会启动移除与旧 buffer_lifetime_ordinal 关联的缓冲区的过程。 不过,在移除完成之前,编解码器仍可照常使用这些缓冲区。另请参阅 RemoveBuffer,无论移除操作是否由 RemoveBuffer 启动(包括不使用动态缓冲区的情况),该函数都可用于检测移除操作何时完成。
缓冲区会一直保留,直到稍后完成移除。在可能多次重复使用缓冲区的情况下,缓冲区仍会保持添加状态。客户端可以使用 RemoveBuffer 发起(和/或确认/隔离)移除操作。编解码器服务器可以单方面启动缓冲区移除;如果服务器执行此操作,则必须发送新的 buffer_constraints_version_ordinal,并将 action_required 设置为 true。其他一些由客户端发起的消息也可以开始移除缓冲区,例如带有 release_input_buffers 和/或 release_output_buffers 的 CloseCurrentStream。如果客户端关闭 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 值。
请求
| 名称 | 类型 |
|---|---|
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 时,才允许使用此消息。
请求
<EMPTY>
EnableOldOutputBuffers
这会告知 StreamProcessor,客户端已准备好处理输出数据包,这些数据包指定的缓冲区具有比最新 buffer_lifetime_ordinal 更早的 buffer_lifetime_ordinal。
如果客户端未发送此消息,StreamProcessor 将忽略任何此类输出,即使 DetailedCodecDescription.supports_dynamic_buffers 为 true 也是如此。对于相关解码器(例如 VP9 解码器),不发送此消息可能会导致输出不符合比特流规范,并且输出可能与比特流预期的视觉效果不同。
此类数据流仅适用于某些比特流格式(例如 VP9),并且很少见,但可能会发生,并且根据比特流规范可能是有效的。例如,这可以通过 VP9 比特流指定,使用 show_existing_frame 在已经输出新尺寸缓冲区后输出旧尺寸缓冲区。
大多数发送此消息的客户端也希望使用 RemoveBuffer 来了解何时可以安全地停止跟踪旧缓冲区。
在大多数情况下,这不会产生任何影响,因为大多数比特流实际上不会发出旧缓冲区,即使比特流规范允许这样做。 旧输出缓冲区对于 RTC 流来说尤其罕见,因为 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 时,才允许使用此消息。
请求
<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 时,才允许使用此消息。
请求
<EMPTY>
FlushEndOfStreamAndCloseStream
此消息是可选的;客户端无需发送此消息。
术语说明:在此消息的名称中,“flush”表示“flush through”(有时称为“drain”)。此消息不会被舍弃。如需舍弃,只需使用新的 stream_lifetime_ordinal 调用 QueueInputPacket,而无需先等待旧数据流的 OnOutputEndOfStream,也无需发送 FlushEndOfStreamAndCloseStream。
目前,除了客户端关闭 StreamProcessor 通道之外,没有其他方法可以取消此消息的刷新效果。
此消息仅在此数据流的 QueueInputEndOfStream() 之后有效。stream_lifetime_ordinal 输入参数必须与 QueueInputEndOfStream() 的 stream_lifetime_ordinal 匹配,否则服务器将关闭通道。
客户端可以使用此消息来刷新(排空,而不是舍弃)数据流的最后输入数据,以便数据流处理器服务器在继续处理下一个数据流之前,为所有输入数据生成相应的输出数据,而无需强制客户端在将另一个数据流的数据加入队列之前等待 OnOutputEndOfStream()。
QueueInputEndOfStream() 与 FlushEndOfStreamAndCloseStream() 之间的区别:QueueInputEndOfStream() 是客户端做出的承诺,即不会再有该流的输入数据(某些流处理器需要此信息,以便流处理器发出最后一个输出数据)。即使已发送 QueueInputEndOfStream(),客户端仍可通过关闭当前数据流(无论是否切换数据流)来完全舍弃当前数据流的其余部分。相比之下,FlushEndOfStreamAndCloseStream() 是客户端发出的请求,要求在继续处理任何新数据流之前,先处理所有先前已加入队列的输入数据,包括显示为 OnOutputEndOfStream()(在成功的情况下)的逻辑“EndOfStream” - 这实质上会将关闭数据流处理从舍弃更改为仅针对此数据流进行刷新。
使用此消息的客户端可以开始为新流提供输入数据,而不会导致旧流数据被舍弃。这就是此消息的目的 - 允许客户端刷新(而不是舍弃)旧数据流的最后数据(而不是关闭或切换数据流时的默认行为,即舍弃)。
由于旧数据流尚未处理完毕,且旧数据流的数据未被舍弃,因此客户端必须准备好继续处理 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 客户端。客户端不应依赖于这是到达客户端的第一条消息。
对于给定的 StreamProcessor 实例,“min”和“max”输入限制条件保证不会更改。当服务器处理 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 可以在低级缓冲区实际具有任何可用数据之前自由发出输出数据包,并使用与 OnOutputPacket() 消息分开的机制来指示数据的存在。对于此类低级缓冲区类型,所发出数据包中数据的下游使用者必须参与低级缓冲区信号机制,以便了解何时可以安全地使用数据。在使用视频解码器和 gralloc 样式缓冲区时,这很可能相关。
error_ bool 允许(但不要求)StreamProcessor 服务器报告在 AU 期间或 AU 之间发生的错误。
error_detected_before 的范围从该数据流上最后一个已传送的输出数据包的末尾开始,如果该数据流上之前没有输出数据包,则从数据流的开头开始。该范围在 output_packet 的开头结束。
error_detected_before 布尔值是单独的,以便可以单独指示不连续性,而与当前数据包是否损坏无关。
error_detected_during 的范围是从此 output_packet 的开头到结尾。
响应
| 名称 | 类型 |
|---|---|
output_packet |
Packet
|
error_detected_before |
bool
|
error_detected_during |
bool
|
OnOutputTimestampHasNoOutput
大多数客户端都可以忽略 OnOutputTimestampHasNoOutput 消息。
OnOutputTimestampHasNoOutput 仅由 supports_dynamic_buffers 为 true 的 StreamProcessor 服务器发送。
当服务器确定具有给定 timestamp_ish 值的先前输入数据包永远不会生成任何输出时,服务器将发送包含该 timestamp_ish 值的消息。
当服务器最终确定时间戳永远不会生成任何输出时,此消息可以被视为 OnOutputPacket 的替代项;这就是名称以“OnOutput”开头的原因。与指示输出的消息类似,当正在进行由数据流驱动的输出重新配置(从 OnOutputConstraints 开始)时,服务器不会发送此消息。
虽然服务器应在允许、可行和实际的情况下尽快发送此消息,但无法保证服务器何时会发送此消息。对于不生成任何输出的某些输入数据包,服务器可能会在消耗相应的输入数据包后很快发送此消息。对于不生成任何输出的其他输入数据包,服务器可能不会发送此消息,直到服务器可以通过延迟方式(例如,涉及 max_num_reorder_frames 的逻辑或任何相关的特定于比特流格式的逻辑)证明相应的输入数据包永远不会生成任何输出。在服务器收到并处理更多输入之前,服务器可以不发送此消息。客户端不得在发送更多输入之前尝试等待接收此消息,因为这可能会造成死锁。
发送时,此消息将在具有相同 timestamp_ish 值的相应输入数据包的 OnFreeInputPacket 消息之后发送。客户端不得延迟输入缓冲区的重复使用,直到收到 OnOutputTimestampHasNoOutput,因为这可能会造成潜在的死锁。
发送时,此消息将在 stream_lifetime_ordinal 流的 OnOutputEndOfStream 消息之前发送。在发送 OnOutputEndOfStream 之前,服务器无需为所有未解析(就输出是/否而言)的输入 timestamp_ish 值发送 OnOutputTimestampHasNoOutput,并且 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 位数字,并在客户端本地保留任何对应的实际时间戳。
如果客户端没有特定理由关注此事件,则应忽略此事件。大多数客户端都可以完全忽略此事件,而不会产生任何不利影响。
响应
| 名称 | 类型 |
|---|---|
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,但这可能随时会中断,而不会被视为服务器端 bug。
之后,可以使用 AddBuffer(逐个)添加分配的缓冲区,并可以使用 RemoveBuffer(逐个)移除。
多个不同的 ParticipateInBufferAllocation 消息可以稍后使用相同的 buffer_lifetime_ordinal 将其缓冲区添加到同一 StreamProcessor 实例。如果客户端想要以增量方式分配缓冲区,或者动态调整缓冲区数量(可能在主动处理期间),这会非常有用。另请参阅此消息的 buffer_lifetime_ordinal 字段。
服务器实现可以使用 sysmem 来帮助在稍后使用 AddBuffer 添加缓冲区时验证缓冲区兼容性。
请求
| 名称 | 类型 |
|---|---|
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 中引用。
请求
| 名称 | 类型 |
|---|---|
payload |
StreamProcessorRemoveBufferRequest
|
响应
| 名称 | 类型 |
|---|---|
payload |
StreamProcessor_RemoveBuffer_Result
|
SetInputBufferPartialSettings
当客户端未使用动态缓冲区时,单个 SetInputBufferPartialSettings() 会向 StreamProcessor 提供客户端指定的输入设置和 BufferCollectionToken,StreamProcessor 将使用该令牌向 sysmem 传达限制。客户端和 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 提供客户端指定的输出设置和 BufferCollectionToken,StreamProcessor 将使用该令牌向 sysmem 传达限制。客户端和 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 中定义
用于创建音频使用方以进行本地渲染的接口。
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
|
无默认应用 |
“Compression”(压缩)
在 fuchsia.media/stream_type.fidl 中定义
描述应用于数据流的压缩。此类型可与 AudioStreamType 或 VideoStreamType 结合使用,以表示特定于媒体的压缩类型。
| 字段 | 类型 | 说明 | 默认 |
|---|---|---|---|
type |
CompressionType
|
应用于数据流的压缩类型。这通常是 ENCODING 值之一,但不得使用 |
无默认应用 |
parameters |
vector<uint8>:8192?
|
描述数据流压缩情况的类型特定、不透明的“带外”参数。 |
无默认应用 |
EncryptionPattern
在 fuchsia.media/stream_common.fidl 中定义
EncryptionPattern
模式加密在子样本的受保护范围(SubsampleEntry 的 encrypted_bytes)内使用加密和明文 16 字节块的模式。此结构指定加密数据块的数量,后跟明文数据块的数量。
| 字段 | 类型 | 说明 | 默认 |
|---|---|---|---|
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 数据。此编码器将接受任意帧边界上的 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。 当此结构体与 |
无默认应用 |
payload_offset |
uint64
|
载荷缓冲区中数据包载荷的偏移量。 此值加上 |
无默认应用 |
payload_size |
uint64
|
载荷的大小(以字节为单位)。 此值加上 |
无默认应用 |
flags |
uint32
|
一组按位或运算的标志(请参阅下面的常量),用于描述此数据包的属性。 |
0 |
buffer_config |
uint64
|
与此数据包关联的缓冲区配置。此字段的语义取决于使用此结构的接口。在许多情况下,此字段不会被使用。此字段适用于明确标识缓冲区配置(即一组载荷缓冲区)的情况。在这种情况下, |
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,而增量比率为 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
|
false | |
pixel_aspect_ratio_width |
uint32
|
1 | |
pixel_aspect_ratio_height |
uint32
|
1 |
Void
在 fuchsia.media/audio_consumer.fidl 中定义
<EMPTY>
枚举
AacAudioObjectType strict
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
| 名称 | 值 | 说明 |
|---|---|---|
MPEG2_AAC_LC |
0 |
MPEG-2 低复杂度 |
MPEG4_AAC_LC |
1 |
MPEG-4 低复杂度 |
严格 AacChannelMode
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
| 名称 | 值 | 说明 |
|---|---|---|
单色 |
0 |
|
STEREO |
2 |
AacVariableBitRate strict
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
可变比特率模式。实际产生的比特率因输入信号和其他编码设置而异。
请参阅 https://wiki.hydrogenaud.io/index.php?title=Fraunhofer_FDK_AAC#Bitrate_Modes
| 名称 | 值 | 说明 |
|---|---|---|
V1 |
1 |
|
V2 |
2 |
|
V3 |
3 |
|
V4 |
4 |
|
V5 |
5 |
AudioBitrateMode strict
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
| 名称 | 值 | 说明 |
|---|---|---|
未指定 |
0 |
|
CBR |
1 |
|
VBR |
2 |
AudioCaptureUsage strict
类型:uint32
在 fuchsia.media/audio_core.fidl 中定义
用于注释音频捕获流用途的用法。音频政策使用 AudioCaptureUsage 来指示音频串流如何相互交互。
| 名称 | 值 | 说明 |
|---|---|---|
背景 |
0 |
该音频流用于在后台捕获音频。这些音频流可能随时处于活动状态,并被视为特权音频流。 示例:监听启动指令 |
FOREGROUND |
1 |
数据流旨在用于常规拍摄功能。当音频流创建者在前台时,用于音频采集的音频流应使用此属性。 示例:录音机 |
SYSTEM_AGENT |
2 |
Stream 适用于与系统代理进行互动。只有在用户表示有意与感兴趣的一方进行互动后,才应使用此功能。 示例:Google 助理、Siri、Alexa |
沟通 |
3 |
Stream 旨在用于某种形式的实时用户间通信。语音/视频聊天应使用此功能。 |
AudioCaptureUsage2 flexible
类型:uint32
在 fuchsia.media/audio_core.fidl 中定义
用于注释音频捕获流用途的用法。音频政策使用 AudioCaptureUsage 来指示音频串流如何相互交互。
| 名称 | 值 | 说明 |
|---|---|---|
背景 |
0 |
该音频流用于在后台捕获音频。这些音频流可能随时处于活动状态,并被视为特权音频流。 示例:监听启动指令 |
FOREGROUND |
1 |
数据流旨在用于常规拍摄功能。当音频流创建者在前台时,用于音频捕获的音频流应使用此音频流。示例:录音机 |
SYSTEM_AGENT |
2 |
Stream 适用于与系统代理进行互动。只有在用户表示有意与相关方进行互动后,才应使用此功能。 示例:Google 助理、Siri、Alexa |
沟通 |
3 |
Stream 旨在用于某种形式的实时用户间通信。 语音/视频聊天应使用此功能。 |
AudioChannelId strict
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
AudioChannelId
用于指定哪个音频声道对应哪个扬声器位置 / 类型。
TODO(b/529511595): Do we need/want more channel IDs than this?
| 名称 | 值 | 说明 |
|---|---|---|
跳过 |
0 |
|
LF |
1 |
|
RF |
2 |
|
CF |
3 |
|
LS |
4 |
|
RS |
5 |
|
LFE |
6 |
|
CS |
7 |
|
LR |
8 |
|
RR |
9 |
|
END_DEFINED |
10 |
|
EXTENDED_CHANNEL_ID_BASE |
1862270976 |
|
上限 |
2147483647 |
AudioOutputRoutingPolicy strict
类型:uint32
在 fuchsia.media/audio_core.fidl 中定义
已弃用
| 名称 | 值 | 说明 |
|---|---|---|
ALL_PLUGGED_OUTPUTS |
0 |
|
LAST_PLUGGED_OUTPUT |
1 |
AudioPcmMode strict
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
| 名称 | 值 | 说明 |
|---|---|---|
线性 |
0 |
|
ALAW |
1 |
|
MULAW |
2 |
AudioRenderUsage strict
类型:uint32
在 fuchsia.media/audio_core.fidl 中定义
用法,用于注释用于呈现音频的流的用途。AudioRenderer 的用途在创建后无法更改。音频政策会使用 AudioRenderUsage 来指示音频串流如何相互交互。
| 名称 | 值 | 说明 |
|---|---|---|
背景 |
0 |
Stream 旨在用于环境音或背景音。可以中断而不会产生后果的音频流应使用此类型。 |
媒体 |
1 |
Stream 旨在用于正常功能。属于正常功能的音频流应使用此类型。 |
INTERRUPTION |
2 |
Stream 旨在中断设备上任何正在运行的功能。 用于中断(例如通知)的音频流应使用此类型。 |
SYSTEM_AGENT |
3 |
Stream 适用于与系统代理进行互动。这应该用于响应用户发起的触发器。 |
沟通 |
4 |
Stream 旨在用于某种形式的实时用户间通信。语音/视频聊天应使用此功能。 |
AudioRenderUsage2 灵活
类型:uint32
在 fuchsia.media/audio_core.fidl 中定义
用法:对用于呈现音频的音频流的用途进行注解。AudioRenderer 的用途在创建后无法更改。音频政策会使用 AudioRenderUsage2 值来指示音频串流如何相互交互。此枚举使用其他音频流类型扩展了原始(严格)枚举 |AudioRenderUsage|。
| 名称 | 值 | 说明 |
|---|---|---|
背景 |
0 |
Stream 旨在用于环境音或背景音。可以中断而不会产生后果的音频流应使用此类型。 |
媒体 |
1 |
Stream 旨在用于正常功能。属于正常功能的音频流应使用此类型。 |
INTERRUPTION |
2 |
Stream 旨在中断设备上任何正在运行的功能。 用于中断(例如通知)的音频流应使用此类型。 |
SYSTEM_AGENT |
3 |
Stream 适用于与系统代理进行互动。这应该用于响应用户发起的触发器。 |
沟通 |
4 |
Stream 旨在用于某种形式的实时用户间通信。语音/视频聊天应使用此功能。 |
ACCESSIBILITY |
5 |
此音频流旨在用于无障碍功能或其他非系统代理语音输出,例如屏幕阅读器 TTS。 |
AudioSampleFormat strict
类型:uint32
在 fuchsia.media/stream_type.fidl 中定义
枚举支持的音频采样格式。
| 名称 | 值 | 说明 |
|---|---|---|
UNSIGNED_8 |
1 |
8 位无符号样本,样本大小为 1 字节。 |
SIGNED_16 |
2 |
16 位有符号样本,采用主机字节序,样本大小为 2 字节。 |
SIGNED_24_IN_32 |
3 |
32 位中的 24 位有符号样本,主机字节序,样本大小为 4 字节。 |
FLOAT |
4 |
32 位浮点样本,样本大小为 4 字节。 |
行为灵活
类型:uint32
在 fuchsia.media/audio_core.fidl 中定义
当多个直播处于活动状态时,应用于直播的行为。
| 名称 | 值 | 说明 |
|---|---|---|
无 |
0 |
混合这些流。 |
橡皮鸭 |
1 |
应用增益来降低其中一个音频流的音量。(-14.0db) |
静音 |
2 |
应用增益以将其中一个音频流静音。(-160.0db) |
CodecProfile flexible
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
允许的编解码器配置文件列表。此列表应具有灵活性,因为将来可以且将会添加编解码器。如果需要,此文件可以同时包含视频和音频配置文件。
| 名称 | 值 | 说明 |
|---|---|---|
H264PROFILE_BASELINE |
0 |
|
H264PROFILE_MAIN |
1 |
|
H264PROFILE_EXTENDED |
2 |
|
H264PROFILE_HIGH |
3 |
|
H264PROFILE_HIGH10PROFILE |
4 |
|
H264PROFILE_HIGH422PROFILE |
5 |
|
H264PROFILE_HIGH444PREDICTIVEPROFILE |
6 |
|
H264PROFILE_SCALABLEBASELINE |
7 |
|
H264PROFILE_SCALABLEHIGH |
8 |
|
H264PROFILE_STEREOHIGH |
9 |
|
H264PROFILE_MULTIVIEWHIGH |
10 |
|
VP8PROFILE_ANY |
11 |
|
VP9PROFILE_PROFILE0 |
12 |
|
VP9PROFILE_PROFILE1 |
13 |
|
VP9PROFILE_PROFILE2 |
14 |
|
VP9PROFILE_PROFILE3 |
15 |
|
HEVCPROFILE_MAIN |
16 |
|
HEVCPROFILE_MAIN10 |
17 |
|
HEVCPROFILE_MAIN_STILL_PICTURE |
18 |
|
MJPEG_BASELINE |
19 |
ColorSpace strict
类型:uint32
在 fuchsia.media/stream_type.fidl 中定义
| 名称 | 值 | 说明 |
|---|---|---|
未知 |
0 |
|
NOT_APPLICABLE |
1 |
|
JPEG |
2 |
|
HD_REC709 |
3 |
|
SD_REC601 |
4 |
Lc3FrameDuration 灵活
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
| 名称 | 值 | 说明 |
|---|---|---|
D10_MS |
1 |
|
D7P5_MS |
2 |
端口灵活
类型:uint32
在 fuchsia.media/stream_processor.fidl 中定义
此枚举表示 StreamProcessor 输入或输出。此消息适用于输入或输出。例如,StreamProcessor.ParticipateInBufferAllocation 消息包含 port 字段。
| 名称 | 值 | 说明 |
|---|---|---|
无效 |
0 |
|
输入 |
1 |
|
输出 |
2 |
SbcAllocation strict
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
| 名称 | 值 | 说明 |
|---|---|---|
ALLOC_LOUDNESS |
0 |
|
ALLOC_SNR |
1 |
SbcBlockCount strict
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
| 名称 | 值 | 说明 |
|---|---|---|
BLOCK_COUNT_4 |
4 |
|
BLOCK_COUNT_8 |
8 |
|
BLOCK_COUNT_12 |
12 |
|
BLOCK_COUNT_16 |
16 |
SbcChannelMode strict
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
| 名称 | 值 | 说明 |
|---|---|---|
单色 |
0 |
|
DUAL |
1 |
|
STEREO |
2 |
|
JOINT_STEREO |
3 |
SbcSubBands 严格执行
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
| 名称 | 值 | 说明 |
|---|---|---|
SUB_BANDS_4 |
4 |
|
SUB_BANDS_8 |
8 |
StreamError strict
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
StreamError
此错误代码封装了 StreamProcessor 服务器可能发出的各种错误。它可以作为 OnStreamFailed 事件发送,也可以作为通道的 epitaph 发送。
| 名称 | 值 | 说明 |
|---|---|---|
未知 |
1 |
原因不明的内部错误。 |
INVALID_INPUT_FORMAT_DETAILS |
2 |
客户端提供的输入格式详细信息无效。 |
INCOMPATIBLE_BUFFERS_PROVIDED |
3 |
服务器收到了不适合执行操作的缓冲区。例如,如果解码器收到的输出缓冲区太小,无法将帧解码到其中,就会发生这种情况。 |
EOS_PROCESSING |
4 |
输入 EOS(流结束)处理失败,因此流失败。 目前,如果在处理 EOS 时触发核心编解码器看门狗,则可能会发生这种情况。 |
DECODER_UNKNOWN |
16777217 |
原因未指定的内部解码器错误。 |
DECODER_DATA_PARSING |
16777218 |
无法解析的输入数据。只有部分解析问题/错误会通过这种方式报告。损坏的输入数据可能会报告为其他 StreamError,也可能不会导致 StreamError。 |
ENCODER_UNKNOWN |
33554433 |
内部编码器错误,原因未指定。 |
DECRYPTOR_UNKNOWN |
50331649 |
解密器内部错误,原因未指定。 |
DECRYPTOR_NO_KEY |
50331650 |
请求的 KeyId 无法供解密器使用。如果该密钥可用,客户端可以稍后重试。 |
VideoColorSpace strict
类型:uint32
在 fuchsia.media/stream_common.fidl 中定义
| 名称 | 值 | 说明 |
|---|---|---|
无效 |
0 |
TABLES
AudioCompressedFormatCvsd
在 fuchsia.media/stream_common.fidl 中定义
AudioCompressedFormatCvsd 目前不包含任何字段,因为我们将使用蓝牙核心规范 v5.3 第 9.2 节中推荐的参数值。
| 序数 | 字段 | 类型 | 说明 |
|---|
AudioCompressedFormatLc3
在 fuchsia.media/stream_common.fidl 中定义
AudioCompressedFormatLc3 不包含任何字段。设置解码器所需的参数将作为 Codec_Specific_Configuration(Assigned Numbers 第 6.12.5 节)嵌入到 FormatDetails.oob_bytes 中。
| 序数 | 字段 | 类型 | 说明 |
|---|
AudioConsumerStatus
在 fuchsia.media/audio_consumer.fidl 中定义
表示使用方的状态。在初始状态下,error 和 presentation_timeline 不存在。提前期字段始终存在。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
error |
AudioConsumerError
|
如果存在,则表示当前生效的错误条件。如果没有错误,则不存在。 |
2 |
presentation_timeline |
TimelineFunction
|
如果存在,则表示呈现时间轴与本地单调时钟之间的当前关系,两者均以纳秒为单位。如果不存在,则表示没有关系。最初不存在。 “呈现时间轴”是指数据包上的 |
3 |
min_lead_time |
uint64
|
表示此 |
4 |
max_lead_time |
uint64
|
表示此 |
CvsdEncoderSettings
在 fuchsia.media/stream_common.fidl 中定义
CVSD 编码器的设置。它目前不包含任何字段,因为我们将使用蓝牙核心规范 v5.3 第 9.2 节中推荐的参数值。
| 序数 | 字段 | 类型 | 说明 |
|---|
DecryptedFormat
在 fuchsia.media/stream_common.fidl 中定义
DecryptedFormat
这描述了解密内容的格式。StreamProcessor 服务器必须在传送输出数据包之前发送该数据包。目前,没有关于解密输出的其他格式详细信息。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
ignore_this_field |
bool
|
EncryptedFormat
在 fuchsia.media/stream_common.fidl 中定义
EncryptedFormat
解密流处理器的流格式详细信息载荷。这是一个稀疏填充的表,用于指定除数据流之外的解密所需参数。只有在字段发生更改时才需要更新字段,但如果重复相同的值,也不会出错。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
3 |
init_vector |
InitVector
|
|
4 |
subsamples |
vector<SubsampleEntry>
|
|
5 |
pattern |
EncryptionPattern
|
|
6 |
scheme |
string
|
|
8 |
key_id |
KeyId
|
|
FormatDetails
在 fuchsia.media/stream_common.fidl 中定义
FormatDetails
这描述/详细说明了 StreamProcessor 的输入或输出格式(输入和输出使用不同的实例)。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
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 始终在新流的第一个输出数据包之前发送)。 |
2 |
mime_type |
string
|
|
3 |
oob_bytes |
vector<uint8>
|
|
4 |
domain |
DomainFormat
|
|
5 |
pass_through_parameters |
vector<Parameter>
|
|
6 |
encoder_settings |
EncoderSettings
|
指示编码器如何对原始数据进行编码。 解码器可能会忽略此字段,但有权拒绝设置了此字段的请求,因为此字段没有意义。 |
7 |
timebase |
uint64
|
输入数据包 timestamp_ish 值的时间基准每秒的 tick 数。 仅当适用于输入数据包有效部分第 0 个字节的输入时间戳不直接对应于任何输出数据包有效部分第 0 个字节时,时基才用于 timestamp_ish 值的可选外推。 如果不需要时间戳外推,则不设置此值,原因可能是输入中缺少时间戳,或者输入是以编码器输入块大小的增量提供的(基于编码器设置并由客户端独立计算)。如果已知需要时间戳外推,或者已知客户端可以接受时间戳外推,则设置此项。 |
8 |
profile |
CodecProfile
|
给定编码器或解码器的编解码器配置文件。 对于编码器:此值完全可选。出于协议兼容性(即 WebRTC)原因,客户端可能需要指定所使用的编解码器配置文件。不过,如果未设置该值,编码器可以自由选择任何受支持的编解码器配置文件。 对于解码器:此值是可选的,但最好提供此值(至少对于未加密的流)。容器格式包含编码配置文件,应将其提供给解码器。某些格式(例如 VP9 和 AV1)会在其基本比特流中包含编码配置文件,因此这些解码器可以确定流的编码配置文件。无论如何,客户端都应尽可能提供经过编码的配置文件。 |
H264EncoderSettings
在 fuchsia.media/stream_common.fidl 中定义
H264 编码器的设置。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
bit_rate |
uint32
|
编码流的目标比特率(每秒位数)。 如果省略,则解读为 200,000。 |
2 |
frame_rate |
uint32
|
编码流的目标每秒帧数。 如果省略,则解读为 30。 |
3 |
gop_size |
uint32
|
每个关键帧的图片数量。设置为 0 将停用关键帧编码,除非 force_key_frame 设置为 true。如果省略,则会被解读为 8。 |
4 |
variable_frame_rate |
bool
|
是否启用帧速率调整以达到目标比特率。 如果省略,则会被解释为 false。 |
5 |
min_frame_rate |
uint32
|
如果启用了 |
6 |
force_key_frame |
bool
|
如果为 true,则下一个编码的帧将是关键帧。如果省略,则解释为 false。 |
7 |
quantization_params |
H264QuantizationParameters
|
允许自定义编码的量化参数。设置此值后提交的每个帧都将使用新值。如果省略,则不会更改编码器默认值。 |
H264QuantizationParameters
在 fuchsia.media/stream_common.fidl 中定义
自定义 h264 编码器参数,以进行宏块量化。值范围为 0 到 51,数字越小,表示质量/比特率越高。虽然编码器应尽可能支持这些字段,但某些编码器可能会忽略这些字段。您可以不设置此表,也可以不设置此表中的某些字段,因为编码器可以确定自己的默认值。如果使用指定值无法达到目标比特率,则用户应预期生成的编码流比特率与请求的比特率不同。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
i_base |
uint32
|
关键帧量化的起始值。 |
2 |
i_min |
uint32
|
关键帧量化允许的最小值。 |
3 |
i_max |
uint32
|
关键帧量化允许的最大值。 |
4 |
p_base |
uint32
|
预测帧量化的起始值。 |
5 |
p_min |
uint32
|
预测帧量化允许的最小值。 |
6 |
p_max |
uint32
|
预测帧量化允许的最大值。 |
HevcEncoderSettings
在 fuchsia.media/stream_common.fidl 中定义
HEVC/H265 编码器的设置。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
bit_rate |
uint32
|
编码流的目标比特率(每秒位数)。如果省略,则默认为 200,000。 |
2 |
frame_rate |
uint32
|
编码流的目标每秒帧数。如果省略,则默认为 30。 |
3 |
gop_size |
uint32
|
每个关键帧的图片数量。如果省略,则默认为 8。 |
InputAudioCapturerConfiguration
在 fuchsia.media/audio_capturer.fidl 中定义
将从输入设备接收数据流的捕获器的配置。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
usage |
AudioCaptureUsage
|
已弃用 - 请使用 usage2 和 AudioCaptureUsage2 |
2 |
usage2 |
AudioCaptureUsage2
|
Lc3EncoderSettings
在 fuchsia.media/stream_common.fidl 中定义
LC3 编码器的设置。包含 LC3 规范 v1.0 中规定的参数。 包含 PcmFormat 未表示的字段。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
nbytes |
uint16
|
用于音频帧编码的外部字节计数值。
根据 LC3 规范 v1.0,每个音频通道可以具有不同的输出字节大小值,但对于 Fuchsia 用例,我们对所有通道使用相同的 |
2 |
frame_duration |
Lc3FrameDuration
|
帧时长与采样频率一起用于确定帧大小。 |
LoopbackAudioCapturerConfiguration
在 fuchsia.media/audio_capturer.fidl 中定义
将接收系统输出的环回流的捕获器的配置。
| 序数 | 字段 | 类型 | 说明 |
|---|
MSbcEncoderSettings
在 fuchsia.media/stream_common.fidl 中定义
mSBC 编码器的设置。没有设置,因为 mSBC 编码器使用 HFP 规范 v1.8 所需的值。
| 序数 | 字段 | 类型 | 说明 |
|---|
包
在 fuchsia.media/stream_processor.fidl 中定义
数据包表示流处理器输入或输出的数据块。
流处理器输出:
当数据包通过 OnOutputPacket() 处于客户端未完成状态时,流处理器将避免修改引用的输出数据。在客户端调用 RecycleOutputPacket(packet_index) 后,流处理器会收到通知,告知客户端再次同意更改引用的数据。
流处理器输入:
客户端最初具有所有可填充的 packet_index,随后会通过 OnFreeInputPacket() 再次获取可填充的 packet_index。客户端不得在 QueueInputPacket() 和 OnFreeInputPacket() 之间修改引用的数据。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
header |
PacketHeader
|
|
2 |
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,以指示客户端已准备好同时处理多个引用相同输出缓冲区的传输中输出数据包。除了比特流格式测试之外,很少有流会因此而产生任何差异。 |
3 |
stream_lifetime_ordinal |
uint64
|
值 1 是创建流处理器后允许的最低值。客户端发送的值必须是奇数。值只能增加。 stream_lifetime_ordinal 表示数据流的生命周期。特定于数据流的所有消息都具有 stream_lifetime_ordinal 值,并且与给定数据流相关的所有消息的值都相同。 |
4 |
start_offset |
uint32
|
此数据包使用的是相关缓冲区的哪个部分。这些密钥对传输到流处理器的输入数据有效,对来自流处理器的输出数据也有效。 对于压缩格式和未压缩音频,[start_offset, start_offset + valid_length_bytes) 中的数据是此数据包引用的连续有效数据。 对于未压缩的视频帧,FormatDetails 是确定哪些字节相关的主要方法。FormatDetails 中的偏移量是相对于此处的 start_offset。valid_length_bytes 必须足够大,才能包含像素数据的完整最后一行,包括最后一行的完整行跨度(而不仅仅是最后一行的像素宽度)。 尽管这些缓冲区已填充,但某些未压缩的视频缓冲区属于 CPU 无法读取的类型。这些字段的存在并不意味着 CPU 有任何方法可以读取未压缩的帧。 |
5 |
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 标头中的边界处。 压缩数据输出 - 流处理器无需完全填充每个输出数据包的缓冲区。 |
6 |
timestamp_ish |
uint64
|
严格来说,此值并非时间戳。它是一个任意无符号 64 位数字,在某些情况下,流处理器会将其从输入数据包原封不动地传递到完全对应的输出数据包。 如需将 timestamp_ish 值从输入传播到输出,必须满足以下条件:
|
7 |
start_access_unit |
bool
|
如果 promise_separate_access_units_on_input(TODO(dustingreen):或任何类似的输出模式)为 true,则必须根据字节 0 是否为访问单元的开头,适当地设置此布尔值。客户端必须知道并正确设置此布尔值。如果此布尔值为 false,则允许服务器推断字节 0 是先前启动的 AU 的延续的第一个字节。(start_offset 处的字节为“字节 0”。) 如果 promise_separate_access_units_on_input 为 false,则系统会忽略此布尔值。 |
8 |
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(对于正常运行的解码器),则允许注入访问单元定界符,但没有必要(为了减少延迟)。客户端永远不需要剥离可能已经存在于数据流中的任何访问单元定界符,此字段的设置无需与任何访问单元定界符的存在/不存在相匹配。 |
9 |
key_frame |
bool
|
用于压缩视频数据包。如果不存在,则应假定为未知。如果为 false,则表示数据包不属于关键帧。 如果为 true,则表示数据包是关键帧的一部分。 |
PacketHeader
在 fuchsia.media/stream_processor.fidl 中定义
PacketHeader
在引用空闲数据包时,我们仅使用 PacketHeader,而不使用 Packet,因为当数据包空闲时,它实际上没有有意义的偏移量或长度等。
填充的数据包还具有 PacketHeader。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
buffer_lifetime_ordinal |
uint64
|
此标头指的是哪个缓冲区配置生命周期。 请参阅 对于 QueueInputPacket(),如果服务器收到的 buffer_lifetime_ordinal 不是当前的输入 buffer_lifetime_ordinal,则会关闭通道。 对于输出数据包,只有在客户端发送了 EnableOldOutputBuffers 的情况下,此值才可以是旧的 buffer_lifetime_ordinal。另请参阅 RemoveBuffer,以确定何时可以安全地停止跟踪旧输出缓冲区(仅与某些视频比特流格式 [例如 VP9] 相关,并且仅与解码器相关)。除了比特流格式测试流之外,很少有流需要发出旧输出缓冲区。 |
2 |
packet_index |
uint32
|
使用 使用 每个端口(输入与输出)和
对于输入,客户端在发送带有 对于输出,服务器在发送带有 可用的 客户端和服务器都应根据已知边界(如有,请参阅上文)验证 packet_index,如果超出边界,则断开连接。 packet_index 值并不表示数据包的使用顺序。客户端不应期望顺序始终保持不变,因为流处理器可以自由地保留输入或输出数据包一段时间,在此期间,其他一些 packet_index 值可能会被多次重复使用。 对于给定的正常运行的 StreamProcessor 实例,输出 packet_index 值在并发未完成的数据包中是唯一的。 服务器应验证客户端是否未重复使用数据包,客户端也可以类似地验证来自服务器的 |
StreamBufferConstraints
在 fuchsia.media/stream_processor.fidl 中定义
此结构体会传达 buffer_constraints_version_ordinal。
过去,此表包含的字段比现在多,但这些字段都已被弃用,取而代之的是使用 sysmem。
此结构体有单独的实例,分别用于流输入和流输出。
有关字段的注意事项:
对于未压缩的视频,始终需要将单独且完整的帧放在各自的缓冲区中(每个数据包一个缓冲区模式)。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
buffer_constraints_version_ordinal |
uint64
|
这是服务器在限制条件上设置的版本号,以便服务器确定客户端何时已赶上服务器发送的最新限制条件。在客户端配置了 buffer_constraints_version_ordinal >= 最新 buffer_constraints_version_ordinal(其 buffer_constraints_action_required 为 true)的输出设置和缓冲区之前,服务器不会发出输出数据。如需了解详情,请参阅 buffer_constraints_action_required 注释。 为简化初始状态处理,不允许 buffer_constraints_version_ordinal 为 0。除 0 之外,奇数和偶数版本序数均允许使用(与 stream_lifetime_ordinal 不同,客户端和服务器都没有理由认为最新版本已过时,因此不允许使用偶数值没有任何好处)。 |
2 |
default_settings |
StreamBufferSettings
|
DEPRECATED - 忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints() |
3 |
per_packet_buffer_bytes_min |
uint32
|
DEPRECATED - 忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints() |
4 |
per_packet_buffer_bytes_recommended |
uint32
|
DEPRECATED - 忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints() |
5 |
per_packet_buffer_bytes_max |
uint32
|
DEPRECATED - 忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints() |
6 |
packet_count_for_server_min |
uint32
|
DEPRECATED - 忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints() |
7 |
packet_count_for_server_recommended |
uint32
|
DEPRECATED - 忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints() |
8 |
packet_count_for_server_recommended_max |
uint32
|
DEPRECATED - 忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints() |
9 |
packet_count_for_server_max |
uint32
|
DEPRECATED - 忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints() |
10 |
packet_count_for_client_min |
uint32
|
DEPRECATED - 忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints() |
11 |
packet_count_for_client_max |
uint32
|
DEPRECATED - 忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints() |
12 |
single_buffer_mode_allowed |
bool
|
DEPRECATED - 忽略。已过时。 |
13 |
is_physically_contiguous_required |
bool
|
DEPRECATED - 忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints() |
14 |
buffer_count_for_server_current |
uint32
|
如果编解码器的 对于输入,编解码器可能需要这么多缓冲区,然后才会处理任何输入。目前,对于输入,此值对于每个 StreamProcessor 实例都是静态的。在添加此数量的输入缓冲区之前,允许客户端发送 QueueInput…() 消息,但在至少添加此数量的输入缓冲区之前,不应期望必然会发出任何输出。对于新启动的数据流,在任何 QueueInputPacket 之前,QueueInputFormatDetails 和 QueueInputEndOfStream 也是如此,因此,即使到目前为止添加的输入缓冲区仍为零,也可以发送前两个。如果编解码器只需要一个输入缓冲区即可向前推进(非连续、非平滑的向前推进也算),则应将其设置为 1。大多数客户端都希望添加少量额外缓冲区,以保持流水线顺畅运行,从而避免在 OnFreeInputPacket 从编解码器传输到客户端的过程中出现处理停滞。将输入数据复制到单独的流缓冲区(有时被视为循环缓冲区)的解码器通常只需要一个输入缓冲区即可实现向前推进,但大多数客户端仍希望添加少量额外的输入缓冲区,以实现更顺畅的线程调度,即使此类解码器核心可能能够以 100% 的利用率运行单个输入缓冲区。 对于视频解码器输出,如果客户端总体上仅 对于视频解码器输出,如果设置了此值,则此值将始终小于或等于 此值可由来自服务器的新 OnOutputConstraints 更新,其中 action_required 为 false。不过,即使“action_required”为 false,客户端也必须确保当前可供编解码器并发使用的缓冲区数量至少达到此数量。 如果客户端将动态缓冲区与视频解码器搭配使用,并且不想关注此字段,则客户端仍应关注 建议上层允许将较小的图片存储在较大的缓冲区中,这样就不必在每次中游尺寸发生变化时都重新分配缓冲区。相反,在这种情况下,几乎总是最好继续使用现有的较大缓冲区,以避免由于分配缓冲区并不总是像预期的那样快,再加上输出缓冲区数量不一定有足够的额外缓冲区来吸收时间意义上的缓冲区重新分配,从而导致渲染卡顿。不过,如果上层确实必须在图片大小发生变化且容纳图片所需的缓冲区空间减小时重新分配缓冲区,则此类客户端必须设置传递给 CreateDecoder 的 force_new_buffers_for_new_dimensions。否则,视频解码器可以开始将较小的图片放入现有的较大缓冲区中,并使用 OnOutputFormat 消息指示这一点。 新增:32
|
15 |
size |
fuchsia.math/SizeU
|
客户端可以随意忽略此字段。 仅当 此字段仅供参考,适用于可能希望了解此信息的客户端。不过,即使客户端从未读取此字段,StreamProcessor 和 sysmem 协议也能正常运行。 这是所需的编码尺寸,无需任何裁剪即可达到显示尺寸。 如果客户端作为 sysmem 参与者直接参与,则客户端不应设置与此大小不兼容的限制,否则分配将失败。此字段不应被视为暗示给定缓冲区只有一个允许的图片大小。一般来说,这是不正确的。相反,此字段表示一个大小,该大小将由 StreamProcessor sysmem 参与者使用传入 SetInputBufferPartialSettings、SetOutputBufferPartialSettings 或 ParticipateInBufferAllocation 的令牌设置的 required_min_size 和 required_max_size 涵盖。 尽管此大小表示特定的宽度和高度,但分配的缓冲区可能允许一系列图片大小(对于视频解码器输出或视频编码器输入)。 新增:32
|
16 |
pixel_format |
fuchsia.images2/PixelFormat
|
客户端可以随意忽略此字段。 仅当 此字段仅供参考,适用于可能希望了解此信息的客户端。不过,即使客户端从未读取此字段,StreamProcessor 和 sysmem 协议也能正常运行。 在 StreamProcessor 服务器支持的像素格式中,有些格式可以承载图像的完整位深,并且广泛支持承载所需位深的图像。假设 pixel_format_modifier 为线性,则此像素格式对于单独考虑的 StreamProcessor 而言性能最高。如果多个符合条件的格式在性能上基本相同,则应选择最常见的格式(或在常见程度大致相同的格式中任意选择)。大多数 StreamProcessor 服务器都会对每个受支持的位深进行硬编码,以将特定格式放入此字段。 目前,我们预计不需要在此处提供列表,但如果您遇到只能通过在此处提供列表(或通过 ParticipateInBufferAllocation 尝试多次测试分配,或通过添加 sysmem 功能)来解决的非测试场景,请随时与我们联系。 一般来说,sysmem 不一定会选择此像素格式,因为这取决于 StreamProcessor 实例和其他 sysmem 参与者支持的全套像素格式。如果只有客户端和 StreamProcessor 是 sysmem 参与者(例如在某些测试中),并且客户端需要此像素格式,则缓冲区分配仍可成功。典型的非测试客户端不需要也不希望限制 sysmem 分配,使其仅允许此像素格式,因为与让 sysmem 选择所有参与者共同支持的格式相比,这样做更有可能导致分配失败。 新增:32
|
StreamBufferPartialSettings 资源
在 fuchsia.media/stream_processor.fidl 中定义
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
buffer_lifetime_ordinal |
uint64
|
每个缓冲区都与一个 输入和输出分别有单独的 buffer_lifetime_ordinal。 值必须为奇数。值只能增加(允许增加 2 以上)。 使用 当新的 buffer_lifetime_ordinal 开始时,系统也会自动开始取消注册并释放与之前的 buffer_lifetime_ordinal 值关联的所有缓冲区,但如果编解码器仍在使用这些缓冲区进行引用(VP9 可以在中流维度切换中执行此操作),则不会强制它们完成取消注册(或释放)。在取消注册完成之前,服务器仍可输出缓冲区(如输出数据包所示)。 如果客户端希望服务器快速丢弃所有缓冲区,则客户端可以发送设置了 |
2 |
buffer_constraints_version_ordinal |
uint64
|
此值表示客户端目前知道/知道的限制条件版本。 对于输入,此值必须始终为 0,因为输入的限制条件不会更改(设置可以更改,但输入不存在设置与当前限制条件同步问题)。 对于输出,这可让服务器在生成更多输出之前,知道客户端何时已充分跟上。 如果没有活跃的数据流,则允许客户端使用相同的 buffer_constraints_version_ordinal 再次重新配置缓冲区。 |
3 |
single_buffer_mode |
bool
|
已弃用:23
DEPRECATED - 忽略。已过时。 |
4 |
packet_count_for_server |
uint32
|
已弃用:23
DEPRECATED - 忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints() |
5 |
packet_count_for_client |
uint32
|
已弃用:23
DEPRECATED - 忽略。使用 fuchsia.sysmem.BufferCollection.SetConstraints() |
6 |
sysmem_token |
client_end:fuchsia.sysmem/BufferCollectionToken
|
已弃用:23
|
7 |
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。
DEPRECATED - 忽略。请改用 SetStreamBufferPartialSettings。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
buffer_lifetime_ordinal |
uint64
|
DEPRECATED - 忽略。请改用 SetStreamBufferPartialSettings。 |
2 |
buffer_constraints_version_ordinal |
uint64
|
DEPRECATED - 忽略。请改用 SetStreamBufferPartialSettings。 |
3 |
packet_count_for_server |
uint32
|
DEPRECATED - 忽略。请改用 SetStreamBufferPartialSettings。 |
4 |
packet_count_for_client |
uint32
|
DEPRECATED - 忽略。请改用 SetStreamBufferPartialSettings。 |
5 |
per_packet_buffer_bytes |
uint32
|
DEPRECATED - 忽略。请改用 SetStreamBufferPartialSettings。 |
6 |
single_buffer_mode |
bool
|
DEPRECATED - 忽略。请改用 SetStreamBufferPartialSettings。 |
StreamOutputConstraints
在 fuchsia.media/stream_processor.fidl 中定义
由流处理器控制的输出配置,包括输出的 StreamBufferConstraints 和输出的 FormatDetails。
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
stream_lifetime_ordinal |
uint64
|
如果客户端在收到 buffer_constraints_action_required 为 true 的 OnOutputConstraints() 时始终立即重新配置输出缓冲区,则可以安全地忽略此字段。 如果客户端知道服务器已被告知丢弃具有相同 stream_lifetime_ordinal 的数据流的其余部分,或者如果此 stream_lifetime_ordinal 字段设置为 0,则即使 buffer_constraints_action_required 为 true,客户端也可以忽略 OnOutputConstraints() 消息。如果最近完成的服务器端输出配置还不是服务器针对新数据流想要/需要的配置,则服务器需要通过 OnOutputConstraints() 重新发送所需的输出配置,并将 stream_lifetime_ordinal 设置为新值,将 buffer_constraints_action_required 设置为 true。 |
2 |
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_constraints_action_required 为 false,客户端也必须注意 buffer_count_for_server_current 的新值,并确保编解码器具有可供编解码器使用的缓冲区计数,且该计数与新值一致。编解码器不会根据当前有多少个缓冲区可用 / 空闲 / 似乎可供编解码器使用来设置 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,则在客户端配置(或重新配置)输出缓冲区之前,服务器不得提供更多输出数据。 |
3 |
buffer_constraints |
StreamBufferConstraints
|
StreamOutputFormat
在 fuchsia.media/stream_processor.fidl 中定义
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
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()。 |
2 |
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 中定义
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
port |
Port
|
必须设置。缓冲区对应的端口(输入或输出)。 |
2 |
buffer_constraints_version_ordinal |
uint64
|
通常,这是客户端根据 OnInputConstraints/OnOutputConstraints 得知的最新 buffer_constraints_version_ordinal。旧值不会影响正确性。 如果服务器已创建 action_required 为 true 的更高 buffer_constraints_version_ordinal 值,则服务器将忽略此消息。如果服务器忽略此消息,则稍后针对此缓冲区的 RemoveBuffer 将快速完成,而不会产生错误。 客户端无需确保每次使用相同的 buffer_lifetime_ordinal 调用 AddBuffer 时都使用相同的 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。 |
3 |
buffer_lifetime_ordinal |
uint64
|
这些值分别限定为输入/输出。 客户端发送的第一条具有新(更高)buffer_lifetime_ordinal 值的消息会开始移除同一端口上具有较低 buffer_lifetime_ordinal 的所有缓冲区。不过,在移除完成之前,编解码器仍可以使用旧缓冲区。 AddBuffer 消息会将缓冲区添加到此 buffer_lifetime_ordinal。 |
4 |
buffer_index |
uint32
|
在 buffer_lifetime_ordinal 下,buffer_index 值在所有已添加但尚未完全移除的缓冲区中必须是唯一的。此值最初由客户端使用此字段分配/指定,然后客户端和服务器都将使用输入与输出、buffer_lifetime_ordinal 和 buffer_index 唯一引用此添加的缓冲区(需要所有这三个部分才能明确指定此缓冲区)。 如需了解如何安全地移除缓冲区并可能重复使用 buffer_index 值,请参阅 RemoveBuffer 文档注释。 与使用 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 下)的两个缓冲区。 |
5 |
buffer |
handle<vmo>
|
这是服务器可用于访问 sysmem 缓冲区的 VMO 句柄。 此 VMO 必须由 sysmem 提供,并且必须与服务器的 sysmem 限制兼容。 系统会先执行 buffer_constraints_version_ordinal 检查,如果该检查失败,系统会直接忽略此消息的其余部分,而不检查 buffer 字段(buffer 会直接被丢弃)。 如果 buffer_constraints_version_ordinal 检查通过,但 对于视频解码器输入缓冲区,客户端可以使用 sysmem 分配缓冲区,并使用 ParticipateInBufferAllocation 和 Port.INPUT 参与此编解码器实现或同一编解码器实现的其他实例。在这种情况下,不需要相同的 StreamProcessor 实例,只需相同的编解码器实现。如果使用不同的 StreamProcessor 实例(但仍来自同一编解码器实现),客户端应注意创建两个 StreamProcessor 实例,并为 CodecFactory 指定相同的要求(例如,以相同的方式设置 secure_input_mode 和 secure_output_mode)。supports_dynamic_buffers 为 true 的视频解码器服务器实现需要支持使用一个 StreamProcessor 实例分配输入缓冲区,然后将这些缓冲区用于其他 StreamProcessor 实例(相比之下,对于输出缓冲区,则不需要这样做)。 对于视频解码器输出缓冲区,可以通过使用 sysmem 分配缓冲区来实现此目的,其中同一个 StreamProcessor 实例参与其中,并使用 ParticipateInBufferAllocation 和 Port.OUTPUT。 服务器应验证此 VMO 是否 (a) 由 sysmem 提供,以及 (b) 是否满足服务器当前的 sysmem 限制。服务器可以在使用此 VMO 之前,通过检查 sysmem 的 CheckVmoConstraints 的结果来验证 (a) 和 (b)。如果该检查失败,服务器可以关闭 StreamProcessor server_end。 |
StreamProcessorOnOutputTimestampHasNoOutputRequest
在 fuchsia.media/stream_processor.fidl 中定义
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
stream_lifetime_ordinal |
uint64
|
所有服务器都会设置此字段。这是输入 |
2 |
timestamp_ish |
uint64
|
所有服务器都会设置此字段。这是输入 |
StreamProcessorParticipateInBufferAllocationRequest 资源
在 fuchsia.media/stream_processor.fidl 中定义
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
port |
Port
|
缓冲区用于哪个端口(输入或输出)。 必须设置。 |
2 |
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,从而导致分配失败。 必须设置。 |
3 |
sysmem2_token |
client_end:fuchsia.sysmem2/BufferCollectionToken
|
服务器使用此 sysmem 令牌直接向 sysmem 告知任何适用的缓冲区限制。这些限制条件可以(在某些情况下必须)取决于此 StreamProcessor 实例的创建方式。例如,在 StreamProcessor 创建期间,secure_input_mode/secure_output_mode 会导致服务器分别为输入/输出设置 secure_required(分别由 Port.INPUT 或 Port.OUTPUT 指定)。 必须设置。 |
4 |
buffer_lifetime_ordinal |
uint64
|
如果设置了此字段,并且之前在同一 StreamProcessor 实例上至少发送过一个具有此 buffer_lifetime_ordinal 的 AddBuffer,且该 AddBuffer 尚未在服务器端移除,则新缓冲区将使用相同的 SingleBufferSettings 进行分配,否则分配会失败。 如果本段落中的任何条件不满足,则效果与未设置此字段相同。 如果未设置此字段,则服务器设置的 sysmem 限制将适用于新 buffer_lifetime_ordinal 的缓冲区,并且新缓冲区的 SingleBufferSettings 可能与任何先前缓冲区的 SingleBufferSettings 都不匹配。 如果服务器具有当前数据流,并且 如果不使用此机制,客户端仍必须确保具有给定 StreamProcessor 实例、端口和 buffer_lifetime_ordinal 的所有 AddBuffer 都具有相同的 SingleBufferSettings。一种方法是在单个 sysmem 缓冲区集合下分配 buffer_lifetime_ordinal 的所有缓冲区。另一种方法是让客户端直接告知 sysmem,新的缓冲区集合必须与先前集合的 SingleBufferSettings 匹配,方法是在客户端使用 不建议客户端在没有 sysmem 帮助且没有 StreamProcessor 帮助的情况下,尝试通过此字段强制使新集合的 SingleBufferSettings 与旧集合的 SingleBufferSettings 匹配,因为 sysmem 会有意允许参与同一集合的客户端使用不同版本的 sysmem 接口,因此客户端可能没有足够的信息来成功强制 SingleBufferSettings 匹配,而无需使用 对于输出,如果客户端使用新的/不同的 sysmem 缓冲区集合向现有 buffer_lifetime_ordinal 添加额外的输出缓冲区,则强烈建议设置此字段,并且建议为所有输出缓冲区分配设置此字段。 对于输入,如果客户端为此消息和 AddBuffer 使用相同的 StreamProcessor 实例(在可行的情况下,建议这样做),则建议对这些输入缓冲区使用此字段。 如果设置了此值,则该值必须与稍后在 AddBuffer 中发送的 buffer_lifetime_ordinal 匹配。 客户端应在可行时设置此字段;请参阅上文。 |
5 |
allow_single_buffer |
bool
|
如果设置为 true,则服务器在向 sysmem 发送 SetConstraints 时,会将所有 如果未设置或设置为 false,则服务器在根据 无论此字段是否设置为 true,客户端都必须 |
StreamProcessorRemoveBufferRequest 资源
在 fuchsia.media/stream_processor.fidl 中定义
| 序数 | 字段 | 类型 | 说明 |
|---|---|---|---|
1 |
port |
Port
|
必须设置。缓冲区对应的端口(输入或输出)。 |
2 |
buffer_lifetime_ordinal |
uint64
|
此参数的作用域为输入或输出,是 buffer_index 有意义的 buffer_lifetime_ordinal。 |
3 |
buffer_index |
uint32
|
之前(以及最近)通过 AddBuffer 或 SetInputBufferPartialSettings / SetOutputBufferPartialSettings 建立的缓冲区的 buffer_index。此值的范围位于输入与输出下以及 buffer_lifetime_ordinal 值下。 使用动态缓冲区时,对于给定的 Port 值和 buffer_lifetime_ordinal 值,AddBuffer 开始和 RemoveBuffer 完成之间的 buffer_index 值(有效 buffer_index 值)必须是唯一的。 使用动态缓冲区的客户端可能不希望在 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
AacBitRate strict
在 fuchsia.media/stream_common.fidl 中定义
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
constant |
AacConstantBitRate
|
|
2 |
variable |
AacVariableBitRate
|
灵活 AacTransport
在 fuchsia.media/stream_common.fidl 中定义
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
raw |
AacTransportRaw
|
|
2 |
latm |
AacTransportLatm
|
|
3 |
adts |
AacTransportAdts
|
ActivityReporter_WatchCaptureActivity2_Result 严格执行
在 fuchsia.media/activity_reporter.fidl 中定义
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
response |
ActivityReporter_WatchCaptureActivity2_Response
|
|
3 |
framework_err |
internal
|
ActivityReporter_WatchRenderActivity2_Result strict
在 fuchsia.media/activity_reporter.fidl 中定义
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
response |
ActivityReporter_WatchRenderActivity2_Response
|
|
3 |
framework_err |
internal
|
AudioCapturerConfiguration strict
在 fuchsia.media/audio_capturer.fidl 中定义
音频捕获器的配置。
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
loopback |
LoopbackAudioCapturerConfiguration
|
|
2 |
input |
InputAudioCapturerConfiguration
|
AudioCompressedFormat flexible
在 fuchsia.media/stream_common.fidl 中定义
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
aac |
AudioCompressedFormatAac
|
|
2 |
sbc |
AudioCompressedFormatSbc
|
|
3 |
cvsd |
AudioCompressedFormatCvsd
|
Added: HEAD
|
4 |
lc3 |
AudioCompressedFormatLc3
|
Added: HEAD
|
AudioConsumerError strict
在 fuchsia.media/audio_consumer.fidl 中定义
表示 AudioConsumer 错误情况。
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
place_holder |
Void
|
AudioCore_GetDbFromVolume2_Result strict
在 fuchsia.media/audio_core.fidl 中定义
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
response |
AudioCore_GetDbFromVolume2_Response
|
|
3 |
framework_err |
internal
|
AudioCore_GetVolumeFromDb2_Result strict
在 fuchsia.media/audio_core.fidl 中定义
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
response |
AudioCore_GetVolumeFromDb2_Response
|
|
3 |
framework_err |
internal
|
AudioFormat strict
在 fuchsia.media/stream_common.fidl 中定义
AudioFormat
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
compressed |
AudioCompressedFormat
|
|
2 |
uncompressed |
AudioUncompressedFormat
|
AudioUncompressedFormat strict
在 fuchsia.media/stream_common.fidl 中定义
AudioUncompressedFormat
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
pcm |
PcmFormat
|
CryptoFormat flexible
在 fuchsia.media/stream_common.fidl 中定义
CryptoFormat
加密(已加密或已解密)格式详细信息。
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
encrypted |
EncryptedFormat
|
|
2 |
decrypted |
DecryptedFormat
|
DomainFormat strict
在 fuchsia.media/stream_common.fidl 中定义
DomainFormat
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
audio |
AudioFormat
|
|
2 |
video |
VideoFormat
|
|
3 |
crypto |
CryptoFormat
|
EncoderSettings 灵活
在 fuchsia.media/stream_common.fidl 中定义
编码器的设置,用于告知编码器如何对原始格式进行编码。
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
sbc |
SbcEncoderSettings
|
|
2 |
aac |
AacEncoderSettings
|
|
3 |
h264 |
H264EncoderSettings
|
|
4 |
hevc |
HevcEncoderSettings
|
|
5 |
cvsd |
CvsdEncoderSettings
|
Added: HEAD
|
6 |
lc3 |
Lc3EncoderSettings
|
Added: HEAD
|
7 |
msbc |
MSbcEncoderSettings
|
Added: HEAD
|
MediumSpecificStreamType strict
在 fuchsia.media/stream_type.fidl 中定义
所有特定于媒介的流类型结构体的并集。
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
audio |
AudioStreamType
|
|
2 |
video |
VideoStreamType
|
|
3 |
text |
TextStreamType
|
|
4 |
subpicture |
SubpictureStreamType
|
StreamProcessor_RemoveBuffer_Result strict
在 fuchsia.media/stream_processor.fidl 中定义
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
response |
StreamProcessor_RemoveBuffer_Response
|
|
3 |
framework_err |
internal
|
使用严格
在 fuchsia.media/audio_core.fidl 中定义
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
render_usage |
AudioRenderUsage
|
|
2 |
capture_usage |
AudioCaptureUsage
|
用法 2:灵活
在 fuchsia.media/audio_core.fidl 中定义
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
render_usage |
AudioRenderUsage2
|
|
2 |
capture_usage |
AudioCaptureUsage2
|
灵活使用状态
在 fuchsia.media/usage_reporter.fidl 中定义
一个或一组音频流的音频政策执行状态。
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
unadjusted |
UsageStateUnadjusted
|
|
2 |
ducked |
UsageStateDucked
|
|
3 |
muted |
UsageStateMuted
|
价值严格执行
在 fuchsia.media/stream_common.fidl 中定义
值
在通用“Parameter”结构体中使用的通用“value”。
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
bool_value |
bool
|
|
2 |
uint64_value |
uint64
|
|
3 |
int64_value |
int64
|
|
4 |
string_value |
string
|
|
5 |
bytes_value |
vector<uint8>
|
VideoCompressedFormat strict
在 fuchsia.media/stream_common.fidl 中定义
VideoCompressedFormat
压缩视频格式详细信息。
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
temp_field_todo_remove |
uint32
|
临时字段,用于在至少有一个实际字段之前让编译器正常运行。请勿在代码中引用此字段。 |
VideoFormat strict
在 fuchsia.media/stream_common.fidl 中定义
VideoFormat
视频(压缩或未压缩)格式详细信息。在这种情况下,“未压缩”可以包括基于块的图片压缩格式,这些格式仍允许对图片数据进行相当快速的随机访问。
| 序数 | 变体 | 类型 | 说明 |
|---|---|---|---|
1 |
compressed |
VideoCompressedFormat
|
|
2 |
uncompressed |
VideoUncompressedFormat
|
BITS
AudioConsumerStartFlags strict
类型:uint32
在 fuchsia.media/audio_consumer.fidl 中定义
传递给 AudioConsumer.Start 的标志。
| 名称 | 值 | 说明 |
|---|---|---|
LOW_LATENCY |
1 | 表示应尽可能缩短延迟时间。 |
SUPPLY_DRIVEN |
2 | 表示数据包传送的时间由外部进程决定,而不是基于需求。设置此标志后,由于数据包到达速率与呈现速率不匹配,服务应会发生下溢或上溢。如果未设置此标志,数据包会按需到达。 |
AudioGainInfoFlags strict
类型:uint32
在 fuchsia.media/audio_device_enumerator.fidl 中定义
| 名称 | 值 | 说明 |
|---|---|---|
静音 |
1 | |
AGC_SUPPORTED |
2 | |
AGC_ENABLED |
4 |
AudioGainValidFlags strict
类型:uint32
在 fuchsia.media/audio_device_enumerator.fidl 中定义
| 名称 | 值 | 说明 |
|---|---|---|
GAIN_VALID |
1 | |
MUTE_VALID |
2 | |
AGC_VALID |
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 |
当用作 |
| RENDER_USAGE2_COUNT |
6
|
uint8 |
|
| RENDER_USAGE_COUNT |
5
|
uint8 |
|
| STREAM_PACKET_FLAG_DISCONTINUITY |
4
|
uint32 |
表示原本在时间上连续的数据包序列中存在不连续性。此标志的确切语义取决于使用 |
| 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] |
压缩类型的标识符。 |
| EncryptionScheme |
string[MAX_ENCRYPTION_SCHEME_SIZE] |
|
| InitVector |
vector[MAX_INIT_VECTOR_SIZE] |
|
| KeyId |
vector[MAX_KEY_ID_SIZE] |