Vytvoření vzdálené aplikace Holographic Remoting pomocí rozhraní OpenXR API

Pokud s Holographic Remotingem začínáte, můžete si přečíst náš přehled.

Důležité

Tento dokument popisuje vytvoření vzdálené aplikace pro HoloLens 2 a Windows Mixed Reality náhlavní soupravy pomocí rozhraní OpenXR API. Vzdálené aplikace pro HoloLens (1. generace) musí používat balíček NuGet verze 1.x.x. To znamená, že vzdálené aplikace napsané pro HoloLens 2 nejsou kompatibilní s HoloLensem 1 a naopak. Dokumentaci k HoloLensu 1 najdete tady.

Aplikace Holographic Remoting můžou streamovat vzdáleně vykreslený obsah do HoloLens 2 a Windows Mixed Reality imerzivní náhlavní soupravy. Můžete také získat přístup k více systémovým prostředkům a integrovat vzdálená imerzivní zobrazení do existujícího softwaru stolního počítače. Vzdálená aplikace přijímá vstupní datový proud z HoloLens 2, vykresluje obsah ve virtuálním imerzivním zobrazení a streamuje rámce obsahu zpět do HoloLens 2. Připojení se provádí pomocí standardní sítě Wi-Fi. Holografická vzdálená komunikace se přidává do desktopové aplikace nebo aplikace pro UPW prostřednictvím paketu NuGet. Vyžaduje se další kód, který zpracovává připojení a vykresluje se v imerzivním zobrazení. Typické připojení vzdálené komunikace bude mít latenci až 50 ms. Aplikace přehrávače může hlásit latenci v reálném čase.

Veškerý kód na této stránce a pracovní projekty najdete v úložišti GitHub s ukázkami holografické komunikace.

Požadavky

Dobrým výchozím bodem je funkční desktopová aplikace nebo aplikace pro UPW založená na OpenXR. Podrobnosti najdete v tématu Začínáme s OpenXR.

Důležité

Každá aplikace využívající Holographic Remoting by měla být ovaná tak, aby používala byt s více vlákny. Použití apartmánu s jedním vláknem je podporováno , ale povede k neoptimální výkon a možná zadrhávání během přehrávání. Při použití C++/WinRT winrt::init_apartment je výchozí byt s více vlákny.

Získání balíčku NuGet pro Holographic Remoting

K přidání balíčku NuGet do projektu v sadě Visual Studio je potřeba provést následující kroky.

  1. Otevřete projekt v sadě Visual Studio.
  2. Klikněte pravým tlačítkem na uzel projektu a vyberte Spravovat balíčky NuGet...
  3. Na zobrazeném panelu vyberte Procházet a vyhledejte Holographic Remoting (Holographic Remoting).
  4. Vyberte Microsoft.Holographic.Remoting.OpenXr, ujistěte se, že je vybraná nejnovější verze 2.x.x , a pak vyberte Nainstalovat.
  5. Pokud se zobrazí dialogové okno Náhled , vyberte OK.
  6. Když se zobrazí dialogové okno licenční smlouvy, vyberte Přijmout .
  7. Opakujte kroky 3 až 6 pro následující balíčky NuGet: OpenXR.Headers, OpenXR.Loader

Poznámka

Verze 1.x.x balíčku NuGet je stále k dispozici pro vývojáře, kteří chtějí cílit na HoloLens 1. Podrobnosti najdete v tématu Přidání holografické komunikace (HoloLens (1. generace)).

Výběr modulu runtime Holographic Remoting OpenXR

Prvním krokem, který musíte udělat ve vzdálené aplikaci, je vybrat modul runtime Holographic Remoting OpenXR, který je součástí balíčku NuGet Microsoft.Holographic.Remoting.OpenXr. Můžete to udělat tak, že proměnnou prostředí nastavíte XR_RUNTIME_JSON na cestu k souboru RemotingXR.json v rámci vaší aplikace. Tuto proměnnou prostředí používá zavaděč OpenXR k tomu, aby nepoužíval výchozí systémový modul runtime OpenXR, ale místo toho přesměrovával na modul runtime OpenXR Holographic Remoting. Při použití balíčku NuGet Microsoft.Holographic.Remoting.OpenXr se soubor RemotingXR.json automaticky zkopíruje během kompilace do výstupní složky. Výběr modulu runtime OpenXR obvykle vypadá takto.

bool EnableRemotingXR() {
    wchar_t executablePath[MAX_PATH];
    if (GetModuleFileNameW(NULL, executablePath, ARRAYSIZE(executablePath)) == 0) {
        return false;
    }
    
    std::filesystem::path filename(executablePath);
    filename = filename.replace_filename("RemotingXR.json");

    if (std::filesystem::exists(filename)) {
        SetEnvironmentVariableW(L"XR_RUNTIME_JSON", filename.c_str());
            return true;
        }

    return false;
}

