Scrivere un'app lettore Holographic Remoting personalizzataWriting a custom Holographic Remoting player app

Importante

Questo documento descrive la creazione di un'applicazione lettore personalizzata per HoloLens 2.This document describes the creation of a custom player application for HoloLens 2. I lettori personalizzati scritti per HoloLens 2 non sono compatibili con le applicazioni remote scritte per HoloLens 1.Custom players written for HoloLens 2 are not compatible with remote applications written for HoloLens 1. Questo implica che entrambe le applicazioni devono usare il pacchetto NuGet versione 2. x. x.This implies that both applications must use NuGet package version 2.x.x.

Grazie alla creazione di un'app lettore di comunicazione remota olografica personalizzata, è possibile creare un'applicazione personalizzata in grado di visualizzare visualizzazioni immersive da in un computer remoto nel HoloLens 2.By creating a custom Holographic Remoting player app, you can create a custom application capable of displaying immersive views from on a remote machine on your HoloLens 2. Tutto il codice in questa pagina e i progetti di lavoro sono disponibili nel repository GitHub degli esempi di comunicazione remota olografica.All code on this page and working projects can be found in the Holographic Remoting samples github repository.

Un lettore di comunicazione remota olografica consente all'app di visualizzare il rendering di contenuto olografico in un computer desktop o in un dispositivo UWP come Xbox One con accesso a più risorse di sistema.A Holographic Remoting player lets your app display holographic content rendered on a desktop PC or UWP device like the Xbox One with access to more system resources. Un'app lettore di comunicazione remota olografica trasmette i dati di input a un'applicazione remota olografica remota e riceve una visualizzazione immersiva come flusso video e audio.A Holographic Remoting player app streams input data to a Holographic Remoting remote application and receives back an immersive view as video and audio stream. La connessione viene eseguita usando il Wi-Fi standard.The connection is made using standard Wi-Fi. Per creare un'app per giocatori, usare un pacchetto NuGet per aggiungere la comunicazione remota olografica all'app UWP.To create a player app, use a NuGet package to add Holographic Remoting to your UWP app. Scrivere quindi il codice per gestire la connessione e visualizzare una visualizzazione immersiva.Then write code to handle the connection and to display an immersive view.

PrerequisitiPrerequisites

Un punto di partenza valido è un'app UWP basata su DirectX funzionante che ha già come destinazione l'API di realtà mista di Windows.A good starting point is a working DirectX based UWP app that already targets the Windows Mixed Reality API. Per informazioni dettagliate, vedere Cenni preliminari sullo sviluppo DirectX.For details see DirectX development overview. Se non si dispone di un'app esistente e si desidera iniziare da zero, il modello di progetto olografico C++ è un punto di partenza valido.If you don't have an existing app and want to start from scratch the C++ holographic project template is a good starting point.

Importante

Qualsiasi app che usa la comunicazione remota olografica deve essere creata per usare un Apartmentmultithread.Any app using Holographic Remoting should be authored to use a multi-threaded apartment. L'uso di un Apartment a thread singolo è supportato, ma comporta prestazioni ottimali e possibilmente balbettanti durante la riproduzione.The use of a single-threaded apartment is supported but will lead to sub-optimal performance and possibly stuttering during playback. Quando si usa C++/WinRT WinRT:: init_apartment un apartment multithread è il valore predefinito.When using C++/WinRT winrt::init_apartment a multi-threaded apartment is the default.

Ottenere il pacchetto NuGet per la comunicazione remota olograficaGet the Holographic Remoting NuGet package

