사용자 지정 홀로그램 원격 플레이어 앱 작성Writing a custom Holographic Remoting player app

중요

이 문서에서는 HoloLens 2에 대 한 사용자 지정 플레이어 응용 프로그램을 만드는 방법을 설명 합니다.This document describes the creation of a custom player application for HoloLens 2. HoloLens 2 용으로 작성 된 사용자 지정 플레이어는 HoloLens 1 용으로 작성 된 원격 응용 프로그램과 호환 되지 않습니다.Custom players written for HoloLens 2 are not compatible with remote applications written for HoloLens 1. 이는 두 응용 프로그램이 모두 NuGet 패키지 버전 2.x 를 사용 해야 함을 의미 합니다.This implies that both applications must use NuGet package version 2.x.x.

사용자 지정 Holographic Remoting player 앱을 만들면 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. 이 페이지 및 작업 프로젝트의 모든 코드는 Holographic Remoting 샘플 github 리포지토리에서 찾을 수 있습니다.All code on this page and working projects can be found in the Holographic Remoting samples github repository.

Holographic 원격 플레이어를 사용 하면 앱이 데스크톱 PC 또는 UWP 장치 (예: Xbox One)에서 렌더링 된 콘텐츠를 더 많은 시스템 리소스에 액세스할 수 있는 Holographic 표시할 수 있습니다.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. Holographic Remoting player 앱은 입력 데이터를 Holographic Remoting 원격 응용 프로그램으로 스트리밍하 고 비디오 및 오디오 스트림으로 몰입 형 보기를 다시 받습니다.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. 연결은 표준 Wi-fi를 사용 하 여 수행 됩니다.The connection is made using standard Wi-Fi. 플레이어 앱을 만들려면 NuGet 패키지를 사용 하 여 Holographic 원격을 UWP 앱에 추가 합니다.To create a player app, use a NuGet package to add Holographic Remoting to your UWP app. 그런 다음 연결을 처리 하 고 몰입 형 뷰를 표시 하는 코드를 작성 합니다.Then write code to handle the connection and to display an immersive view.

사전 요구 사항Prerequisites

좋은 출발점은 이미 Windows Mixed Reality API를 대상으로 하는 작동 하는 DirectX 기반 UWP 앱입니다.A good starting point is a working DirectX based UWP app that already targets the Windows Mixed Reality API. 자세한 내용은 DirectX 개발 개요를 참조 하세요.For details see DirectX development overview. 기존 앱이 없고 처음부터 시작 하려면 c + + holographic 프로젝트 템플릿이 좋은 출발점입니다.If you don't have an existing app and want to start from scratch the C++ holographic project template is a good starting point.

중요

Holographic 원격을 사용 하는 모든 앱은 다중 스레드 아파트를 사용 하도록 작성 되어야 합니다.Any app using Holographic Remoting should be authored to use a multi-threaded apartment. 단일 스레드 아파트 를 사용 하는 것은 지원 되지만, 재생 하는 동안 일지 성능이 저하 될 수 있습니다.The use of a single-threaded apartment is supported but will lead to sub-optimal performance and possibly stuttering during playback. C + +/WinRT winrt:: init_apartment 사용 하는 경우 다중 스레드 아파트는 기본값입니다.When using C++/WinRT winrt::init_apartment a multi-threaded apartment is the default.

Holographic 원격 NuGet 패키지 가져오기Get the Holographic Remoting NuGet package

Visual Studio에서 프로젝트에 NuGet 패키지를 추가 하려면 다음 단계를 수행 해야 합니다.The following steps are required to add the NuGet package to a project in Visual Studio.

  1. Visual Studio에서 프로젝트를 엽니다.Open the project in Visual Studio.
  2. 프로젝트 노드를 마우스 오른쪽 단추로 클릭 하 고 NuGet 패키지 관리 ... 를 선택 합니다.Right-click the project node and select Manage NuGet Packages...
  3. 표시 되는 패널에서 찾아보기 를 선택한 다음 "Holographic Remoting"을 검색 합니다.In the panel that appears, select Browse and then search for "Holographic Remoting".
  4. Holographic 를 선택 하 고 최신 2.x 버전을 선택 하 고 설치 를 선택 합니다.Select Microsoft.Holographic.Remoting, ensure to pick the latest 2.x.x version and select Install.
  5. 미리 보기 대화 상자가 표시 되 면 확인 을 선택 합니다.If the Preview dialog appears, select OK.
  6. 사용권 계약 대화 상자가 나타나면 동의 함을 선택 합니다.Select I Accept when the license agreement dialog appears.

중요

build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idlNuGet 패키지 내에는 Holographic Remoting에서 노출 하는 API에 대 한 자세한 설명서가 포함 되어 있습니다.The build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl inside the NuGet package contains detailed documentation for the API exposed by Holographic Remoting.