Vytvoření instance XrInstance s rozšířením Holographic Remoting

První akce, které by měla typická aplikace OpenXR provést, jsou výběr rozšíření OpenXR a vytvoření instance XrInstance. Specifikace jádra OpenXR neposkytuje žádné rozhraní API specifické pro vzdálené komunikace. Z tohoto důvodu Holographic Remoting zavádí vlastní rozšíření OpenXR s názvem XR_MSFT_holographic_remoting. Ujistěte se, že XR_MSFT_HOLOGRAPHIC_REMOTING_EXTENSION_NAME je součástí XrInstanceCreateInfo volání xrCreateInstance.

Tip

Ve výchozím nastavení se vykreslený obsah vaší aplikace streamuje jenom do holografického vzdáleného přehrávače spuštěného na HoloLens 2 nebo na Windows Mixed Reality náhlavní soupravě. Pokud chcete zobrazit také vykreslený obsah na vzdáleném počítači, například prostřednictvím prohození okna, poskytuje Holographic Remoting druhé rozšíření OpenXR s názvem XR_MSFT_holographic_remoting_frame_mirroring. Pokud chcete tuto funkci používat, nezapomeňte toto rozšíření také povolit pomocí XR_MSFT_HOLOGRAPHIC_REMOTING_FRAME_MIRRORING_EXTENSION_NAME příkazu .

Důležité

Další informace o rozhraní API rozšíření OpenXR pro Holographic Remoting najdete ve specifikaci , kterou najdete v úložišti GitHubu s ukázkami holografické vzdálené komunikace.

Připojení k zařízení

Jakmile vaše vzdálená aplikace vytvoří XrInstance a prostřednictvím xrGetSystemu zadá dotaz na XrSystemId, bude možné navázat připojení k zařízení přehrávače.

Upozornění

Modul runtime Holographic Remoting OpenXR může po navázání připojení poskytovat pouze data specifická pro zařízení, jako jsou konfigurace zobrazení nebo režimy prolnutí prostředí. xrEnumerateViewConfigurations, , xrEnumerateViewConfigurationViewsxrGetViewConfigurationProperties, xrEnumerateEnvironmentBlendModesa xrGetSystemProperties vám poskytnou výchozí hodnoty odpovídající tomu, co byste obvykle získali, když se před úplným připojením připojíte k přehrávači běžícímu na HoloLens 2. Před navázáním připojení důrazně doporučujeme tyto metody nevolat. Návrh se používá tyto metody po úspěšném vytvoření XrSession a stavu relace je alespoň XR_SESSION_STATE_READY.

Obecné vlastnosti, jako je maximální přenosová rychlost, povolený zvuk, videokodek nebo rozlišení streamu hloubkové vyrovnávací paměti, je možné nakonfigurovat následujícím xrRemotingSetContextPropertiesMSFT způsobem.

XrRemotingRemoteContextPropertiesMSFT contextProperties;
contextProperties = XrRemotingRemoteContextPropertiesMSFT{static_cast<XrStructureType>(XR_TYPE_REMOTING_REMOTE_CONTEXT_PROPERTIES_MSFT)};
contextProperties.enableAudio = false;
contextProperties.maxBitrateKbps = 20000;
contextProperties.videoCodec = XR_REMOTING_VIDEO_CODEC_H265_MSFT;
contextProperties.depthBufferStreamResolution = XR_REMOTING_DEPTH_BUFFER_STREAM_RESOLUTION_HALF_MSFT;
xrRemotingSetContextPropertiesMSFT(m_instance.Get(), m_systemId, &contextProperties);

Připojení je možné provést jedním ze dvou způsobů.

  1. Vzdálená aplikace se připojí k přehrávači běžícímu na zařízení.
  2. Přehrávač spuštěný na zařízení se připojí ke vzdálené aplikaci.

Pokud chcete navázat připojení ze vzdálené aplikace k zařízení přehrávače, zavolejte metodu xrRemotingConnectMSFT určující název hostitele a port prostřednictvím XrRemotingConnectInfoMSFT struktury. Port používaný přehrávačem Holographic Remoting Player je 8265.

XrRemotingConnectInfoMSFT connectInfo{static_cast<XrStructureType>(XR_TYPE_REMOTING_CONNECT_INFO_MSFT)};
connectInfo.remoteHostName = "192.168.x.x";
connectInfo.remotePort = 8265;
connectInfo.secureConnection = false;
xrRemotingConnectMSFT(m_instance.Get(), m_systemId, &connectInfo);

