Een Holographic Remoting Remote-app schrijven met behulp van de OpenXR API

Als u geen gebruik hebt van Holographic Remoting, kunt u ons overzicht lezen.

Belangrijk

In dit document wordt beschreven hoe u een externe toepassing maakt voor HoloLens 2 en Windows Mixed Reality headsets met behulp van de OpenXR-API. Externe toepassingen voor HoloLens (1e generatie) moeten NuGet-pakketversie 1.x.x gebruiken. Dit betekent dat externe toepassingen die zijn geschreven voor HoloLens 2 niet compatibel zijn met HoloLens 1 en vice versa. De documentatie voor HoloLens 1 vindt u hier.

Holografische externe apps kunnen extern weergegeven inhoud streamen naar HoloLens 2 en Windows Mixed Reality immersive headsets. U kunt ook toegang krijgen tot meer systeembronnen en externe insluitende weergaven integreren in bestaande desktop-pc-software. Een externe app ontvangt een invoergegevensstroom van HoloLens 2, geeft inhoud weer in een virtuele insluitende weergave en streamt inhoudsframes terug naar HoloLens 2. De verbinding wordt gemaakt met behulp van standaard Wi-Fi. Holografische externe communicatie wordt toegevoegd aan een desktop- of UWP-app via een NuGet-pakket. Er is aanvullende code vereist waarmee de verbinding wordt verwerkt en in een insluitende weergave wordt weergegeven. Een typische externe verbinding heeft een lage latentie van wel 50 ms. De speler-app kan de latentie in realtime rapporteren.

Alle code op deze pagina en werkprojecten zijn te vinden in de GitHub-opslagplaats holographic Remoting-voorbeelden.

Vereisten

Een goed uitgangspunt is een werkende desktop- of UWP-app op basis van OpenXR. Zie Aan de slag met OpenXR voor meer informatie.

Belangrijk

Elke app die gebruikmaakt van Holographic Remoting moet worden geschreven voor het gebruik van een appartement met meerdere threads. Het gebruik van een appartement met één schroefdraad wordt ondersteund, maar leidt tot suboptimale prestaties en mogelijk haperingen tijdens het afspelen. Wanneer u C++/WinRT winrt::init_apartment is een appartement met meerdere threads de standaardinstelling.

Download het Holographic Remoting NuGet-pakket

De volgende stappen zijn vereist om het NuGet-pakket toe te voegen aan een project in Visual Studio.

  1. Open het project in Visual Studio.
  2. Klik met de rechtermuisknop op het projectknooppunt en selecteer NuGet-pakketten beheren...
  3. Selecteer bladeren in het deelvenster dat wordt weergegeven en zoek vervolgens naar 'Holographic Remoting'.
  4. Selecteer Microsoft.Holographic.Remoting.OpenXr, controleer of de meest recente versie 2.x.x is geselecteerd en selecteer vervolgens Installeren.
  5. Als het dialoogvenster Voorbeeld wordt weergegeven, selecteert u OK.
  6. Selecteer Ik ga akkoord wanneer het dialoogvenster met de licentieovereenkomst wordt weergegeven.
  7. Herhaal de stappen 3 tot en met 6 voor de volgende NuGet-pakketten: OpenXR.Headers, OpenXR.Loader

Notitie

Versie 1.x.x van het NuGet-pakket is nog steeds beschikbaar voor ontwikkelaars die holoLens 1 willen targeten. Zie HoloOgraphic Remoting (HoloLens (1e generatie) toevoegen voor meer informatie.

Selecteer de Holographic Remoting OpenXR-runtime

De eerste stap die u in uw externe app moet uitvoeren, is het selecteren van de Holographic Remoting OpenXR-runtime, die deel uitmaakt van het Microsoft.Holographic.Remoting.OpenXr NuGet-pakket. U kunt dit doen door de XR_RUNTIME_JSON omgevingsvariabele in te stellen op het pad van het bestand RemotingXR.json in uw app. Deze omgevingsvariabele wordt gebruikt door het OpenXR-laadprogramma om niet de standaard OpenXR-runtime van het systeem te gebruiken, maar in plaats daarvan om te leiden naar de Holographic Remoting OpenXR-runtime. Wanneer u het NuGet-pakket Microsoft.Holographic.Remoting.OpenXr gebruikt, wordt het bestand RemotingXR.json automatisch gekopieerd naar de uitvoermap. De OpenXR-runtimeselectie ziet er doorgaans als volgt uit.

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;
}