응용 프로그램의 appxmanifest.xml을 수정 합니다.Modify the Package.appxmanifest of the application

응용 프로그램이 NuGet 패키지에 의해 추가 된 Microsoft.Holographic.AppRemoting.dll을 인식 하도록 하려면 프로젝트에서 다음 단계를 수행 해야 합니다.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. 솔루션 탐색기에서 appxmanifest.xml 파일을 마우스 오른쪽 단추로 클릭 하 고 연결 프로그램 ...을 선택 합니다.In the Solution Explorer right-click on the Package.appxmanifest file and select Open With...
  2. XML (텍스트) 편집기 를 선택 하 고 확인 을 선택 합니다.Select XML (Text) Editor and select OK
  3. 파일에 다음 줄을 추가 하 고 저장 합니다.Add 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>

플레이어 컨텍스트 만들기Create the player context

첫 번째 단계로 응용 프로그램은 플레이어 컨텍스트를 만들어야 합니다.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();

경고

Holographic Remoting은 원격 특정 런타임을 사용 하 여 Windows의 일부인 Windows Mixed Reality 런타임을 대체 하는 방식으로 작동 합니다.Holographic Remoting works by replacing the Windows Mixed Reality runtime which is part of Windows with a remoting specific runtime. 플레이어 컨텍스트를 만드는 동안이 작업을 수행 합니다.This is done during the creation of the player context. 이러한 이유로 플레이어 컨텍스트를 만들기 전에 Windows Mixed Reality API를 호출 하면 예기치 않은 동작이 발생할 수 있습니다.For that reason any call on any Windows Mixed Reality API before creating the player context can result in unexpected behavior. 권장 되는 방법은 혼합 현실 API와의 상호 작용 전에 가능한 한 빨리 플레이어 컨텍스트를 만드는 것입니다.The recommended approach is to create the player context as early as possible before interaction with any Mixed Reality API. 이후에 만들어지거나 검색 된 개체를 사용 하 여를 호출 하기 전에 Windows Mixed Reality API를 통해 만들어지거나 검색 된 개체를 혼합 하지 마세요 PlayerContext::Create .Never mix objects created or retrieved through any Windows Mixed Reality API before the call to PlayerContext::Create with objects created or retrieved afterwards.

그런 다음 HolographicSpace. CreateForCoreWindow를 호출 하 여 HolographicSpace를 만들 수 있습니다.Next the HolographicSpace can be created, by calling HolographicSpace.CreateForCoreWindow.

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

원격 앱에 연결Connect to the remote app

플레이어 앱이 콘텐츠를 렌더링할 준비가 되 면 원격 앱에 대 한 연결을 설정할 수 있습니다.Once the player app is ready for rendering content a connection to the remote app can be established.

다음 방법 중 하나로 연결을 설정할 수 있습니다.The connection can be established in one of the following ways:

  1. HoloLens 2에서 실행 중인 플레이어 앱은 원격 앱에 연결 됩니다.The player app running on HoloLens 2 connects to the remote app.
  2. 원격 앱은 HoloLens 2에서 실행 중인 플레이어 앱에 연결 합니다.The remote app connects to the player app running on HoloLens 2.

플레이어 앱에서 원격 앱으로 연결 하려면 Connect 호스트 이름 및 포트를 지정 하는 플레이어 컨텍스트의 메서드를 호출 합니다.To connect from the player app to the remote app call the Connect method on the player context specifying the hostname and port. 기본 포트는 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()
}

중요

모든 c + +/WinRT API와 마찬가지로 처리 해야 하 Connect 는 WinRT:: hresult_error을 throw 할 수 있습니다.As with any C++/WinRT API Connect might throw an winrt::hresult_error which needs to be handled.

플레이어 앱에서 들어오는 연결을 수신 하는 작업은 메서드를 호출 하 여 수행할 수 있습니다 Listen .Listening for incoming connections on the player app can be done by calling the Listen method. 이 호출 중에 핸드셰이크 포트와 전송 포트를 모두 지정할 수 있습니다.Both the handshake port and transport port can be specified during this call. 핸드셰이크 포트는 초기 핸드셰이크에 사용 됩니다.The handshake port is used for the initial handshake. 그러면 전송 포트를 통해 데이터가 전송 됩니다.The data is then sent over the transport port. 기본적으로 포트 번호 82658266 이 사용 됩니다.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()
}

PlayerContext 연결 상태를 모니터링 하는 세 개의 이벤트를 노출 합니다.The PlayerContext exposes three events to monitor the state of the connection

  1. OnConnected: 원격 앱에 대 한 연결이 성공적으로 설정 되 면 트리거됩니다.OnConnected: Triggered when a connection to the remote app has been successfully established.