I passaggi seguenti sono necessari per aggiungere il pacchetto NuGet a un progetto in Visual Studio.The following steps are required to add the NuGet package to a project in Visual Studio.

  1. Aprire il progetto in Visual Studio.Open the project in Visual Studio.
  2. Fare clic con il pulsante destro del mouse sul nodo del progetto e scegliere Gestisci pacchetti NuGet...Right-click the project node and select Manage NuGet Packages...
  3. Nel pannello visualizzato selezionare Sfoglia e quindi cercare "comunicazione remota olografica".In the panel that appears, select Browse and then search for "Holographic Remoting".
  4. Selezionare Microsoft. olografic. Remoting, assicurarsi di selezionare la versione 2. x. x più recente e selezionare Installa.Select Microsoft.Holographic.Remoting, ensure to pick the latest 2.x.x version and select Install.
  5. Se viene visualizzata la finestra di dialogo Anteprima , fare clic su OK.If the Preview dialog appears, select OK.
  6. Selezionare Accetto quando viene visualizzata la finestra di dialogo contratto di licenza.Select I Accept when the license agreement dialog appears.

Importante

Il contenuto del build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl pacchetto NuGet contiene la documentazione dettagliata per l'API esposta dalla comunicazione remota olografica.The build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl inside the NuGet package contains detailed documentation for the API exposed by Holographic Remoting.

Modificare il pacchetto. appxmanifest dell'applicazioneModify the Package.appxmanifest of the application

Per fare in modo che l'applicazione sia in grado di riconoscere il Microsoft.Holographic.AppRemoting.dll aggiunto dal pacchetto NuGet, è necessario eseguire i passaggi seguenti per il progetto:To make the application aware of the Microsoft.Holographic.AppRemoting.dll added by the NuGet package, the following steps need to be taken on the project:

  1. Nella Esplora soluzioni fare clic con il pulsante destro del mouse sul file Package. appxmanifest e scegliere Apri con...In the Solution Explorer right-click on the Package.appxmanifest file and select Open With...
  2. Seleziona editor XML (testo) e seleziona OKSelect XML (Text) Editor and select OK
  3. Aggiungere le righe seguenti al file e salvareAdd the following lines to the file and save
  </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>

Creare il contesto del lettoreCreate the player context

Come primo passaggio, l'applicazione deve creare un contesto del lettore.As a first step the application should create a player context.

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

Avviso

La comunicazione remota olografica funziona sostituendo il runtime della realtà mista di Windows che fa parte di Windows con un runtime specifico di .NET Remoting.Holographic Remoting works by replacing the Windows Mixed Reality runtime which is part of Windows with a remoting specific runtime. Questa operazione viene eseguita durante la creazione del contesto del lettore.This is done during the creation of the player context. Per questo motivo qualsiasi chiamata a qualsiasi API di realtà mista di Windows prima di creare il contesto del lettore può causare un comportamento imprevisto.For that reason any call on any Windows Mixed Reality API before creating the player context can result in unexpected behavior. L'approccio consigliato consiste nel creare il contesto del lettore il prima possibile prima di interagire con qualsiasi API di realtà mista.The recommended approach is to create the player context as early as possible before interaction with any Mixed Reality API. Non combinare mai oggetti creati o recuperati tramite qualsiasi API di realtà mista di Windows prima della chiamata a PlayerContext::Create con gli oggetti creati o recuperati in seguito.Never mix objects created or retrieved through any Windows Mixed Reality API before the call to PlayerContext::Create with objects created or retrieved afterwards.

Successivamente, è possibile creare HolographicSpace, chiamando HolographicSpace. CreateForCoreWindow.Next the HolographicSpace can be created, by calling HolographicSpace.CreateForCoreWindow.

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

Connettersi all'app remotaConnect to the remote app

Quando l'App Player è pronta per il rendering del contenuto, è possibile stabilire una connessione all'app remota.Once the player app is ready for rendering content a connection to the remote app can be established.

La connessione può essere stabilita in uno dei modi seguenti:The connection can be established in one of the following ways:

  1. L'App Player in esecuzione su HoloLens 2 si connette all'app remota.The player app running on HoloLens 2 connects to the remote app.
  2. L'app remota si connette all'App Player in esecuzione su HoloLens 2.The remote app connects to the player app running on HoloLens 2.

Per connettersi dall'App Player all'app remota, chiamare il Connect metodo sul contesto del lettore specificando il nome host e la porta.To connect from the player app to the remote app call the Connect method on the player context specifying the hostname and port. La porta predefinita è 8265.The default port is 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()
}

