Pisanie zdalnej aplikacji Holographic Remoting przy użyciu interfejsu API OpenXR

Jeśli jesteś nowym użytkownikom systemu Holographic Remoting, zapoznaj się z naszym omówieniem.

Ważne

W tym dokumencie opisano tworzenie aplikacji zdalnej dla HoloLens 2 i Windows Mixed Reality przy użyciu interfejsu API OpenXR. Aplikacje zdalne dla HoloLens (1. generacji) muszą używać NuGet pakietu w wersji 1.x.x. Oznacza to, że aplikacje zdalne napisane dla HoloLens 2 nie są zgodne HoloLens 1 i na odwrót. Dokumentację dla HoloLens 1 można znaleźć tutaj.

Aplikacje Holographic Remoting mogą przesyłać strumieniowo zdalnie renderowana zawartość do HoloLens 2 i Windows Mixed Reality immersywnych zestawów nagłownych. Możesz również uzyskać dostęp do większej liczby zasobów systemowych i zintegrować zdalne widoki immersywne z istniejącym oprogramowaniem na komputerze stacjonarnym. Aplikacja zdalna odbiera strumień danych wejściowych z platformy HoloLens 2, renderuje zawartość w wirtualnym widoku immersywnie i przesyła strumieniowo ramki zawartości z powrotem do HoloLens 2. Połączenie jest nawiązane przy użyciu standardowej sieci Wi-Fi. Komunikacja zdalna holograficzna jest dodawana do aplikacji klasycznej lub UWP za pośrednictwem NuGet zdalnego. Wymagany jest dodatkowy kod, który obsługuje połączenie i renderuje w widoku immersyjnym. Typowe połączenie komunikacji zdalnej będzie mieć opóźnienie do 50 ms. Aplikacja odtwarzacza może zgłaszać opóźnienie w czasie rzeczywistym.

Cały kod na tej stronie i projekty robocze można znaleźć w repozytorium GitHub Przykłady dotyczące komunikacji zdalnej systemu Holographic.

Wymagania wstępne

Dobrym punktem wyjścia jest dobrą aplikację komputerową lub UWP opartą na platformie OpenXR. Aby uzyskać szczegółowe informacje , zobacz Getting started with OpenXR (Wprowadzenie do openXR).

Ważne

Każda aplikacja korzystająca z usługi Holographic Remoting powinna być authored w celu używania wielowątkowego miski. Korzystanie z jednowątkowego typu schowek jest obsługiwane, ale prowadzi do nie optymalnej wydajności i być może stuttering podczas odtwarzania. W przypadku korzystania z C++/WinRT winrt::init_apartment domyślną wartością jest wielowątkowy kompilator.

Pobierz pakiet aplikacji Holographic Remoting NuGet

Poniższe kroki są wymagane do dodania pakietu NuGet do projektu w Visual Studio.

  1. Otwórz projekt w programie Visual Studio.
  2. Kliknij prawym przyciskiem myszy węzeł projektu i wybierz pozycję Zarządzaj NuGet pakietów...
  3. W wyświetlonym panelu wybierz pozycję Przeglądaj , a następnie wyszukaj pozycję "Holographic Remoting".
  4. Wybierz pozycję Microsoft.Holographic.Remoting.OpenXr, upewnij się, że wybrano najnowszą wersję 2.x.x , a następnie wybierz pozycję Zainstaluj.
  5. Jeśli zostanie wyświetlone okno dialogowe Podgląd, wybierz przycisk OK.
  6. Wybierz pozycję Akceptuję , gdy pojawi się okno dialogowe umowy licencyjnej.
  7. Powtórz kroki od 3 do 6 dla następujących pakietów NuGet: OpenXR.Headers, OpenXR.Loader

Uwaga

Wersja 1.x.x pakietu NuGet jest nadal dostępna dla deweloperów, którzy chcą korzystać z wersji HoloLens 1. Aby uzyskać szczegółowe informacje, zobacz Add Holographic Remoting (HoloLens (1. generacja)).

Wybieranie środowiska uruchomieniowego OpenXR Holographic Remoting