XrInstance maken met holographic remoting extension

De eerste acties die een typische OpenXR-app moet uitvoeren, zijn OpenXR-extensies selecteren en een XrInstance maken. De Kernspecificatie van OpenXR biedt geen api voor externe communicatie. Daarom introduceert Holographic Remoting een eigen OpenXR-extensie met de naam XR_MSFT_holographic_remoting. Zorg ervoor dat XR_MSFT_HOLOGRAPHIC_REMOTING_EXTENSION_NAME deze is opgenomen in de XrInstanceCreateInfo van de aanroep xrCreateInstance.

Tip

Standaard wordt de weergegeven inhoud van uw app alleen gestreamd naar de Holographic Remoting-speler die wordt uitgevoerd op een HoloLens 2 of op een Windows Mixed Reality headsets. Als u ook de weergegeven inhoud op de externe pc wilt weergeven, bijvoorbeeld via een wisselketen van een venster, biedt Holographic Remoting een tweede OpenXR-extensie met de naam XR_MSFT_holographic_remoting_frame_mirroring. Zorg ervoor dat u deze extensie ook inschakelt met voor XR_MSFT_HOLOGRAPHIC_REMOTING_FRAME_MIRRORING_EXTENSION_NAME het geval u die functionaliteit wilt gebruiken.

Belangrijk

Voor meer informatie over de Holographic Remoting OpenXR-extensie-API, bekijkt u de specificatie die te vinden is in de GitHub-opslagplaats holographic Remoting-voorbeelden.

Verbinding maken met het apparaat

Nadat uw externe app de XrInstance heeft gemaakt en de XrSystemId via xrGetSystem heeft opgevraagd, kan er een verbinding met het spelerapparaat tot stand worden gebracht.

Waarschuwing

De Holographic Remoting OpenXR-runtime kan alleen apparaatspecifieke gegevens leveren, zoals weergaveconfiguraties of omgevingsmengingsmodi nadat een verbinding tot stand is gebracht. xrEnumerateViewConfigurations, xrEnumerateViewConfigurationViews, xrGetViewConfigurationProperties, xrEnumerateEnvironmentBlendModes, en xrGetSystemProperties krijgt u standaardwaarden die overeenkomen met wat u normaal gesproken krijgt als u verbinding maakt met een speler die wordt uitgevoerd op een HoloLens 2, voordat u volledig verbinding maakt. Het wordt sterk aanbevolen om deze methoden niet aan te roepen voordat er een verbinding tot stand is gebracht. De suggestie wordt deze methoden gebruikt nadat de XrSession is gemaakt en de sessiestatus ten minste XR_SESSION_STATE_READY is.

Algemene eigenschappen, zoals maximale bitsnelheid, ingeschakelde audio, videocodec of resolutie van dieptebufferstromen, kunnen als volgt worden geconfigureerd xrRemotingSetContextPropertiesMSFT .

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);

De verbinding kan op twee manieren tot stand worden gebracht.

  1. De externe app maakt verbinding met de speler die op het apparaat wordt uitgevoerd.
  2. De speler die op het apparaat wordt uitgevoerd, maakt verbinding met de externe app.

Als u een verbinding tot stand wilt brengen tussen de externe app en het spelerapparaat, roept u de xrRemotingConnectMSFT methode aan die de hostnaam en poort opgeeft via de XrRemotingConnectInfoMSFT structuur. De poort die wordt gebruikt door de Holographic Remoting Player is 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);

