Écriture d’une application de lecteur de communication à distance holographique personnalisée

Si vous débutez avec la communication à distance holographique, vous pouvez lire notre vue d’ensemble.

Important

Ce document décrit la création d’une application de lecteur personnalisée pour HoloLens 2. Les lecteurs personnalisés écrits pour HoloLens 2 ne sont pas compatibles avec les applications distantes écrites pour HoloLens 1. Cela implique que les deux applications doivent utiliser le package NuGet version 2.x.x.

En créant une application de lecteur de communication à distance holographique personnalisée, vous pouvez créer une application personnalisée capable d’afficher des vues immersives à partir d’un ordinateur distant sur votre HoloLens 2. Tout le code de cette page et des projets de travail se trouve dans le référentiel github d’exemples de communication à distance holographiques.

Un lecteur de communication à distance holographique permet à votre application d’afficher du contenu holographique rendu sur un PC de bureau ou un appareil UWP comme la Xbox One avec accès à davantage de ressources système. Une application de lecteur de communication à distance holographique diffuse des données d’entrée vers une application distante de communication à distance Holographique et reçoit une vue immersive sous forme de flux vidéo et audio. La connexion est établie à l’aide du Wi-Fi standard. Pour créer une application de lecteur, utilisez un package NuGet pour ajouter la communication à distance holographique à votre application UWP. Écrivez ensuite du code pour gérer la connexion et afficher une vue immersive.

Prérequis

Un bon point de départ est une application UWP Basée sur DirectX qui cible déjà l’API Windows Mixed Reality. Pour plus d’informations, consultez Vue d’ensemble du développement DirectX. Si vous n’avez pas d’application existante et que vous souhaitez commencer à zéro, le modèle de projet holographique C++ est un bon point de départ.

Important

Toute application utilisant la communication à distance holographique doit être créée pour utiliser un appartement multithread. L’utilisation d’un appartement à thread unique est prise en charge, mais entraîne des performances sous-optimales et peut-être un bégaiement pendant la lecture. Lorsque vous utilisez C++/WinRT winrt::init_apartment un appartement multithread est la valeur par défaut.

Obtenir le package NuGet de communication à distance holographique

Les étapes suivantes sont nécessaires pour ajouter le package NuGet à un projet dans Visual Studio.

  1. Ouvrez le projet dans Visual Studio.
  2. Cliquez avec le bouton droit sur le nœud du projet, puis sélectionnez Gérer les packages NuGet...
  3. Dans le panneau qui s’affiche, sélectionnez Parcourir , puis recherchez « Communication à distance holographique ».
  4. Sélectionnez Microsoft.Holographic.Remoting, veillez à choisir la dernière version 2.x.x, puis sélectionnez Installer.
  5. Si la boîte de dialogue Aperçu s’affiche, sélectionnez OK.
  6. Sélectionnez J’accepte lorsque la boîte de dialogue contrat de licence s’affiche.

Important

Le build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl package NuGet contient une documentation détaillée pour l’API exposée par la communication à distance holographique.

Modifier le Package.appxmanifest de l’application

Pour que l’application prenne en compte les Microsoft.Holographic.AppRemoting.dll ajoutées par le package NuGet, les étapes suivantes doivent être effectuées sur le projet :

  1. Dans le Explorateur de solutions, cliquez avec le bouton droit sur le fichier Package.appxmanifest et sélectionnez Ouvrir avec...
  2. Sélectionnez Éditeur XML (texte) et ok
  3. Ajoutez les lignes suivantes au fichier et enregistrez
  </Capabilities>

  <!--Add lines below -->
  <Extensions>
    <Extension Category="windows.activatableClass.inProcessServer">
      <InProcessServer>
        <Path>Microsoft.Holographic.AppRemoting.dll</Path>
        <ActivatableClass ActivatableClassId="Microsoft.Holographic.AppRemoting.PlayerContext" ThreadingModel="both" />
      </InProcessServer>
    </Extension>
  </Extensions>
  <!--Add lines above -->

</Package>

Créer le contexte du joueur

Dans un premier temps, l’application doit créer un contexte de joueur.

