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

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

Ważne

W tym dokumencie opisano tworzenie aplikacji zdalnej dla zestawów HoloLens 2 i zestawów 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 odwrotnie. 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. Możesz również uzyskać dostęp do większej liczby zasobów systemowych i zintegrować zdalne widoki immersyjne z istniejącym oprogramowaniem na komputerze stacjonarnym. Aplikacja zdalna odbiera strumień danych wejściowych z usługi HoloLens 2, renderuje zawartość w wirtualnym widoku immersyjnym 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 platformy Holographic jest dodawana do aplikacji klasycznej lub aplikacji platformy uniwersalnej systemu Windows za pośrednictwem NuGet pakietów. Wymagany jest dodatkowy kod, który obsługuje połączenie i renderuje w widoku immersyjnym. Typowe połączenie zdalne będzie mieć nawet 50 ms opóźnienia. Aplikacja odtwarzacza może zgłaszać opóźnienia w czasie rzeczywistym.

Cały kod na tej stronie i projekty robocze można znaleźć w repozytorium GitHub przykładów komunikacji zdalnej systemu Holographic.

Wymagania wstępne

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

Ważne

Każdą aplikację korzystającą z komunikacji zdalnej Holographic należy ować tak, aby używać wielowątkowego miski. Użycie jednowątkowej klatki 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ą domyślną jest wielowątkowy rozmiar).

Pobierz pakiet komunikacji zdalnej NuGet Holographic

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 zostanie wyświetlone 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 zmienną środowiskową na ścieżkę pliku XR_RUNTIME_JSON 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 wygląda zwykle w następujący sposób.

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 rozszerzenia XrInstance z rozszerzeniem holograficznego komunikacji zdalnej

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 XR_MSFT_HOLOGRAPHIC_REMOTING_EXTENSION_NAME się, że znajduje się on w informacji 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 na Windows Mixed Reality nagłownym. Aby również wyświetlić 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ż XR_MSFT_HOLOGRAPHIC_REMOTING_FRAME_MIRRORING_EXTENSION_NAME włączane przy użyciu funkcji , jeśli chcesz użyć tej funkcji.

Ważne

Aby dowiedzieć się więcej o interfejsie API rozszerzenia OpenXR usługi Holographic Remoting, zapoznaj się ze specyfikacją, którą można znaleźć w repozytorium GitHub przykładów usługi Holographic Remoting.

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 po nawiązaniu połączenia. xrEnumerateViewConfigurationsWartości , , , i będą zawierały wartości domyślne, zgodne z tym, co zwykle otrzymasz, jeśli połączysz się z odtwarzaczem uruchomionym na HoloLens 2, przed pełnym xrEnumerateViewConfigurationViews xrGetViewConfigurationProperties xrEnumerateEnvironmentBlendModes xrGetSystemProperties podłączeniem. Zdecydowanie zaleca się, aby nie wywołać tych metod przed nawiązaniu połączenia. Sugestia jest używana przy tych metodach 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, wywołaj metodę określającą nazwę hosta i xrRemotingConnectMSFT port za pośrednictwem struktury XrRemotingConnectInfoMSFT . 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 handshake, 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 8265 i 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 być rozłączony podczas wywołania lub xrRemotingConnectMSFT xrRemotingListenMSFT . 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, gdy stanem połączenia jest utworzenie sesji, zakończy się pomyślnie, ale stan sesji natychmiast zostanie XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT XR_SESSION_STATE_LOSS_PENDING.

Implementacja systemu Holographic Remoting obsługuje xrCreateSession oczekiwanie na połączenie. Możesz wywołać wywołanie lub natychmiast, po którym następuje wywołanie , które spowoduje zablokowanie połączenia i xrRemotingConnectMSFT xrRemotingListenMSFT oczekiwanie na jego połączenie. Limit czasu jest stały na 10 sekund. Jeśli w tym czasie można nawiązyć połączenie, tworzenie sesji XrSession zakończy się pomyślnie, 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 na stan sesji, również XR_SESSION_STATE_LOSS_PENDING XR_REMOTING_CONNECTION_STATE_CONNECTED_MSFT XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT 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żesz przesłać teksturę do obiektu xrEndFrame przy użyciu obiektu , który nie jest łańcuchem do XrRemotingFrameMirrorImageInfoMSFT 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 Niestandardowe kanały danych z interfejsem API OpenXR.

Opcjonalnie: mowa

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

[!IMPORTANT] Szczegółową specyfikację można znaleźć w repozytorium GitHub Samples (Przykłady dotyczące komunikacji zdalnej na platformie Holographic).

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 się pomyślnie, zgodnie z tym zdarzeniem, aplikacja zdalna zostanie powiadomiona o wygenerowaniu wyniku rozpoznawania mowy w XR_TYPE_EVENT_DATA_REMOTING_SPEECH_RECOGNIZER_STATE_CHANGED_MSFT aplikacji odtwarzacza. Struktura zdarzeń jest umieszczana w kolejce zdarzeń, gdy zmieni się stan rozpoznawania XrEventDataRemotingSpeechRecognizerStateChangedMSFT mowy po stronie odtwarzacza.

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

Uwaga

To XrRemotingSpeechRecognitionConfidenceMSFT bezpośrednie mapowanie wyliku 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ż