Pierwszym krokiem, który należy wykonać w aplikacji zdalnej, jest wybranie środowiska uruchomieniowego OpenXR Holographic Remoting, które jest częścią pakietu NuGet Microsoft.Holographic.Remoting.OpenXr. Możesz to zrobić, ustawiając XR_RUNTIME_JSON zmienną środowiskową na ścieżkę pliku RemotingXR.json w aplikacji. Ta zmienna środowiskowa jest używana przez modułu ładującego OpenXR, aby nie używać domyślnego środowiska uruchomieniowego OpenXR systemu, ale zamiast tego przekierowywać do środowiska uruchomieniowego OpenXR Holographic Remoting. W przypadku korzystania z pakietu Microsoft.Holographic.Remoting.OpenXr NuGet plik RemotingXR.json jest automatycznie kopiowany podczas kompilacji do folderu wyjściowego, wybór środowiska uruchomieniowego OpenXR zwykle wygląda następująco.

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

Tworzenie XrInstance z rozszerzeniem Holographic Remoting Extension

Pierwsze akcje, które powinna podjąć typowa aplikacja OpenXR, to wybranie rozszerzeń OpenXR i utworzenie rozszerzenia XrInstance. Podstawowa specyfikacja OpenXR nie zapewnia żadnego interfejsu API komunikacji zdalnej. Z tego powodu system Holographic Remoting wprowadza własne rozszerzenie OpenXR o nazwie XR_MSFT_holographic_remoting. Upewnij się, XR_MSFT_HOLOGRAPHIC_REMOTING_EXTENSION_NAME że znajduje się on w XrInstanceCreateInfo wywołania xrCreateInstance.

Porada

Domyślnie renderowana zawartość aplikacji jest przesyłana strumieniowo tylko do odtwarzacza Holographic Remoting uruchomionego na komputerze HoloLens 2 lub w Windows Mixed Reality nagłownym. Aby wyświetlić również renderowana zawartość na komputerze zdalnym, na przykład za pośrednictwem łańcucha wymiany okna, usługa Holographic Remoting udostępnia drugie rozszerzenie OpenXR o nazwie XR_MSFT_holographic_remoting_frame_mirroring. Upewnij się, że to rozszerzenie jest również włączane przy XR_MSFT_HOLOGRAPHIC_REMOTING_FRAME_MIRRORING_EXTENSION_NAME użyciu funkcji , jeśli chcesz użyć tej funkcji.

Ważne

Aby dowiedzieć się więcej na temat interfejsu API rozszerzenia OpenXR Holographic Remoting, zapoznaj się ze specyfikacją, którą można znaleźć w repozytorium GitHub przykładów dotyczących komunikacji zdalnej systemu Holographic.

Połączenie z urządzeniem

Po utworzeniu przez aplikację zdalną interfejsu XrInstance i utworzeniu zapytania o XrSystemId za pośrednictwem narzędzia xrGetSystem można nawiązane połączenie z urządzeniem odtwarzacza.

Ostrzeżenie

Środowisko uruchomieniowe OpenXR Holographic Remoting może dostarczać dane specyficzne dla urządzenia, takie jak konfiguracje widoku lub tryby mieszania środowiska, dopiero po nawiązaniu połączenia. xrEnumerateViewConfigurationsWartości xrEnumerateViewConfigurationViews, xrGetViewConfigurationProperties, , xrEnumerateEnvironmentBlendModesi xrGetSystemProperties będą zawierały wartości domyślne zgodne z tym, co zwykle można uzyskać w przypadku nawiązania połączenia z odtwarzaczem uruchomionym na HoloLens 2, przed pełnym podłączeniem. Zdecydowanie zaleca się, aby nie wywołać tych metod przed nawiązaniu połączenia. Sugestia jest używana z tymi metodami po pomyślnym utworzeniu sesji XrSession, a stan sesji jest co najmniej XR_SESSION_STATE_READY.

Ogólne właściwości, takie jak maksymalna prędkość transmisji bitów, włączony dźwięk, koder-koder wideo lub rozdzielczość strumienia buforu głębokości, można skonfigurować w xrRemotingSetContextPropertiesMSFT następujący sposób.

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

Połączenie można nawiązaniu na jeden z dwóch sposobów.

  1. Aplikacja zdalna łączy się z odtwarzaczem uruchomionym na urządzeniu.
  2. Odtwarzacz uruchomiony na urządzeniu łączy się z aplikacją zdalną.