// class declaration:

#include <winrt/Microsoft.Holographic.AppRemoting.h>

...

private:
// PlayerContext used to connect with a Holographic Remoting remote app and display remotely rendered frames
winrt::Microsoft::Holographic::AppRemoting::PlayerContext m_playerContext = nullptr;
// class implementation:

// Create the player context
// IMPORTANT: This must be done before creating the HolographicSpace (or any other call to the Holographic API).
m_playerContext = winrt::Microsoft::Holographic::AppRemoting::PlayerContext::Create();

Avertissement

Un lecteur personnalisé injecte une couche intermédiaire entre l’application de lecteur et le runtime Windows Mixed Reality fourni avec Windows. Cette opération est effectuée lors de la création du contexte du joueur. Pour cette raison, tout appel sur n’importe quelle API Windows Mixed Reality avant de créer le contexte du joueur peut entraîner un comportement inattendu. L’approche recommandée consiste à créer le contexte du joueur le plus tôt possible avant d’interagir avec n’importe quelle API Mixed Reality. Ne mélangez jamais d’objets créés ou récupérés par le biais d’une API Windows Mixed Reality avant l’appel à PlayerContext::Create avec des objets créés ou récupérés par la suite.

Ensuite, vous pouvez créer HolographicSpace en appelant HolographicSpace.CreateForCoreWindow.

m_holographicSpace = winrt::Windows::Graphics::Holographic::HolographicSpace::CreateForCoreWindow(window);

Se connecter à l’application distante

Une fois que l’application de lecteur est prête pour le rendu du contenu, une connexion à l’application distante peut être établie.

La connexion peut être établie de l’une des manières suivantes :

  1. L’application de lecteur s’exécutant sur HoloLens 2 se connecte à l’application distante.
  2. L’application distante se connecte à l’application de lecteur exécutée sur HoloLens 2.

Pour vous connecter à partir de l’application de lecteur à l’application distante, appelez la Connect méthode sur le contexte du lecteur en spécifiant le nom d’hôte et le port. Le port par défaut est 8265.

try
{
    m_playerContext.Connect(m_hostname, m_port);
}
catch(winrt::hresult_error& e)
{
    // Failed to connect. Get an error details via e.code() and e.message()
}

Important

Comme avec n’importe quelle API Connect C++/WinRT peut lever un winrt::hresult_error qui doit être géré.

Vous pouvez écouter les connexions entrantes sur l’application lecteur en appelant la Listen méthode . Le port de négociation et le port de transport peuvent être spécifiés pendant cet appel. Le port d’établissement d’une liaison est utilisé pour la négociation initiale. Les données sont ensuite envoyées sur le port de transport. Par défaut, les numéros de port 8265 et 8266 sont utilisés.

try
{
    m_playerContext.Listen(L"0.0.0.0", m_port, m_port + 1);
}
catch(winrt::hresult_error& e)
{
    // Failed to listen. Get an error details via e.code() and e.message()
}

expose PlayerContext trois événements pour surveiller l’état de la connexion

  1. OnConnected : déclenché lorsqu’une connexion à l’application distante a été établie avec succès.
m_onConnectedEventToken = m_playerContext.OnConnected([]() 
{
    // Handle connection successfully established
});
  1. OnDisconnected : déclenché si une connexion établie est terminée ou si une connexion n’a pas pu être établie.