m_onConnectedEventToken = m_playerContext.OnConnected([]() 
{
    // Handle connection successfully established
});
  1. OnDisconnected: 설정 된 연결이 종료 되거나 연결을 설정할 수 없는 경우 트리거됩니다.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.
    }
}

참고

가능한 ConnectionFailureReason 값은 파일에 설명 되어 있습니다 Microsoft.Holographic.AppRemoting.idl .Possible ConnectionFailureReason values are documented in the Microsoft.Holographic.AppRemoting.idl file.

  1. OnListening: 들어오는 연결에 대 한 수신 대기를 시작 합니다.OnListening: When listening for incoming connections starts.
m_onListeningEventToken = m_playerContext.OnListening([]()
{
    // Handle start listening for incoming connections
});

또한 플레이어 컨텍스트의 속성을 사용 하 여 연결 상태를 쿼리할 수 있습니다 ConnectionState .Additionally the connection state can be queried using the ConnectionState property on the player context.

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

원격으로 렌더링 된 프레임을 표시 합니다.Display the remotely rendered frame

원격으로 렌더링 된 콘텐츠를 표시 하려면 PlayerContext::BlitRemoteFrame HolographicFrame를 렌더링 하는 동안를 호출 합니다.To display the remotely rendered content, call PlayerContext::BlitRemoteFrame while rendering a HolographicFrame.

BlitRemoteFrame 현재 HolographicFrame에 대 한 백 버퍼가 렌더링 대상으로 바인딩되어야 합니다.BlitRemoteFrame requires that the back buffer for the current HolographicFrame is bound as render target. 백 버퍼는 Direct3D11BackBuffer 속성을 통해 HolographicCameraRenderingParameters 에서 받을 수 있습니다.The back buffer can be received from the HolographicCameraRenderingParameters via the Direct3D11BackBuffer property.

호출 되 면 BlitRemoteFrame 원격 응용 프로그램에서 수신 된 최신 프레임을 HolographicFrame의 백 버퍼에 복사 합니다.When called, BlitRemoteFrame copies the latest received frame from the remote application into the BackBuffer of the HolographicFrame. 원격 응용 프로그램에서 원격 프레임을 렌더링 하는 동안 포커스 지점을 지정 하는 경우에도 포커스 지점 집합이 설정 됩니다.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();

참고

PlayerContext::BlitRemoteFrame 현재 프레임의 포커스 지점을 덮어쓸 수 있습니다.PlayerContext::BlitRemoteFrame potentially overwrites the focus point for the current frame.

성공 하면를 BlitRemoteFrame 반환 BlitResult::Success_Color 합니다.On success, BlitRemoteFrame returns BlitResult::Success_Color. 그렇지 않으면 실패 원인을 반환 합니다.Otherwise it returns the failure reason:

  • BlitResult::Failed_NoRemoteFrameAvailable: 사용할 수 있는 원격 프레임이 없기 때문에 실패 했습니다.BlitResult::Failed_NoRemoteFrameAvailable: Failed because no remote frame is available.
  • BlitResult::Failed_NoCamera: 카메라가 없어 실패 했습니다.BlitResult::Failed_NoCamera: Failed because no camera present.
  • BlitResult::Failed_RemoteFrameTooOld: 원격 프레임이 너무 오래 되어 실패 했습니다 (PlayerContext:: BlitRemoteFrameTimeout 속성 참조).BlitResult::Failed_RemoteFrameTooOld: Failed because remote frame is too old (see PlayerContext::BlitRemoteFrameTimeout property).

중요

2.1.0 버전부터 사용자 지정 플레이어를 사용 하 여 Holographic 원격을 통해 깊이 재 프로젝션을 사용할 수 있습니다.Starting with version 2.1.0 it is possible with a custom player to use depth reprojection via Holographic Remoting.

BlitResult``````BlitResult::Success_Color_Depth는 다음과 같은 경우에도 반환할 수 있습니다.BlitResult can also return BlitResult::Success_Color_Depth under the following conditions:

이러한 조건이 충족 되 면 BlitRemoteFrame 원격 깊이가 현재 바인딩된 로컬 깊이 버퍼로 array.blit 됩니다.If these conditions are met BlitRemoteFrame will blit the remote depth into the currently bound local depth buffer. 그러면 원격 렌더링 된 콘텐츠와 깊이 교차 하는 추가 로컬 콘텐츠를 렌더링할 수 있습니다.You can then render additional local content, which will have depth intersection with the remote rendered content. 또한 사용자 지정 플레이어에서 HolographicCameraRenderingParameters. CommitDirect3D11DepthBuffer 를 통해 로컬 수준 버퍼를 커밋하여 원격 및 로컬 렌더링 된 콘텐츠에 대해 깊이 있게 프로젝션 할 수 있습니다.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. 자세한 내용은 깊이 Reprojection 을 참조 하세요.See Depth Reprojection for details.

프로젝션 변환 모드Projection Transform Mode