Luisteren naar binnenkomende verbindingen in de externe app kan worden uitgevoerd door de xrRemotingListenMSFT methode aan te roepen. Zowel de handshakepoort als de transportpoort kunnen worden opgegeven via de XrRemotingListenInfoMSFT structuur. De handshakepoort wordt gebruikt voor de eerste handshake. De gegevens worden vervolgens verzonden via de transportpoort. Standaard worden 8265 en 8266 gebruikt.

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);

De verbindingsstatus moet worden verbroken wanneer u of xrRemotingListenMSFTaanroeptxrRemotingConnectMSFT. U kunt de verbindingsstatus op elk gewenst moment ophalen nadat u een XrInstance hebt gemaakt en een query hebt uitgevoerd voor de XrSystemId via xrRemotingGetConnectionStateMSFT.

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

Beschikbare verbindingsstatussen zijn:

  • XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT
  • XR_REMOTING_CONNECTION_STATE_CONNECTING_MSFT
  • XR_REMOTING_CONNECTION_STATE_CONNECTED_MSFT

Belangrijk

xrRemotingConnectMSFT of xrRemotingListenMSFT moet worden aangeroepen voordat u probeert een XrSession te maken via xrCreateSession. Als u probeert een XrSession te maken terwijl de verbindingsstatus is XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT , wordt het maken van de sessie voltooid, maar wordt de sessiestatus onmiddellijk overgezet naar XR_SESSION_STATE_LOSS_PENDING.

Holographic Remoting's implementatie van xrCreateSession ondersteuning wachtend op een verbinding tot stand is gebracht. U kunt aanroepen xrRemotingConnectMSFT of xrRemotingListenMSFT onmiddellijk gevolgd door een aanroep naar xrCreateSession, waardoor wordt geblokkeerd en gewacht tot er een verbinding tot stand is gebracht. De time-out met xrRemotingConnectMSFT is vastgesteld op 10 seconden en onbeperkt met xrRemotingListenMSFT. Als er binnen deze tijd een verbinding tot stand kan worden gebracht, wordt de XrSession gemaakt en wordt de sessiestatus overgezet naar XR_SESSION_STATE_READY. Als er geen verbinding tot stand kan worden gebracht, slaagt het maken van de sessie ook, maar wordt onmiddellijk overgezet naar XR_SESSION_STATE_LOSS_PENDING.

Over het algemeen is de verbindingsstatus gekoppeld aan de XrSession-status. Elke wijziging in de verbindingsstatus is ook van invloed op de sessiestatus. Als de verbindingsstatus bijvoorbeeld overschakelt van XR_REMOTING_CONNECTION_STATE_CONNECTED_MSFT naar XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT de sessie, wordt de status ook overgezet naar XR_SESSION_STATE_LOSS_PENDING.

Afhandeling van specifieke gebeurtenissen voor externe communicatie

De Holographic Remoting OpenXR-runtime geeft drie gebeurtenissen weer, die belangrijk zijn voor het bewaken van de status van een verbinding.

  1. XR_TYPE_REMOTING_EVENT_DATA_CONNECTED_MSFT: Wordt geactiveerd wanneer een verbinding met het apparaat tot stand is gebracht.
  2. XR_TYPE_REMOTING_EVENT_DATA_DISCONNECTED_MSFT: Wordt geactiveerd als een tot stand gebrachte verbinding wordt gesloten of als er geen verbinding tot stand kan worden gebracht.
  3. XR_TYPE_REMOTING_EVENT_DATA_LISTENING_MSFT: wanneer het luisteren naar binnenkomende verbindingen wordt gestart.

Deze gebeurtenissen worden in een wachtrij geplaatst en uw externe app moet regelmatig uit de wachtrij lezen via 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;
	}
}

Lokaal gestreamde inhoud bekijken