Aby nawiązać połączenie z aplikacji zdalnej do urządzenia odtwarzacza, xrRemotingConnectMSFT wywołaj metodę określającą nazwę hosta i port za pośrednictwem XrRemotingConnectInfoMSFT struktury . Port używany przez urządzenie Holographic Remoting Player to 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);

Nasłuchiwanie połączeń przychodzących w aplikacji zdalnej można wykonać przez wywołanie xrRemotingListenMSFT metody . Zarówno port uściśli, jak i port transportu można określić za pośrednictwem XrRemotingListenInfoMSFT struktury. Port uściślinia jest używany do początkowego ugody. Dane są następnie wysyłane za pośrednictwem portu transportu. Domyślnie używane są wartości 8265i 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);

Stan połączenia musi zostać rozłączony podczas wywołania lub xrRemotingConnectMSFTxrRemotingListenMSFT. Stan połączenia można uzyskać w dowolnym momencie po utworzeniu XrInstance i utworzeniu zapytania o element XrSystemId za pośrednictwem .xrRemotingGetConnectionStateMSFT

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

Dostępne stany połączenia to:

  • XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT
  • XR_REMOTING_CONNECTION_STATE_CONNECTING_MSFT
  • XR_REMOTING_CONNECTION_STATE_CONNECTED_MSFT

Ważne

xrRemotingConnectMSFT Przed xrRemotingListenMSFT próbą utworzenia XrSession za pośrednictwem xrCreateSession należy wywołać znak lub . Jeśli spróbujesz utworzyć sesję XrSession XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT , gdy stan połączenia to tworzenie sesji zakończy się pomyślnie, ale stan sesji zostanie natychmiast XR_SESSION_STATE_LOSS_PENDING.

Implementacja systemu Holographic Remoting obsługuje xrCreateSession oczekiwanie na połączenie. Możesz wywołać wywołanie lub xrRemotingConnectMSFTxrRemotingListenMSFT natychmiast po wywołaniu do , co spowoduje zablokowanie połączenia i oczekiwanie na jego połączenie. Limit czasu jest stały na 10 sekund. Jeśli w tym czasie można nawiązane połączenie, tworzenie sesji XrSession zakończy się powodzeniem, a stan sesji zostanie XR_SESSION_STATE_READY. W przypadku, gdy nie można nawiązyć połączenia, tworzenie sesji również zakończy się powodzeniem, ale natychmiast przechodzi do XR_SESSION_STATE_LOSS_PENDING.

Ogólnie rzecz biorąc, stan połączenia jest kilka ze stanem XrSession. Każda zmiana stanu połączenia ma również wpływ na stan sesji. Jeśli na przykład stan połączenia zostanie przełączyny z XR_REMOTING_CONNECTION_STATE_CONNECTED_MSFTXR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT na stan sesji, również XR_SESSION_STATE_LOSS_PENDING stanu.

Obsługa komunikacji zdalnej określonych zdarzeń

Środowisko uruchomieniowe OpenXR Holographic Remoting uwidacznia trzy zdarzenia, które są ważne do monitorowania stanu połączenia.

  1. XR_TYPE_REMOTING_EVENT_DATA_CONNECTED_MSFT: wyzwalane po pomyślnym nawiązaniu połączenia z urządzeniem.
  2. XR_TYPE_REMOTING_EVENT_DATA_DISCONNECTED_MSFT: wyzwalane w przypadku zamknięcia nawiązanego połączenia lub nie można nawiązanego połączenia.
  3. XR_TYPE_REMOTING_EVENT_DATA_LISTENING_MSFT: Podczas nasłuchiwania połączeń przychodzących rozpoczyna się.

Te zdarzenia są umieszczane w kolejce, a aplikacja zdalna musi regularnie odczytywać dane z kolejki za pośrednictwem usługi 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;
	}
}

Podgląd przesyłanej strumieniowo zawartości lokalnie