Naslouchání příchozím připojením ve vzdálené aplikaci je možné provést voláním xrRemotingListenMSFT metody . Port handshake i transportní port je možné zadat prostřednictvím XrRemotingListenInfoMSFT struktury . Port metody handshake se používá pro počáteční metodu handshake. Data se pak odešlou přes přenosový port. Ve výchozím nastavení se používají 8265 a 8266 .

XrRemotingListenInfoMSFT listenInfo{static_cast<XrStructureType>(XR_TYPE_REMOTING_LISTEN_INFO_MSFT)};
listenInfo.listenInterface = "0.0.0.0";
listenInfo.handshakeListenPort = 8265;
listenInfo.transportListenPort = 8266;
listenInfo.secureConnection = false;
xrRemotingListenMSFT(m_instance.Get(), m_systemId, &listenInfo);

Stav připojení musí být odpojen při volání xrRemotingConnectMSFT nebo xrRemotingListenMSFT. Stav připojení můžete získat v libovolném okamžiku po vytvoření instance XrInstance a dotazování na XrSystemId prostřednictvím xrRemotingGetConnectionStateMSFT.

XrRemotingConnectionStateMSFT connectionState;
xrRemotingGetConnectionStateMSFT(m_instance.Get(), m_systemId, &connectionState, nullptr);

Dostupné stavy připojení jsou:

  • XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT
  • XR_REMOTING_CONNECTION_STATE_CONNECTING_MSFT
  • XR_REMOTING_CONNECTION_STATE_CONNECTED_MSFT

Důležité

xrRemotingConnectMSFT nebo xrRemotingListenMSFT musí být volána před pokusem o vytvoření XrSession prostřednictvím xrCreateSession. Pokud se pokusíte vytvořit XrSession ve stavu XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT připojení, vytvoření relace proběhne úspěšně, ale stav relace okamžitě přejde na XR_SESSION_STATE_LOSS_PENDING.

Implementace xrCreateSession holografické vzdálené komunikace podporuje čekání na navázání připojení. Můžete zavolat xrRemotingConnectMSFT nebo xrRemotingListenMSFT okamžitě následovat volání xrCreateSession, které zablokuje a počká na navázání připojení. Časový limit pro xrRemotingConnectMSFT je pevný na 10 sekund a neomezený pro xrRemotingListenMSFT. Pokud je možné během této doby navázat připojení, vytvoření XrSession proběhne úspěšně a stav relace přejde na XR_SESSION_STATE_READY. V případě, že není možné navázat žádné připojení, bude vytvoření relace také úspěšné, ale okamžitě přejde na XR_SESSION_STATE_LOSS_PENDING.

Obecně platí, že stav připojení je spojený se stavem XrSession. Jakákoli změna stavu připojení má vliv také na stav relace. Pokud se například stav připojení přepne z XR_REMOTING_CONNECTION_STATE_CONNECTED_MSFT do XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT stavu relace, přejde také do XR_SESSION_STATE_LOSS_PENDING.

Zpracování zvláštních událostí vzdálené komunikace

Modul runtime Holographic Remoting OpenXR zveřejňuje tři události, které jsou důležité pro monitorování stavu připojení.

  1. XR_TYPE_REMOTING_EVENT_DATA_CONNECTED_MSFT: Aktivuje se po úspěšném navázání připojení k zařízení.
  2. XR_TYPE_REMOTING_EVENT_DATA_DISCONNECTED_MSFT: Aktivuje se, pokud je navázané připojení ukončeno nebo se připojení nepodařilo navázat.
  3. XR_TYPE_REMOTING_EVENT_DATA_LISTENING_MSFT: Při naslouchání příchozím připojením se spustí.

Tyto události se umístí do fronty a vzdálená aplikace musí pravidelně číst z fronty přes xrPollEvent.

auto pollEvent = [&](XrEventDataBuffer& eventData) -> bool {
	eventData.type = XR_TYPE_EVENT_DATA_BUFFER;
	eventData.next = nullptr;
	return CHECK_XRCMD(xrPollEvent(m_instance.Get(), &eventData)) == XR_SUCCESS;
};