Importante

Come per qualsiasi API C++/WinRT, Connect può generare un WinRT:: hresult_error che deve essere gestito.As with any C++/WinRT API Connect might throw an winrt::hresult_error which needs to be handled.

L'ascolto delle connessioni in ingresso nell'App Player può essere eseguito chiamando il Listen metodo.Listening for incoming connections on the player app can be done by calling the Listen method. Durante questa chiamata è possibile specificare sia la porta di handshake che la porta di trasporto.Both the handshake port and transport port can be specified during this call. La porta di handshake viene utilizzata per l'handshake iniziale.The handshake port is used for the initial handshake. I dati vengono quindi inviati tramite la porta di trasporto.The data is then sent over the transport port. Per impostazione predefinita vengono usati il numero di porta 8265 e 8266 .By default port number 8265 and 8266 are used.

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

PlayerContextEspone tre eventi per monitorare lo stato della connessione.The PlayerContext exposes three events to monitor the state of the connection

  1. OnConnected: attivato quando una connessione all'app remota è stata stabilita correttamente.OnConnected: Triggered when a connection to the remote app has been successfully established.
m_onConnectedEventToken = m_playerContext.OnConnected([]() 
{
    // Handle connection successfully established
});
  1. Disconnected: attivato se una connessione stabilita viene terminata o non è stato possibile stabilire una connessione.OnDisconnected: Triggered if an established connection is terminated or a connection couldn't be established.