한 가지 문제는 Holographic Remoting을 통해 깊이 다시 프로젝션을 사용 하는 경우 사용자 지정 플레이어 앱에서 직접 렌더링 하는 로컬 콘텐츠와 다른 프로젝션 변환을 사용 하 여 원격 콘텐츠를 렌더링할 수 있는 것입니다.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. 일반적인 사용 사례는 선수 및 원격 측면에서 근거리 및 far 평면 ( HolographicCamera:: SetNearPlaneDistanceHolographicCamera:: SetFarPlaneDistance를 통해)에 대해 서로 다른 값을 지정 하는 것입니다.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 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.

버전 2.1.0 부터를 통해 프로젝션 변환 모드를 제어할 수 있습니다 PlayerContext::ProjectionTransformConfig .Starting with version 2.1.0 you can control the projection transform mode via PlayerContext::ProjectionTransformConfig. 지원되는 값은 다음과 같습니다.Supported values are:

  • Local - HolographicCameraPose::P rojectiontransform 는 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 -프로젝션 변환은 원격 앱에서 지정 된 근거리/원거리 평면 거리를 반영 합니다.Remote - Projection transform reflects the near/far plane distances specified by the remote app.
  • Merged -원격 앱 및 사용자 지정 플레이어 앱의 근거리/Far 비행기 거리가 병합 됩니다.Merged - Near/Far plane distances from your remote app and your custom player app are merged. 기본적으로이 작업은 근거리 평면 거리의 최소 및 최대 평면 거리의 최대값을 차지 하 여 수행 됩니다.By default this is done by taking the minimum of the near plane distances and the maximum of the far plane distances. 원격 또는 로컬 쪽이 반전 된 경우 (근처 < 멀리 떨어져 있는 경우 멀리 떨어져 있는 근거리/원거리 비행기 거리가 대칭 이동 합니다.In case either the remote or local side are inverted, say far < near, the remote near/far plane distances are flipped.

선택 사항: BlitRemoteFrameTimeout 설정 Optional: Set BlitRemoteFrameTimeout

중요

PlayerContext::BlitRemoteFrameTimeout 는 버전 2.0.9부터 지원 됩니다.PlayerContext::BlitRemoteFrameTimeout is supported starting with version 2.0.9.

PlayerContext::BlitRemoteFrameTimeout속성은 새 원격 프레임을 받지 못한 경우 원격 프레임을 다시 사용 하는 시간을 지정 합니다.The PlayerContext::BlitRemoteFrameTimeout property specifies the amount of time a remote frame is reused if no new remote frame is received.

일반적인 사용 사례는 특정 시간 동안 새 프레임을 받지 못한 경우 BlitRemoteFrame 시간 제한을 사용 하 여 빈 화면을 표시 하는 것입니다.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. 사용 하도록 설정 하면 메서드의 반환 형식을 BlitRemoteFrame 사용 하 여 로컬로 렌더링 된 대체 콘텐츠로 전환할 수도 있습니다.When enabled the return type of the BlitRemoteFrame method can also be used to switch to a locally rendered fallback content.

시간 제한을 사용 하도록 설정 하려면 속성 값을 100 밀리초 보다 크거나 같은 기간으로 설정 합니다.To enable the timeout, set the property value to a duration equal or greater than 100 ms. 시간 제한을 사용 하지 않도록 설정 하려면 속성을 0 duration으로 설정 합니다.To disable the timeout, set the property to zero duration. 제한 시간을 설정 하 고 설정 된 기간 동안 원격 프레임을 받지 못한 경우에는 BlitRemoteFrame이 실패 하 고 Failed_RemoteFrameTooOld 새 원격 프레임을 받을 때까지 반환 됩니다.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);

선택 사항: 마지막 원격 프레임에 대 한 통계 가져오기Optional: Get statistics about the last remote frame

성능 또는 네트워크 문제를 진단 하려면 속성을 통해 마지막 원격 프레임에 대 한 통계를 검색할 수 있습니다 PlayerContext::LastFrameStatistics .To diagnose performance or network issues, statistics about the last remote frame can be retrieved via the PlayerContext::LastFrameStatistics property. 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();

자세한 내용은 PlayerFrameStatistics 파일의 설명서를 참조 하십시오 Microsoft.Holographic.AppRemoting.idl .For more information, see the PlayerFrameStatistics documentation in the Microsoft.Holographic.AppRemoting.idl file.

선택 사항: 사용자 지정 데이터 채널Optional: Custom data channels

사용자 지정 데이터 채널은 이미 설정 된 원격 연결을 통해 사용자 데이터를 전송 하는 데 사용할 수 있습니다.Custom data channels can be used to send user data over the already established remoting connection. 자세한 내용은 사용자 지정 데이터 채널 을 참조 하세요.See custom data channels for more information.

참고 항목See Also