XrEventDataBuffer eventData{};
while (pollEvent(eventData)) {
	switch (eventData.type) {
	
	...
	
	case XR_TYPE_REMOTING_EVENT_DATA_LISTENING_MSFT: {
		DEBUG_PRINT("Holographic Remoting: Listening on port %d",
					reinterpret_cast<const XrRemotingEventDataListeningMSFT*>(&eventData)->listeningPort);
		break;
	}
	case XR_TYPE_REMOTING_EVENT_DATA_CONNECTED_MSFT: {
		DEBUG_PRINT("Holographic Remoting: Connected.");
		break;
	}
	case XR_TYPE_REMOTING_EVENT_DATA_DISCONNECTED_MSFT: {
		DEBUG_PRINT("Holographic Remoting: Disconnected - Reason: %d",
					reinterpret_cast<const XrRemotingEventDataDisconnectedMSFT*>(&eventData)->disconnectReason);
		break;
	}
}

Místní náhled streamovaného obsahu

K zobrazení stejného obsahu ve vzdálené aplikaci, který se odešle do zařízení, XR_MSFT_holographic_remoting_frame_mirroring je možné použít rozšíření. S tímto rozšířením můžete odeslat texturu do objektu xrEndFrame pomocí objektu XrRemotingFrameMirrorImageInfoMSFT , který není zřetězený s XrFrameEndInfo následujícím způsobem.

XrFrameEndInfo frameEndInfo{XR_TYPE_FRAME_END_INFO};
...

XrRemotingFrameMirrorImageD3D11MSFT mirrorImageD3D11{
    static_cast<XrStructureType>(XR_TYPE_REMOTING_FRAME_MIRROR_IMAGE_D3D11_MSFT)};
mirrorImageD3D11.texture = m_window->GetNextSwapchainTexture();

XrRemotingFrameMirrorImageInfoMSFT mirrorImageEndInfo{
    static_cast<XrStructureType>(XR_TYPE_REMOTING_FRAME_MIRROR_IMAGE_INFO_MSFT)};
mirrorImageEndInfo.image = reinterpret_cast<const XrRemotingFrameMirrorImageBaseHeaderMSFT*>(&mirrorImageD3D11);

frameEndInfo.next = &mirrorImageEndInfo;

xrEndFrame(m_session.Get(), &frameEndInfo);

m_window->PresentSwapchain();

Výše uvedený příklad používá texturu řetězce swapů DX11 a zobrazí okno ihned po volání xrEndFrame. Použití není omezeno na výměnu textur řetězců. Navíc není nutná žádná další synchronizace GPU. Podrobnosti o využití a omezeních najdete ve specifikaci rozšíření. Pokud vaše vzdálená aplikace používá DX12, použijte XrRemotingFrameMirrorImageD3D12MSFT místo XrRemotingFrameMirrorImageD3D11MSFT.

Volitelné: Vlastní datové kanály

Počínaje verzí 2.5.0 je možné s rozhraním OpenXR API používat vlastní datové kanály k odesílání uživatelských dat přes již navázané vzdálené připojení. Další informace najdete v tématu Vlastní datové kanály s rozhraním OpenXR API.

Volitelné: Řeč

Od verze 2.6.0XR_MSFT_holographic_remoting_speech rozšíření umožňuje vzdálené aplikaci reagovat na hlasové příkazy zjištěné aplikací přehrávače pomocí rozhraní OpenXR API.

[! DŮLEŽITÉ] Podrobnou specifikaci najdete v úložišti GitHubu s ukázkami holografické komunikace.

Pokud chcete inicializovat rozpoznávání řeči v aplikaci přehrávače, může vzdálená aplikace volat xrInitializeRemotingSpeechMSFT. Toto volání přenáší parametry inicializace řeči, které se skládají z jazyka, slovníku frází a obsahu gramatického souboru, do aplikace přehrávače.

Poznámka

Před verzí 2.6.1 musí být rozpoznávání řeči inicializováno pouze jednou za XrSession.

Pokud bylo vytvoření rozpoznávání řeči úspěšné, jak je uvedeno v XR_TYPE_EVENT_DATA_REMOTING_SPEECH_RECOGNIZER_STATE_CHANGED_MSFT události, bude vzdálená aplikace upozorněna na vygenerování výsledku rozpoznávání řeči v aplikaci přehrávače. Struktura XrEventDataRemotingSpeechRecognizerStateChangedMSFT událostí se umístí do fronty událostí, když se změní stav rozpoznávání řeči na straně hráče.

XrRemotingSpeechRecognizerStateMSFT definuje všechny možné stavy rozpoznávání řeči na straně hráče a XrEventDataRemotingSpeechRecognizedMSFT struktura události se umístí do fronty událostí, pokud rozpoznávání řeči na straně hráče má rozpoznanou frázi. Jakmile bude vzdálená aplikace upozorněna na rozpoznanou frázi, může rozpoznanou frázi načíst voláním xrRetrieveRemotingSpeechRecognizedTextMSFT.

Poznámka

Je XrRemotingSpeechRecognitionConfidenceMSFT přímé mapování výčtu SpeechRecognitionConfidence vráceného s výsledkem rozpoznávání řeči rozhraním API pro rozpoznávání řeči systému Windows.

Volitelné: Synchronizace souřadnicového systému

Počínaje verzí 2.7.0 je možné synchronizaci souřadnicového systému použít k zarovnání prostorových dat mezi přehrávačem a vzdálenou aplikací. Další informace najdete v tématu Synchronizace souřadnicového systému s holografickou vzdálené komunikace – přehled.

Viz také