Xbox 上的 UWP 应用的 4K 视频播放

本主题介绍如何在 Xbox 上的 UWP 应用中启用和实现 4K 视频内容的播放。 此信息适用于任何受支持的 4K 视频播放格式。 但对于当前代主机,4K 播放的首选视频编解码器是高效视频编码(HEVC)。

借助 HEVC,你可以提供高质量的视频,提高压缩效率和降低带宽使用率,同时支持卓越的视觉保真度。 利用 HEVC,媒体应用可以通过较低的比特率要求流式传输 4K 内容。 这将确保更流畅的播放和更好的用户体验,即使在带宽受限的环境中也是如此。 本主题介绍启用 4K(包括 HEVC)播放标志的必要步骤,以及优化 Xbox 上播放性能的最佳做法。

启用时的行为差异

在应用程序中启用 4K 播放会更改 Xbox作系统处理应用程序的方式。 在 Xbox Series S 和 Series X 主机上,除了允许播放 4K 视频外,应用程序还将分配额外的 3.25GB 图形内存。 此内存与系统分配给 UWP 应用程序的正常内存分开。

此外,应用程序将无法与 Xbox 主机上的游戏同时运行 -- 当用户启动游戏时,你的应用将暂停和关闭。 同样地,当应用启动时,用户将不得不等待他们正在玩的任何游戏完全关闭。 因此,应用需要在能够播放背景音乐和能够播放 4K 视频内容之间进行选择。

在 appxmanifest 中启用 4K 播放

Xbox One S 支持 4K 和 HDR10 视频播放(原始 Xbox One 限制为 1080p)。 所有这些功能都使用应用清单中的特殊 hevcPlayback 功能启用。 再次,该标志可以在任何受支持的格式下启用 4K 视频播放(但建议使用 HEVC)。

代码示例

<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  IgnorableNamespaces="uap mp rescap">

...

  <Capabilities>
    <Capability Name="internetClient" />
    <rescap:Capability Name="hevcPlayback" />
  </Capabilities>
</Package>

能力检查

建议使用 UWP API ProtectionCapabilities.IsTypeSupported来确定 HEVC/4K/HDCP 支持,而不是根据控制台类型进行判断。

下面是一些简短的示例。

  1. 硬件 HEVC 解码支持