Aby wyświetlić tę samą zawartość w aplikacji zdalnej, która jest wysyłana do urządzenia, XR_MSFT_holographic_remoting_frame_mirroring można użyć rozszerzenia. Za pomocą tego rozszerzenia można przesłać teksturę do obiektu xrEndFrame XrRemotingFrameMirrorImageInfoMSFT przy użyciu obiektu , który nie jest łańcuchem do obiektu XrFrameEndInfo w następujący sposób.

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

W powyższym przykładzie użyto tekstury łańcucha wymiany DX11 i przedstawia okno bezpośrednio po wywołaniu xrEndFrame. Użycie nie jest ograniczone do zamiany tekstur łańcucha. Ponadto dodatkowa synchronizacja procesora GPU nie jest wymagana. Aby uzyskać szczegółowe informacje na temat użycia i ograniczeń, zapoznaj się ze specyfikacją rozszerzenia. Jeśli aplikacja zdalna korzysta z dx12, użyj XrRemotingFrameMirrorImageD3D12MSFT zamiast XrRemotingFrameMirrorImageD3D11MSFT.

Opcjonalnie: Niestandardowe kanały danych

Począwszy od wersji 2.5.0, niestandardowe kanały danych mogą być używane z interfejsem API OpenXR do wysyłania danych użytkownika za pośrednictwem już ustanowionego połączenia komunikacji zdalnej. Aby uzyskać więcej informacji, zobacz Custom Data Channels with the OpenXR API (Niestandardowe kanały danych za pomocą interfejsu API OpenXR).

Opcjonalnie: mowa

Począwszy od wersji 2.6.0, XR_MSFT_holographic_remoting_speech rozszerzenie umożliwia aplikacji zdalnej reagowanie na polecenia mowy wykryte przez aplikację odtwarzacza za pomocą interfejsu API OpenXR.

[! WAŻNE] Szczegółową specyfikację można znaleźć w repozytorium GitHub Przykłady komunikacji zdalnej holograficznej.

Aby zainicjować aparat rozpoznawania mowy w aplikacji odtwarzacza, aplikacja zdalna może wywołać .xrInitializeRemotingSpeechMSFT To wywołanie przesyła parametry inicjowania mowy, które składają się z języka, słownika fraz i zawartości pliku gramatyki, do aplikacji odtwarzacza.

Uwaga

Przed wersją 2.6.1 aparat rozpoznawania mowy musi zostać zainicjowany tylko raz na .XrSession

Jeśli tworzenie rozpoznawania mowy zakończyło się pomyślnie, XR_TYPE_EVENT_DATA_REMOTING_SPEECH_RECOGNIZER_STATE_CHANGED_MSFT jak wskazuje zdarzenie, aplikacja zdalna zostanie powiadomiona o wygenerowaniu wyniku rozpoznawania mowy w aplikacji odtwarzacza. Struktura XrEventDataRemotingSpeechRecognizerStateChangedMSFT zdarzeń jest umieszczana w kolejce zdarzeń po zmianie stanu rozpoznawania mowy po stronie odtwarzacza.

XrRemotingSpeechRecognizerStateMSFT definiuje wszystkie możliwe XrEventDataRemotingSpeechRecognizedMSFT stany rozpoznawania mowy po stronie odtwarzacza, a struktura zdarzeń jest umieszczana w kolejce zdarzeń, jeśli aparat rozpoznawania mowy po stronie odtwarzacza ma rozpoznaną frazę. Gdy aplikacja zdalna zostanie powiadomiona o rozpoznanej frazie, może pobrać rozpoznaną frazę, wywołując .xrRetrieveRemotingSpeechRecognizedTextMSFT

Uwaga

Jest XrRemotingSpeechRecognitionConfidenceMSFT to bezpośrednie mapowanie wyli roku SpeechRecognitionConfidence zwróconego z wynikiem rozpoznawania mowy przez interfejs API rozpoznawania Windows Rozpoznawania mowy.

Opcjonalnie: synchronizacja systemu współrzędnych

Począwszy od wersji 2.7.0, synchronizacja systemu współrzędnych może służyć do wyrównywania danych przestrzennych między odtwarzaczem i aplikacją zdalną. Aby uzyskać więcej informacji, zobacz Coordinate System Synchronization with Holographic Remoting Overview (Synchronizacja systemu współrzędnych z usługą Holographic Remoting — omówienie).

Zobacz też