m_onDisconnectedEventToken = m_playerContext.OnDisconnected([](ConnectionFailureReason failureReason)
{
    switch (failureReason)
    {
        // Handle connection failed or terminated.
        // See ConnectionFailureReason for possible reasons.
    }
}

Nota

I ConnectionFailureReason valori possibili sono documentati nel Microsoft.Holographic.AppRemoting.idl file.Possible ConnectionFailureReason values are documented in the Microsoft.Holographic.AppRemoting.idl file.

  1. Onlistening: durante l'ascolto delle connessioni in ingresso viene avviato.OnListening: When listening for incoming connections starts.
m_onListeningEventToken = m_playerContext.OnListening([]()
{
    // Handle start listening for incoming connections
});

Inoltre, è possibile eseguire query sullo stato della connessione utilizzando la ConnectionState proprietà nel contesto del lettore.Additionally the connection state can be queried using the ConnectionState property on the player context.

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

Visualizzare il frame sottoposto a rendering remotoDisplay the remotely rendered frame

Per visualizzare il contenuto di cui è stato eseguito il rendering in remoto, chiamare PlayerContext::BlitRemoteFrame durante il rendering di un HolographicFrame.To display the remotely rendered content, call PlayerContext::BlitRemoteFrame while rendering a HolographicFrame.

BlitRemoteFrame richiede che il buffer nascosto per la HolographicFrame corrente sia associato come destinazione di rendering.BlitRemoteFrame requires that the back buffer for the current HolographicFrame is bound as render target. Il buffer nascosto può essere ricevuto da HolographicCameraRenderingParameters tramite la proprietà Direct3D11BackBuffer .The back buffer can be received from the HolographicCameraRenderingParameters via the Direct3D11BackBuffer property.

Quando viene chiamato, BlitRemoteFrame copia l'ultimo frame ricevuto dall'applicazione remota nel buffer di HolographicFrame.When called, BlitRemoteFrame copies the latest received frame from the remote application into the BackBuffer of the HolographicFrame. Inoltre, il set di punti di interesse è impostato, se l'applicazione remota ha specificato un punto di attivazione durante il rendering del frame remoto.Additionally the focus point set is set, if the remote application has specified a focus point during the rendering of the remote frame.

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

Nota

PlayerContext::BlitRemoteFrame potenzialmente sovrascrive il punto di messa a fuoco per il frame corrente.PlayerContext::BlitRemoteFrame potentially overwrites the focus point for the current frame.

Se l'operazione riesce, BlitRemoteFrame restituisce BlitResult::Success_Color .On success, BlitRemoteFrame returns BlitResult::Success_Color. In caso contrario, restituisce il motivo dell'errore:Otherwise it returns the failure reason:

  • BlitResult::Failed_NoRemoteFrameAvailable: Operazione non riuscita perché non è disponibile un frame remoto.BlitResult::Failed_NoRemoteFrameAvailable: Failed because no remote frame is available.
  • BlitResult::Failed_NoCamera: Operazione non riuscita perché non è presente alcuna fotocamera.BlitResult::Failed_NoCamera: Failed because no camera present.
  • BlitResult::Failed_RemoteFrameTooOld: Non riuscito perché il frame remoto è troppo vecchio (vedere la proprietà PlayerContext:: BlitRemoteFrameTimeout).BlitResult::Failed_RemoteFrameTooOld: Failed because remote frame is too old (see PlayerContext::BlitRemoteFrameTimeout property).

Importante

A partire dalla versione 2.1.0 è possibile usare un lettore personalizzato per usare la riproiezione di profondità tramite la comunicazione remota olografica.Starting with version 2.1.0 it is possible with a custom player to use depth reprojection via Holographic Remoting.

BlitResult può restituire anche BlitResult::Success_Color_Depth nelle condizioni seguenti:BlitResult can also return BlitResult::Success_Color_Depth under the following conditions:

Se queste condizioni vengono soddisfatte BlitRemoteFrame , blit la profondità remota nel buffer di profondità locale attualmente associato.If these conditions are met BlitRemoteFrame will blit the remote depth into the currently bound local depth buffer. È quindi possibile eseguire il rendering di contenuto locale aggiuntivo, che avrà una profondità di intersezione con il contenuto di cui è stato eseguito il rendering remoto.You can then render additional local content, which will have depth intersection with the remote rendered content. Inoltre, è possibile eseguire il commit del buffer di profondità locale tramite HolographicCameraRenderingParameters. CommitDirect3D11DepthBuffer nel lettore personalizzato per ottenere una riproiezione della profondità per il contenuto remoto e locale di cui è stato eseguito il rendering.Additionally you can commit the local depth buffer via HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer in your custom player to have depth reprojection for remote and local rendered content. Per informazioni dettagliate, vedere riproiezione approfondita .See Depth Reprojection for details.

Modalità di trasformazione proiezioneProjection Transform Mode

Un problema che emerge quando si usa la riproiezione di profondità tramite la comunicazione remota olografica è che il contenuto remoto può essere sottoposto a rendering con una trasformazione di proiezione diversa rispetto al contenuto locale di cui è stato eseguito il rendering direttamente dall'App Player personalizzata.One problem, which surfaces when using depth reprojection via Holographic Remoting is that the remote content can be rendered with a different projection transform than local content directly rendered by your custom player app. Un caso d'uso comune è quello di specificare valori diversi per il piano near e lontano (tramite HolographicCamera:: SetNearPlaneDistance e HolographicCamera:: SetFarPlaneDistance) sul lato Player e sul lato remoto.A common use-case is to specify different values for near and far plane (via HolographicCamera::SetNearPlaneDistance and HolographicCamera::SetFarPlaneDistance) on the player side and the remote side. In questo caso, non è chiaro se la trasformazione della proiezione sul lato Player deve riflettere le distanze del piano remoto vicino/lontano o quelle locali.In this case, it's not clear if the projection transform on the player side should reflect the remote near/far plane distances or the local ones.

A partire dalla versione 2.1.0 è possibile controllare la modalità di trasformazione della proiezione tramite PlayerContext::ProjectionTransformConfig .Starting with version 2.1.0 you can control the projection transform mode via PlayerContext::ProjectionTransformConfig. I valori supportati sono:Supported values are:

  • Local - HolographicCameraPose::P rojectiontransform restituisce una trasformazione di proiezione, che riflette le distanze del piano vicino/lontano impostate dall'App Player personalizzata in HolographicCamera.Local - HolographicCameraPose::ProjectionTransform returns a projection transform, which reflects the near/far plane distances set by your custom player app on the HolographicCamera.
  • Remote -La trasformazione della proiezione riflette le distanze del piano vicino/lontano specificate dall'app remota.Remote - Projection transform reflects the near/far plane distances specified by the remote app.
  • Merged -Le distanze del piano vicino/estremo dall'app remota e l'app per giocatori personalizzata sono unite.Merged - Near/Far plane distances from your remote app and your custom player app are merged. Per impostazione predefinita, questa operazione viene eseguita impostando il valore minimo delle distanze vicino al piano e il valore massimo delle distanze del piano lontano.By default this is done by taking the minimum of the near plane distances and the maximum of the far plane distances. Nel caso in cui il lato remoto o locale sia invertito, ad esempio lontano < vicino, le distanze del piano remoto vicino/lontano vengono capovolte.In case either the remote or local side are inverted, say far < near, the remote near/far plane distances are flipped.

Facoltativo: set BlitRemoteFrameTimeout Optional: Set BlitRemoteFrameTimeout

Importante

PlayerContext::BlitRemoteFrameTimeout è supportato a partire dalla versione 2.0.9.PlayerContext::BlitRemoteFrameTimeout is supported starting with version 2.0.9.

La PlayerContext::BlitRemoteFrameTimeout proprietà specifica l'intervallo di tempo in cui un frame remoto viene riutilizzato se non viene ricevuto alcun nuovo frame remoto.The PlayerContext::BlitRemoteFrameTimeout property specifies the amount of time a remote frame is reused if no new remote frame is received.

Un caso d'uso comune è quello di abilitare il timeout BlitRemoteFrame per visualizzare una schermata vuota se non vengono ricevuti nuovi frame per un determinato periodo di tempo.A common use-case is to enable the BlitRemoteFrame timeout to display a blank screen if no new frames are received for a certain amount of time. Quando è abilitata BlitRemoteFrame , è possibile usare il tipo restituito del metodo anche per passare a un contenuto di fallback sottoposto a rendering in locale.When enabled the return type of the BlitRemoteFrame method can also be used to switch to a locally rendered fallback content.

Per abilitare il timeout, impostare il valore della proprietà su una durata uguale o maggiore di 100 ms.To enable the timeout, set the property value to a duration equal or greater than 100 ms. Per disabilitare il timeout, impostare la proprietà su zero Duration.To disable the timeout, set the property to zero duration. Se il timeout è abilitato e non viene ricevuto un frame remoto per la durata del set, BlitRemoteFrame avrà esito negativo e restituirà Failed_RemoteFrameTooOld un risultato fino a quando non viene ricevuto un nuovo frame remoto.If the timeout is enabled and no remote frame is received for the set duration, BlitRemoteFrame will fail and return Failed_RemoteFrameTooOld until a new remote frame is received.

using namespace std::chrono_literals;

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

Facoltativo: ottenere le statistiche sull'ultimo frame remotoOptional: Get statistics about the last remote frame

Per diagnosticare problemi di prestazioni o di rete, è possibile recuperare le statistiche sull'ultimo frame remoto tramite la PlayerContext::LastFrameStatistics Proprietà.To diagnose performance or network issues, statistics about the last remote frame can be retrieved via the PlayerContext::LastFrameStatistics property. Le statistiche vengono aggiornate durante la chiamata a HolographicFrame::P resentusingcurrentprediction.Statistics are updated during the call to HolographicFrame::PresentUsingCurrentPrediction.

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

Per ulteriori informazioni, vedere la PlayerFrameStatistics documentazione nel Microsoft.Holographic.AppRemoting.idl file.For more information, see the PlayerFrameStatistics documentation in the Microsoft.Holographic.AppRemoting.idl file.

Facoltativo: canali di dati personalizzatiOptional: Custom data channels

I canali di dati personalizzati possono essere utilizzati per inviare dati utente tramite la connessione remota già stabilita.Custom data channels can be used to send user data over the already established remoting connection. Per ulteriori informazioni, vedere canali di dati personalizzati .See custom data channels for more information.

Vedere ancheSee Also