IsTypeSupported(""video/mp4;codecs="hvc1,mp4a";features="decode-res-x=3840,decode-res-y=2160,decode-bitrate=20000,decode-fps=30,decode-bpc=10"", "com.microsoft.playready.hardware")
  1. 4K HEVC 解码/显示支持
IsTypeSupported(""video/mp4;codecs="hvc1,mp4a";features="decode-res-x=3840,decode-res-y=2160,decode-bitrate=20000,decode-fps=30,decode-bpc=10,display-res-x=3840,display-res-y=2160,display-bpc=8"", "com.microsoft.playready.hardware")
  1. 4K HEVC 解码和显示/HDR 支持
IsTypeSupported(""video/mp4;codecs="hvc1,mp4a";features="decode-res-x=3840,decode-res-y=2160,decode-bitrate=20000,decode-fps=30,decode-bpc=10,display-res-x=3840,display-res-y=2160,display-bpc=10, hdr=1"", "com.microsoft.playready.hardware")
  1. HDCP 2.2 支持(建议在 4K 检查后进行此操作,因为速度较慢)
IsTypeSupported (""video/mp4;codecs="hvc1,mp4a";features="hdcp=2"", "com.microsoft.playready.hardware")

这些查询将在原始 Xbox One 上返回 NotSupported,这意味着没有硬件 HEVC 解码支持(它仅支持软件解码)。 在所有其他主机上(Xbox One S 及更高版本),第一个查询将始终返回 Probably,其余查询将返回 Probably,具体取决于连接的显示。

4K 应用程序的提示

内存使用情况信息

还有一个 API 用于检索更准确的内存使用情况信息,该信息仅适用于已启用 HEVC 的应用的 Xbox。 下面的代码示例位于C++中。 若要使用它,请将名为 IApplicationStatics2.h的新头文件添加到项目中,并将以下代码列表粘贴到其中。

#pragma once

#include "Windows.Foundation.h"
#include "Inspectable.h"
#include <cstdint>

typedef struct ExtendedMemoryInfo
{
    uint64_t appMemoryUsage;
    uint64_t appMemoryLimit;
    uint64_t extendedMemoryUsage;
    uint64_t extendedMemoryLimit;
} ExtendedMemoryInfo;

interface __declspec(uuid("dd36a017-b640-45f7-a023-1615cf098923"))
    IApplicationResourcesStatics2 : ::IInspectable
{
    virtual HRESULT GetExtendedMemoryInfo(ExtendedMemoryInfo* memoryInfo) = 0;
};

接下来,在您的主 XAML 页面中添加一个名为 TextBlockMemoryInfo,您可以使用它查看内存信息的输出。

<Canvas Width="500"
        HorizontalAlignment="Right"
        VerticalAlignment="Top"
        ZIndex="1">
    <TextBlock x:Name="MemoryInfo"
               Foreground="#88FFFFFF"
               FontSize="30" />
</Canvas>

然后,在主 XAML 页面的 .cpp 文件中,添加以下函数(也在页面的 .h 文件中声明它)。

#include "IApplicationResourcesStatics2.h"
 
// ...
 
fire_and_forget MainPage::PeriodicMemoryQuery()
{
    co_await resume_background();
 
    auto factoryInspectable =
        winrt::get_activation_factory<IInspectable>(L"Windows.Xbox.ApplicationModel.ApplicationResources").as<::IInspectable>();
    winrt::com_ptr<IApplicationResourcesStatics2> appResources;
    factoryInspectable->QueryInterface(IID_PPV_ARGS(&appResources));
    ExtendedMemoryInfo memInfo;
 
    while (true)
    {
        // Check memory every 3s, and post to the UI thread to display.
        Sleep(3000);
 
        appResources->GetExtendedMemoryInfo(&memInfo);
        Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Low, [memInfo, this]() {
            std::wstring memPayload = L"AppUsage: ";
            memPayload += winrt::to_hstring(static_cast<uint64_t>(memInfo.appMemoryUsage / 1024.0f / 1024.0f)).c_str();
            memPayload += L"MB\nExtendedUsage: ";
            memPayload += winrt::to_hstring(static_cast<uint64_t>(memInfo.extendedMemoryUsage / 1024.0f / 1024.0f)).c_str();
            memPayload += L"MB\nTotal: ";
            memPayload += winrt::to_hstring(static_cast<uint64_t>((memInfo.appMemoryUsage + memInfo.extendedMemoryUsage) / 1024.0f / 1024.0f)).c_str();
            memPayload += L"MB";
            MemoryInfo().Text(memPayload.c_str());
            });
    }
}

从页面的构造函数调用该函数,它将定期更新 MemoryInfo

appMemory 属性指的是一般堆使用情况。 extendedMemory 属性提供有关 Xbox Series S 和 Series X 的图形分区信息。

切换显示模式

在开始播放之前,你的应用必须将显示/电视切换到内容的适当显示模式(以匹配类型/分辨率/刷新率)。 Xbox 上的枚举和切换显示模式由 HdmiDisplayInformation 处理。

  1. 使用 HdmiDisplayInformation.GetSupportedDisplayModes 检索支持的显示模式列表。

  2. 使用 HdmiDisplayInformation.RequestSetCurrentDisplayModeAsync HDMIDisplayInformation::RequestSetDisplayModeAsync 设置所需的显示模式。

注意

如果需要,SDR 视频内容将在 HDR10 显示模式下播放(显示管道将执行基本颜色空间/eotf 转换)。 还支持在 SDR 显示模式下播放 HDR10 视频内容,并应用自动音调映射(这是在媒体管道中完成的)。

但是,我们建议播放完成后,使用 HdmiDisplayInformation.SetDefaultDisplayModeAsync切换回默认显示模式(SDR)。 这是因为在 HDR/Dolby 视觉显示模式中,应用程序 UI 可能无法准确转换颜色,因此你可能会注意到颜色问题(特别是文本呈现)。

支持自动 3:2 下拉,因此始终对所有媒体播放使用 60Hz 模式是正常的。 媒体播放不支持 120Hz 模式。

下面是使用自定义媒体源或 MSE 时的一些建议(使用内置的 AdaptiveMediaSource 将正确设置这些属性)。

  1. 强烈建议在设置媒体类型时将 MF_MT_DECODER_USE_MAX_RESOLUTION 属性设置为 TRUE。 这将确保更流畅/无故障的播放,并优化内存使用情况。

  2. 出于相同的原因,请将 MF_MT_DECODER_MAX_DPB_COUNT 设置为 3。

另请参阅