报告 Miracast 对 Windows 8.1 上的区块和统计信息进行编码
注意
从 Windows 10(WDDM 2.0)开始,操作系统附带了可在任何 GPU 上运行的内置 Miracast 堆栈。 有关 Microsoft Miracast 堆栈以及从 Windows 10 开始支持 Miracast 显示器的驱动程序和硬件要求的信息,请参阅以下文档:
Device.Graphics.WDDM13.DisplayRender.WirelessDisplay 上的相关 WHLK 文档
驱动程序开发人员不应再实现自定义 Miracast 堆栈。 Microsoft可能会在将来的 Windows 版本中删除对自定义 Miracast 堆栈的支持。
在 Windows 8.1 上,显示硬件可以通过将帧拆分为多个部分或 对区块进行编码来处理通过 Miracast 无线显示链接发送的每个视频帧。 每个区块都有一个唯一的区块 ID,该 ID 是从帧号和帧部件(或切片)编号生成的。 必须为与同一桌面帧更新相关的每个区块分配相同的帧编号。
报告区块处理
驱动程序可以在多个处理步骤(例如将颜色转换与编码分离)或单个步骤中,对通过 Miracast 无线链接发送的帧进行编码。 每个处理步骤都应在帧内分配一个唯一的帧部件号。
Miracast 用户模式驱动程序或显示微型端口驱动程序每次必须通知操作系统:
- 硬件已完成帧的处理步骤。
- 紧接在帧的每个部分发送到网络之前。
假定特定报告处理步骤的时间是向操作系统报告事件的时间,因此必须尽快报告阶段。
除了使用 Windows 事件跟踪(ETW)内核级跟踪设施记录这些事件之外,操作系统不采取任何操作。 然而,此信息对于衡量和调查性能问题非常重要。
驱动程序可以使用以下可能的方法之一提供通知:
- Miracast 用户模式驱动程序调用 ReportStatistic 回调函数来报告具有 MIRACAST_STATISTIC_TYPE_CHUNK_PROCESSING_COMPLETE 类型的详细信息,或者通过 MIRACAST_STATISTIC_TYPE_CHUNK_SENT 指示区块即将发送到网络堆栈进行传输。
- 显示微型端口驱动程序使用DXGK_INTERRUPT_MICACAST_CHUNK_PROCESSING_COMPLETE中断类型报告区块处理的详细信息,尽管此报告只能在中断时进行。 除了记录区块信息之外,还创建并排队了区块数据包,以便 Miracast 用户模式驱动程序可以通过调用 GetNextChunkData 回调函数来检索它。
- 显示微型端口驱动程序在任何 IRQL 级别调用 DxgkCbReportChunkInfo 回调函数。 此函数仅记录区块信息,并且不会对任何区块数据包进行排队。
如果未更新桌面映像,但驱动程序需要再次对桌面图像进行编码以提高质量,则应使用相同的帧号和部件号。 性能工具触发同一帧和部件号的第二个编码完整事件,指示执行同一帧的第二次编码。
每个帧的最后一个切片必须有一个帧部件号为零,这表示帧的最后一个切片到性能工具。
若要确保主图面的正确同步,如果像素管道执行编码,则不应在编码完成访问主图面之前报告任何请求的翻转操作。 此行为可防止演示者在从主图面进行读取时呈现到主图面。
Miracast 用户模式驱动程序应在处理帧的每个阶段通知操作系统:
开始帧、区块类型 MIRACAST_CHUNK_TYPE_FRAME_START
表示操作系统要求驱动程序显示新桌面帧的点。 尽管从技术上说,Miracast 用户模式驱动程序可以报告此阶段,但处理新帧的开始始终涉及显示微型端口驱动程序,因此应由该驱动程序报告。
颜色转换完成,区块类型 MIRACAST_CHUNK_TYPE_COLOR_CONVERT_COMPLETE
某些解决方案具有单独的颜色转换和编码阶段。 在此类解决方案中,应尽快报告颜色转换完成处理事件,驱动程序应使用 DXGK_MIRACAST_CHUNK_INFO。ProcessingTime 成员报告硬件执行操作所需的时间。 如果整个帧一次性全部转换,而不是在切片中转换,则部件号应为零。
编码完整区块类型 MIRACAST_CHUNK_TYPE_ENCODE_COMPLETE
指示 H.264 编码已完成。 应完成DXGK_MIRACAST_CHUNK_INFO结构的 ProcessingTime 和 EncodeRate 成员。
帧发送,使用 MIRACAST_STATISTIC_TYPE_CHUNK_SENT 调用 ReportStatistic
指示 Miracast 用户模式驱动程序即将将此帧/部件号的数据包发送到网络 API 进行传输。 如果此帧/部件的数据是使用对网络 API 的多个调用发送的,则只应在发送第一个数据包之前记录它。 应在调用网络 API 之前进行调用。 此计时很重要,因为如果网络 API 阻止调用,我们不希望阻止的时间计入图形堆栈中帧的处理。
删除的帧、区块类型 MIRACAST_CHUNK_TYPE_FRAME_DROPPED
如果驱动程序随时决定它不会完成帧/部件的处理,并将其发送到接收器,则应报告丢弃的帧。 在此上下文中,仅当驱动程序通过记录 MIRACAST_CHUNK_TYPE_FRAME_START开始处理帧时,才会考虑删除帧。 如果驱动程序计算它将跳过此帧而不进行任何处理,则它可以记录 MIRACAST_CHUNK_TYPE_FRAME_DROPPED 而不记录 MIRACAST_CHUNK_TYPE_FRAME_START。
驱动程序定义的区块类型 MIRACAST_CHUNK_TYPE_ENCODE_DRIVER_DEFINED_1 或 _2
这些区块类型可用于帮助你了解方案的性能。 示例包括:
- 驱动程序使用这些类型来指示为此帧创建了 I-Frame。
- 驱动程序在帧的最后一个切片发送到包含编码帧总大小的网络 API 后记录另一个数据包。
帧颜色转换示例
以下示例演示如何转换帧颜色,以及显示微型端口驱动程序如何报告颜色转换的完成情况。
对MIRACAST_CHUNK_INFO结构成员的表引用包括:
ChunkType 是 MIRACAST_CHUNK_TYPE_XXX 值。
FrameNumber 和 PartNumber 是 ChunkId 联合的成员。
ProcessingTime 是以微秒为单位的时间。
EncodeRate 每秒以千比特为单位。
MIRACAST_STATISTIC_TYPE_CHUNK_SENT用于涉及对 ReportStatistic 调用的处理阶段。
在不使用切片的情况下报告单个帧
处理阶段 | ChunkType | FrameNumber | PartNumber | ProcessingTime | EncodeRate |
---|---|---|---|---|---|
开始处理帧 | FRAME_START | 101 | 0 | 0 | 0 |
颜色转换已完成 | COLOR_CONVERT_COMPLETE | 101 | 0 | 950 | 0 |
编码已完成 | ENCODE_COMPLETE | 101 | 0 | 1042 | 15000 |
在调用将数据发送到网络 ReportStatistic 调用之前 | 不适用 | 101 (ChunkSent.ChunkId.FrameNumber 的值) | 0 ( ChunkSent.ChunkId.PartNumber 的值) | n/a | n/a |
报告单个帧,使用切片进行处理
处理阶段 | ChunkType | FrameNumber | PartNumber | ProcessingTime | EncodeRate |
---|---|---|---|---|---|
开始处理帧 | FRAME_START | 101 | 0 | 0 | 0 |
颜色转换已完成 | COLOR_CONVERT_COMPLETE | 101 | 0 | 950 | 0 |
切片 1 的编码已完成 | ENCODE_COMPLETE | 101 | 1 | 1042 | 15000 |
切片 2 的编码已完成 | ENCODE_COMPLETE | 101 | 0 | 400 | 15000 |
在调用将切片 1 数据发送到网络 ReportStatistic 调用之前 | 不适用 | 101(切片 1 的 ChunkSent.ChunkId.FrameNumber 的值) | 1(切片 1 的 ChunkSent.ChunkId.PartNumber 的值) | n/a | n/a |
在调用将切片 2 数据发送到网络 ReportStatistic 调用之前 | 不适用 | 101(切片 2 的 ChunkSent.ChunkId.FrameNumber 的值) | 0 (切片 2 的 ChunkSent.ChunkId.FrameNumber 的值) | n/a | n/a |
报告原始帧,处理后重新编码,而不使用切片
处理阶段 | ChunkType | FrameNumber | PartNumber | ProcessingTime | EncodeRate |
---|---|---|---|---|---|
开始处理帧 | FRAME_START | 101 | 0 | 0 | 0 |
颜色转换已完成 | COLOR_CONVERT_COMPLETE | 101 | 0 | 950 | 0 |
编码已完成 | ENCODE_COMPLETE | 101 | 0 | 1042 | 15000 |
在调用将原始帧的数据发送到网络 ReportStatistic 调用之前 | 不适用 | 101 (ChunkSent.ChunkId.FrameNumber 的值) | 0 ( ChunkSent.ChunkId.PartNumber 的值) | n/a | n/a |
重新编码已完成 | ENCODE_COMPLETE | 101 | 0 | 500 | 15000 |
在调用以将数据重新编码的帧发送到网络 ReportStatistic 之前 | 不适用 | 101 (ChunkSent.ChunkId.FrameNumber 的值) | 0 ( ChunkSent.ChunkId.PartNumber 的值) | n/a | n/a |
报告协议事件
当 Miracast 用户模式驱动程序使用 MIRACAST_STATISTIC_DATA 调用 ReportStatistic 函数来报告协议事件时。StatisticType 设置为MIRACAST_STATISTIC_TYPE_EVENT,操作系统会记录事件,但不采取其他操作。 然而,这些事件对于诊断和性能调查非常有用。
MIRACAST_PROTOCOL_EVENT枚举包括可以报告的可能协议事件类型。
报告协议错误
当 Miracast 连接的会话正在进行时,如果 Miracast 用户模式驱动程序发现错误,则应在 MiracastStatus 参数中使用适当的MIRACAST_STATUS错误状态信息调用 ReportSessionStatus 回调函数。 报告错误时,操作会话始终会销毁会话。
尽管操作系统只是记录 ReportSessionStatus Status 参数进行诊断,并且不根据其值执行任何操作,但驱动程序应使用此参数来区分错误的不同原因。