m_onDisconnectedEventToken = m_playerContext.OnDisconnected([](ConnectionFailureReason failureReason)
{
    switch (failureReason)
    {
        // Handle connection failed or terminated.
        // See ConnectionFailureReason for possible reasons.
    }
}

Notes

Les valeurs possibles ConnectionFailureReason sont documentées dans le Microsoft.Holographic.AppRemoting.idlfichier.

  1. OnListening : lorsque l’écoute des connexions entrantes démarre.
m_onListeningEventToken = m_playerContext.OnListening([]()
{
    // Handle start listening for incoming connections
});

En outre, l’état de la connexion peut être interrogé à l’aide de la ConnectionState propriété sur le contexte du lecteur.

winrt::Microsoft::Holographic::AppRemoting::ConnectionState state = m_playerContext.ConnectionState();

Afficher le cadre rendu à distance

Pour afficher le contenu rendu à distance, appelez PlayerContext::BlitRemoteFrame lors du rendu d’un HolographicFrame.

BlitRemoteFrame nécessite que la mémoire tampon d’arrière-mémoire pour l’HolographicFrame actuel soit liée en tant que cible de rendu. La mémoire tampon d’arrière-plan peut être reçue à partir de HolographicCameraRenderingParameters via la propriété Direct3D11BackBuffer .

Lorsqu’elle est appelée, BlitRemoteFrame copie la dernière image reçue de l’application distante dans le backbuffer de l’HolographicFrame. En outre, le jeu de points de focus est défini, si l’application distante a spécifié un point de focus pendant le rendu de l’image distante.

// Blit the remote frame into the backbuffer for the HolographicFrame.
winrt::Microsoft::Holographic::AppRemoting::BlitResult result = m_playerContext.BlitRemoteFrame();

Notes

PlayerContext::BlitRemoteFrame remplace potentiellement le point de focus pour l’image actuelle.

En cas de réussite, BlitRemoteFrame retourne BlitResult::Success_Color. Sinon, elle retourne la raison de l’échec :

  • BlitResult::Failed_NoRemoteFrameAvailable: Échec, car aucune trame distante n’est disponible.
  • BlitResult::Failed_NoCamera: Échec car aucune caméra n’est présente.
  • BlitResult::Failed_RemoteFrameTooOld: Échec car l’image distante est trop ancienne (consultez la propriété PlayerContext::BlitRemoteFrameTimeout).

Important

À compter de la version 2.1.0 , il est possible avec un lecteur personnalisé d’utiliser la reprojection de profondeur via la communication à distance holographique.

BlitResult peut également retourner BlitResult::Success_Color_Depth dans les conditions suivantes :

Si ces conditions sont remplies, BlitRemoteFrame blit la profondeur distante dans la mémoire tampon de profondeur locale actuellement liée. Vous pouvez ensuite afficher du contenu local supplémentaire, qui aura une intersection de profondeur avec le contenu rendu à distance. En outre, vous pouvez valider la mémoire tampon de profondeur locale via HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer dans votre lecteur personnalisé pour avoir une reprojection de profondeur pour le contenu rendu local et distant.

Mode de transformation de projection

Un problème, qui se produit lors de l’utilisation de la reprojection de profondeur via la communication à distance holographique, est que le contenu distant peut être rendu avec une transformation de projection différente du contenu local directement rendu par votre application de lecteur personnalisée. Un cas d’usage courant consiste à spécifier différentes valeurs pour les plans proches et lointains (via HolographicCamera::SetNearPlaneDistance et HolographicCamera::SetFarPlaneDistance) côté lecteur et côté distant. Dans ce cas, il n’est pas clair si la transformation de projection côté joueur doit refléter les distances distantes du plan proche/lointain ou les distances locales.

À partir de la version 2.1.0, vous pouvez contrôler le mode de transformation de projection via PlayerContext::ProjectionTransformConfig. Les valeurs prises en charge sont les suivantes :

  • Local - HolographicCameraPose::P rojectionTransform retourne une transformation de projection, qui reflète les distances de plan proche/lointain définies par votre application de lecteur personnalisée sur holographicCamera.
  • Remote - La transformation de projection reflète les distances du plan proche/lointain spécifiées par l’application distante.
  • Merged - Les distances de plan proche/lointain de votre application distante et de votre application de lecteur personnalisée sont fusionnées. Par défaut, cela est effectué en prenant le minimum des distances du plan proche et le maximum des distances du plan lointain. Dans le cas où le côté distant ou local sont inversés, par exemple loin < près, les distances du plan distant proche/lointain sont retournées.

Facultatif : Définir BlitRemoteFrameTimeout

Important

PlayerContext::BlitRemoteFrameTimeout est pris en charge à partir de la version 2.0.9.

La PlayerContext::BlitRemoteFrameTimeout propriété spécifie la durée de réutilisation d’une image distante si aucune nouvelle image distante n’est reçue.

Un cas d’usage courant consiste à activer le délai d’expiration de BlitRemoteFrame pour afficher un écran vide si aucune nouvelle image n’est reçue pendant un certain laps de temps. Lorsqu’elle est activée, le type de retour de la BlitRemoteFrame méthode peut également être utilisé pour basculer vers un contenu de secours rendu localement.

Pour activer le délai d’expiration, définissez la valeur de la propriété sur une durée égale ou supérieure à 100 ms. Pour désactiver le délai d’expiration, définissez la propriété sur zéro durée. Si le délai d’expiration est activé et qu’aucune image distante n’est reçue pendant la durée définie, BlitRemoteFrame échoue et retourne Failed_RemoteFrameTooOld jusqu’à ce qu’une nouvelle image distante soit reçue.

using namespace std::chrono_literals;

// Set the BlitRemoteFrame timeout to 0.5s
m_playerContext.BlitRemoteFrameTimeout(500ms);

Facultatif : obtenir des statistiques sur la dernière trame distante

Pour diagnostiquer les problèmes de performances ou de réseau, les statistiques sur la dernière trame distante peuvent être récupérées via la PlayerContext::LastFrameStatistics propriété . Les statistiques sont mises à jour lors de l’appel à HolographicFrame::P resentUsingCurrentPrediction.

// Get statistics for the last presented frame.
winrt::Microsoft::Holographic::AppRemoting::PlayerFrameStatistics statistics = m_playerContext.LastFrameStatistics();

Pour plus d’informations, consultez la PlayerFrameStatistics documentation dans le Microsoft.Holographic.AppRemoting.idlfichier .

Facultatif : canaux de données personnalisés

Les canaux de données personnalisés peuvent être utilisés pour envoyer des données utilisateur via la connexion à distance déjà établie. Pour plus d’informations, consultez Canaux de données personnalisés.

Facultatif : Over-Rendering

La communication à distance holographique prédit l’emplacement de la tête de l’utilisateur au moment où les images rendues apparaissent sur les écrans. Toutefois, cette prédiction est une approximation. Par conséquent, la fenêtre d’affichage prédite sur l’application distante et la fenêtre d’affichage réelle ultérieure sur l’application joueur peuvent différer. Des écarts plus forts (par exemple, en raison d’un mouvement imprévisible) peuvent provoquer des régions noires aux bordures du frustum visuel. À compter de la version 2.6.0 , vous pouvez utiliser Over-Rendering pour réduire les régions noires et améliorer la qualité visuelle en augmentant artificiellement la fenêtre d’affichage au-delà du frustum d’affichage.

Over-Rendering pouvez être activé via PlayerContext::ConfigureOverRendering.

le OverRenderingConfig spécifie une augmentation de taille fractionnaire à la fenêtre d’affichage réelle, de sorte que la fenêtre d’affichage prédite devient plus grande et moins de coupe se produit. Avec une taille de fenêtre d’affichage accrue, la densité de pixels diminue, de sorte que OverRenderingConfig vous permet également d’augmenter la résolution. Si l’augmentation de la fenêtre d’affichage est égale à la résolution, la densité des pixels reste la même. OverRenderingConfig est défini comme :

struct OverRenderingConfig
{
    float HorizontalViewportIncrease; // The fractional horizontal viewport increase. (e.g. 10% -> 0.1).
    float VerticalViewportIncrease; // The fractional vertical viewport increase. (e.g. 10% -> 0.1).
                
    float HorizontalResolutionIncrease; // The fractional horizontal resolution increase. (e.g. 10% -> 0.1).
    float VerticalResolutionIncrease; // The fractional vertical resolution increase. (e.g. 10% -> 0.1).
};

Facultatif : Synchronisation du système de coordonnées

À compter de la version 2.7.0, la synchronisation du système de coordonnées peut être utilisée pour aligner les données spatiales entre le lecteur et l’application distante. Pour plus d’informations, consultez Vue d’ensemble de la synchronisation du système de coordonnées avec la communication à distance holographique.

Voir aussi