Escritura de una aplicación remota de comunicación remota holográfica mediante la API de OpenXR
Si no está familiarizado con la comunicación remota holográfica, es posible que desee leer nuestra información general.
Importante
En este documento se describe la creación de una aplicación remota para auriculares HoloLens 2 y Windows Mixed Reality mediante la API de OpenXR. Las aplicaciones remotas para HoloLens (1.ª generación) deben usar la versión 1.x.x del paquete NuGet. Esto implica que las aplicaciones remotas escritas para HoloLens 2 no son compatibles con HoloLens 1 y viceversa. La documentación de HoloLens 1 se puede encontrar aquí.
Las aplicaciones de comunicación remota holográfica pueden transmitir contenido representado de forma remota a HoloLens 2 y Windows Mixed Reality cascos envolventes. También puede acceder a más recursos del sistema e integrar vistas inmersivas remotas en el software de pc de escritorio existente. Una aplicación remota recibe un flujo de datos de entrada de HoloLens 2, representa el contenido en una vista envolvente virtual y transmite los fotogramas de contenido a HoloLens 2. La conexión se realiza mediante Wi-Fi estándar. La comunicación remota holográfica se agrega a una aplicación de escritorio o UWP a través de un paquete NuGet. Se requiere código adicional que controla la conexión y se representa en una vista inmersiva. Una conexión remota típica tendrá tan solo 50 ms de latencia. La aplicación del reproductor puede informar de la latencia en tiempo real.
Todo el código de esta página y los proyectos de trabajo se pueden encontrar en el repositorio de github de ejemplos de comunicación remota holográfica.
Requisitos previos
Un buen punto de partida es una aplicación de escritorio o UWP basada en OpenXR en funcionamiento. Para obtener más información, consulte Introducción a OpenXR.
Importante
Cualquier aplicación que use la comunicación remota holográfica debe crearse para usar un apartamento multiproceso. El uso de un apartamento de un solo subproceso es compatible, pero dará lugar a un rendimiento sub-óptimo y posiblemente tartamudez durante la reproducción. Cuando se usa C++/WinRT winrt::init_apartment un apartamento multiproceso es el valor predeterminado.
Obtención del paquete NuGet de comunicación remota holográfica
Los pasos siguientes son necesarios para agregar el paquete NuGet a un proyecto de Visual Studio.
- Abra el proyecto en Visual Studio.
- Haga clic con el botón derecho en el nodo del proyecto y seleccione Administrar paquetes NuGet...
- En el panel que aparece, seleccione Examinar y busque "Comunicación remota holográfica".
- Seleccione Microsoft.Holographic.Remoting.OpenXr, asegúrese de que está seleccionada la versión 2.x.x más reciente y, a continuación, seleccione Instalar.
- Si aparece el cuadro de diálogo Vista previa , seleccione Aceptar.
- Seleccione Acepto cuando aparezca el cuadro de diálogo contrato de licencia.
- Repita los pasos del 3 al 6 para los siguientes paquetes NuGet: OpenXR.Headers, OpenXR.Loader
Nota:
La versión 1.x.x del paquete NuGet sigue estando disponible para los desarrolladores que quieran tener como destino HoloLens 1. Para obtener más información, consulte Agregar comunicación remota holográfica (HoloLens (1.ª generación)).
Seleccione el entorno de ejecución de OpenXR de comunicación remota holográfica.
El primer paso que debe realizar en la aplicación remota es seleccionar el entorno de ejecución de OpenXR holographic Remoting, que forma parte del paquete NuGet Microsoft.Holographic.Remoting.OpenXr. Para ello, establezca la variable de XR_RUNTIME_JSON
entorno en la ruta de acceso del archivo RemotingXR.json dentro de la aplicación. El cargador de OpenXR usa esta variable de entorno para no usar el entorno de ejecución de OpenXR predeterminado del sistema, sino para redirigirlo al entorno de ejecución de OpenXR de comunicación remota holográfica. Cuando se usa el paquete NuGet Microsoft.Holographic.Remoting.OpenXr, el archivo RemotingXR.json se copia automáticamente durante la compilación en la carpeta de salida, la selección en tiempo de ejecución de OpenXR suele tener el siguiente aspecto.
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;
}
Creación de XrInstance con la extensión de comunicación remota holográfica
Las primeras acciones que debe realizar una aplicación de OpenXR típica son seleccionar extensiones OpenXR y crear una XrInstance. La especificación del núcleo de OpenXR no proporciona ninguna API específica de comunicación remota. Por ese motivo, Holographic Remoting presenta su propia extensión OpenXR denominada XR_MSFT_holographic_remoting
. Asegúrese de que XR_MSFT_HOLOGRAPHIC_REMOTING_EXTENSION_NAME
está incluido en la XrInstanceCreateInfo de la llamada xrCreateInstance.
Sugerencia
De forma predeterminada, el contenido representado de la aplicación solo se transmite al reproductor de comunicación remota holográfica que se ejecuta en un HoloLens 2 o en un auricular Windows Mixed Reality. Para mostrar también el contenido representado en el equipo remoto, a través de una cadena de intercambio de una ventana, por ejemplo, Holographic Remoting proporciona una segunda extensión OpenXR denominada XR_MSFT_holographic_remoting_frame_mirroring
. Asegúrese de habilitar también esta extensión mediante XR_MSFT_HOLOGRAPHIC_REMOTING_FRAME_MIRRORING_EXTENSION_NAME
en caso de que desee usar esa funcionalidad.
Importante
Para obtener información sobre la API de extensión Holographic Remoting OpenXR, consulte la especificación que se puede encontrar en el repositorio de github de ejemplos de holographic Remoting.
Conexión al dispositivo
Una vez que la aplicación remota ha creado la XrInstance y consultado el XrSystemId a través de xrGetSystem, se puede establecer una conexión con el dispositivo del reproductor.
Advertencia
El entorno de ejecución de OpenXR de comunicación remota holográfica solo puede proporcionar datos específicos del dispositivo, como configuraciones de vista o modos de combinación de entornos después de que se haya establecido una conexión.
xrEnumerateViewConfigurations
, xrEnumerateViewConfigurationViews
, xrGetViewConfigurationProperties
, xrEnumerateEnvironmentBlendModes
y xrGetSystemProperties
le proporcionará valores predeterminados, que coinciden con lo que normalmente obtendría si se conecta a un jugador que se ejecuta en un HoloLens 2, antes de estar totalmente conectado.
Se recomienda encarecidamente no llamar a estos métodos antes de que se haya establecido una conexión. La sugerencia se usa estos métodos después de que la XrSession se haya creado correctamente y el estado de la sesión sea al menos XR_SESSION_STATE_READY.
Las propiedades generales, como la velocidad de bits máxima, el audio habilitado, el códec de vídeo o la resolución de flujos de búfer de profundidad, se pueden configurar a través de xrRemotingSetContextPropertiesMSFT
como se indica a continuación.
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);
La conexión se puede realizar de dos maneras.
- La aplicación remota se conecta al reproductor que se ejecuta en el dispositivo.
- El reproductor que se ejecuta en el dispositivo se conecta a la aplicación remota.
Para establecer una conexión desde la aplicación remota al dispositivo del reproductor, llame al xrRemotingConnectMSFT
método que especifica el nombre de host y el puerto a través de la XrRemotingConnectInfoMSFT
estructura. El puerto utilizado por el reproductor de comunicación remota holográfica es 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);
La escucha de conexiones entrantes en la aplicación remota se puede realizar llamando al xrRemotingListenMSFT
método . Tanto el puerto de protocolo de enlace como el puerto de transporte se pueden especificar a través de la XrRemotingListenInfoMSFT
estructura . El puerto de protocolo de enlace se usa para el protocolo de enlace inicial. A continuación, los datos se envían a través del puerto de transporte. De forma predeterminada, se usan 8265 y 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);
El estado de conexión debe desconectarse al llamar a xrRemotingConnectMSFT
o xrRemotingListenMSFT
. Puede obtener el estado de conexión en cualquier momento después de crear una XrInstance y consultar para el XrSystemId a través de xrRemotingGetConnectionStateMSFT
.
XrRemotingConnectionStateMSFT connectionState;
xrRemotingGetConnectionStateMSFT(m_instance.Get(), m_systemId, &connectionState, nullptr);
Los estados de conexión disponibles son:
- XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT
- XR_REMOTING_CONNECTION_STATE_CONNECTING_MSFT
- XR_REMOTING_CONNECTION_STATE_CONNECTED_MSFT
Importante
xrRemotingConnectMSFT
o xrRemotingListenMSFT
se debe llamar a antes de intentar crear una XrSession a través de xrCreateSession. Si intenta crear una XrSession mientras el estado de conexión es XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT
la creación de la sesión se realizará correctamente, pero el estado de la sesión pasará inmediatamente a XR_SESSION_STATE_LOSS_PENDING.
La implementación de la comunicación remota holográfica de xrCreateSession
admite la espera de que se establezca una conexión. Puede llamar a xrRemotingConnectMSFT
o xrRemotingListenMSFT
inmediatamente seguido de una llamada a xrCreateSession
, que bloqueará y esperará a que se establezca una conexión. El tiempo de espera con xrRemotingConnectMSFT
se fija en 10 segundos e ilimitado con xrRemotingListenMSFT
. Si se puede establecer una conexión dentro de este tiempo, la creación de XrSession se realizará correctamente y el estado de la sesión pasará a XR_SESSION_STATE_READY. En caso de que no se pueda establecer ninguna conexión, la creación de la sesión también se realiza correctamente, pero pasa inmediatamente a XR_SESSION_STATE_LOSS_PENDING.
En general, el estado de conexión es pareja con el estado XrSession. Cualquier cambio en el estado de conexión también afecta al estado de la sesión. Por ejemplo, si el estado de conexión cambia de al XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT
estado de XR_REMOTING_CONNECTION_STATE_CONNECTED_MSFT
sesión también pasará a XR_SESSION_STATE_LOSS_PENDING.
Control de eventos específicos de la comunicación remota
El entorno de ejecución de OpenXR de comunicación remota holográfica expone tres eventos, que son importantes para supervisar el estado de una conexión.
-
XR_TYPE_REMOTING_EVENT_DATA_CONNECTED_MSFT
: se desencadena cuando se ha establecido correctamente una conexión con el dispositivo. -
XR_TYPE_REMOTING_EVENT_DATA_DISCONNECTED_MSFT
: se desencadena si se cierra una conexión establecida o no se puede establecer una conexión. -
XR_TYPE_REMOTING_EVENT_DATA_LISTENING_MSFT
: cuando se inicia la escucha de conexiones entrantes.
Estos eventos se colocan en una cola y la aplicación remota debe leer de la cola con regularidad a través de 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;
}
}
Vista previa del contenido transmitido localmente
Para mostrar el mismo contenido en la aplicación remota que se envía al dispositivo, se puede usar la XR_MSFT_holographic_remoting_frame_mirroring
extensión. Con esta extensión, puede enviar una textura a xrEndFrame mediante que XrRemotingFrameMirrorImageInfoMSFT
no se encadene a XrFrameEndInfo como se indica a continuación.
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();
En el ejemplo anterior se usa una textura de cadena de intercambio DX11 y se presenta la ventana inmediatamente después de la llamada a xrEndFrame. El uso no está restringido a intercambiar texturas de cadena. Además, no se requiere ninguna sincronización de GPU adicional. Para obtener más información sobre el uso y las restricciones, consulte la especificación de la extensión. Si la aplicación remota usa DX12, use XrRemotingFrameMirrorImageD3D12MSFT en lugar de XrRemotingFrameMirrorImageD3D11MSFT.
Opcional: Canales de datos personalizados
A partir de la versión 2.5.0, los canales de datos personalizados se pueden usar con la API de OpenXR para enviar datos de usuario a través de la conexión remota ya establecida. Para obtener más información, consulte Canales de datos personalizados con la API de OpenXR.
Opcional: Voz
A partir de la versión 2.6.0, la XR_MSFT_holographic_remoting_speech
extensión permite que la aplicación remota reaccione a los comandos de voz detectados por la aplicación reproductora con la API de OpenXR.
[! IMPORTANTE] La especificación detallada se puede encontrar en el repositorio de github de ejemplos de comunicación remota holográfica.
Para inicializar un reconocedor de voz en la aplicación del reproductor, la aplicación remota puede llamar a xrInitializeRemotingSpeechMSFT
.
Esta llamada transmite parámetros de inicialización de voz, que constan de un idioma, un diccionario de frases y el contenido de un archivo de gramática, a la aplicación del reproductor.
Nota:
Antes de la versión 2.6.1 , el reconocedor de voz solo debe inicializarse una vez por XrSession
cada .
Si la creación del reconocedor de voz se realizó correctamente, como indica el XR_TYPE_EVENT_DATA_REMOTING_SPEECH_RECOGNIZER_STATE_CHANGED_MSFT
evento, se notificará a la aplicación remota cuando se haya generado un resultado de reconocimiento de voz en la aplicación del reproductor.
La XrEventDataRemotingSpeechRecognizerStateChangedMSFT
estructura de eventos se coloca en la cola de eventos cuando cambia el estado del reconocedor de voz en el lado del jugador.
XrRemotingSpeechRecognizerStateMSFT
define todos los estados posibles del reconocedor de voz en el lado del jugador y la estructura del XrEventDataRemotingSpeechRecognizedMSFT
evento se coloca en la cola de eventos si el reconocedor de voz del lado del jugador tiene una frase reconocida.
Una vez notificada a la aplicación remota sobre una frase reconocida, puede recuperar la frase reconocida llamando a xrRetrieveRemotingSpeechRecognizedTextMSFT
.
Nota:
XrRemotingSpeechRecognitionConfidenceMSFT
es una asignación directa de la enumeración SpeechRecognitionConfidence devuelta con el resultado del reconocimiento de voz por la API de reconocimiento de voz de Windows.
Opcional: Sincronización del sistema de coordenadas
A partir de la versión 2.7.0, se puede usar la sincronización del sistema de coordenadas para alinear los datos espaciales entre el reproductor y la aplicación remota. Para obtener más información, vea Información general sobre la sincronización del sistema de coordenadas con comunicación remota holográfica.
Consulta también
- Introducción a la comunicación remota holográfica
- Escritura de una aplicación de reproductor de comunicación remota holográfica personalizada
- Establecer una conexión segura con la comunicación remota holográfica
- Solución de problemas y limitaciones de la comunicación remota holográfica
- Términos de licencia de software de comunicación remota holográfica
- Declaración de privacidad de Microsoft