Als u dezelfde inhoud wilt weergeven in de externe app die naar het apparaat wordt verzonden, kan de XR_MSFT_holographic_remoting_frame_mirroring extensie worden gebruikt. Met deze extensie kunt u als volgt een patroon verzenden naar xrEndFrame met behulp van de XrRemotingFrameMirrorImageInfoMSFT die niet is gekoppeld aan de XrFrameEndInfo.

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();

In het bovenstaande voorbeeld wordt een DX11-wisselketenpatroon gebruikt en wordt het venster direct na het aanroepen van xrEndFrame weergegeven. Het gebruik is niet beperkt tot het wisselen van ketenpatroon. Bovendien is er geen extra GPU-synchronisatie vereist. Raadpleeg de extensiespecificatie voor meer informatie over gebruik en beperkingen. Als uw externe app DX12 gebruikt, gebruikt u XrRemotingFrameMirrorImageD3D12MSFT in plaats van XrRemotingFrameMirrorImageD3D11MSFT.

Optioneel: Aangepaste gegevenskanalen

Vanaf versie 2.5.0 kunnen aangepaste gegevenskanalen worden gebruikt met de OpenXR-API om gebruikersgegevens te verzenden via de reeds tot stand gebrachte externe verbinding. Zie Aangepaste gegevenskanalen met de OpenXR-API voor meer informatie.

Optioneel: Spraak

Vanaf versie 2.6.0 kan de XR_MSFT_holographic_remoting_speech externe app reageren op spraakopdrachten die zijn gedetecteerd door de speler-app met de OpenXR API.

[! BELANGRIJK] De gedetailleerde specificatie vindt u in de GitHub-opslagplaats holographic Remoting-voorbeelden.

Als u een spraakherkenning wilt initialiseren in de speler-app, kan de externe app aanroepen xrInitializeRemotingSpeechMSFT. Met deze aanroep worden parameters voor spraak-initialisatie, die bestaan uit een taal, een woordenlijst met woordgroepen en de inhoud van een grammaticabestand, verzonden naar de speler-app.

Notitie

Vóór versie 2.6.1 mag de spraakherkenning slechts eenmaal XrSessionper worden geïnitialiseerd.

Als het maken van de spraakherkenning is geslaagd, zoals aangegeven door de XR_TYPE_EVENT_DATA_REMOTING_SPEECH_RECOGNIZER_STATE_CHANGED_MSFT gebeurtenis, wordt de externe app op de hoogte gesteld wanneer er een spraakherkenningsresultaat is gegenereerd in de speler-app. De XrEventDataRemotingSpeechRecognizerStateChangedMSFT gebeurtenisstructuur wordt in de gebeurteniswachtrij geplaatst wanneer de status van de spraakherkenning aan de kant van de speler verandert.

XrRemotingSpeechRecognizerStateMSFT definieert alle mogelijke statussen van de spraakherkenning aan de kant van de speler en de XrEventDataRemotingSpeechRecognizedMSFT gebeurtenisstructuur wordt in de gebeurteniswachtrij geplaatst als de spraakherkenning aan de kant van de speler een herkende woordgroep heeft. Nadat de externe app op de hoogte is gesteld van een herkende woordgroep, kan deze de herkende woordgroep ophalen door aan te roepen xrRetrieveRemotingSpeechRecognizedTextMSFT.

Notitie

De XrRemotingSpeechRecognitionConfidenceMSFT is een directe toewijzing van de opsomming SpeechRecognitionConfidence die wordt geretourneerd met het spraakherkenningsresultaat door de Windows Spraakherkennings-API.

Optioneel: Systeemsynchronisatie coördineren

Vanaf versie 2.7.0 kan systeemsynchronisatie coördineren worden gebruikt om ruimtelijke gegevens uit te lijnen tussen de speler en de externe app. Zie Overzicht systeemsynchronisatie coördineren met Holographic Remoting voor meer informatie.

Zie ook