Full Code of alvr-org/ALVR for AI

master 1a4194ff1379 cached
495 files
3.6 MB
974.2k tokens
2819 symbols
1 requests
Download .txt
Showing preview only (3,886K chars total). Download the full file or copy to clipboard to get everything.
Repository: alvr-org/ALVR
Branch: master
Commit: 1a4194ff1379
Files: 495
Total size: 3.6 MB

Directory structure:
gitextract_unk25vpb/

├── .cargo/
│   └── config.toml
├── .clang-format
├── .editorconfig
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   └── bug_report.md
│   ├── dependabot.yml
│   └── workflows/
│       ├── prepare-release.yml
│       ├── queue.yml
│       ├── rust.yml
│       ├── stale.yml
│       └── wiki.yml
├── .gitignore
├── .gitmodules
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Cargo.toml
├── LICENSE
├── README.md
├── about.toml
├── alvr/
│   ├── adb/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── commands.rs
│   │       ├── lib.rs
│   │       └── parse.rs
│   ├── audio/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── lib.rs
│   │       ├── linux.rs
│   │       └── windows.rs
│   ├── client_core/
│   │   ├── Cargo.toml
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── build.rs
│   │   ├── cbindgen.toml
│   │   └── src/
│   │       ├── audio.rs
│   │       ├── c_api.rs
│   │       ├── connection.rs
│   │       ├── lib.rs
│   │       ├── logging_backend.rs
│   │       ├── sockets.rs
│   │       ├── statistics.rs
│   │       ├── storage.rs
│   │       └── video_decoder/
│   │           ├── android.rs
│   │           └── mod.rs
│   ├── client_mock/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── main.rs
│   ├── client_openxr/
│   │   ├── Cargo.toml
│   │   ├── cbindgen.toml
│   │   ├── resources/
│   │   │   ├── drawable/
│   │   │   │   └── ic_launcher_foreground.xml
│   │   │   ├── mipmap-anydpi-v26/
│   │   │   │   └── ic_launcher.xml
│   │   │   └── values/
│   │   │       └── ic_launcher_background.xml
│   │   └── src/
│   │       ├── c_api.rs
│   │       ├── extra_extensions/
│   │       │   ├── body_tracking_bd.rs
│   │       │   ├── body_tracking_fb.rs
│   │       │   ├── eye_gaze_interaction.rs
│   │       │   ├── eye_tracking_social.rs
│   │       │   ├── face_tracking2_fb.rs
│   │       │   ├── face_tracking_pico.rs
│   │       │   ├── facial_tracking_htc.rs
│   │       │   ├── mod.rs
│   │       │   ├── motion_tracking_bd.rs
│   │       │   ├── multimodal_input.rs
│   │       │   ├── passthrough_fb.rs
│   │       │   └── passthrough_htc.rs
│   │       ├── graphics.rs
│   │       ├── interaction.rs
│   │       ├── lib.rs
│   │       ├── lobby.rs
│   │       ├── passthrough.rs
│   │       └── stream.rs
│   ├── common/
│   │   ├── Cargo.toml
│   │   ├── LICENSE
│   │   ├── README.md
│   │   └── src/
│   │       ├── average.rs
│   │       ├── c_api.rs
│   │       ├── connection_result.rs
│   │       ├── inputs.rs
│   │       ├── lib.rs
│   │       ├── logging.rs
│   │       ├── primitives.rs
│   │       └── version.rs
│   ├── dashboard/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── build.rs
│   │   └── src/
│   │       ├── dashboard/
│   │       │   ├── components/
│   │       │   │   ├── about.rs
│   │       │   │   ├── debug.rs
│   │       │   │   ├── devices.rs
│   │       │   │   ├── installation.rs
│   │       │   │   ├── logs.rs
│   │       │   │   ├── mod.rs
│   │       │   │   ├── new_version_popup.rs
│   │       │   │   ├── notifications.rs
│   │       │   │   ├── settings.rs
│   │       │   │   ├── settings_controls/
│   │       │   │   │   ├── array.rs
│   │       │   │   │   ├── boolean.rs
│   │       │   │   │   ├── choice.rs
│   │       │   │   │   ├── collapsible.rs
│   │       │   │   │   ├── dictionary.rs
│   │       │   │   │   ├── mod.rs
│   │       │   │   │   ├── notice.rs
│   │       │   │   │   ├── number.rs
│   │       │   │   │   ├── optional.rs
│   │       │   │   │   ├── presets/
│   │       │   │   │   │   ├── builtin_schema.rs
│   │       │   │   │   │   ├── higher_order_choice.rs
│   │       │   │   │   │   ├── mirror.rs
│   │       │   │   │   │   ├── mod.rs
│   │       │   │   │   │   └── schema.rs
│   │       │   │   │   ├── reset.rs
│   │       │   │   │   ├── section.rs
│   │       │   │   │   ├── switch.rs
│   │       │   │   │   ├── text.rs
│   │       │   │   │   ├── up_down.rs
│   │       │   │   │   └── vector.rs
│   │       │   │   ├── setup_wizard.rs
│   │       │   │   └── statistics.rs
│   │       │   └── mod.rs
│   │       ├── data_sources.rs
│   │       ├── data_sources_wasm.rs
│   │       ├── linux_checks.rs
│   │       ├── logging_backend.rs
│   │       ├── main.rs
│   │       └── steamvr_launcher/
│   │           ├── linux_steamvr.rs
│   │           ├── mod.rs
│   │           └── windows_steamvr.rs
│   ├── events/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── lib.rs
│   ├── filesystem/
│   │   ├── Cargo.toml
│   │   ├── build.rs
│   │   └── src/
│   │       └── lib.rs
│   ├── graphics/
│   │   ├── Cargo.toml
│   │   ├── resources/
│   │   │   ├── lobby_line.wgsl
│   │   │   ├── lobby_quad.wgsl
│   │   │   ├── staging_fragment.glsl
│   │   │   ├── staging_vertex.glsl
│   │   │   └── stream.wgsl
│   │   └── src/
│   │       ├── lib.rs
│   │       ├── lobby.rs
│   │       ├── staging.rs
│   │       └── stream.rs
│   ├── gui_common/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── basic_components/
│   │       │   ├── button_group.rs
│   │       │   ├── mod.rs
│   │       │   ├── modal.rs
│   │       │   └── switch.rs
│   │       ├── lib.rs
│   │       └── theme.rs
│   ├── launcher/
│   │   ├── Cargo.toml
│   │   ├── build.rs
│   │   └── src/
│   │       ├── actions.rs
│   │       ├── main.rs
│   │       └── ui.rs
│   ├── packets/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── lib.rs
│   ├── server_core/
│   │   ├── Cargo.toml
│   │   ├── cbindgen.toml
│   │   └── src/
│   │       ├── bitrate.rs
│   │       ├── c_api.rs
│   │       ├── connection.rs
│   │       ├── hand_gestures.rs
│   │       ├── haptics.rs
│   │       ├── input_mapping.rs
│   │       ├── lib.rs
│   │       ├── logging_backend.rs
│   │       ├── sockets.rs
│   │       ├── statistics.rs
│   │       ├── tracking/
│   │       │   ├── body.rs
│   │       │   ├── face.rs
│   │       │   ├── mod.rs
│   │       │   └── vmc.rs
│   │       └── web_server.rs
│   ├── server_io/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   └── src/
│   │       ├── firewall.rs
│   │       ├── lib.rs
│   │       ├── openvr_drivers.rs
│   │       └── openvrpaths.rs
│   ├── server_openvr/
│   │   ├── Cargo.toml
│   │   ├── LICENSE
│   │   ├── LICENSE-Valve
│   │   ├── build.rs
│   │   ├── cpp/
│   │   │   ├── ALVR-common/
│   │   │   │   ├── common-utils.cpp
│   │   │   │   ├── common-utils.h
│   │   │   │   ├── exception.cpp
│   │   │   │   ├── exception.h
│   │   │   │   └── packet_types.h
│   │   │   ├── alvr_server/
│   │   │   │   ├── ChaperoneUpdater.cpp
│   │   │   │   ├── Controller.cpp
│   │   │   │   ├── Controller.h
│   │   │   │   ├── FakeViveTracker.cpp
│   │   │   │   ├── FakeViveTracker.h
│   │   │   │   ├── HMD.cpp
│   │   │   │   ├── HMD.h
│   │   │   │   ├── IDRScheduler.cpp
│   │   │   │   ├── IDRScheduler.h
│   │   │   │   ├── Logger.cpp
│   │   │   │   ├── Logger.h
│   │   │   │   ├── NalParsing.cpp
│   │   │   │   ├── Paths.cpp
│   │   │   │   ├── Paths.h
│   │   │   │   ├── PoseHistory.cpp
│   │   │   │   ├── PoseHistory.h
│   │   │   │   ├── Settings.cpp
│   │   │   │   ├── Settings.h
│   │   │   │   ├── TrackedDevice.cpp
│   │   │   │   ├── TrackedDevice.h
│   │   │   │   ├── Utils.h
│   │   │   │   ├── ViveTrackerProxy.cpp
│   │   │   │   ├── ViveTrackerProxy.h
│   │   │   │   ├── alvr_server.cpp
│   │   │   │   ├── bindings.h
│   │   │   │   ├── driverlog.cpp
│   │   │   │   ├── driverlog.h
│   │   │   │   ├── include/
│   │   │   │   │   ├── openvr_math.h
│   │   │   │   │   └── picojson.h
│   │   │   │   ├── nvEncodeAPI.h
│   │   │   │   ├── openvr_driver_wrap.h
│   │   │   │   └── shader/
│   │   │   │       ├── ColorCorrectionPixelShader.hlsl
│   │   │   │       ├── CompressAxisAlignedPixelShader.hlsl
│   │   │   │       ├── FoveatedRendering.hlsli
│   │   │   │       ├── FrameRender.fx
│   │   │   │       ├── FrameRenderPS.hlsl
│   │   │   │       ├── FrameRenderVS.hlsl
│   │   │   │       └── rgbtoyuv420.hlsl
│   │   │   ├── platform/
│   │   │   │   ├── linux/
│   │   │   │   │   ├── CEncoder.cpp
│   │   │   │   │   ├── CEncoder.h
│   │   │   │   │   ├── CrashHandler.cpp
│   │   │   │   │   ├── EncodePipeline.cpp
│   │   │   │   │   ├── EncodePipeline.h
│   │   │   │   │   ├── EncodePipelineNvEnc.cpp
│   │   │   │   │   ├── EncodePipelineNvEnc.h
│   │   │   │   │   ├── EncodePipelineSW.cpp
│   │   │   │   │   ├── EncodePipelineSW.h
│   │   │   │   │   ├── EncodePipelineVAAPI.cpp
│   │   │   │   │   ├── EncodePipelineVAAPI.h
│   │   │   │   │   ├── FormatConverter.cpp
│   │   │   │   │   ├── FormatConverter.h
│   │   │   │   │   ├── FrameRender.cpp
│   │   │   │   │   ├── FrameRender.h
│   │   │   │   │   ├── Renderer.cpp
│   │   │   │   │   ├── Renderer.h
│   │   │   │   │   ├── ffmpeg_helper.cpp
│   │   │   │   │   ├── ffmpeg_helper.h
│   │   │   │   │   ├── protocol.h
│   │   │   │   │   └── shader/
│   │   │   │   │       ├── color.comp
│   │   │   │   │       ├── color.comp.spv
│   │   │   │   │       ├── ffr.comp
│   │   │   │   │       ├── ffr.comp.spv
│   │   │   │   │       ├── quad.comp
│   │   │   │   │       ├── quad.comp.spv
│   │   │   │   │       ├── rgbtoyuv420.comp
│   │   │   │   │       └── rgbtoyuv420.comp.spv
│   │   │   │   ├── macos/
│   │   │   │   │   ├── CEncoder.h
│   │   │   │   │   └── CrashHandler.cpp
│   │   │   │   └── win32/
│   │   │   │       ├── CEncoder.cpp
│   │   │   │       ├── CEncoder.h
│   │   │   │       ├── ColorCorrectionPixelShader.cso
│   │   │   │       ├── CompressAxisAlignedPixelShader.cso
│   │   │   │       ├── CrashHandler.cpp
│   │   │   │       ├── FFR.cpp
│   │   │   │       ├── FFR.h
│   │   │   │       ├── FrameRender.cpp
│   │   │   │       ├── FrameRender.h
│   │   │   │       ├── FrameRenderPS.cso
│   │   │   │       ├── FrameRenderVS.cso
│   │   │   │       ├── NvCodecUtils.h
│   │   │   │       ├── NvEncoder.cpp
│   │   │   │       ├── NvEncoder.h
│   │   │   │       ├── NvEncoderD3D11.cpp
│   │   │   │       ├── NvEncoderD3D11.h
│   │   │   │       ├── OvrDirectModeComponent.cpp
│   │   │   │       ├── OvrDirectModeComponent.h
│   │   │   │       ├── QuadVertexShader.cso
│   │   │   │       ├── VideoEncoder.cpp
│   │   │   │       ├── VideoEncoder.h
│   │   │   │       ├── VideoEncoderAMF.cpp
│   │   │   │       ├── VideoEncoderAMF.h
│   │   │   │       ├── VideoEncoderNVENC.cpp
│   │   │   │       ├── VideoEncoderNVENC.h
│   │   │   │       ├── VideoEncoderSW.cpp
│   │   │   │       ├── VideoEncoderSW.h
│   │   │   │       ├── VideoEncoderVPL.cpp
│   │   │   │       ├── VideoEncoderVPL.h
│   │   │   │       ├── d3d-render-utils/
│   │   │   │       │   ├── QuadVertexShader.hlsl
│   │   │   │       │   ├── RenderPipeline.cpp
│   │   │   │       │   ├── RenderPipeline.h
│   │   │   │       │   ├── RenderPipelineYUV.cpp
│   │   │   │       │   ├── RenderPipelineYUV.h
│   │   │   │       │   ├── RenderUtils.cpp
│   │   │   │       │   └── RenderUtils.h
│   │   │   │       ├── rgbtoyuv420.cso
│   │   │   │       └── shared/
│   │   │   │           ├── d3drender.cpp
│   │   │   │           └── d3drender.h
│   │   │   └── shared/
│   │   │       ├── amf/
│   │   │       │   └── public/
│   │   │       │       ├── common/
│   │   │       │       │   ├── AMFFactory.cpp
│   │   │       │       │   ├── AMFFactory.h
│   │   │       │       │   ├── AMFMath.h
│   │   │       │       │   ├── AMFSTL.cpp
│   │   │       │       │   ├── AMFSTL.h
│   │   │       │       │   ├── ByteArray.h
│   │   │       │       │   ├── CPUCaps.h
│   │   │       │       │   ├── CurrentTimeImpl.cpp
│   │   │       │       │   ├── CurrentTimeImpl.h
│   │   │       │       │   ├── DataStream.h
│   │   │       │       │   ├── DataStreamFactory.cpp
│   │   │       │       │   ├── DataStreamFile.cpp
│   │   │       │       │   ├── DataStreamFile.h
│   │   │       │       │   ├── DataStreamMemory.cpp
│   │   │       │       │   ├── DataStreamMemory.h
│   │   │       │       │   ├── IOCapsImpl.cpp
│   │   │       │       │   ├── IOCapsImpl.h
│   │   │       │       │   ├── InterfaceImpl.h
│   │   │       │       │   ├── ObservableImpl.h
│   │   │       │       │   ├── PropertyStorageExImpl.cpp
│   │   │       │       │   ├── PropertyStorageExImpl.h
│   │   │       │       │   ├── PropertyStorageImpl.h
│   │   │       │       │   ├── Thread.cpp
│   │   │       │       │   ├── Thread.h
│   │   │       │       │   ├── TraceAdapter.cpp
│   │   │       │       │   ├── TraceAdapter.h
│   │   │       │       │   └── Windows/
│   │   │       │       │       └── ThreadWindows.cpp
│   │   │       │       └── include/
│   │   │       │           ├── components/
│   │   │       │           │   ├── Ambisonic2SRenderer.h
│   │   │       │           │   ├── AudioCapture.h
│   │   │       │           │   ├── Capture.h
│   │   │       │           │   ├── ChromaKey.h
│   │   │       │           │   ├── ColorSpace.h
│   │   │       │           │   ├── Component.h
│   │   │       │           │   ├── ComponentCaps.h
│   │   │       │           │   ├── CursorCapture.h
│   │   │       │           │   ├── DisplayCapture.h
│   │   │       │           │   ├── FFMPEGAudioConverter.h
│   │   │       │           │   ├── FFMPEGAudioDecoder.h
│   │   │       │           │   ├── FFMPEGAudioEncoder.h
│   │   │       │           │   ├── FFMPEGComponents.h
│   │   │       │           │   ├── FFMPEGEncoderAV1.h
│   │   │       │           │   ├── FFMPEGEncoderH264.h
│   │   │       │           │   ├── FFMPEGEncoderHEVC.h
│   │   │       │           │   ├── FFMPEGFileDemuxer.h
│   │   │       │           │   ├── FFMPEGFileMuxer.h
│   │   │       │           │   ├── FFMPEGVideoDecoder.h
│   │   │       │           │   ├── FRC.h
│   │   │       │           │   ├── HQScaler.h
│   │   │       │           │   ├── MediaSource.h
│   │   │       │           │   ├── PreAnalysis.h
│   │   │       │           │   ├── PreProcessing.h
│   │   │       │           │   ├── SupportedCodecs.h
│   │   │       │           │   ├── VQEnhancer.h
│   │   │       │           │   ├── VideoCapture.h
│   │   │       │           │   ├── VideoConverter.h
│   │   │       │           │   ├── VideoDecoderUVD.h
│   │   │       │           │   ├── VideoEncoderAV1.h
│   │   │       │           │   ├── VideoEncoderHEVC.h
│   │   │       │           │   ├── VideoEncoderVCE.h
│   │   │       │           │   ├── VideoStitch.h
│   │   │       │           │   └── ZCamLiveStream.h
│   │   │       │           └── core/
│   │   │       │               ├── AudioBuffer.h
│   │   │       │               ├── Buffer.h
│   │   │       │               ├── Compute.h
│   │   │       │               ├── ComputeFactory.h
│   │   │       │               ├── Context.h
│   │   │       │               ├── CurrentTime.h
│   │   │       │               ├── D3D12AMF.h
│   │   │       │               ├── Data.h
│   │   │       │               ├── Debug.h
│   │   │       │               ├── Dump.h
│   │   │       │               ├── Factory.h
│   │   │       │               ├── Interface.h
│   │   │       │               ├── Plane.h
│   │   │       │               ├── Platform.h
│   │   │       │               ├── PropertyStorage.h
│   │   │       │               ├── PropertyStorageEx.h
│   │   │       │               ├── Result.h
│   │   │       │               ├── Surface.h
│   │   │       │               ├── Trace.h
│   │   │       │               ├── Variant.h
│   │   │       │               ├── Version.h
│   │   │       │               └── VulkanAMF.h
│   │   │       ├── backward.cpp
│   │   │       ├── backward.hpp
│   │   │       ├── threadtools.cpp
│   │   │       └── threadtools.h
│   │   └── src/
│   │       ├── graphics.rs
│   │       ├── lib.rs
│   │       ├── props.rs
│   │       └── tracking.rs
│   ├── session/
│   │   ├── Cargo.toml
│   │   ├── build.rs
│   │   └── src/
│   │       ├── lib.rs
│   │       └── settings.rs
│   ├── sockets/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── control_socket.rs
│   │       ├── lib.rs
│   │       └── stream_socket/
│   │           ├── mod.rs
│   │           ├── tcp.rs
│   │           └── udp.rs
│   ├── system_info/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── android.rs
│   │       └── lib.rs
│   ├── vrcompositor_wrapper/
│   │   ├── Cargo.toml
│   │   ├── build.rs
│   │   ├── drm-lease-shim.cpp
│   │   └── src/
│   │       └── main.rs
│   ├── vulkan_layer/
│   │   ├── .gitignore
│   │   ├── Cargo.toml
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── build.rs
│   │   ├── layer/
│   │   │   ├── alvr_x86_64.json
│   │   │   ├── device_api.cpp
│   │   │   ├── device_api.hpp
│   │   │   ├── layer.cpp
│   │   │   ├── layer.h
│   │   │   ├── private_data.cpp
│   │   │   ├── private_data.hpp
│   │   │   ├── settings.cpp
│   │   │   ├── settings.h
│   │   │   ├── surface_api.cpp
│   │   │   ├── surface_api.hpp
│   │   │   ├── swapchain_api.cpp
│   │   │   └── swapchain_api.hpp
│   │   ├── src/
│   │   │   └── lib.rs
│   │   ├── util/
│   │   │   ├── custom_allocator.cpp
│   │   │   ├── custom_allocator.hpp
│   │   │   ├── extension_list.cpp
│   │   │   ├── extension_list.hpp
│   │   │   ├── logger.cpp
│   │   │   ├── logger.h
│   │   │   ├── platform_set.hpp
│   │   │   ├── pose.cpp
│   │   │   ├── pose.hpp
│   │   │   ├── timed_semaphore.cpp
│   │   │   └── timed_semaphore.hpp
│   │   └── wsi/
│   │       ├── display.cpp
│   │       ├── display.hpp
│   │       ├── headless/
│   │       │   ├── surface_properties.cpp
│   │       │   ├── surface_properties.hpp
│   │       │   ├── swapchain.cpp
│   │       │   └── swapchain.hpp
│   │       ├── surface_properties.hpp
│   │       ├── swapchain_base.cpp
│   │       ├── swapchain_base.hpp
│   │       ├── wsi_factory.cpp
│   │       └── wsi_factory.hpp
│   └── xtask/
│       ├── Cargo.toml
│       ├── LICENSE
│       ├── README.md
│       ├── build.rs
│       ├── firewall/
│       │   ├── alvr-firewalld.xml
│       │   ├── alvr_fw_config.sh
│       │   └── ufw-alvr
│       ├── flatpak/
│       │   ├── README.md
│       │   ├── build_and_install.sh
│       │   ├── com.valvesoftware.Steam.Utility.alvr.desktop
│       │   ├── com.valvesoftware.Steam.Utility.alvr.json
│       │   ├── run_with_adb_keys.sh
│       │   └── setup_xdg_shortcut.sh
│       ├── licenses_template.hbs
│       ├── patches/
│       │   ├── 0001-Add-AV_VAAPI_DRIVER_QUIRK_HEVC_ENCODER_ALIGN_64_16-f.patch
│       │   ├── 0001-av1-encode-backport.patch
│       │   ├── 0001-clip-constants-used-with-shift-instr.patch
│       │   ├── 0001-guid-conftest.patch
│       │   ├── 0001-lavu-hwcontext_vulkan-Fix-importing-RGBx-frames-to-C.patch
│       │   ├── 0001-update-rc-modes.patch
│       │   ├── 0001-vaapi_encode-Add-filler_data-option.patch
│       │   ├── 0001-vaapi_encode-Allow-to-dynamically-change-bitrate-and.patch
│       │   ├── 0001-vaapi_encode-Enable-global-header.patch
│       │   └── 0001-vaapi_encode_h265-Set-vui_parameters_present_flag.patch
│       ├── resources/
│       │   ├── alvr.desktop
│       │   └── driver.vrdrivermanifest
│       └── src/
│           ├── build.rs
│           ├── ci.rs
│           ├── command.rs
│           ├── dependencies.rs
│           ├── format.rs
│           ├── main.rs
│           ├── packaging.rs
│           └── version.rs
└── wiki/
    ├── ALVR-Checklist.md
    ├── ALVR-wired-setup-(ALVR-over-USB).md
    ├── Building-From-Source.md
    ├── Controller-latency.md
    ├── FFmpeg-Hardware-Encoding-Testing.md
    ├── Fixed-Foveated-Rendering-(FFR).md
    ├── Hand-tracking-controller-bindings.md
    ├── Headset-and-ALVR-streamer-on-separate-networks.md
    ├── Home.md
    ├── How-ALVR-works.md
    ├── Information-and-Recommendations.md
    ├── Installation-guide.md
    ├── Installing-ALVR-and-using-SteamVR-on-Linux-through-Flatpak.md
    ├── Linux-Troubleshooting.md
    ├── My-game-is-not-working-properly!-Help!.md
    ├── Other-resources.md
    ├── Real-time-video-upscaling-experiments.md
    ├── Roadmap.md
    ├── Settings-tutorial.md
    ├── Troubleshooting.md
    └── _Sidebar.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .cargo/config.toml
================================================
[alias]
xtask = "run -p alvr_xtask --"

[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]


================================================
FILE: .clang-format
================================================
BasedOnStyle:  WebKit
IndentWidth: 4
ColumnLimit: 100
BinPackArguments: false
BinPackParameters: false
AlignAfterOpenBracket: BlockIndent
BreakBeforeBraces: Attach
InsertNewlineAtEOF: true


================================================
FILE: .editorconfig
================================================
# Editor configuration, see https://editorconfig.org

[*.{c,cpp,h,hpp}]
indent_style = space
indent_size = 4
tab_width = 4
max_line_length = 100
end_of_line = lf
insert_final_newline = true

[.editorconfig]
indent_style = space
indent_size = 4
tab_width = 4
end_of_line = lf
insert_final_newline = true


================================================
FILE: .gitattributes
================================================
* text=auto eol=lf

alvr/server_openvr/cpp/alvr_server/include/** linguist-vendored
alvr/server_openvr/cpp/alvr_server/nvEncodeAPI.h linguist-vendored
alvr/server_openvr/cpp/platform/win32/NvCodecUtils.h linguist-vendored
alvr/server_openvr/cpp/platform/win32/NvEncoder.cpp linguist-vendored
alvr/server_openvr/cpp/platform/win32/NvEncoder.h linguist-vendored
alvr/server_openvr/cpp/shared/** linguist-vendored
# note: some of these folders contain ALVR code, but only a minor amount
alvr/vulkan_layer/layer/** linguist-vendored
alvr/vulkan_layer/util/** linguist-vendored
alvr/vulkan_layer/wsi/** linguist-vendored


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: alvr
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug Report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

<!-- Note: If the bug affects multiple games, please open an issue for each game with the name of the game in the title. -->


## Description
<!-- Please add a brief summary of your issue -->

<!-- If this is a regression, please do some bisection testing in the nightly releases history to find the first release that manifests the problem. -->

## General Troubleshooting
- [ ] I carefully followed the instructions in the [README](https://github.com/alvr-org/ALVR/blob/master/README.md) and successfully completed the setup wizard
- [ ] I read the [ALVR GitHub Wiki](https://github.com/alvr-org/ALVR/wiki)

## Environment

### Hardware
**Note**: for Linux, an upload to the [`hw-probe`](https://linux-hardware.org/) database is preferred: `hw-probe -all -upload`

**CPU**:

**GPU**:

**GPU Driver Version**:

**Audio**:

### Installation
**ALVR Version**:

**ALVR Settings File**:

**SteamVR Version**:

**Install Type**:
- [ ] Packaged (`exe`, `deb`, `rpm`, etc)
- [ ] Portable (`zip`)
- [ ] Source

**OS Name and Version** (`winver` on Windows or `grep PRETTY_NAME /etc/os-release` on most Linux distributions):

<!-- Feature Requests
The quickest way to get a new feature is to file a pull request; these will be considered, but may be closed if they're something we're not actively planning to work on. -->


================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
  - package-ecosystem: "cargo" # See documentation for possible values
    directory: "/" # Location of package manifests
    schedule:
      interval: "monthly"
    ignore:
      - dependency-name: "*"
        update-types: [ "version-update:semver-minor","version-update:semver-patch" ]


================================================
FILE: .github/workflows/prepare-release.yml
================================================
name: Create release

env:
  CARGO_TERM_COLOR: always

on:
  workflow_dispatch:
    inputs:
      version:
        description: "Version"
        required: false
        default: ""

jobs:
  prepare_release:
    runs-on: windows-2022
    outputs:
      release_ref: ${{ steps.output_ref.outputs.release_ref }}
      upload_url: ${{ steps.create_release.outputs.upload_url }}
      release_id: ${{ steps.create_release.outputs.id }}
    steps:
      - name: Configure git
        run: git config --global core.autocrlf false

      - uses: actions/checkout@v2

      - uses: actions-rs/toolchain@v1
        with:
          toolchain: stable

      - name: Bump version
        id: bump_version
        env:
          RUST_BACKTRACE: 1
        run: |
          $versionarg = "${{ github.event.inputs.version }}"
          $versionarg = If ($versionarg.Length -gt 0) { "--version $versionarg" } else { "" }
          $out = cargo xtask bump $versionarg.split()
          echo $out
          cargo update -p alvr_common
          echo "::set-output name=version_tag::$(echo $out | sls -CaseSensitive -Pattern '^v.*$')"

      - name: Push changes
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: "[Auto] Bump version"

      - name: Output ref for later checkouts
        id: output_ref
        run: echo "::set-output name=release_ref::$(git rev-parse HEAD)"

      - name: Create Release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ steps.bump_version.outputs.version_tag }}
          release_name: ALVR ${{ steps.bump_version.outputs.version_tag }}
          draft: true
          prerelease: false
          commitish: ${{ steps.output_ref.outputs.release_ref }}

  build_windows_streamer:
    runs-on: windows-2022
    needs: [prepare_release]
    steps:
      - uses: actions/checkout@v2
        with:
          ref: ${{ needs.prepare_release.outputs.release_ref }}
          submodules: true

      - uses: actions-rs/toolchain@v1
        with:
          toolchain: stable
          override: true

      - uses: crazy-max/ghaction-chocolatey@v1
        with:
          args: install zip unzip pkgconfiglite wixtoolset

      - name: Build and package ALVR
        id: build
        env:
          RUST_BACKTRACE: 1
        run: |
          cargo xtask package-streamer --gpl --ci
          cargo xtask package-launcher --ci

      - name: Upload streamer
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ needs.prepare_release.outputs.upload_url }}
          asset_path: ./build/alvr_streamer_windows.zip
          asset_name: alvr_streamer_windows.zip
          asset_content_type: application/zip
      - name: Upload launcher
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ needs.prepare_release.outputs.upload_url }}
          asset_path: ./build/alvr_launcher_windows.zip
          asset_name: alvr_launcher_windows.zip
          asset_content_type: application/zip

  build_linux_streamer:
    runs-on: ubuntu-22.04
    needs: [prepare_release]
    steps:
      - uses: actions/checkout@v2
        with:
          ref: ${{ needs.prepare_release.outputs.release_ref }}
          submodules: true

      - uses: actions-rs/toolchain@v1
        with:
          toolchain: stable
          override: true

      - name: Build and install dependencies
        env:
          RUST_BACKTRACE: 1
        run: |
          sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 25088A0359807596
          echo "deb http://ppa.launchpad.net/pipewire-debian/pipewire-upstream/ubuntu $(lsb_release -cs) main" | sudo tee -a /etc/apt/sources.list.d/pipewire-upstream.list
          sudo apt-get update
          sudo apt-get install libfuse2 build-essential pkg-config nasm libva-dev libdrm-dev libvulkan-dev libx264-dev libx265-dev cmake libasound2-dev libjack-jackd2-dev libxrandr-dev libunwind-dev libgtk-3-dev libpipewire-0.3-dev libspa-0.2-dev

      - name: Build and package ALVR (.tar.gz)
        id: build
        env:
          RUST_BACKTRACE: 1
        run: |
          cargo xtask package-streamer --gpl --ci
          cargo xtask package-launcher --ci

      - name: Upload streamer (tar.gz)
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ needs.prepare_release.outputs.upload_url }}
          asset_path: ./build/alvr_streamer_linux.tar.gz
          asset_name: alvr_streamer_linux.tar.gz
          asset_content_type: application/gzip
      - name: Upload launcher
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ needs.prepare_release.outputs.upload_url }}
          asset_path: ./build/alvr_launcher_linux.tar.gz
          asset_name: alvr_launcher_linux.tar.gz
          asset_content_type: application/gzip

  build_flatpak_bundle:
    runs-on: ubuntu-latest
    needs: [prepare_release]
    steps:
      - uses: actions/checkout@v2
        with:
          ref: ${{ needs.prepare_release.outputs.release_ref }}
          submodules: true

      - name: Build and install dependencies
        env:
          RUST_BACKTRACE: 1
        run: |
          sudo apt-get update
          sudo apt-get install flatpak flatpak-builder
          sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo

      - name: Build and package ALVR flatpak (.flatpak)
        id: build_flatpak
        run: |
          sudo flatpak-builder --repo=.flatpak-repo --install-deps-from=flathub --force-clean --default-branch=stable --arch=x86_64 .flatpak-build-dir alvr/xtask/flatpak/com.valvesoftware.Steam.Utility.alvr.json
          flatpak build-bundle .flatpak-repo com.valvesoftware.Steam.Utility.alvr.flatpak com.valvesoftware.Steam.Utility.alvr stable --runtime

      - name: Upload flatpak streamer for Linux
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ needs.prepare_release.outputs.upload_url }}
          asset_path: com.valvesoftware.Steam.Utility.alvr.flatpak
          asset_name: com.valvesoftware.Steam.Utility.alvr.flatpak
          asset_content_type: application/octet-stream

  build_android_client:
    runs-on: ubuntu-latest
    needs: [prepare_release]
    steps:
      - uses: actions/checkout@v2
        with:
          ref: ${{ needs.prepare_release.outputs.release_ref }}
          submodules: true
        
      - uses: actions-rs/toolchain@v1
        with:
          toolchain: stable
          target: aarch64-linux-android
          override: true
      - uses: actions/setup-java@v2
        with:
          distribution: "temurin"
          java-version: "17"
      - uses: android-actions/setup-android@v3
        with:
          packages: "platforms;android-32"
      - uses: nttld/setup-ndk@v1
        id: setup-ndk
        with:
          ndk-version: r26b

      - name: Build and package ALVR
        id: build
        env:
          RUST_BACKTRACE: 1
          ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
        run: cargo xtask package-client --ci

      - name: Sign APK
        uses: ilharp/sign-android-release@v1
        id: sign_apk
        with:
          releaseDir: build/alvr_client_android
          signingKey: ${{ secrets.SIGNING_KEY }}
          keyAlias: ${{ secrets.KEY_ALIAS }}
          keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
          keyPassword: ${{ secrets.KEY_PASSWORD }}
          buildToolsVersion: 34.0.0

      - name: Upload APK
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ needs.prepare_release.outputs.upload_url }}
          asset_path: ${{ steps.sign_apk.outputs.signedFile }}
          asset_name: alvr_client_android.apk
          asset_content_type: application/vnd.android.package-archive


================================================
FILE: .github/workflows/queue.yml
================================================
name: Merge queue only checks

# Merge queue checks need to be selected as required for prs to actually run, so simply skip them on prs
on:
  pull_request:
  merge_group:

env:
  CARGO_TERM_COLOR: always

jobs:
  check-linux-old:
    if: github.event_name == 'merge_group'
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy
      - uses: Swatinem/rust-cache@v2

      - name: Install dependencies
        run: |
          sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 25088A0359807596
          echo "deb http://ppa.launchpad.net/pipewire-debian/pipewire-upstream/ubuntu $(lsb_release -cs) main" | sudo tee -a /etc/apt/sources.list.d/pipewire-upstream.list
          sudo add-apt-repository universe
          sudo apt-get update
          sudo apt-get install libfuse2 build-essential pkg-config nasm libva-dev libdrm-dev libvulkan-dev libx264-dev libx265-dev cmake libasound2-dev libjack-jackd2-dev libxrandr-dev libunwind-dev libgtk-3-dev libpipewire-0.3-dev libspa-0.2-dev

      - name: Prepare deps
        env:
          RUST_BACKTRACE: 1
        run:  cargo xtask prepare-deps --platform linux --no-nvidia

      - run: cargo clippy

  check-msrv-windows:
    if: github.event_name == 'merge_group'
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2

      # Fix actions rust install and msrv both being stupid
      - run: rustup update

      - name: Prepare deps
        env:
          RUST_BACKTRACE: 1
        run: cargo xtask prepare-deps --platform windows

      - run: cargo xtask check-msrv

  check-msrv-linux:
    if: github.event_name == 'merge_group'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2

      - name: Install dependencies
        run: |
          sudo apt update
          sudo apt install build-essential pkg-config nasm libva-dev libdrm-dev libvulkan-dev libx264-dev libasound2-dev libxrandr-dev libunwind-dev libgtk-3-dev libpipewire-0.3-dev libspa-0.2-dev

      - name: Prepare deps
        env:
          RUST_BACKTRACE: 1
        run:  cargo xtask prepare-deps --platform linux --no-nvidia

      - run: cargo xtask check-msrv

  check-licenses:
    if: github.event_name == 'merge_group'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2

      - run: cargo xtask check-licenses


================================================
FILE: .github/workflows/rust.yml
================================================
name: Rust

on:
  pull_request:
    branches: [master]
  merge_group:

env:
  CARGO_TERM_COLOR: always

jobs:
  check-windows:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy
      - uses: Swatinem/rust-cache@v2

      - name: Prepare deps
        env:
          RUST_BACKTRACE: 1
        run: cargo xtask prepare-deps --platform windows

      - run: cargo xtask clippy --ci

  check-linux:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy
      - uses: Swatinem/rust-cache@v2

      - name: Install dependencies
        run: |
          sudo apt update
          sudo apt install build-essential pkg-config nasm libva-dev libdrm-dev libvulkan-dev libx264-dev libasound2-dev libxrandr-dev libunwind-dev libgtk-3-dev libpipewire-0.3-dev libspa-0.2-dev

      - name: Prepare deps
        env:
          RUST_BACKTRACE: 1
        run:  cargo xtask prepare-deps --platform linux --no-nvidia

      - run: cargo xtask clippy --ci

  check-macos:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy
      - uses: Swatinem/rust-cache@v2

      # This step currently does nothing on macos, but might in the future
      # - run: cargo xtask prepare-deps --platform macos

      - run: cargo clippy

  build-android:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: aarch64-linux-android
      - uses: Swatinem/rust-cache@v2
      - uses: actions/setup-java@v2
        with:
          distribution: 'temurin'
          java-version: '17'
      - uses: android-actions/setup-android@v3
        with:
          packages: 'platforms;android-32'
      - uses: nttld/setup-ndk@v1
        id: setup-ndk
        with:
          ndk-version: r26b

      - name: Install deps
        run: cargo install cargo-apk

        # Create folder without content to make the build succeed
      - run: mkdir -p deps/android_openxr/arm64-v8a

      - name: Build client
        env:
          ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
        working-directory: ./alvr/client_openxr
        run: cargo xtask build-client

  tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2

      - name: Run tests
        run: cargo test -p alvr_session

  check-format:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt

      - run: cargo xtask check-format


================================================
FILE: .github/workflows/stale.yml
================================================
name: 'Close stale issues'
on:
  schedule:
    - cron: '0 0 * * *'

jobs:
  stale:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/stale@v9
        with:
          stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
          exempt-issue-labels: 'bug,documentation,enhancement,good-first-issue,hep-wanted,needs-testing,release'
          exempt-draft-pr: true


================================================
FILE: .github/workflows/wiki.yml
================================================
name: Publish to GitHub Wiki

on:
  push:
    branches: [master]
  workflow_dispatch:

jobs:
  wiki:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Publish to wiki
        uses: cmbrose/github-docs-to-wiki@v0.24
        with:
          githubToken: ${{ secrets.GH_PAT }}
          rootDocsFolder: "wiki"


================================================
FILE: .gitignore
================================================
Debug
Release
*.opensdf
*.sdf
*.suo
*.filters
*.user
*.dll
*.exe
*.mexw64
*.aps

# editor
.vs/
.idea/

# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets

release-files/

# Ignore generated file with harvested file paths for WiX
wix/harvested.wxs

# Other WiX files
*.wixobj
*.wixpdb
*.msi

# Generated by Cargo
# will have compiled files and executables
/target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
#Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# build result
/build/
dist

.vscode/
.DS_Store
.ccls-cache

# dependencies installed by xtask
deps

# dependencies installed by node
node_modules

# The .gitignore for android is project folder.

# flatpak
.flatpak*

ALVR-Launcher

#allows adding CMake files for some IDEs to parse C++ files correctly
CMakeLists.txt
cmake-build-debug/

*.jks

================================================
FILE: .gitmodules
================================================
[submodule "openvr"]
	path = openvr
	url = https://github.com/ValveSoftware/openvr.git
	shallow = true


================================================
FILE: CHANGELOG.md
================================================
# Changelog

## v20.11.0

* Add flatpak launcher (by @failboat78 #2207)
* Fix Linux/Nvenc error popups (by @failboat78 #2338)
* Add debug groups (by @zarik5 #2332)
* Fix black screen on Focus 3 (by @zarik5 #2346)
* Fix launcher installation popup (by @zarik5 #2356)
* Fix crash on invalid haptics (by @zarik5 #2355)
* Rework logging (by @zarik5 #2351)
* Disable "Adapt to framerate" by default (by @zarik5)
* Show body skeleton in lobby (by @zarik5 #2366)
* Add multimodal input (by @zarik5 #2367)
* Fix high CPU usage on Linux (by @The-personified-devil #2372 #2375)
* Fix stream being half width resolution (by @zarik5 #2378)

## v20.10.0

* Internal refactors of the client graphics (wgpu) and server code architecture (by @zarik5)
* Fix Quest 3 not supporting 120Hz (by @The-personified-devil)
* Tracking timing jitter (by @zarik5 #2285)
* Support VRChat hand tracking (by @ReinaS-64892 @AdalynBlack @zarik5 #2295, @zarik5 #2313 #2323)
* Fix crash with some games (by @szneqz #2309)
* Fix crash when shutting down launcher (by @zarik5 #2320)
* Fix crash with vibration on Focus 3 (by @zarik5 #2324)

### v20.9.1 (2024-07-06)

* Fix performance issues on lobby room.

## v20.9.0 (2024-07-06)

* Display license inside the dashboard (by @zarik5 #2117)
* Add GPU checks for Linux (by @Meister1593 #2110)
* Reorder settings (by @zarik5 #2119)
* Shallow rename "client" -> "device" (by @zarik5 #2120)
* Update manifest for AppLab (by @zarik5 #2146)
* Allow recentering in the lobby (by @zarik5 #2155)
* Tweak graph labels and colors (by @zarik5 #2176)
* Fix controller detection on Pico Neo 3 Link (by @HoLo85 #2192)
* Loosen restrictions on device selection with VoiceMeeter (by @xuan25 #2209)
* Fix HEVC black screen on Linux/VAAPI (by @Nibor62 #2203)
* Show hands and controllers in the lobby (by @zarik5 #2218)
* Add PipeWire support on Linux (by @Meister1593 #1973)

### v20.8.1 (2024-05-08)

* Fix crash on Linux (by @SniperJoe #2108)

## v20.8.0 (2024-05-04)

* Bring back settings tabs (by @Meister1593 #2076)
* Make FFE shader much lighter (by @yoyobuae #2083)
* Improve firewall rules on Linux (by @Meister1593 #2078)
* Fix error message not displaying correctly on Linux sometimes (by @SniperJoe #2088)
* Fix Nvidia encoder on some Linux systems (by @Xaphiosis @nowrep #2074)
* Fix client warmstart crash (by @ShootingKing-AM #2084)
* Fix segfault on Linux (by @SniperJoe #2090)
* Fix protocol break in v20.7.0 (by @zarik5 2098)

### v20.7.1 (2024-04-11)

* Fix colors on Pico (by @shinyquagsire23 and @zarik5)
* Fix joystick gesture offset on right hand (by @jarettmillard #2065)

## v20.7.0 (2024-04-06)

* Add AV1 support on Windows/AMD (by @barnabwhy #1967)
* Add AV1 support on Linux/Nvidia (by @wsippel #1975, @Vixea #1994)
* Add HDR support on Windows (by @shinyquagsire23 #2030)
* Add full range encoding support (by @shinyquagsire23 #2011, @Vixea #1971)
* Fix VAAPI encoder on Intel GPUs (by @nowrep #1981)
* Add Pre-Analysis support on Windows/AMD (by @barnabwhy #1985)
* Add linux hardware encoding checks (by @Meister1593 #2042 #2055)
* Add full body tracking support on Quest (by @barnabwhy #1979, @galister #1984)
* Fix aux-bones in SteamVR (by @shinyquagsire23 #2009)
* Make USB connection work when WiFi is disabled (by @Meister1593 #1962)
* Add mDNS discovery on the server (by @zarik5 #1978)
* Fix audio when disconnecting headphones in headset (by @Okabintaro #2025 #2040)
* Add compatibility layer for surround audio devices (by @barnabwhy #2026)
* Fix black screen on Vive Focus 3, XR Elite (by @zarik5)
* Fix stuttering on Linux after recentering (by @galister #2017)
* Fixes for Flatpak (by @jkcdarunday #1980, @Meister1593 #2039 #2044)
* Change colors of lobby room (by @barnabwhy #1968)
* Remove WIX installer (by @zarik5)
* Remove AppImage (by @Meister1593 #2056)

### v20.6.1 (2024-01-26)

* Add AV1 support, only for Linux/VAAPI, with 10bits support (by @wsippel #1955 #1964)
* Fix image corruption on h264/VAAPI (by @galister / @nowrep #1956)

## v20.6.0 (2024-01-10)

* Add tongue tracking for Quest Pro (by @zarik5)
  * This is a breaking change in the protocol, but only affects Quest Pro users.
  * Only VRCFT ALVR module v1.2.0 and up is supported
* Add Quest 3 emulation mode + icons for SteamVR HUD (by @Goodguy140 #1926)
* Add Type of Service (ToS) socket settings, tested only on Linux (by @Vixea #1946)
* Add software decoding option and fallback (by @20kdc #1933)
* Add Baseline encoding option for h264 (by @20kdc #1932)
* Fix ADB connection (by @The-personified-devil #1942)
* Fix rare bug preventing reconnections on wifi (by @zarik5)

## v20.5.0 (2023-12-05)

* Fix Vulkan layer GPU loading (by @nairaner #1847)
* Fix dynamic bitrate for VAAPI (by @nowrep #1863)
* Add notification tips (by @zarik5 #1865)
* Fix hand tracking for Lynx R1 (by @technobaboo #1874)
* Various wiki updates
* Fix battery update during streming (by @zarik5)
* Fix playspace recentering delay (by @zarik5)
* Support eye tracking for Pico 4 Pro (by @zarik5 @Meister1593 #1897)
* Add desktop file for Flatpak (by @Vixea #1906)
* Install audio dependencies from the setup wizard (by @Meister1593 #1893, @zarik5)
* Significantly reduce latency with NVENC on Linux (by @nowrep @Xaphiosis #1911)
* Fix SteamVR hanging when restarting on Linux (by @Vixea @zarik5)
* Other dashboard updates

### v20.4.3 (2023-10-06)

* Fix dashboard crash on Windows
* Fix settings reset bug when upgrading (session extrapolation failed)

### v20.4.2 (2023-09-22)

* Fix YVR crash because of invalid controller bindings

### v20.4.1 (2023-09-19)

* Fix inverted `Enable skeleton` switch
* Add `Only touch` gestures option

## v20.4.0 (2023-09-15)

* Full hand tracking gestures support, with joystick (by @barnabwhy #1794)
* Fully remappable controller buttons (by @zarik5 #1817)
* Custom controller profile (by @zarik5)
* Fix Nvidia support on Linux (by @Killrmemz #1830)

### v20.3.1 (2023-09-11)

* Fix some controller buttons not working
* Fix changing controller emulation profile not triggering a SteamVR restart
* Add back Rift S controller emulation profile

## v20.3.0 (2023-09-08)

* Add Lynx R1 headset support (by @zarik5 #1823)
  * Currently there is an issue with hand tracking which is being investigated
* Make settings sections collapsible (by @zarik5)
* Other UI tweaks (by @zarik5)
* *Actually* fix controller freeze (by @zarik5)
* Fix Pico controller buttons (by @zarik5 @galister @Meister1593 #1820)
* Fix bitrate hikes when "Adapt to framerate" is enabled (by @zarik5)
* Fix Nvenc encoder on Linux (by @Killrmemz #1824)
* Timeout connection if lingering (by @zarik5)
* Fix warmstart crash on client (by @ShootingKing-AM #1813)

### v20.2.1 (2023-08-27)

* Fix VRCFaceTracking mode panicing.
* (Potential) Fix for dashboard crash on Wayland.

## v20.2.0 (2023-08-26)

* Add Flatpak build (by @CharlieQLe #1683 #1724 #1735 #1742, @Meister1593 #1769)
* Finish VRCFaceTracking support (by @zarik5)
  * You can download the ALVR Module from the VRCFaceTracking app itself.
  * Only supports the Quest Pro at the moment.
* New more performant sockets implementation (by @zarik5)
  * Zero copy + zero allocations, and provides better packet prioritization.
* Avoid controller freezing during high latency (by @zarik5)
* Add message popups on Linux (disabled on the appimage build) (by @zarik5 #1711)
* Show backtrace on unhandled exceptions (Windows only) (by @zarik5)
  * Previously these would make SteamVR hard crash without any useful log
* Optionally show full backtraces for logs (by @zarik5)
* Add option to select client log level (by zarik5)
* Make Log tab stick to bottom (by @zarik5)
* Encoder fixes on Linux (by @nowrep #1751 #1753 #1767 #1768 #1796, @Vixea #1805)
* Use Constant bitrate mode by default
* Support rolling video recording (by @zarik5)
* Fix OpenGL crash on the client (by @ShootingKing-AM #1801)
* Fix white dashboard bug on Linux (by @zarik5)

## v20.1.0 (2023-06-20)

* Fix firewall rules on Windows (by @zarik5)
* Fix firewall rules on linux for the tar.gz (by @Vixea #1675)
* Add bitrate graph (by @zarik5 #1689)
* Add encoder latency limiter (by @zarik5 #1678)
* Fix network latency limiter (by @zarik5)
* Fix image corruption on AMD (by @zarik5 #1681)
* Fix dashboard audio dropdowns on Linux (by @zarik5)
* Add connection status for clients (by @zarik5 #1688)
* Fix HMD plugged status (by @zarik5)
* Fix crash on some Unreal Engine 5 games (by @deiteris #1685)
* Add option to disable game render optimization (by @zarik5)
* Add separate history size for bitrate (by @zarik5)

# v20.0.0 (2023-06-02)

* New OpenXR-based client, add support for Vive Focus 3/XR Elite, Pico 4/Neo 3 and YVR 1/2. Worked on by:
  * @zarik5 #1321
  * @galister #1321, #1442
  * @deiteris #1434, #1439, #1445
* New egui (OpenGL) dashboard
  * The launcher is replaced by the new dashboard executable.
  * by @Kirottu #1247 #1274, @zarik5, @m00nwtchr #1292, @TheComputerNerd88 #1574 #1575 #1576 1582
* Add position and rotation recentering modes (by @zarik5 #1321)
  * Defaults to local floor and local yaw.
* Add support for eye and face tracking (by @zarik5 #1577)
  * Currently supporting VRChat Eye OSC, VRCFaceTracking support coming soon
* Reduce game rendering latency (by @zarik5)
* Apply some settings in real-time (by @zarik5 #1635)
* New more consistent controller prediction algorithm (by @zarik5 #1561)
* Controller input fixes (by @zarik5 #1560)
* Soft-toggle controllers at runtime (by @galister #1600)
* New wiki hosted in the main git tree (by @m00nwtchr #1309)
* Send client log to streamer (by @zarik5)
* Encoder improvements (by @nowrep #1562 #1565 #1568, @deiteris #1403 #1422 #1400 #1402, @zarik5 #1564)
* Remove Forward Error Correction (by @zarik5: #1384, #1389; @deiteris: #1386, #1387, #1390)
* Unified code for NAL parsing (by @deiteris #1403, #1422, #1400, #1402)
* Some tweaks for alvr_client_core compatibility (by @ShootingKing-AM #1580 #1578 #1586 #1624 #1621)
* Fix server build with clang (by @nowrep)

### v19.1.1 (2023-03-03)

* Relax discovery protocol for future ALVR versions

## v19.1.0 (2023-02-14)

* Encoder improvements and new Linux server compositor:
  * @deiteris #1227, #1252, #1281, #1287, #1302, #1304, #1318, #1331, #1336, #1368, #1393, #1367, #1397
  * @Vixea #1227, #1254, #1412
  * @nowrep #1251, #1261, #1253, #1267, #1264, #1266, #1273, #1272, #1277, #1280, #1279, #1278, #1282, #1265, #1294, #1295, #1312, #1314, #1316, #1325, #1328, #1326, #1330, #1334, #1338, #1329, #1346, #1350, #1357, #1352, #1348, #1365, #1349, #1361, #1370, #1372, #1393
  * @m00nwtchr #1347
  * @galister #1428, #1429
* Controller fixes (by @Timocop #1236 #1241)
* Vulkan layer fixes (by @nowrep #1291, #1293, #1324, #1339, #1376)
* Show client IP in the headset and dashboard (by @zarik5)
* Disable Wi-Fi scans (by @zarik5)
* Reduce lag after loading screens (by @zarik5)
* Fix server debug builds (by @nowrep #1288)
* Add trigger/grip threshold (by @sctanf)
* Don't spam stdout on Linux (by @nowrep #1317)
* Fix recentering on Linux (by @nowrep #1353)


================================================
FILE: CONTRIBUTING.md
================================================
# Style

Checklist for code style. This is on top of common Rust styling rules. These rules are not mandatory but I might point them out if not respected in PRs :) -zarik

## Naming

- Respect Rust naming conventions (not respecting this will cause a warning).
- Add useful information in the name, with the exception of indices for iterating.
- Do not put type or scope information in the name.
- Avoid abbreviations.
- Avoid prefixes and suffixes.
- if necessary prefer suffixes rather than prefixes.
- `_ref` or `_mut` suffixes are accepted when you want to put emphasis on that the variable is a mutable reference, and so assigning values has side effects, even if not consumed later. Suffixes are not needed if the variable is only mutable or instead a immutable reference.
- Use `maybe_` prefix if the variable is an `Option` or `Result`. Omit if it's clear from the context. Never use it for parameter or field definitions.
- Shadowing is encouraged.
- If shadowing cannot be used and two variables have similar meaning but different types, suffix the variable with the least useful or least specialized type with its type. Example:

    ```rust
    let myfile_string = "./file.txt";
    let myfile = Path::new(my_file_string);
    ```

- If both directory and file paths are used in the same context, suffix directories with `_dir` and files with `_path`. Suffix file names with `_fname`.

## Top level definitions

- For each file, define in order: private imports, public imports, ffi bindings import, private constants, public constants, private structs, public structs, private top level functions, public top level functions.

### Imports

- Do not leave spaces between imports, only between the private and public import blocks.
- Define imports in alphabetical order (use cargo fmt).
- Group imports using braces when there are common parts of the path.

### Structs

- Prefer adding trait bounds to the impl type parameters instead of struct type parameters
- Define in order: struct, Default impl, custom impl, Drop impl, all in the same module. Do not split the custom impl.

## Spacing

Smartly use empty newlines between blocks of code to improve legibility

- Rust recommends not to specify the return keyword when returning at the end of a function. To put emphasis on the return expression, isolate it with a empty new line just before.
- Inside each block (function, if/else/while/for etc or just braces) make so that there are roughly 2 to 6 blocks of code separated by empty lines for the amount of code that fits in a single screen (long functions that span multiple screens can have way more than 6 block). Check existing codebase for an example.
- Spaces between groups of statements should be done so the groups are similar is size and that each achieves a specific purpose. You should be able to easily describe what the group does in few words, even if you don't comment it (because the meaning should be self evident).
- Do not define variables at the start of the function/block, but do define them at the start of the functional group delimited by spaces.

## Comments

- It's important to use comments when the meaning or inner workings of a piece of code is not clear from the context. Well-named symbols (variables and functions) are often enough. In doubt do use comments.
- Do not add comments about how certain parts of the language/std library work, unless it's about quirks of features.

## Panicking and error handling

- Use of `panic!()` is discouraged
- When matching exhaustively, prefer `unreachable!()` over `panic!()` for certain branches.
- `unwrap()` is discouraged, but prefer `unwrap()` over `expect()` (bubble up the error instead).
- Prefer `.get()` to index a collection rather than `[]`, unless extremely certain it will never index out of bounds.
- Add a `// # Safety` comment before a statement that contains a `unwrap()` or raw indexing, explaining why it should never crash.
- Use `todo!()` to mark unfinished code (it returns `!` and so it helps with the missing return statement).

## Code repetition and maintainability

- Lean towards the DRY rule, without overdoing it.
- Extract a piece of code (in a function or lambda) only when it is used two or more times and it doesn't depend on many parameters.
- Always extract constants for "arbitrary" values (literals) which are chosen with no absolute rule and makes sense to change in the future. Example: time interval between resending discovery packet. Opposite example: number of eyes on a human head (it's always going to be 2, no need to use a constant to change its value in the future :) ).
- Prefer defining constants at the start of the file, even if used locally in a single function.
- Prefer using "complex" types for constants, if the std library allows it. Example: prefer using `Duration` instead of an integer type if the constant represents a time duration. Same with `Path` vs string.

## Structural soundness

- Try to avoid invalid states in the data, using Rust enums. Example: do not use `resumed` + `streaming` boolean variables if the state `resumed == false` + `streaming == true` is invalid. Instead use `enum State { Paused, Resumed, Streaming }`.
- Make full use of pattern matching with `if let` and `while let`, this reduces the use of `unwrap()`.


================================================
FILE: Cargo.toml
================================================
[workspace]
resolver = "2"
members = ["alvr/*"]

[workspace.package]
version = "21.0.0-dev12"
edition = "2024"
rust-version = "1.88"
authors = ["alvr-org"]
license = "MIT"

[workspace.dependencies]
alvr_adb = { path = "alvr/adb" }
alvr_audio = { path = "alvr/audio" }
alvr_client_core = { path = "alvr/client_core" }
alvr_common = { path = "alvr/common" }
alvr_events = { path = "alvr/events" }
alvr_filesystem = { path = "alvr/filesystem" }
alvr_graphics = { path = "alvr/graphics" }
alvr_gui_common = { path = "alvr/gui_common" }
alvr_packets = { path = "alvr/packets" }
alvr_server_core = { path = "alvr/server_core"}
alvr_server_io = { path = "alvr/server_io" }
alvr_session = { path = "alvr/session" }
alvr_sockets = { path = "alvr/sockets" }
alvr_system_info = { path = "alvr/system_info" }

[profile.release]
debug = "limited"
strip = false

[profile.distribution]
inherits = "release"
lto = true


================================================
FILE: LICENSE
================================================
Copyright (c) 2018-2019 polygraphene
Copyright (c) 2020-2024 alvr-org

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

================================================
FILE: README.md
================================================
<p align="center"> <img width="500" src="resources/ALVR-Grey.svg"/> </p>

# ALVR - Air Light VR

[![badge-discord][]][link-discord] [![badge-matrix][]][link-matrix] [![badge-opencollective][]][link-opencollective]

Stream VR games from your PC to your headset over Wi-Fi.  
This is a fork of [ALVR](https://github.com/polygraphene/ALVR).

### Direct download (latest version):
### [Windows Launcher](https://github.com/alvr-org/ALVR/releases/latest/download/alvr_launcher_windows.zip) | [Linux Launcher](https://github.com/alvr-org/ALVR/releases/latest/download/alvr_launcher_linux.tar.gz)

## Compatibility

|          VR Headset          |                                        Support                                         |
| :--------------------------: | :------------------------------------------------------------------------------------: |
|       Apple Vision Pro       |    :heavy_check_mark: ([store link](https://apps.apple.com/app/alvr/id6479728026))     |
|      Quest 1/2/3/3S/Pro      | :heavy_check_mark: ([store link](https://www.meta.com/experiences/7674846229245715) *) |
|     Pico Neo 3/4/4 Ultra     |                                   :heavy_check_mark:                                   |
|    Play For Dream YVR 1/2/MR |                                   :heavy_check_mark:                                   |
| Vive Focus 3/Vision/XR Elite |                                   :heavy_check_mark:                                   |
|           Lynx R1            |                                   :heavy_check_mark:                                   |
|     PhoneVR (smartphone)     |     :heavy_check_mark: ** ([repo](https://github.com/PhoneVR-Developers/PhoneVR))      |
|        Android/Monado        |                                      :warning: **                                      |
|          Oculus Go           |                 :x: ([old repo](https://github.com/polygraphene/ALVR))                 |

\* ALVR for Quest 1 is not available through the Meta store.  
\** Works on some smartphones, but has not been extensively tested.  

|     PC OS      |                                    Support                                    |
| :------------: | :---------------------------------------------------------------------------: |
| Windows 10/11  | :heavy_check_mark: ([store link](https://store.steampowered.com/app/3312710)) |
| Windows XP/7/8 |                                      :x:                                      |
|     Linux      |                             :heavy_check_mark:***                             |
|     macOS      |                                      :x:                                      |

\*** Please check the wiki for detailed compatibility information.

### Requirements

-   A supported standalone VR headset (see compatibility table above).
-   SteamVR.
-   A high-end gaming PC:
    -   See the OS compatibility table above.
    -   NVIDIA GPU with NVENC support (GTX 1000 series or newer), an AMD GPU with AMF VCE support, or an INTEL GPU with VPL support (Arc, Tiger Lake or newer), with the latest drivers.
    -   On laptops with both an integrated GPU (Intel HD, AMD iGPU) and a dedicated GPU (NVIDIA GTX/RTX, AMD HD/R5/R7), make sure to assign the dedicated GPU (or "high performance graphics adapter") to ALVR and SteamVR for the best performance and compatibility.  
        (NVIDIA: Nvidia Control Panel → 3D Settings → Application Settings; AMD: similar method)

-   Network:
    -   802.11ac 5 GHz Wi-Fi for the headset, and wired Ethernet for the PC is recommended.
    -   The PC and the headset must be connected to the same router (or use a routed connection as described [here](https://github.com/alvr-org/ALVR/wiki/ALVR-v14-and-Above)).

## Installation

Follow the [installation guide](https://github.com/alvr-org/ALVR/wiki/Installation-guide).

## Troubleshooting

-   See the [Troubleshooting](https://github.com/alvr-org/ALVR/wiki/Troubleshooting) page, and [Linux Troubleshooting](https://github.com/alvr-org/ALVR/wiki/Linux-Troubleshooting) if applicable.
-   Configuration recommendations and additional information can be found [here](https://github.com/alvr-org/ALVR/wiki/Information-and-Recommendations).

## Uninstallation

Open `ALVR Dashboard.exe`, go to the `Installation` tab, then press `Remove firewall rules`.  
Close the ALVR window and delete the ALVR folder.

## Build from Source

Follow the [build guide](https://github.com/alvr-org/ALVR/wiki/Building-From-Source).

## License

ALVR is licensed under the [MIT License](LICENSE).

## Privacy Policy

ALVR apps do not directly collect any personal data.

## Donate

If you would like to support this project, you can donate through our [Open Source Collective account](https://opencollective.com/alvr).

[badge-discord]: https://img.shields.io/discord/720612397580025886?style=for-the-badge&logo=discord&color=5865F2 "Join us on Discord"
[link-discord]: https://discord.gg/ALVR
[badge-matrix]: https://img.shields.io/static/v1?label=chat&message=%23alvr&style=for-the-badge&logo=matrix&color=blueviolet "Join us on Matrix"
[link-matrix]: https://matrix.to/#/#alvr:ckie.dev?via=ckie.dev
[badge-opencollective]: https://img.shields.io/opencollective/all/alvr?style=for-the-badge&logo=opencollective&color=79a3e6 "Donate"
[link-opencollective]: https://opencollective.com/alvr


================================================
FILE: about.toml
================================================
accepted = [
    "MIT",
    "Apache-2.0",
    "Apache-2.0 WITH LLVM-exception",
    "BSD-2-Clause",
    "BSD-3-Clause",
    "BSL-1.0",
    "bzip2-1.0.6",
    "CC0-1.0",
    "CDLA-Permissive-2.0",
    "ISC",
    "LicenseRef-UFL-1.0",
    "MPL-2.0",
    "OFL-1.1",
    "OpenSSL",
    "Ubuntu-font-1.0",
    "Unicode-DFS-2016",
    "Unicode-3.0",
    "Unlicense",
    "Zlib",
    "zlib-acknowledgement",
]
targets = [
    "x86_64-pc-windows-msvc",
    "x86_64-unknown-linux-gnu",
    "aarch64-linux-android",
    "wasm32-unknown-unknown",
]
workarounds = ["ring"]
filter-noassertion = true


================================================
FILE: alvr/adb/Cargo.toml
================================================
[package]
name = "alvr_adb"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
license.workspace = true

[dependencies]
alvr_common.workspace = true
alvr_filesystem.workspace = true
alvr_system_info.workspace = true
alvr_session.workspace = true

anyhow = "1"
ureq = "3"
zip = "4"


================================================
FILE: alvr/adb/src/commands.rs
================================================
// https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/docs/user/adb.1.md

use crate::parse::{self, Device, ForwardedPorts};
use alvr_filesystem as afs;
use anyhow::{Context, Result, anyhow};
use std::{
    collections::HashSet,
    io::{Cursor, Read},
    process::Command,
    str::FromStr,
    time::Duration,
};
use zip::ZipArchive;

#[cfg(windows)]
use std::os::windows::process::CommandExt;

// https://developer.android.com/tools/releases/platform-tools#revisions
// NOTE: At the time of writing this comment, the revisions section above
// shows the latest version as 35.0.2, but the latest that can be downloaded
// by specifying a version is 35.0.0
const PLATFORM_TOOLS_VERSION: &str = "-latest"; // E.g. "_r35.0.0"

#[cfg(target_os = "linux")]
const PLATFORM_TOOLS_OS: &str = "linux";
#[cfg(target_os = "macos")]
const PLATFORM_TOOLS_OS: &str = "darwin";
#[cfg(windows)]
const PLATFORM_TOOLS_OS: &str = "windows";

const REQUEST_TIMEOUT: Duration = Duration::from_secs(5);

fn get_command(adb_path: &str, args: &[&str]) -> Command {
    let mut command = Command::new(adb_path);
    command.args(args);

    #[cfg(windows)]
    command.creation_flags(0x08000000); // CREATE_NO_WINDOW

    command
}

pub fn download(url: &str, progress_callback: impl Fn(usize, Option<usize>)) -> Result<Vec<u8>> {
    let agent: ureq::Agent = ureq::Agent::config_builder()
        .timeout_global(Some(REQUEST_TIMEOUT))
        .build()
        .into();
    let response = agent.get(url).call()?;
    let maybe_expected_size = response
        .headers()
        .get("Content-Length")
        .and_then(|v| v.to_str().ok()?.parse::<usize>().ok());
    let mut result = maybe_expected_size
        .map(Vec::with_capacity)
        .unwrap_or_default();
    let mut reader = response.into_body().into_reader();
    let mut buffer = vec![0; 65535];
    loop {
        let read_count: usize = reader.read(&mut buffer)?;
        if read_count == 0 {
            break;
        }
        result.extend_from_slice(&buffer[..read_count]);
        let current_size = result.len();
        (progress_callback)(current_size, maybe_expected_size);
    }

    Ok(result)
}

///////////
// Activity

pub fn get_process_id(
    adb_path: &str,
    device_serial: &str,
    process_name: &str,
) -> Result<Option<usize>> {
    let output = get_command(
        adb_path,
        &["-s", device_serial, "shell", "pidof", process_name],
    )
    .output()
    .context(format!("Failed to get ID of process {process_name}"))?;
    let text = String::from_utf8_lossy(&output.stdout).trim().to_owned();
    if text.is_empty() {
        return Ok(None);
    }
    let process_id = text
        .parse::<usize>()
        .context("Failed to parse process ID")?;

    Ok(Some(process_id))
}

pub fn is_activity_resumed(
    adb_path: &str,
    device_serial: &str,
    activity_name: &str,
) -> Result<bool> {
    let output = get_command(
        adb_path,
        &[
            "-s",
            device_serial,
            "shell",
            "dumpsys",
            "activity",
            activity_name,
        ],
    )
    .output()
    .context(format!("Failed to get state of activity {activity_name}"))?;
    let text = String::from_utf8_lossy(&output.stdout);
    if let Some(line) = text
        .lines()
        .map(|l| l.trim())
        .find(|l| l.contains("mResumed"))
    {
        let (entry, _) = line
            .split_once(' ')
            .ok_or(anyhow!("Failed to split resumed state line"))?;
        let (_, value) = entry
            .split_once('=')
            .ok_or(anyhow!("Failed to split resumed state entry"))?;
        match value {
            "true" => Ok(true),
            "false" => Ok(false),
            _ => Err(anyhow!("Failed to parse resumed state value"))?,
        }
    } else {
        Err(anyhow!("Failed to find resumed state line"))
    }
}

///////////////////
// ADB Installation

pub fn require_adb(
    layout: &afs::Layout,
    progress_callback: impl Fn(usize, Option<usize>),
) -> Result<String> {
    if let Some(path) = get_adb_path(layout) {
        Ok(path)
    } else {
        install_adb(layout, progress_callback).context("Failed to install ADB")?;
        Ok(get_adb_path(layout).context("Failed to get ADB path after installation")?)
    }
}

fn install_adb(
    layout: &afs::Layout,
    progress_callback: impl Fn(usize, Option<usize>),
) -> Result<()> {
    let mut reader = Cursor::new(download_adb(progress_callback)?);
    ZipArchive::new(&mut reader)?.extract(layout.executables_dir.clone())?;

    Ok(())
}

fn download_adb(progress_callback: impl Fn(usize, Option<usize>)) -> Result<Vec<u8>> {
    let url = get_platform_tools_url();

    download(&url, progress_callback).context(format!("Failed to download ADB from {url}"))
}

fn get_platform_tools_url() -> String {
    format!(
        "https://dl.google.com/android/repository/platform-tools{PLATFORM_TOOLS_VERSION}-{PLATFORM_TOOLS_OS}.zip"
    )
}

///////////////
// Applications

pub fn start_application(adb_path: &str, device_serial: &str, application_id: &str) -> Result<()> {
    get_command(
        adb_path,
        &[
            "-s",
            device_serial,
            "shell",
            "monkey",
            "-p",
            application_id,
            "1",
        ],
    )
    .output()
    .context(format!("Failed to start {application_id}"))?;

    Ok(())
}

//////////
// Devices

pub fn list_devices(adb_path: &str) -> Result<Vec<Device>> {
    let output = get_command(adb_path, &["devices", "-l"])
        .output()
        .context("Failed to list ADB devices")?;
    let text = String::from_utf8_lossy(&output.stdout);
    let devices = text
        .lines()
        .skip(1)
        .filter_map(parse::parse_device)
        .collect();

    Ok(devices)
}

///////////
// Packages

pub fn install_package(adb_path: &str, device_serial: &str, apk_path: &str) -> Result<()> {
    get_command(adb_path, &["-s", device_serial, "install", "-r", apk_path])
        .output()
        .context(format!("Failed to install {apk_path}"))?;

    Ok(())
}

pub fn is_package_installed(
    adb_path: &str,
    device_serial: &str,
    application_id: &str,
) -> Result<bool> {
    let found = list_installed_packages(adb_path, device_serial)
        .context(format!(
            "Failed to check if package {application_id} is installed"
        ))?
        .contains(application_id);

    Ok(found)
}

pub fn uninstall_package(adb_path: &str, device_serial: &str, application_id: &str) -> Result<()> {
    get_command(
        adb_path,
        &["-s", device_serial, "uninstall", application_id],
    )
    .output()
    .context(format!("Failed to uninstall {application_id}"))?;

    Ok(())
}

pub fn list_installed_packages(adb_path: &str, device_serial: &str) -> Result<HashSet<String>> {
    let output = get_command(
        adb_path,
        &["-s", device_serial, "shell", "pm", "list", "package"],
    )
    .output()
    .context("Failed to list installed packages")?;
    let text = String::from_utf8_lossy(&output.stdout);
    let packages = text.lines().map(|l| l.replace("package:", "")).collect();

    Ok(packages)
}

////////
// Paths

/// Returns the path of a local (i.e. installed by ALVR) or OS version of `adb` if found, `None` otherwise.
pub fn get_adb_path(layout: &afs::Layout) -> Option<String> {
    let exe_name = afs::exec_fname("adb").to_owned();
    let adb_path = get_command(&exe_name, &[])
        .output()
        .is_ok()
        .then_some(exe_name);

    adb_path.or_else(|| {
        let path = layout.local_adb_exe();

        path.try_exists()
            .unwrap_or(false)
            .then(|| path.to_string_lossy().to_string())
    })
}

////////
// Utility
pub fn get_uptime(adb_path: &str, device_serial: &str) -> Result<Duration> {
    let output = get_command(
        adb_path,
        &["-s", device_serial, "shell", "cat", "/proc/uptime"],
    )
    .output()
    .context("Failed to get system uptime")?;

    let output_str = String::from_utf8_lossy(&output.stdout);

    let uptime_string = output_str
        .split_ascii_whitespace()
        .next()
        .context("Empty result from /proc/uptime")?;

    let uptime = f64::from_str(uptime_string).context("Cannot parse uptime into an f64")?;

    Duration::try_from_secs_f64(uptime).context("Invalid f64 value for a duration ")
}

//////////////////
// Port forwarding

pub fn list_forwarded_ports(adb_path: &str, device_serial: &str) -> Result<Vec<ForwardedPorts>> {
    let output = get_command(adb_path, &["-s", device_serial, "forward", "--list"])
        .output()
        .context(format!(
            "Failed to list forwarded ports of device {device_serial:?}"
        ))?;
    let text = String::from_utf8_lossy(&output.stdout);
    let forwarded_ports = text
        .lines()
        .filter_map(parse::parse_forwarded_ports)
        .collect();

    Ok(forwarded_ports)
}

pub fn forward_port(adb_path: &str, device_serial: &str, port: u16) -> Result<()> {
    get_command(
        adb_path,
        &[
            "-s",
            device_serial,
            "forward",
            &format!("tcp:{port}"),
            &format!("tcp:{port}"),
        ],
    )
    .output()
    .context(format!(
        "Failed to forward port {port:?} of device {device_serial:?}"
    ))?;

    Ok(())
}

/////////
// Server

pub fn kill_server(adb_path: &str) -> Result<()> {
    get_command(adb_path, &["kill-server"])
        .output()
        .context("Failed to kill ADB server")?;

    Ok(())
}


================================================
FILE: alvr/adb/src/lib.rs
================================================
pub mod commands;
mod parse;

use alvr_common::anyhow::Result;
use alvr_common::{dbg_connection, error, warn};
use alvr_session::WiredClientAutoLaunchConfig;
use alvr_system_info::{
    ClientFlavor, PACKAGE_NAME_GITHUB_DEV, PACKAGE_NAME_GITHUB_STABLE, PACKAGE_NAME_STORE,
};
use std::collections::HashSet;
use std::time::Duration;

pub enum WiredConnectionStatus {
    Ready,
    NotReady(String),
}

pub struct WiredConnection {
    adb_path: String,
}

impl WiredConnection {
    pub fn new(
        layout: &alvr_filesystem::Layout,
        download_progress_callback: impl Fn(usize, Option<usize>),
    ) -> Result<Self> {
        let adb_path = commands::require_adb(layout, download_progress_callback)?;

        Ok(Self { adb_path })
    }

    pub fn setup(
        &self,
        control_port: u16,
        stream_port: u16,
        client_type: &ClientFlavor,
        client_autolaunch: Option<WiredClientAutoLaunchConfig>,
    ) -> Result<WiredConnectionStatus> {
        let Some(device_serial) = commands::list_devices(&self.adb_path)?
            .into_iter()
            .filter_map(|d| d.serial)
            .find(|s| !s.starts_with("127.0.0.1"))
        else {
            return Ok(WiredConnectionStatus::NotReady(
                "No wired devices found".to_owned(),
            ));
        };

        let ports = HashSet::from([control_port, stream_port]);
        let forwarded_ports: HashSet<u16> =
            commands::list_forwarded_ports(&self.adb_path, &device_serial)?
                .into_iter()
                .map(|f| f.local)
                .collect();
        let missing_ports = ports.difference(&forwarded_ports);
        for port in missing_ports {
            commands::forward_port(&self.adb_path, &device_serial, *port)?;
            dbg_connection!(
                "setup_wired_connection: Forwarded port {port} of device {device_serial}"
            );
        }

        let Some(process_name) = get_process_name(&self.adb_path, &device_serial, client_type)
        else {
            return Ok(WiredConnectionStatus::NotReady(
                "No suitable ALVR client is installed".to_owned(),
            ));
        };

        if commands::get_process_id(&self.adb_path, &device_serial, &process_name)?.is_none() {
            if let Some(client_autolaunch) = client_autolaunch {
                if client_autolaunch.boot_delay > 0 {
                    match commands::get_uptime(&self.adb_path, &device_serial) {
                        Ok(uptime) => {
                            if uptime < Duration::from_secs(client_autolaunch.boot_delay.into()) {
                                return Ok(WiredConnectionStatus::NotReady(
                                    "Waiting for device boot".to_owned(),
                                ));
                            }
                        }
                        Err(failure) => {
                            warn!("wired_connection: get_uptime failed with {}", failure);
                        }
                    }
                }

                commands::start_application(&self.adb_path, &device_serial, &process_name)?;
                Ok(WiredConnectionStatus::NotReady(
                    "Starting ALVR client".to_owned(),
                ))
            } else {
                Ok(WiredConnectionStatus::NotReady(
                    "ALVR client is not running".to_owned(),
                ))
            }
        } else if !commands::is_activity_resumed(&self.adb_path, &device_serial, &process_name)? {
            Ok(WiredConnectionStatus::NotReady(
                "ALVR client is paused".to_owned(),
            ))
        } else {
            Ok(WiredConnectionStatus::Ready)
        }
    }
}

impl Drop for WiredConnection {
    fn drop(&mut self) {
        dbg_connection!("wired_connection: Killing ADB server");
        if let Err(e) = commands::kill_server(&self.adb_path) {
            error!("{e:?}");
        }
    }
}

pub fn get_process_name(
    adb_path: &str,
    device_serial: &str,
    flavor: &ClientFlavor,
) -> Option<String> {
    let fallbacks = match flavor {
        ClientFlavor::Store => {
            if alvr_common::is_stable() {
                vec![PACKAGE_NAME_STORE, PACKAGE_NAME_GITHUB_STABLE]
            } else {
                vec![PACKAGE_NAME_GITHUB_DEV]
            }
        }
        ClientFlavor::Github => {
            if alvr_common::is_stable() {
                vec![PACKAGE_NAME_GITHUB_STABLE, PACKAGE_NAME_STORE]
            } else {
                vec![PACKAGE_NAME_GITHUB_DEV]
            }
        }
        ClientFlavor::Custom(name) => {
            if alvr_common::is_stable() {
                vec![name, PACKAGE_NAME_STORE, PACKAGE_NAME_GITHUB_STABLE]
            } else {
                vec![name, PACKAGE_NAME_GITHUB_DEV]
            }
        }
    };

    fallbacks
        .iter()
        .find(|name| {
            commands::is_package_installed(adb_path, device_serial, name)
                .is_ok_and(|installed| installed)
        })
        .map(|name| (*name).to_string())
}


================================================
FILE: alvr/adb/src/parse.rs
================================================
// https://cs.android.com/android/platform/superproject/main/+/7dbe542b9a93fb3cee6c528e16e2d02a26da7cc0:packages/modules/adb/transport.cpp;l=1409
// The serial number is printed with a "%-22s" format, meaning that it's a left-aligned space-padded string of 22 characters.
const SERIAL_NUMBER_COLUMN_LENGTH: usize = 22;

// https://cs.android.com/android/platform/superproject/main/+/7dbe542b9a93fb3cee6c528e16e2d02a26da7cc0:packages/modules/adb/adb.h;l=104-122
#[derive(Debug)]
pub enum ConnectionState {
    Authorizing,
    Bootloader,
    Connecting,
    Detached,
    Device,
    Host,
    NoPermissions, // https://cs.android.com/android/platform/superproject/main/+/main:system/core/diagnose_usb/diagnose_usb.cpp;l=83-90
    Offline,
    Recovery,
    Rescue,
    Sideload,
    Unauthorized,
}

pub fn parse_connection_state(value: &str) -> Option<ConnectionState> {
    match value {
        "authorizing" => Some(ConnectionState::Authorizing),
        "bootloader" => Some(ConnectionState::Bootloader),
        "connecting" => Some(ConnectionState::Connecting),
        "detached" => Some(ConnectionState::Detached),
        "device" => Some(ConnectionState::Device),
        "host" => Some(ConnectionState::Host),
        "offline" => Some(ConnectionState::Offline),
        "recovery" => Some(ConnectionState::Recovery),
        "rescue" => Some(ConnectionState::Rescue),
        "sideload" => Some(ConnectionState::Sideload),
        "unauthorized" => Some(ConnectionState::Unauthorized),
        _ => None,
    }
}

fn parse_pair(pair: &str) -> Option<String> {
    let mut slice = pair.split(':');
    let _key = slice.next();

    slice.next().map(|value| value.to_string())
}

// https://cs.android.com/android/platform/superproject/main/+/7dbe542b9a93fb3cee6c528e16e2d02a26da7cc0:packages/modules/adb/adb.h;l=95-100
#[derive(Debug)]
pub enum TransportType {
    Usb,
    Local,
    Any,
    Host,
}

pub fn parse_transport_type(pair: &str) -> Option<TransportType> {
    let mut slice = pair.split(':');
    let _key = slice.next();

    if let Ok(value) = slice.next()?.parse::<u8>() {
        match value {
            0 => Some(TransportType::Usb),
            1 => Some(TransportType::Local),
            2 => Some(TransportType::Any),
            3 => Some(TransportType::Host),
            _ => None,
        }
    } else {
        None
    }
}

// https://cs.android.com/android/platform/superproject/main/+/7dbe542b9a93fb3cee6c528e16e2d02a26da7cc0:packages/modules/adb/transport.cpp;l=1398
#[derive(Debug)]
pub struct Device {
    pub connection_state: Option<ConnectionState>,
    pub device: Option<String>,
    pub model: Option<String>,
    pub product: Option<String>,
    pub serial: Option<String>,
    pub transport_type: Option<TransportType>,
}

pub fn parse_device(line: &str) -> Option<Device> {
    if line.len() < SERIAL_NUMBER_COLUMN_LENGTH {
        return None;
    }
    let (left, right) = line.split_at(SERIAL_NUMBER_COLUMN_LENGTH);
    let serial = (!left.contains("(no serial number)")).then(|| left.trim().to_owned());
    let mut remaining = right.trim();

    let connection_state = if remaining.starts_with("no permissions") {
        // Since the current user's name can be printed in the error message,
        // we are gambling that there's not a "]" in it.
        if let Some((_, right)) = remaining.split_once(']') {
            remaining = right;
            Some(ConnectionState::NoPermissions)
        } else {
            None
        }
    } else if let Some((left, right)) = remaining.split_once(' ') {
        remaining = right;
        parse_connection_state(left)
    } else {
        None
    };

    let mut slices = remaining.split_whitespace();
    let product = slices.next().and_then(parse_pair);
    let model = slices.next().and_then(parse_pair);
    let device = slices.next().and_then(parse_pair);
    let transport_type = slices.next().and_then(parse_transport_type);

    Some(Device {
        connection_state,
        device,
        model,
        product,
        serial,
        transport_type,
    })
}

#[derive(Debug)]
pub struct ForwardedPorts {
    pub local: u16,
    pub remote: u16,
    pub serial: String,
}

pub fn parse_forwarded_ports(line: &str) -> Option<ForwardedPorts> {
    let mut slices = line.split_whitespace();
    let serial = slices.next();
    let local = parse_port(slices.next()?);
    let remote = parse_port(slices.next()?);

    if let Some(serial) = serial
        && let Some(local) = local
        && let Some(remote) = remote
    {
        Some(ForwardedPorts {
            local,
            remote,
            serial: serial.to_owned(),
        })
    } else {
        None
    }
}

fn parse_port(value: &str) -> Option<u16> {
    let mut slices = value.split(':');
    let _protocol = slices.next();
    let maybe_port = slices.next();

    maybe_port.and_then(|p| p.parse::<u16>().ok())
}


================================================
FILE: alvr/audio/Cargo.toml
================================================
[package]
name = "alvr_audio"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
license.workspace = true

[dependencies]
alvr_common.workspace = true
alvr_session.workspace = true
alvr_sockets.workspace = true

cpal = "0.16"
rodio = "0.21"
serde = "1"

[target.'cfg(windows)'.dependencies]
widestring = "1"
windows = { version = "0.61", features = [
    "Win32_Devices_FunctionDiscovery",
    "Win32_Foundation",
    "Win32_Media_Audio_Endpoints",
    "Win32_System_Com_StructuredStorage",
    "Win32_System_Variant",
    "Win32_UI_Shell_PropertiesSystem",
] }

[target.'cfg(target_os = "linux")'.dependencies]
pipewire = { version = "0.8.0", features = ["v0_3_49"] }
libspa-sys = "0.8.0"


================================================
FILE: alvr/audio/src/lib.rs
================================================
#[cfg(windows)]
mod windows;

#[cfg(target_os = "linux")]
pub mod linux;

#[cfg(windows)]
pub use crate::windows::*;

use alvr_common::{
    ConnectionError, ToAny,
    anyhow::{self, Context, Result, bail},
    info,
    parking_lot::Mutex,
};
use alvr_session::{AudioBufferingConfig, CustomAudioDeviceConfig, MicrophoneDevicesConfig};
use alvr_sockets::{StreamReceiver, StreamSender};
use cpal::{
    BufferSize, Host, Sample, SampleFormat, StreamConfig,
    traits::{DeviceTrait, HostTrait, StreamTrait},
};
use rodio::{OutputStreamBuilder, Source};
use std::{collections::VecDeque, sync::Arc, thread, time::Duration};

pub use cpal::Device;

fn device_from_custom_config(
    host: &Host,
    config: &CustomAudioDeviceConfig,
    is_output: bool,
) -> Result<Device> {
    let mut devices = if is_output {
        host.output_devices()?
    } else {
        host.input_devices()?
    };

    Ok(match config {
        CustomAudioDeviceConfig::NameSubstring(name_substring) => devices
            .find(|d| {
                d.name()
                    .map(|name| name.to_lowercase().contains(&name_substring.to_lowercase()))
                    .unwrap_or(false)
            })
            .with_context(|| {
                format!("Cannot find audio device which name contains \"{name_substring}\"")
            })?,
        CustomAudioDeviceConfig::Index(index) => devices
            .nth(*index)
            .with_context(|| format!("Cannot find audio device at index {index}"))?,
    })
}

pub fn new_output(config: Option<&CustomAudioDeviceConfig>) -> Result<Device> {
    let host = cpal::default_host();

    let device = match config {
        None => host
            .default_output_device()
            .context("No output audio device found")?,
        Some(config) => device_from_custom_config(&host, config, true)?,
    };

    Ok(device)
}

pub fn new_input(config: Option<CustomAudioDeviceConfig>) -> Result<Device> {
    let host = cpal::default_host();

    let device = match config {
        None => host
            .default_input_device()
            .context("No input audio device found")?,
        Some(config) => device_from_custom_config(&host, &config, false)?,
    };

    Ok(device)
}

// returns (sink, source)
pub fn new_virtual_microphone_pair(config: MicrophoneDevicesConfig) -> Result<(Device, Device)> {
    // No-op on Windows (this is windows specific code)
    let host = cpal::default_host();

    let (sink_name, source_name) = match config {
        MicrophoneDevicesConfig::Automatic => {
            // NOTE: This will iterate over all devices for every option it tries, if the audio
            // code is slow, change that first
            return [
                MicrophoneDevicesConfig::VAC,
                MicrophoneDevicesConfig::VBCable,
                MicrophoneDevicesConfig::VoiceMeeter,
                MicrophoneDevicesConfig::VoiceMeeterAux,
                MicrophoneDevicesConfig::VoiceMeeterVaio3,
            ]
            .into_iter()
            .find_map(|cable_type| new_virtual_microphone_pair(cable_type).ok())
            .context("No microphones found");
        }

        MicrophoneDevicesConfig::VAC => ("Line 1", "Line 1"),
        MicrophoneDevicesConfig::VBCable => ("CABLE Input", "CABLE Output"),
        MicrophoneDevicesConfig::VoiceMeeter => ("VoiceMeeter Input", "VoiceMeeter Output"),
        MicrophoneDevicesConfig::VoiceMeeterAux => {
            ("VoiceMeeter Aux Input", "VoiceMeeter Aux Output")
        }
        MicrophoneDevicesConfig::VoiceMeeterVaio3 => {
            ("VoiceMeeter VAIO3 Input", "VoiceMeeter VAIO3 Output")
        }

        MicrophoneDevicesConfig::Custom { sink, source } => {
            return Ok((
                device_from_custom_config(&host, &sink, true)?,
                device_from_custom_config(&host, &source, false)?,
            ));
        }
    };

    let sink = host
            .output_devices()?
            .find(|d| d.name().unwrap_or_default().contains(sink_name))
            .context("Virtual Audio Cable, VB-CABLE or VoiceMeeter not found. Please install or reinstall one")?;

    let source = host
        .input_devices()?
        .find(|d| d.name().unwrap_or_default().contains(source_name))
        .context("Matching output microphone not found. Did you rename it?")?;

    Ok((sink, source))
}

pub fn input_sample_rate(dev: &Device) -> Result<u32> {
    let config = dev
        .default_input_config()
        // On Windows, loopback devices are not recognized as input devices. Use output config.
        .or_else(|_| dev.default_output_config())?;

    Ok(config.sample_rate().0)
}

pub enum AudioRecordState {
    Recording,
    ShouldStop,
    Err(Option<anyhow::Error>),
}

pub enum AudioChannel {
    FrontLeft,
    FrontRight,
    Center,
    SurroundLeft,
    SurroundRight,
    BackLeft,
    BackRight,
    Top,
    HighFrontLeft,
    HighFrontRight,
    HighFrontCenter,
    HighBackLeft,
    HighBackRight,
    LowFrequency,
}

fn downmix_channels(channels: &[AudioChannel], data: &[u8], out_channels: u16) -> Vec<u8> {
    let mut left = 0.0;
    let mut right = 0.0;

    for i in 0..channels.len() {
        let [l, r] = match &channels[i] {
            AudioChannel::FrontLeft => [1.0, 0.0],
            AudioChannel::FrontRight => [0.0, 1.0],
            AudioChannel::Center => [0.707, 0.707],
            AudioChannel::SurroundLeft => [0.707, 0.0],
            AudioChannel::SurroundRight => [0.0, 0.707],
            AudioChannel::BackLeft => [0.707, 0.0],
            AudioChannel::BackRight => [0.0, 0.707],
            AudioChannel::Top => [0.577, 0.577],
            AudioChannel::HighFrontLeft => [0.707, 0.0],
            AudioChannel::HighFrontRight => [0.0, 0.707],
            AudioChannel::HighFrontCenter => [0.5, 0.5],
            AudioChannel::HighBackLeft => [0.5, 0.0],
            AudioChannel::HighBackRight => [0.0, 0.5],
            _ => [0.0, 0.0],
        };
        let val = i16::from_ne_bytes([data[i * 2], data[i * 2 + 1]]).to_sample::<f32>();
        left += val * l;
        right += val * r;
    }

    if out_channels == 1 {
        let bytes = ((left + right) / 2.0).to_sample::<i16>().to_ne_bytes();
        vec![bytes[0], bytes[1]]
    } else {
        let left_bytes = left.to_sample::<i16>().to_ne_bytes();
        let right_bytes = right.to_sample::<i16>().to_ne_bytes();
        vec![left_bytes[0], left_bytes[1], right_bytes[0], right_bytes[1]]
    }
}

fn downmix_audio(data: Vec<u8>, in_channels: u16, out_channels: u16) -> Vec<u8> {
    if in_channels == out_channels {
        data
    } else if in_channels == 1 && out_channels == 2 {
        data.chunks_exact(2)
            .flat_map(|c| vec![c[0], c[1], c[0], c[1]])
            .collect()
    } else {
        let channels = match in_channels {
            2 => vec![AudioChannel::FrontLeft, AudioChannel::FrontRight],
            3 => vec![
                AudioChannel::FrontLeft,
                AudioChannel::FrontRight,
                AudioChannel::LowFrequency,
            ],
            4 => vec![
                AudioChannel::FrontLeft,
                AudioChannel::FrontRight,
                AudioChannel::BackLeft,
                AudioChannel::BackRight,
            ],
            6 => vec![
                AudioChannel::FrontRight,
                AudioChannel::Center,
                AudioChannel::LowFrequency,
                AudioChannel::SurroundLeft, // Sometimes actually BackLeft, has same level so it's okay
                AudioChannel::SurroundRight, // Sometimes actually BackRight, has same level so it's okay
            ],
            8 => vec![
                AudioChannel::FrontLeft,
                AudioChannel::FrontRight,
                AudioChannel::Center,
                AudioChannel::LowFrequency,
                AudioChannel::BackLeft,
                AudioChannel::BackRight,
                AudioChannel::SurroundLeft,
                AudioChannel::SurroundRight,
            ],
            _ => unreachable!("Invalid input channel count"),
        };

        data.chunks_exact(in_channels as usize * 2)
            .flat_map(|c| downmix_channels(&channels, c, out_channels))
            .collect()
    }
}

#[allow(unused_variables)]
pub fn record_audio_blocking(
    is_running: Arc<dyn Fn() -> bool + Send + Sync>,
    mut sender: StreamSender<()>,
    device: &Device,
    channels_count: u16,
    mute: bool,
) -> Result<()> {
    let config = device
        .default_input_config()
        // On Windows, loopback devices are not recognized as input devices. Use output config.
        .or_else(|_| device.default_output_config())?;

    if config.channels() > 8 {
        bail!(
            "Audio devices with more than 8 channels are not supported. {}",
            "Please turn off surround audio."
        );
    } else if config.channels() == 5 || config.channels() == 7 {
        bail!(
            "Audio devices with {} channels are not supported.",
            config.channels()
        );
    }

    let stream_config = StreamConfig {
        channels: config.channels(),
        sample_rate: config.sample_rate(),
        buffer_size: BufferSize::Default,
    };

    let state = Arc::new(Mutex::new(AudioRecordState::Recording));

    let stream = device.build_input_stream_raw(
        &stream_config,
        config.sample_format(),
        {
            let state = Arc::clone(&state);
            let is_running = Arc::clone(&is_running);
            move |data, _| {
                let data = if config.sample_format() == SampleFormat::F32 {
                    data.bytes()
                        .chunks_exact(4)
                        .flat_map(|b| {
                            f32::from_ne_bytes([b[0], b[1], b[2], b[3]])
                                .to_sample::<i16>()
                                .to_ne_bytes()
                                .to_vec()
                        })
                        .collect()
                } else {
                    data.bytes().to_vec()
                };

                let data = downmix_audio(data, config.channels(), channels_count);

                if is_running() {
                    sender.send_header_with_payload(&(), &data).ok();
                } else {
                    *state.lock() = AudioRecordState::ShouldStop;
                }
            }
        },
        {
            let state = Arc::clone(&state);
            move |e| *state.lock() = AudioRecordState::Err(Some(e.into()))
        },
        None,
    )?;

    #[cfg(windows)]
    if mute && device.supports_output() {
        crate::windows::set_mute_windows_device(device, true).ok();
    }

    let mut res = stream.play().to_any();

    if res.is_ok() {
        while matches!(*state.lock(), AudioRecordState::Recording) && is_running() {
            thread::sleep(Duration::from_millis(500))
        }

        if let AudioRecordState::Err(e) = &mut *state.lock() {
            res = Err(e.take().unwrap());
        }
    }

    #[cfg(windows)]
    if mute && device.supports_output() {
        set_mute_windows_device(device, false).ok();
    }

    res
}

// Audio callback. This is designed to be as less complex as possible. Still, when needed, this
// callback can render a fade-out autonomously.
#[inline]
pub fn get_next_frame_batch(
    sample_buffer: &mut VecDeque<f32>,
    channels_count: usize,
    batch_frames_count: usize,
) -> Vec<f32> {
    if sample_buffer.len() / channels_count >= batch_frames_count {
        let mut batch = sample_buffer
            .drain(0..batch_frames_count * channels_count)
            .collect::<Vec<_>>();

        if sample_buffer.len() / channels_count < batch_frames_count {
            // Render fade-out. It is completely contained in the current batch
            for f in 0..batch_frames_count {
                let volume = 1. - f as f32 / batch_frames_count as f32;
                for c in 0..channels_count {
                    batch[f * channels_count + c] *= volume;
                }
            }
        }
        // fade-ins and cross-fades are rendered in the receive loop directly inside sample_buffer.

        batch
    } else {
        vec![0.; batch_frames_count * channels_count]
    }
}

// The receive loop is resposible for ensuring smooth transitions in case of disruptions (buffer
// underflow, overflow, packet loss). In case the computation takes too much time, the audio
// callback will gracefully handle an interruption, and the callback timing and sound wave
// continuity will not be affected.
pub fn receive_samples_loop(
    is_running: impl Fn() -> bool,
    receiver: &mut StreamReceiver<()>,
    sample_buffer: Arc<Mutex<VecDeque<f32>>>,
    channels_count: usize,
    batch_frames_count: usize,
    average_buffer_frames_count: usize,
) -> Result<()> {
    let mut recovery_sample_buffer = vec![];
    while is_running() {
        let data = match receiver.recv(Duration::from_millis(500)) {
            Ok(data) => data,
            Err(ConnectionError::TryAgain(_)) => continue,
            Err(ConnectionError::Other(e)) => return Err(e),
        };
        let (_, packet) = data.get()?;

        let new_samples = packet
            .chunks_exact(2)
            .map(|c| i16::from_ne_bytes([c[0], c[1]]).to_sample::<f32>())
            .collect::<Vec<_>>();

        let mut sample_buffer_ref = sample_buffer.lock();

        if data.had_packet_loss() {
            info!("Audio packet loss!");

            if sample_buffer_ref.len() / channels_count < batch_frames_count {
                sample_buffer_ref.clear();
            } else {
                // clear remaining samples
                sample_buffer_ref.drain(batch_frames_count * channels_count..);
            }

            recovery_sample_buffer.clear();
        }

        if sample_buffer_ref.len() / channels_count < batch_frames_count {
            recovery_sample_buffer.extend(sample_buffer_ref.drain(..));
        }

        if sample_buffer_ref.is_empty() || data.had_packet_loss() {
            recovery_sample_buffer.extend(&new_samples);

            if recovery_sample_buffer.len() / channels_count
                > average_buffer_frames_count + batch_frames_count
            {
                // Fade-in
                for f in 0..batch_frames_count {
                    let volume = f as f32 / batch_frames_count as f32;
                    for c in 0..channels_count {
                        recovery_sample_buffer[f * channels_count + c] *= volume;
                    }
                }

                if data.had_packet_loss()
                    && sample_buffer_ref.len() / channels_count == batch_frames_count
                {
                    // Add a fade-out to make a cross-fade.
                    for f in 0..batch_frames_count {
                        let volume = 1. - f as f32 / batch_frames_count as f32;
                        for c in 0..channels_count {
                            recovery_sample_buffer[f * channels_count + c] +=
                                sample_buffer_ref[f * channels_count + c] * volume;
                        }
                    }

                    sample_buffer_ref.clear();
                }

                sample_buffer_ref.extend(recovery_sample_buffer.drain(..));
                info!("Audio recovered");
            }
        } else {
            sample_buffer_ref.extend(&new_samples);
        }

        // todo: use smarter policy with EventTiming
        let buffer_frames_size = sample_buffer_ref.len() / channels_count;
        if buffer_frames_size > 2 * average_buffer_frames_count + batch_frames_count {
            info!("Audio buffer overflow! size: {buffer_frames_size}");

            let drained_samples = sample_buffer_ref
                .drain(0..(buffer_frames_size - average_buffer_frames_count) * channels_count)
                .collect::<Vec<_>>();

            // Render a cross-fade.
            for f in 0..batch_frames_count {
                let volume = f as f32 / batch_frames_count as f32;
                for c in 0..channels_count {
                    let index = f * channels_count + c;
                    sample_buffer_ref[index] = sample_buffer_ref[index]
                        .mul_add(volume, drained_samples[index] * (1. - volume));
                }
            }
        }
    }

    Ok(())
}

struct StreamingSource {
    sample_buffer: Arc<Mutex<VecDeque<f32>>>,
    current_batch: Vec<f32>,
    current_batch_cursor: usize,
    channels_count: usize,
    sample_rate: u32,
    batch_frames_count: usize,
}

impl Source for StreamingSource {
    fn current_span_len(&self) -> Option<usize> {
        None
    }

    fn channels(&self) -> u16 {
        self.channels_count as _
    }

    fn sample_rate(&self) -> u32 {
        self.sample_rate
    }

    fn total_duration(&self) -> Option<std::time::Duration> {
        None
    }
}

impl Iterator for StreamingSource {
    type Item = f32;

    #[inline]
    fn next(&mut self) -> Option<f32> {
        if self.current_batch_cursor == 0 {
            self.current_batch = get_next_frame_batch(
                &mut self.sample_buffer.lock(),
                self.channels_count,
                self.batch_frames_count,
            );
        }

        let sample = self.current_batch[self.current_batch_cursor];

        self.current_batch_cursor =
            (self.current_batch_cursor + 1) % (self.batch_frames_count * self.channels_count);

        Some(sample)
    }
}

pub fn play_audio_loop(
    is_running: impl Fn() -> bool,
    device: &Device,
    channels_count: u16,
    sample_rate: u32,
    config: AudioBufferingConfig,
    receiver: &mut StreamReceiver<()>,
) -> Result<()> {
    // Size of a chunk of frames. It corresponds to the duration if a fade-in/out in frames.
    let batch_frames_count = sample_rate as usize * config.batch_ms as usize / 1000;

    // Average buffer size in frames
    let average_buffer_frames_count =
        sample_rate as usize * config.average_buffering_ms as usize / 1000;

    let sample_buffer = Arc::new(Mutex::new(VecDeque::new()));

    let stream = OutputStreamBuilder::from_device(device.clone())?.open_stream()?;

    stream.mixer().add(StreamingSource {
        sample_buffer: Arc::clone(&sample_buffer),
        current_batch: vec![],
        current_batch_cursor: 0,
        channels_count: channels_count as _,
        sample_rate,
        batch_frames_count,
    });

    receive_samples_loop(
        is_running,
        receiver,
        sample_buffer,
        channels_count as _,
        batch_frames_count,
        average_buffer_frames_count,
    )
    .ok();

    Ok(())
}


================================================
FILE: alvr/audio/src/linux.rs
================================================
use alvr_common::{ConnectionError, anyhow::Result, debug, error, parking_lot::Mutex};
use alvr_session::AudioBufferingConfig;
use alvr_sockets::{StreamReceiver, StreamSender};

use std::os::unix::fs::FileTypeExt;
use std::{
    collections::VecDeque,
    fs, io,
    path::Path,
    sync::{
        Arc,
        atomic::{AtomicBool, Ordering},
    },
    thread::{self, sleep},
    time::Duration,
};

use pipewire::{
    channel::Receiver,
    context::Context,
    core::Core,
    keys,
    main_loop::MainLoop,
    properties,
    spa::{
        param::audio::{AudioFormat, AudioInfoRaw},
        pod::{self, Pod, Value, serialize::PodSerializer},
        utils::Direction,
    },
    stream::{Stream, StreamFlags, StreamListener, StreamState},
};

pub fn try_load_pipewire() -> Result<()> {
    if let Err(e) = probe_pipewire() {
        if !matches!(e, pipewire::Error::CreationFailed) {
            return Err(e.into());
        }
        error!("Could not initialize PipeWire.");

        let is_under_flatpak = std::env::var("FLATPAK_ID").is_ok();
        let is_pw_socket_available =
            std::env::var("XDG_RUNTIME_DIR").is_ok_and(|xdg_runtime_dir| {
                let pw_socket_path = Path::new(&xdg_runtime_dir).join("pipewire-0");
                fs::metadata(&pw_socket_path).is_ok_and(|m| m.file_type().is_socket())
            });

        if is_under_flatpak && !is_pw_socket_available {
            error!(
                "Please visit the following page to find help on how to fix broken audio on flatpak."
            );
            error!(
                "https://github.com/alvr-org/ALVR/wiki/Installing-ALVR-and-using-SteamVR-on-Linux-through-Flatpak#failed-to-create-pipewire-errors"
            );
        }
        error!("Make sure PipeWire is installed on your system, running and it's version is at least 0.3.49.
        To retry, please restart SteamVR with ALVR.");
    }
    Ok(())
}

fn probe_pipewire() -> Result<(), pipewire::Error> {
    let mainloop = MainLoop::new(None)?;
    let context = Context::new(&mainloop)?;
    context.connect(None)?;
    Ok(())
}

#[derive(Clone, Copy)]
pub struct AudioInfo {
    pub sample_rate: u32,
    pub channel_count: u32,
}

struct Terminate;

// fixme: Opening pavucontrol while audio is actively streaming
//  will cause audio cut out for short time,
//  possibly related to fast state changes caused by pavucontrol
static MIC_STREAMING: AtomicBool = AtomicBool::new(false);

pub fn audio_loop(
    is_running: impl Fn() -> bool,
    sender: StreamSender<()>,
    speaker_info: Option<AudioInfo>,
    receiver: &mut StreamReceiver<()>,
    mic_info: Option<(AudioInfo, AudioBufferingConfig)>,
) {
    let sample_queue = Arc::new(Mutex::new(VecDeque::new()));
    MIC_STREAMING.store(false, Ordering::Relaxed);

    let (pw_sender, pw_receiver) = pipewire::channel::channel();

    // Stall pipewire startup until we're actually streaming to not cause latency by packet buildup
    if !is_running() {
        return;
    }

    let pw_thread = thread::spawn({
        let sample_queue = sample_queue.clone();
        let mic_info = mic_info.as_ref().map(|(info, _)| *info);

        move || {
            if let Err(e) = pw_main_loop(pw_receiver, sender, speaker_info, sample_queue, mic_info)
            {
                error!("Unhandled pipewire audio device error, please report it on GitHub: {e}");
            }
            debug!("Pipewire audio loop exiting");
        }
    });

    while is_running() {
        if let Some((mic_info, buffering)) = &mic_info {
            let rate = mic_info.sample_rate as usize;

            let batch_frames_count = rate * buffering.batch_ms as usize / 1000;
            let average_buffer_frames_count = rate * buffering.average_buffering_ms as usize / 1000;

            if let Err(e) = crate::receive_samples_loop(
                || is_running() && MIC_STREAMING.load(Ordering::Relaxed),
                receiver,
                sample_queue.clone(),
                mic_info.channel_count as usize,
                batch_frames_count,
                average_buffer_frames_count,
            ) {
                error!("Receive samples loop encountered error {e:?}");
            }

            // if we end up here then no consumer is currently connected to the output
            // so discard audio packets to not cause a buildup
            if matches!(
                receiver.recv(Duration::from_millis(500)),
                Err(ConnectionError::Other(_))
            ) {
                break;
            }
        } else {
            sleep(Duration::from_millis(500));
        }
    }

    if pw_sender.send(Terminate).is_err() {
        error!(
            "Couldn't send pipewire termination signal, deinitializing forcefully.
                Restart the VR app to reinitialize the audio device."
        );

        unsafe { pipewire::deinit() };
    }

    pw_thread.join().ok();
}

fn pw_main_loop(
    pw_receiver: Receiver<Terminate>,
    audio_sender: StreamSender<()>,
    speaker_info: Option<AudioInfo>,
    sample_queue: Arc<Mutex<VecDeque<f32>>>,
    mic_info: Option<AudioInfo>,
) -> Result<(), pipewire::Error> {
    debug!("Starting pipewire thread");
    let mainloop = MainLoop::new(None)?;

    let _receiver = pw_receiver.attach(mainloop.as_ref(), {
        let mainloop = mainloop.clone();
        move |_| mainloop.quit()
    });

    let context = Context::new(&mainloop)?;
    let pw_core = context.connect(None)?;

    let _speaker = if let Some(info) = speaker_info {
        debug!("Creating pw output audio stream");
        Some(create_speaker_stream(
            &pw_core,
            audio_sender,
            info.sample_rate,
            info.channel_count,
        )?)
    } else {
        None
    };

    let _mic = if let Some(info) = mic_info {
        debug!("Creating pw microphone stream");
        Some(create_mic_stream(
            &pw_core,
            sample_queue,
            info.sample_rate,
            info.channel_count,
        )?)
    } else {
        None
    };

    debug!("Running pipewire thread");
    mainloop.run();

    Ok(())
}

fn audio_info_to_vec(audio_info: AudioInfoRaw) -> Vec<u8> {
    PodSerializer::serialize(
        io::Cursor::new(Vec::new()),
        &Value::Object(pod::Object {
            type_: libspa_sys::SPA_TYPE_OBJECT_Format,
            id: libspa_sys::SPA_PARAM_EnumFormat,
            properties: audio_info.into(),
        }),
    )
    .unwrap()
    .0
    .into_inner()
}

fn create_speaker_stream(
    pw_core: &Core,
    mut sender: StreamSender<()>,
    sample_rate: u32,
    channel_count: u32,
) -> Result<(Stream, StreamListener<i16>), pipewire::Error> {
    let stream = Stream::new(
        pw_core,
        "alvr-audio",
        properties::properties! {
            *keys::NODE_NAME => "ALVR Audio",
            *keys::MEDIA_NAME => "alvr-audio",
            *keys::MEDIA_TYPE => "Audio",
            *keys::MEDIA_CATEGORY => "Capture",
            *keys::MEDIA_CLASS => "Audio/Sink",
            *keys::MEDIA_ROLE => "Game",
        },
    )?;

    let listener: StreamListener<i16> = stream
        .add_local_listener()
        .process(move |stream, _| {
            if let Some(mut pw_buf) = stream.dequeue_buffer()
                && let Some(pw_buf) = pw_buf.datas_mut().first_mut()
            {
                let size = pw_buf.chunk_mut().size() as usize;

                if let Some(data) = pw_buf.data() {
                    // Data is given as s16le in the correct layout by pipewire already,
                    // no need to do conversions
                    sender.send_header_with_payload(&(), &data[0..size]).ok();
                }
            }
        })
        .register()?;

    let mut audio_info = AudioInfoRaw::new();
    audio_info.set_format(AudioFormat::S16LE);
    audio_info.set_rate(sample_rate);
    audio_info.set_channels(channel_count);

    stream.connect(
        Direction::Input,
        None,
        StreamFlags::AUTOCONNECT | StreamFlags::MAP_BUFFERS,
        &mut [Pod::from_bytes(&audio_info_to_vec(audio_info)).unwrap()],
    )?;

    Ok((stream, listener))
}

fn create_mic_stream(
    pw_core: &Core,
    sample_queue: Arc<Mutex<VecDeque<f32>>>,
    sample_rate: u32,
    channel_count: u32,
) -> Result<(Stream, StreamListener<f32>), pipewire::Error> {
    let stream = Stream::new(
        pw_core,
        "alvr-mic",
        properties::properties! {
            *keys::NODE_NAME => "ALVR Microphone",
            *keys::MEDIA_NAME => "alvr-mic",
            *keys::MEDIA_TYPE => "Audio",
            *keys::MEDIA_CATEGORY => "Playback",
            *keys::MEDIA_CLASS => "Audio/Source",
            *keys::MEDIA_ROLE => "Communication",
        },
    )?;

    let chan_size = std::mem::size_of::<f32>();
    let listener: StreamListener<f32> = stream
        .add_local_listener()
        .state_changed(move |_, _, _, new_state| {
            MIC_STREAMING.store(new_state == StreamState::Streaming, Ordering::Relaxed);
        })
        .process(move |stream, _| {
            fill_pw_buf(
                sample_queue.clone(),
                chan_size,
                channel_count as usize,
                stream,
            );
        })
        .register()?;

    let mut audio_info = AudioInfoRaw::new();
    audio_info.set_format(AudioFormat::F32LE);
    audio_info.set_rate(sample_rate);
    audio_info.set_channels(channel_count);

    stream.connect(
        Direction::Output,
        None,
        StreamFlags::AUTOCONNECT | StreamFlags::MAP_BUFFERS,
        &mut [Pod::from_bytes(&audio_info_to_vec(audio_info)).unwrap()],
    )?;

    Ok((stream, listener))
}

fn fill_pw_buf(
    sample_queue: Arc<Mutex<VecDeque<f32>>>,
    chan_size: usize,
    chan_count: usize,
    stream: &pipewire::stream::StreamRef,
) {
    if let Some(mut pw_buf) = stream.dequeue_buffer() {
        let requested = pw_buf.requested() as usize;

        if let Some(pw_data) = pw_buf.datas_mut().first_mut()
            && let Some(slice) = pw_data.data()
            && let Some(mut samples) = sample_queue.try_lock()
        {
            // TODO: Would it be more correct to try to split it up over multiple datas?
            // Or is the requested size already right for the first data chunk?

            let mut it = slice
                .chunks_exact_mut(chan_size)
                .take(requested * chan_count);
            let pw_sample_count = it.len();

            let (front, back) = samples.as_slices();
            let copy_sample =
                |(chunk, sample): (&mut [u8], &f32)| chunk.copy_from_slice(&sample.to_le_bytes());

            // Split up so the compiler actually optimizes this properly
            it.by_ref().zip(front).for_each(copy_sample);
            it.zip(back).for_each(copy_sample);

            let sample_count = pw_sample_count.min(samples.len());
            drop(samples.drain(..sample_count));

            let chunk = pw_data.chunk_mut();
            *chunk.offset_mut() = 0;
            *chunk.stride_mut() = (chan_size * chan_count) as _;
            *chunk.size_mut() = (sample_count * chan_size) as _;
        }
    }
}


================================================
FILE: alvr/audio/src/windows.rs
================================================
use alvr_common::anyhow::{Result, bail};
use cpal::{Device, platform::DeviceInner};
use rodio::DeviceTrait;
use windows::{
    Win32::{
        Devices::FunctionDiscovery::PKEY_Device_FriendlyName,
        Media::Audio::{
            DEVICE_STATE_ACTIVE, Endpoints::IAudioEndpointVolume, IMMDevice, IMMDeviceEnumerator,
            MMDeviceEnumerator, eCapture, eRender,
        },
        System::Com::{self, CLSCTX_ALL, COINIT_MULTITHREADED, STGM_READ},
    },
    core::GUID,
};

fn get_windows_device(device: &Device) -> Result<IMMDevice> {
    let device_name = device.name()?;

    unsafe {
        // This will fail the second time is called, ignore the error
        Com::CoInitializeEx(None, COINIT_MULTITHREADED).ok().ok();

        let imm_device_enumerator: IMMDeviceEnumerator =
            Com::CoCreateInstance(&MMDeviceEnumerator, None, CLSCTX_ALL)?;

        let direction = if device.supports_output() {
            eRender
        } else {
            eCapture
        };
        let imm_device_collection =
            imm_device_enumerator.EnumAudioEndpoints(direction, DEVICE_STATE_ACTIVE)?;

        for i in 0..imm_device_collection.GetCount()? {
            let imm_device = imm_device_collection.Item(i)?;

            let imm_device_name = imm_device
                .OpenPropertyStore(STGM_READ)?
                .GetValue(&PKEY_Device_FriendlyName)?
                .to_string();

            if imm_device_name == device_name {
                return Ok(imm_device);
            }
        }

        bail!("No device found with specified name")
    }
}

pub fn get_windows_device_id(device: &Device) -> Result<String> {
    unsafe {
        let imm_device = get_windows_device(device)?;

        let id_str_ptr = imm_device.GetId()?;
        let id_str = id_str_ptr.to_string()?;
        Com::CoTaskMemFree(Some(id_str_ptr.0 as _));

        Ok(id_str)
    }
}

// device must be an output device
pub fn set_mute_windows_device(device: &Device, mute: bool) -> Result<()> {
    unsafe {
        let imm_device = get_windows_device(device)?;

        let endpoint_volume = imm_device.Activate::<IAudioEndpointVolume>(CLSCTX_ALL, None)?;

        endpoint_volume.SetMute(mute, &GUID::zeroed())?;
    }

    Ok(())
}

pub fn is_same_device(device1: &Device, device2: &Device) -> bool {
    let DeviceInner::Wasapi(dev1) = device1.as_inner();
    let DeviceInner::Wasapi(dev2) = device2.as_inner();

    dev1 == dev2
}


================================================
FILE: alvr/client_core/Cargo.toml
================================================
[package]
name = "alvr_client_core"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
license.workspace = true

[lib]
crate-type = ["rlib", "staticlib", "cdylib"]

[features]
link-stdcpp-shared = []
default = ["link-stdcpp-shared"]

[dependencies]
alvr_audio.workspace = true
alvr_common.workspace = true
alvr_graphics.workspace = true
alvr_packets.workspace = true
alvr_session.workspace = true
alvr_sockets.workspace = true
alvr_system_info.workspace = true

app_dirs2 = "2"
mdns-sd = "0.14"
rand = "0.9"
serde = "1"
serde_json = "1"

[target.'cfg(target_os = "android")'.dependencies]
android_logger = "0.15"
ndk = { version = "0.9", features = ["api-level-28", "audio", "media"] }
ndk-context = "0.1"

[target.'cfg(not(target_os = "android"))'.dependencies]
env_logger = "0.11"


================================================
FILE: alvr/client_core/LICENSE
================================================
Copyright (c) 2020-2024 alvr-org

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

================================================
FILE: alvr/client_core/README.md
================================================
# alvr_client_core

Rust crate containing all major components for an ALVR client except the XR-API-related code.


================================================
FILE: alvr/client_core/build.rs
================================================
fn main() {
    let platform_name = std::env::var("CARGO_CFG_TARGET_OS").unwrap();

    if platform_name == "android" {
        println!("cargo:rustc-link-lib=log");
        println!("cargo:rustc-link-lib=EGL");
        println!("cargo:rustc-link-lib=GLESv3");
        println!("cargo:rustc-link-lib=android");

        #[cfg(feature = "link-stdcpp-shared")]
        println!("cargo:rustc-link-lib=c++_shared");
    }
}


================================================
FILE: alvr/client_core/cbindgen.toml
================================================
language = "C"
header = "/* ALVR is licensed under the MIT license. https://github.com/alvr-org/ALVR/blob/master/LICENSE */"
pragma_once = true
autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
cpp_compat = true
tab_width = 4
documentation_style = "c99"

[enum]
rename_variants = "QualifiedScreamingSnakeCase"

[parse]
parse_deps = true
include = ["alvr_common"]



================================================
FILE: alvr/client_core/src/audio.rs
================================================
use alvr_audio::Device;
use alvr_common::{
    anyhow::{Result, bail},
    parking_lot::Mutex,
};
use alvr_session::AudioBufferingConfig;
use alvr_sockets::{StreamReceiver, StreamSender};
use ndk::audio::{
    AudioCallbackResult, AudioDirection, AudioError, AudioFormat, AudioInputPreset,
    AudioPerformanceMode, AudioSharingMode, AudioStreamBuilder,
};
use std::{
    collections::VecDeque,
    mem, slice,
    sync::{Arc, mpsc},
    time::Duration,
};

const INPUT_SAMPLES_MAX_BUFFER_COUNT: usize = 20;
const INPUT_RECV_TIMEOUT: Duration = Duration::from_millis(20);

#[allow(unused_variables)]
pub fn record_audio_blocking(
    is_running: Arc<dyn Fn() -> bool + Send + Sync>,
    mut sender: StreamSender<()>,
    device: &Device,
    channels_count: u16,
    mute: bool,
) -> Result<()> {
    assert_eq!(
        channels_count, 1,
        "This code only supports mono microphone input"
    );

    let sample_rate = alvr_audio::input_sample_rate(device)?;

    let error = Arc::new(Mutex::new(None::<AudioError>));

    let (samples_sender, samples_receiver) =
        mpsc::sync_channel::<Vec<u8>>(INPUT_SAMPLES_MAX_BUFFER_COUNT);

    let stream = AudioStreamBuilder::new()?
        .direction(AudioDirection::Input)
        .channel_count(1)
        .sample_rate(sample_rate as _)
        .format(AudioFormat::PCM_I16)
        .input_preset(AudioInputPreset::VoiceCommunication)
        .performance_mode(AudioPerformanceMode::LowLatency)
        .sharing_mode(AudioSharingMode::Shared)
        .data_callback(Box::new(move |_, data_ptr, frames_count| {
            let buffer_size = frames_count as usize * mem::size_of::<i16>();

            let sample_buffer =
                unsafe { slice::from_raw_parts(data_ptr as *mut u8, buffer_size) }.to_vec();

            // it will block only when the channel is full
            samples_sender.send(sample_buffer).ok();

            AudioCallbackResult::Continue
        }))
        .error_callback({
            let error = Arc::clone(&error);
            Box::new(move |_, e| *error.lock() = Some(e.into()))
        })
        .open_stream()?;

    // If configuration changed, the stream must be restarted
    if stream.channel_count() != 1
        || stream.sample_rate() != sample_rate as i32
        || stream.format() != AudioFormat::PCM_I16
    {
        bail!("Invalid audio configuration");
    }

    stream.request_start()?;

    while is_running() && error.lock().is_none() {
        while let Ok(sample_buffer) = samples_receiver.recv_timeout(INPUT_RECV_TIMEOUT) {
            sender.send_header_with_payload(&(), &sample_buffer).ok();
        }
    }

    // Note: request_stop() is asynchronous, and must be called always, even on error
    stream.request_stop()?;

    if let Some(e) = *error.lock() {
        return Err(e.into());
    }

    Ok(())
}

#[allow(unused_variables)]
pub fn play_audio_loop(
    is_running: impl Fn() -> bool,
    device: &Device,
    channels_count: u16,
    sample_rate: u32,
    config: AudioBufferingConfig,
    receiver: &mut StreamReceiver<()>,
) -> Result<()> {
    assert_eq!(channels_count, 2, "This code only supports stereo output");

    // the client sends invalid sample rates sometimes, and we crash if we try and use one
    // (batch_frames_count ends up zero and the audio callback gets confused)
    if sample_rate < 8000 {
        bail!("Invalid audio sample rate");
    }

    let batch_frames_count = sample_rate as usize * config.batch_ms as usize / 1000;
    let average_buffer_frames_count =
        sample_rate as usize * config.average_buffering_ms as usize / 1000;

    let sample_buffer = Arc::new(Mutex::new(VecDeque::new()));
    let error = Arc::new(Mutex::new(None));

    let stream = AudioStreamBuilder::new()?
        .direction(AudioDirection::Output)
        .channel_count(2)
        .sample_rate(sample_rate as _)
        .format(AudioFormat::PCM_Float)
        .frames_per_data_callback(batch_frames_count as _)
        .performance_mode(AudioPerformanceMode::LowLatency)
        .sharing_mode(AudioSharingMode::Shared)
        .data_callback({
            let sample_buffer = Arc::clone(&sample_buffer);
            Box::new(move |_, data_ptr, frames_count| {
                assert!(frames_count == batch_frames_count as i32);

                let samples = alvr_audio::get_next_frame_batch(
                    &mut *sample_buffer.lock(),
                    2,
                    batch_frames_count as _,
                );

                let out_frames = unsafe {
                    // 2 channels
                    slice::from_raw_parts_mut(data_ptr as *mut f32, frames_count as usize * 2)
                };
                out_frames.copy_from_slice(&samples);

                AudioCallbackResult::Continue
            })
        })
        .error_callback({
            let error = Arc::clone(&error);
            Box::new(move |_, e| *error.lock() = Some(e))
        })
        .open_stream()?;

    // If configuration changed, the stream must be restarted
    if stream.channel_count() != 2
        || stream.sample_rate() != sample_rate as i32
        || stream.format() != AudioFormat::PCM_Float
        || stream.frames_per_data_callback() != Some(batch_frames_count as _)
    {
        bail!("Invalid audio configuration");
    }

    stream.request_start()?;

    alvr_audio::receive_samples_loop(
        || is_running() && error.lock().is_none(),
        receiver,
        sample_buffer,
        2,
        batch_frames_count,
        average_buffer_frames_count,
    )
    .ok();

    // Note: request_stop() is asynchronous, and must be called always, even on error
    stream.request_stop()?;

    if let Some(e) = *error.lock() {
        return Err(e.into());
    }

    Ok(())
}


================================================
FILE: alvr/client_core/src/c_api.rs
================================================
#![expect(dead_code)]

use crate::{
    ClientCapabilities, ClientCoreContext, ClientCoreEvent, storage,
    video_decoder::{self, VideoDecoderConfig, VideoDecoderSource},
};
use alvr_common::{
    AlvrCodecType, AlvrFov, AlvrPose, AlvrQuat, AlvrViewParams, DeviceMotion, Pose, ViewParams,
    anyhow::Result,
    debug, error,
    glam::{UVec2, Vec2, Vec3},
    info,
    parking_lot::Mutex,
    warn,
};
use alvr_graphics::{
    GraphicsContext, HandData, LobbyRenderer, LobbyViewParams, SDR_FORMAT_GL, StreamRenderer,
    StreamViewParams,
};
use alvr_packets::{ButtonEntry, ButtonValue, FaceData, TrackingData};
use alvr_session::{
    CodecType, FoveatedEncodingConfig, MediacodecPropType, MediacodecProperty, UpscalingConfig,
};
use std::{
    cell::RefCell,
    ffi::{CStr, CString, c_char, c_void},
    ptr,
    rc::Rc,
    slice,
    time::{Duration, Instant},
};

static CLIENT_CORE_CONTEXT: Mutex<Option<ClientCoreContext>> = Mutex::new(None);
static HUD_MESSAGE: Mutex<String> = Mutex::new(String::new());
static SETTINGS: Mutex<String> = Mutex::new(String::new());
static SERVER_VERSION: Mutex<String> = Mutex::new(String::new());
static DECODER_CONFIG_BUFFER: Mutex<Vec<u8>> = Mutex::new(vec![]);

// Core interface:

#[repr(C)]
pub struct AlvrClientCapabilities {
    default_view_width: u32,
    default_view_height: u32,
    max_view_width: u32,
    max_view_height: u32,
    refresh_rates: *const f32,
    refresh_rates_count: u64,
    foveated_encoding: bool,
    encoder_high_profile: bool,
    encoder_10_bits: bool,
    encoder_av1: bool,
    prefer_10bit: bool,
    preferred_encoding_gamma: f32,
    prefer_hdr: bool,
}

#[repr(u8)]
pub enum AlvrEvent {
    HudMessageUpdated,
    StreamingStarted {
        view_width: u32,
        view_height: u32,
        refresh_rate_hint: f32,
        encoding_gamma: f32,
        enable_foveated_encoding: bool,
        enable_hdr: bool,
    },
    StreamingStopped,
    Haptics {
        device_id: u64,
        duration_s: f32,
        frequency: f32,
        amplitude: f32,
    },
    /// Note: All subsequent DecoderConfig events should be ignored until reconnection
    DecoderConfig {
        codec: AlvrCodecType,
    },
    // Unimplemented
    RealTimeConfig {},
}

#[repr(C)]
pub struct AlvrVideoFrameData {
    callback_context: *mut c_void,
    timestamp_ns: u64,
    buffer_ptr: *const u8,
    buffer_size: u64,
}

#[repr(C)]
#[derive(Clone, Default)]
pub struct AlvrDeviceMotion {
    device_id: u64,
    pose: AlvrPose,
    linear_velocity: [f32; 3],
    angular_velocity: [f32; 3],
}

#[allow(dead_code)]
#[repr(C)]
pub enum AlvrButtonValue {
    Binary(bool),
    Scalar(f32),
}

#[allow(dead_code)]
#[repr(u8)]
pub enum AlvrLogLevel {
    Error,
    Warn,
    Info,
    Debug,
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_initialize_logging() {
    crate::init_logging();
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_path_string_to_id(path: *const c_char) -> u64 {
    alvr_common::hash_string(unsafe { CStr::from_ptr(path) }.to_str().unwrap())
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_log(level: AlvrLogLevel, message: *const c_char) {
    let message = unsafe { CStr::from_ptr(message) }.to_str().unwrap();
    match level {
        AlvrLogLevel::Error => error!("[ALVR NATIVE] {message}"),
        AlvrLogLevel::Warn => warn!("[ALVR NATIVE] {message}"),
        AlvrLogLevel::Info => info!("[ALVR NATIVE] {message}"),
        AlvrLogLevel::Debug => debug!("[ALVR NATIVE] {message}"),
    }
}

#[unsafe(no_mangle)]
#[cfg_attr(not(debug_assertions), expect(unused_variables))]
pub extern "C" fn alvr_dbg_client_impl(message: *const c_char) {
    alvr_common::dbg_client_impl!("{}", unsafe { CStr::from_ptr(message) }.to_str().unwrap())
}

#[unsafe(no_mangle)]
#[cfg_attr(not(debug_assertions), expect(unused_variables))]
pub extern "C" fn alvr_dbg_decoder(message: *const c_char) {
    alvr_common::dbg_decoder!("{}", unsafe { CStr::from_ptr(message) }.to_str().unwrap())
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_log_time(tag: *const c_char) {
    let tag = unsafe { CStr::from_ptr(tag) }.to_str().unwrap();
    error!("[ALVR NATIVE] {tag}: {:?}", Instant::now());
}

fn string_to_c_str(buffer: *mut c_char, value: &str) -> u64 {
    let cstring = CString::new(value).unwrap();
    if !buffer.is_null() {
        unsafe {
            ptr::copy_nonoverlapping(cstring.as_ptr(), buffer, cstring.as_bytes_with_nul().len());
        }
    }

    cstring.as_bytes_with_nul().len() as u64
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_mdns_service(service_buffer: *mut c_char) -> u64 {
    string_to_c_str(service_buffer, alvr_sockets::MDNS_SERVICE_TYPE)
}

/// To make sure the value is correct, call after alvr_initialize()
#[unsafe(no_mangle)]
pub extern "C" fn alvr_hostname(hostname_buffer: *mut c_char) -> u64 {
    string_to_c_str(hostname_buffer, &storage::Config::load().hostname)
}

/// To make sure the value is correct, call after alvr_initialize()
#[unsafe(no_mangle)]
pub extern "C" fn alvr_protocol_id(protocol_buffer: *mut c_char) -> u64 {
    string_to_c_str(protocol_buffer, &storage::Config::load().protocol_id)
}

#[cfg(target_os = "android")]
#[unsafe(no_mangle)]
pub extern "C" fn alvr_try_get_permission(permission: *const c_char) {
    alvr_system_info::try_get_permission(unsafe { CStr::from_ptr(permission) }.to_str().unwrap());
}

/// NB: for android, `context` must be thread safe.
#[cfg(target_os = "android")]
#[unsafe(no_mangle)]
pub extern "C" fn alvr_initialize_android_context(java_vm: *mut c_void, context: *mut c_void) {
    unsafe { ndk_context::initialize_android_context(java_vm, context) };
}

/// On android, alvr_initialize_android_context() must be called first, then alvr_initialize().
#[unsafe(no_mangle)]
pub extern "C" fn alvr_initialize(capabilities: AlvrClientCapabilities) {
    let default_view_resolution = UVec2::new(
        capabilities.default_view_width,
        capabilities.default_view_height,
    );

    let max_view_resolution = UVec2::new(capabilities.max_view_width, capabilities.max_view_height);

    let refresh_rates = unsafe {
        slice::from_raw_parts(
            capabilities.refresh_rates,
            capabilities.refresh_rates_count as usize,
        )
    }
    .to_vec();

    let capabilities = ClientCapabilities {
        platform: alvr_system_info::platform(None, None),
        default_view_resolution,
        max_view_resolution,
        refresh_rates,
        foveated_encoding: capabilities.foveated_encoding,
        encoder_high_profile: capabilities.encoder_high_profile,
        encoder_10_bits: capabilities.encoder_10_bits,
        encoder_av1: capabilities.encoder_av1,
        prefer_10bit: capabilities.prefer_10bit,
        preferred_encoding_gamma: capabilities.preferred_encoding_gamma,
        prefer_hdr: capabilities.prefer_hdr,
    };
    *CLIENT_CORE_CONTEXT.lock() = Some(ClientCoreContext::new(capabilities));
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_destroy() {
    *CLIENT_CORE_CONTEXT.lock() = None;

    #[cfg(target_os = "android")]
    unsafe {
        ndk_context::release_android_context()
    };
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_resume() {
    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        context.resume();
    }
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_pause() {
    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        context.pause();
    }
}

/// Returns true if there was a new event
#[unsafe(no_mangle)]
pub extern "C" fn alvr_poll_event(out_event: *mut AlvrEvent) -> bool {
    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock()
        && let Some(event) = context.poll_event()
    {
        let event = match event {
            ClientCoreEvent::UpdateHudMessage(message) => {
                *HUD_MESSAGE.lock() = message;

                AlvrEvent::HudMessageUpdated
            }
            ClientCoreEvent::StreamingStarted(stream_config) => {
                *SETTINGS.lock() = serde_json::to_string(&stream_config.settings).unwrap();
                *SERVER_VERSION.lock() = stream_config.server_version.to_string();

                AlvrEvent::StreamingStarted {
                    view_width: stream_config.negotiated_config.view_resolution.x,
                    view_height: stream_config.negotiated_config.view_resolution.y,
                    refresh_rate_hint: stream_config.negotiated_config.refresh_rate_hint,
                    encoding_gamma: stream_config.negotiated_config.encoding_gamma,
                    enable_foveated_encoding: stream_config
                        .negotiated_config
                        .enable_foveated_encoding,
                    enable_hdr: stream_config.negotiated_config.enable_hdr,
                }
            }
            ClientCoreEvent::StreamingStopped => AlvrEvent::StreamingStopped,
            ClientCoreEvent::Haptics {
                device_id,
                duration,
                frequency,
                amplitude,
            } => AlvrEvent::Haptics {
                device_id,
                duration_s: duration.as_secs_f32(),
                frequency,
                amplitude,
            },
            ClientCoreEvent::DecoderConfig { codec, config_nal } => {
                *DECODER_CONFIG_BUFFER.lock() = config_nal;

                AlvrEvent::DecoderConfig {
                    codec: match codec {
                        CodecType::H264 => AlvrCodecType::H264,
                        CodecType::Hevc => AlvrCodecType::Hevc,
                        CodecType::AV1 => AlvrCodecType::AV1,
                    },
                }
            }
            ClientCoreEvent::RealTimeConfig(_) => AlvrEvent::RealTimeConfig {},
        };

        unsafe { *out_event = event };

        true
    } else {
        false
    }
}

// Returns the length of the message. message_buffer can be null.
#[unsafe(no_mangle)]
pub extern "C" fn alvr_hud_message(message_buffer: *mut c_char) -> u64 {
    let cstring = CString::new(HUD_MESSAGE.lock().clone()).unwrap();
    if !message_buffer.is_null() {
        unsafe {
            ptr::copy_nonoverlapping(
                cstring.as_ptr(),
                message_buffer,
                cstring.as_bytes_with_nul().len(),
            );
        }
    }

    cstring.as_bytes_with_nul().len() as u64
}

/// Settings will be updated after receiving StreamingStarted event
#[unsafe(no_mangle)]
pub extern "C" fn alvr_get_settings_json(out_buffer: *mut c_char) -> u64 {
    string_to_c_str(out_buffer, &SETTINGS.lock())
}

/// Will be updated after receiving StreamingStarted event
#[unsafe(no_mangle)]
pub extern "C" fn alvr_get_server_version(out_buffer: *mut c_char) -> u64 {
    string_to_c_str(out_buffer, &SERVER_VERSION.lock())
}

/// Returns the number of bytes of the decoder_buffer
#[unsafe(no_mangle)]
pub extern "C" fn alvr_get_decoder_config(out_buffer: *mut c_char) -> u64 {
    let buffer = DECODER_CONFIG_BUFFER.lock();

    let size = buffer.len();

    if !out_buffer.is_null() {
        unsafe { ptr::copy_nonoverlapping(buffer.as_ptr(), out_buffer.cast(), size) }
    }

    size as u64
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_send_battery(device_id: u64, gauge_value: f32, is_plugged: bool) {
    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        context.send_battery(device_id, gauge_value, is_plugged);
    }
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_send_playspace(width: f32, height: f32) {
    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        context.send_playspace(Some(Vec2::new(width, height)));
    }
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_send_active_interaction_profile(
    device_id: u64,
    profile_id: u64,
    input_ids_ptr: *const u64,
    input_ids_count: u64,
) {
    let input_ids = if !input_ids_ptr.is_null() {
        unsafe { slice::from_raw_parts(input_ids_ptr, input_ids_count as usize) }
    } else {
        &[]
    };

    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        context.send_active_interaction_profile(
            device_id,
            profile_id,
            input_ids.iter().cloned().collect(),
        );
    }
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_send_button(path_id: u64, value: AlvrButtonValue) {
    let value = match value {
        AlvrButtonValue::Binary(value) => ButtonValue::Binary(value),
        AlvrButtonValue::Scalar(value) => ButtonValue::Scalar(value),
    };

    // crate::send_buttons(vec![ButtonEntry { path_id, value }]);
    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        context.send_buttons(vec![ButtonEntry { path_id, value }]);
    }
}

/// The view poses need to be in local space, as if the head is at the origin.
/// view_params: array of 2
#[unsafe(no_mangle)]
pub extern "C" fn alvr_send_view_params(view_params: *const AlvrViewParams) {
    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        context.send_view_params(unsafe {
            [
                alvr_common::from_capi_view_params(&(*view_params)),
                alvr_common::from_capi_view_params(&(*view_params.offset(1))),
            ]
        });
    }
}

/// hand_skeleton:
/// * outer ptr: array of 2 (can be null);
/// * inner ptr: array of 26 (can be null if hand is absent)
///
/// combined_eye_gaze: can be null if eye gaze is absent
#[unsafe(no_mangle)]
pub extern "C" fn alvr_send_tracking(
    poll_timestamp_ns: u64,
    device_motions: *const AlvrDeviceMotion,
    device_motions_count: u64,
    hand_skeletons: *const *const AlvrPose,
    combined_eye_gaze: *const AlvrQuat,
) {
    let mut raw_motions = vec![AlvrDeviceMotion::default(); device_motions_count as _];
    unsafe {
        ptr::copy_nonoverlapping(
            device_motions,
            raw_motions.as_mut_ptr(),
            device_motions_count as usize,
        );
    }

    let device_motions = raw_motions
        .into_iter()
        .map(|motion| {
            (
                motion.device_id,
                DeviceMotion {
                    pose: alvr_common::from_capi_pose(&motion.pose),
                    linear_velocity: Vec3::from_slice(&motion.linear_velocity),
                    angular_velocity: Vec3::from_slice(&motion.angular_velocity),
                },
            )
        })
        .collect::<Vec<_>>();

    let hand_skeletons = if !hand_skeletons.is_null() {
        let hand_skeletons = unsafe { slice::from_raw_parts(hand_skeletons, 2) };
        let hand_skeletons = hand_skeletons
            .iter()
            .map(|&hand_skeleton| {
                (!hand_skeleton.is_null()).then(|| {
                    let hand_skeleton = unsafe { slice::from_raw_parts(hand_skeleton, 26) };

                    let mut array = [Pose::IDENTITY; 26];

                    for (pose, capi_pose) in array.iter_mut().zip(hand_skeleton.iter()) {
                        *pose = Pose {
                            orientation: alvr_common::from_capi_quat(&capi_pose.orientation),
                            position: Vec3::from_slice(&capi_pose.position),
                        };
                    }

                    array
                })
            })
            .collect::<Vec<_>>();

        [hand_skeletons[0], hand_skeletons[1]]
    } else {
        [None, None]
    };

    let eyes_combined = if !combined_eye_gaze.is_null() {
        Some(alvr_common::from_capi_quat(unsafe { &*combined_eye_gaze }))
    } else {
        None
    };

    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        context.send_tracking(TrackingData {
            poll_timestamp: Duration::from_nanos(poll_timestamp_ns),
            device_motions,
            hand_skeletons,
            face: FaceData {
                eyes_combined,
                ..Default::default()
            },
            body: None,
        });
    }
}

/// Safety: `context` must be thread safe and valid until the StreamingStopped event.
#[unsafe(no_mangle)]
pub extern "C" fn alvr_set_decoder_input_callback(
    callback_context: *mut c_void,
    callback: extern "C" fn(AlvrVideoFrameData) -> bool,
) {
    struct CallbackContext(*mut c_void);
    unsafe impl Send for CallbackContext {}

    let callback_context = CallbackContext(callback_context);

    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        context.set_decoder_input_callback(Box::new(move |timestamp, buffer| {
            // Make sure to capture the struct itself instead of just the pointer to make the
            // borrow checker happy
            let callback_context = &callback_context;

            callback(AlvrVideoFrameData {
                callback_context: callback_context.0,
                timestamp_ns: timestamp.as_nanos() as u64,
                buffer_ptr: buffer.as_ptr(),
                buffer_size: buffer.len() as u64,
            })
        }));
    }
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_report_frame_decoded(target_timestamp_ns: u64) {
    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        context.report_frame_decoded(Duration::from_nanos(target_timestamp_ns));
    }
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_report_fatal_decoder_error(message: *const c_char) {
    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        context.report_fatal_decoder_error(unsafe { CStr::from_ptr(message).to_str().unwrap() });
    }
}

/// out_view_params must be a vector of 2 elements
/// out_view_params is populated only if the core context is valid
#[unsafe(no_mangle)]
pub extern "C" fn alvr_report_compositor_start(
    target_timestamp_ns: u64,
    out_view_params: *mut AlvrViewParams,
) {
    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        let view_params =
            context.report_compositor_start(Duration::from_nanos(target_timestamp_ns));

        unsafe {
            *out_view_params = alvr_common::to_capi_view_params(&view_params[0]);
            *out_view_params.offset(1) = alvr_common::to_capi_view_params(&view_params[1]);
        }
    }
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_report_submit(target_timestamp_ns: u64, vsync_queue_ns: u64) {
    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        context.report_submit(
            Duration::from_nanos(target_timestamp_ns),
            Duration::from_nanos(vsync_queue_ns),
        );
    }
}

// OpenGL-related interface

thread_local! {
    static GRAPHICS_CONTEXT: RefCell<Option<Rc<GraphicsContext>>> = const { RefCell::new(None) };
    static LOBBY_RENDERER: RefCell<Option<LobbyRenderer>> = const { RefCell::new(None) };
    static STREAM_RENDERER: RefCell<Option<StreamRenderer>> = const { RefCell::new(None) };
}

#[repr(C)]
pub struct AlvrLobbyViewParams {
    swapchain_index: u32,
    view_params: AlvrViewParams,
}

#[repr(C)]
pub struct AlvrStreamViewParams {
    swapchain_index: u32,
    reprojection_rotation: AlvrQuat,
    fov: AlvrFov,
}

#[repr(C)]
pub struct AlvrStreamConfig {
    view_resolution_width: u32,
    view_resolution_height: u32,
    swapchain_textures: *mut *const u32,
    swapchain_length: u32,
    enable_foveation: bool,
    foveation_center_size_x: f32,
    foveation_center_size_y: f32,
    foveation_center_shift_x: f32,
    foveation_center_shift_y: f32,
    foveation_edge_ratio_x: f32,
    foveation_edge_ratio_y: f32,
    enable_upscaling: bool,
    upscaling_edge_direction: bool,
    upscaling_edge_threshold: f32,
    upscaling_edge_sharpness: f32,
    upscale_factor: f32,
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_initialize_opengl() {
    GRAPHICS_CONTEXT.set(Some(Rc::new(GraphicsContext::new_gl())));
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_destroy_opengl() {
    GRAPHICS_CONTEXT.set(None);
}

fn convert_swapchain_array(
    swapchain_textures: *mut *const u32,
    swapchain_length: u32,
) -> [Vec<u32>; 2] {
    let swapchain_length = swapchain_length as usize;
    let mut left_swapchain = vec![0; swapchain_length];
    unsafe {
        ptr::copy_nonoverlapping(
            *swapchain_textures,
            left_swapchain.as_mut_ptr(),
            swapchain_length,
        )
    };
    let mut right_swapchain = vec![0; swapchain_length];
    unsafe {
        ptr::copy_nonoverlapping(
            *swapchain_textures.offset(1),
            right_swapchain.as_mut_ptr(),
            swapchain_length,
        )
    };

    [left_swapchain, right_swapchain]
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_resume_opengl(
    preferred_view_width: u32,
    preferred_view_height: u32,
    swapchain_textures: *mut *const u32,
    swapchain_length: u32,
) {
    LOBBY_RENDERER.set(Some(LobbyRenderer::new(
        GRAPHICS_CONTEXT.with_borrow(|c| c.as_ref().unwrap().clone()),
        UVec2::new(preferred_view_width, preferred_view_height),
        convert_swapchain_array(swapchain_textures, swapchain_length),
        "",
    )));
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_pause_opengl() {
    STREAM_RENDERER.set(None);
    LOBBY_RENDERER.set(None)
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_update_hud_message_opengl(message: *const c_char) {
    LOBBY_RENDERER.with_borrow(|renderer| {
        if let Some(renderer) = renderer {
            renderer.update_hud_message(unsafe { CStr::from_ptr(message) }.to_str().unwrap());
        }
    });
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_start_stream_opengl(config: AlvrStreamConfig) {
    let view_resolution = UVec2::new(config.view_resolution_width, config.view_resolution_height);
    let swapchain_textures =
        convert_swapchain_array(config.swapchain_textures, config.swapchain_length);
    let foveated_encoding = config.enable_foveation.then_some(FoveatedEncodingConfig {
        force_enable: true,
        center_size_x: config.foveation_center_size_x,
        center_size_y: config.foveation_center_size_y,
        center_shift_x: config.foveation_center_shift_x,
        center_shift_y: config.foveation_center_shift_y,
        edge_ratio_x: config.foveation_edge_ratio_x,
        edge_ratio_y: config.foveation_edge_ratio_y,
    });
    let upscaling = config.enable_upscaling.then_some(UpscalingConfig {
        edge_direction: config.upscaling_edge_direction,
        edge_sharpness: config.upscaling_edge_sharpness,
        edge_threshold: config.upscaling_edge_threshold,
        upscale_factor: config.upscale_factor,
    });

    STREAM_RENDERER.set(Some(StreamRenderer::new(
        GRAPHICS_CONTEXT.with_borrow(|c| c.as_ref().unwrap().clone()),
        view_resolution,
        alvr_graphics::compute_target_view_resolution(view_resolution, &upscaling),
        swapchain_textures,
        SDR_FORMAT_GL,
        foveated_encoding,
        true,
        false, // TODO: limited range fix config
        1.0,   // TODO: encoding gamma config
        upscaling,
    )));
}

// todo: support hands
#[unsafe(no_mangle)]
pub extern "C" fn alvr_render_lobby_opengl(
    view_inputs: *const AlvrLobbyViewParams,
    render_background: bool,
) {
    let view_inputs = unsafe {
        [
            LobbyViewParams {
                swapchain_index: (*view_inputs).swapchain_index,
                view_params: alvr_common::from_capi_view_params(&(*view_inputs).view_params),
            },
            LobbyViewParams {
                swapchain_index: (*view_inputs.offset(1)).swapchain_index,
                view_params: alvr_common::from_capi_view_params(
                    &(*view_inputs.offset(1)).view_params,
                ),
            },
        ]
    };

    LOBBY_RENDERER.with_borrow(|renderer| {
        if let Some(renderer) = renderer {
            renderer.render(
                view_inputs,
                [
                    HandData {
                        grip_motion: None,
                        detached_grip_motion: None,
                        skeleton_joints: None,
                    },
                    HandData {
                        grip_motion: None,
                        detached_grip_motion: None,
                        skeleton_joints: None,
                    },
                ],
                None,
                None,
                render_background,
                false,
            );
        }
    });
}

/// view_params: array of 2
#[unsafe(no_mangle)]
pub extern "C" fn alvr_render_stream_opengl(
    hardware_buffer: *mut c_void,
    view_params: *const AlvrStreamViewParams,
) {
    STREAM_RENDERER.with_borrow(|renderer| {
        if let Some(renderer) = renderer {
            let left_params = unsafe { &*view_params };
            let right_params = unsafe { &*view_params.offset(1) };
            renderer.render(
                hardware_buffer,
                [
                    StreamViewParams {
                        swapchain_index: left_params.swapchain_index,
                        input_view_params: ViewParams {
                            pose: Pose::IDENTITY,
                            fov: alvr_common::from_capi_fov(&left_params.fov),
                        },
                        output_view_params: ViewParams {
                            pose: Pose {
                                orientation: alvr_common::from_capi_quat(
                                    &left_params.reprojection_rotation,
                                ),
                                position: Vec3::ZERO,
                            },
                            fov: alvr_common::from_capi_fov(&left_params.fov),
                        },
                    },
                    StreamViewParams {
                        swapchain_index: right_params.swapchain_index,
                        input_view_params: ViewParams {
                            pose: Pose::IDENTITY,
                            fov: alvr_common::from_capi_fov(&right_params.fov),
                        },
                        output_view_params: ViewParams {
                            pose: Pose {
                                orientation: alvr_common::from_capi_quat(
                                    &right_params.reprojection_rotation,
                                ),
                                position: Vec3::ZERO,
                            },
                            fov: alvr_common::from_capi_fov(&right_params.fov),
                        },
                    },
                ],
                None,
            );
        }
    });
}

// Decoder-related interface

static DECODER_SOURCE: Mutex<Option<VideoDecoderSource>> = Mutex::new(None);

#[repr(u8)]
pub enum AlvrMediacodecPropType {
    Float,
    Int32,
    Int64,
    String,
}

#[repr(C)]
pub union AlvrMediacodecPropValue {
    float_: f32,
    int32: i32,
    int64: i64,
    string: *const c_char,
}

#[repr(C)]
pub struct AlvrMediacodecOption {
    key: *const c_char,
    ty: AlvrMediacodecPropType,
    value: AlvrMediacodecPropValue,
}

#[repr(C)]
pub struct AlvrDecoderConfig {
    codec: AlvrCodecType,
    force_software_decoder: bool,
    max_buffering_frames: f32,
    buffering_history_weight: f32,
    options: *const AlvrMediacodecOption,
    options_count: u64,
    config_buffer: *const u8,
    config_buffer_size: u64,
}

/// alvr_initialize() must be called before alvr_create_decoder
#[unsafe(no_mangle)]
pub extern "C" fn alvr_create_decoder(config: AlvrDecoderConfig) {
    let config = VideoDecoderConfig {
        codec: match config.codec {
            AlvrCodecType::H264 => CodecType::H264,
            AlvrCodecType::Hevc => CodecType::Hevc,
            AlvrCodecType::AV1 => CodecType::AV1,
        },
        force_software_decoder: config.force_software_decoder,
        max_buffering_frames: config.max_buffering_frames,
        buffering_history_weight: config.buffering_history_weight,
        options: if !config.options.is_null() {
            let options =
                unsafe { slice::from_raw_parts(config.options, config.options_count as usize) };
            options
                .iter()
                .map(|option| unsafe {
                    let key = CStr::from_ptr(option.key).to_str().unwrap();
                    let prop = match option.ty {
                        AlvrMediacodecPropType::Float => MediacodecProperty {
                            ty: MediacodecPropType::Float,
                            value: option.value.float_.to_string(),
                        },
                        AlvrMediacodecPropType::Int32 => MediacodecProperty {
                            ty: MediacodecPropType::Int32,
                            value: option.value.int32.to_string(),
                        },
                        AlvrMediacodecPropType::Int64 => MediacodecProperty {
                            ty: MediacodecPropType::Int64,
                            value: option.value.int64.to_string(),
                        },
                        AlvrMediacodecPropType::String => MediacodecProperty {
                            ty: MediacodecPropType::String,
                            value: CStr::from_ptr(option.value.string)
                                .to_str()
                                .unwrap()
                                .to_owned(),
                        },
                    };

                    (key.to_owned(), prop)
                })
                .collect()
        } else {
            vec![]
        },
        config_buffer: unsafe {
            slice::from_raw_parts(config.config_buffer, config.config_buffer_size as usize).to_vec()
        },
    };

    let (mut sink, source) =
        video_decoder::create_decoder(config, |maybe_timestamp: Result<Duration>| {
            if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
                match maybe_timestamp {
                    Ok(timestamp) => context.report_frame_decoded(timestamp),
                    Err(e) => context.report_fatal_decoder_error(&e.to_string()),
                }
            }
        });

    *DECODER_SOURCE.lock() = Some(source);

    if let Some(context) = &*CLIENT_CORE_CONTEXT.lock() {
        context.set_decoder_input_callback(Box::new(move |timestamp, buffer| {
            sink.push_nal(timestamp, buffer)
        }));
    }
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_destroy_decoder() {
    *DECODER_SOURCE.lock() = None;
}

// Returns true if the timestamp and buffer has been written to
#[unsafe(no_mangle)]
pub extern "C" fn alvr_get_frame(
    out_timestamp_ns: *mut u64,
    out_buffer_ptr: *mut *mut c_void,
) -> bool {
    if let Some(source) = &mut *DECODER_SOURCE.lock()
        && let Some((timestamp, buffer_ptr)) = source.get_frame()
    {
        unsafe {
            *out_timestamp_ns = timestamp.as_nanos() as u64;
            *out_buffer_ptr = buffer_ptr;
        }

        true
    } else {
        false
    }
}

#[unsafe(no_mangle)]
pub extern "C" fn alvr_rotation_delta(source: AlvrQuat, destination: AlvrQuat) -> AlvrQuat {
    alvr_common::to_capi_quat(
        &(alvr_common::from_capi_quat(&source).inverse()
            * alvr_common::from_capi_quat(&destination)),
    )
}


================================================
FILE: alvr/client_core/src/connection.rs
================================================
#![allow(clippy::if_same_then_else)]

use crate::{
    ClientCapabilities, ClientCoreEvent,
    logging_backend::{LOG_CHANNEL_SENDER, LogMirrorData},
    sockets::AnnouncerSocket,
    statistics::StatisticsManager,
    storage::Config,
};
use alvr_common::{
    ALVR_VERSION, AnyhowToCon, ConResult, ConnectionError, ConnectionState, LifecycleState,
    ViewParams, dbg_connection, debug, error, info,
    parking_lot::{Condvar, Mutex, RwLock},
    wait_rwlock, warn,
};
use alvr_packets::{
    AUDIO, ClientConnectionResult, ClientControlPacket, ClientStatistics, ConnectionAcceptedInfo,
    HAPTICS, Haptics, STATISTICS, ServerControlPacket, StreamConfigPacket, TRACKING, TrackingData,
    VIDEO, VideoPacketHeader, VideoStreamingCapabilities, VideoStreamingCapabilitiesExt,
};
use alvr_session::{SocketProtocol, settings_schema::Switch};
use alvr_sockets::{
    ControlSocketSender, KEEPALIVE_INTERVAL, KEEPALIVE_TIMEOUT, PeerType, ProtoControlSocket,
    StreamSender, StreamSocketBuilder,
};
use std::{
    collections::VecDeque,
    sync::{Arc, mpsc},
    thread,
    time::{Duration, Instant},
};

#[cfg(target_os = "android")]
use crate::audio;
#[cfg(not(target_os = "android"))]
use alvr_audio as audio;

const INITIAL_MESSAGE: &str = concat!(
    "Searching for streamer...\n",
    "Open ALVR on your PC then click \"Trust\"\n",
    "next to the device entry",
);
const SUCCESS_CONNECT_MESSAGE: &str = "Successful connection!\nPlease wait...";
const STREAM_STARTING_MESSAGE: &str = "The stream will begin soon\nPlease wait...";
const SERVER_RESTART_MESSAGE: &str = "The streamer is restarting\nPlease wait...";
const SERVER_DISCONNECTED_MESSAGE: &str = "The streamer has disconnected.";
const CONNECTION_TIMEOUT_MESSAGE: &str = "Connection timeout.";

const SOCKET_INIT_RETRY_INTERVAL: Duration = Duration::from_millis(500);
const CONNECTION_RETRY_INTERVAL: Duration = Duration::from_secs(1);
const HANDSHAKE_ACTION_TIMEOUT: Duration = Duration::from_secs(2);
const STREAMING_RECV_TIMEOUT: Duration = Duration::from_millis(500);

const MAX_UNREAD_PACKETS: usize = 10; // Applies per stream

pub type DecoderCallback = dyn FnMut(Duration, &[u8]) -> bool + Send;

#[derive(Default)]
pub struct ConnectionContext {
    pub state: RwLock<ConnectionState>,
    pub disconnected_notif: Condvar,
    pub control_sender: Mutex<Option<ControlSocketSender<ClientControlPacket>>>,
    pub tracking_sender: Mutex<Option<StreamSender<TrackingData>>>,
    pub statistics_sender: Mutex<Option<StreamSender<ClientStatistics>>>,
    pub statistics_manager: Mutex<Option<StatisticsManager>>,
    pub decoder_callback: Mutex<Option<Box<DecoderCallback>>>,
    pub global_view_params_queue: Mutex<VecDeque<(Duration, [ViewParams; 2])>>,
    pub max_prediction: RwLock<Duration>,
}

fn set_hud_message(event_queue: &Mutex<VecDeque<ClientCoreEvent>>, message: &str) {
    let message = format!(
        "ALVR v{}\nhostname: {}\nIP: {}\n\n{message}",
        *ALVR_VERSION,
        Config::load().hostname,
        alvr_system_info::local_ip(),
    );

    event_queue
        .lock()
        .push_back(ClientCoreEvent::UpdateHudMessage(message));
}

fn is_streaming(ctx: &ConnectionContext) -> bool {
    *ctx.state.read() == ConnectionState::Streaming
}

pub fn connection_lifecycle_loop(
    capabilities: ClientCapabilities,
    ctx: Arc<ConnectionContext>,
    lifecycle_state: Arc<RwLock<LifecycleState>>,
    event_queue: Arc<Mutex<VecDeque<ClientCoreEvent>>>,
) {
    dbg_connection!("connection_lifecycle_loop: Begin");

    set_hud_message(&event_queue, INITIAL_MESSAGE);

    while *lifecycle_state.read() != LifecycleState::ShuttingDown {
        if *lifecycle_state.read() == LifecycleState::Resumed {
            if let Err(e) = connection_pipeline(
                capabilities.clone(),
                Arc::clone(&ctx),
                Arc::clone(&lifecycle_state),
                Arc::clone(&event_queue),
            ) {
                let message = format!("Connection error:\n{e}\nCheck the PC for more details");
                set_hud_message(&event_queue, &message);
                error!("Connection error: {e}");
            }
        } else {
            debug!("Skip try connection because the device is sleeping");
        }

        *ctx.state.write() = ConnectionState::Disconnected;
        ctx.disconnected_notif.notify_all();

        thread::sleep(CONNECTION_RETRY_INTERVAL);
    }

    dbg_connection!("connection_lifecycle_loop: End");
}

fn connection_pipeline(
    capabilities: ClientCapabilities,
    ctx: Arc<ConnectionContext>,
    lifecycle_state: Arc<RwLock<LifecycleState>>,
    event_queue: Arc<Mutex<VecDeque<ClientCoreEvent>>>,
) -> ConResult {
    dbg_connection!("connection_pipeline: Begin");

    let (mut proto_control_socket, server_ip) = {
        let config = Config::load();
        let announcer_socket = AnnouncerSocket::new(&config.hostname).to_con()?;
        let listener_socket =
            alvr_sockets::get_server_listener(HANDSHAKE_ACTION_TIMEOUT).to_con()?;

        loop {
            if *lifecycle_state.write() != LifecycleState::Resumed {
                return Ok(());
            }

            announcer_socket.announce().ok();

            if let Ok(pair) = ProtoControlSocket::connect_to(
                SOCKET_INIT_RETRY_INTERVAL,
                PeerType::Server(&listener_socket),
            ) {
                set_hud_message(&event_queue, SUCCESS_CONNECT_MESSAGE);
                break pair;
            }
        }
    };

    let mut connection_state_lock = ctx.state.write();
    let disconnect_notif = Arc::new(Condvar::new());

    *connection_state_lock = ConnectionState::Connecting;

    // TODO: Don't fetch cpal sample rate, get directly from AAudio
    let microphone_sample_rate =
        alvr_audio::input_sample_rate(&alvr_audio::new_input(None).to_con()?).to_con()?;

    dbg_connection!("connection_pipeline: Send stream capabilities");
    proto_control_socket
        .send(&ClientConnectionResult::ConnectionAccepted(Box::new(
            ConnectionAcceptedInfo {
                client_protocol_id: alvr_common::protocol_id_u64(),
                platform_string: capabilities.platform.to_string(),
                server_ip,
                streaming_capabilities: Some(
                    VideoStreamingCapabilities {
                        default_view_resolution: capabilities.default_view_resolution,
                        max_view_resolution: capabilities.max_view_resolution,
                        refresh_rates: capabilities.refresh_rates,
                        microphone_sample_rate,
                        foveated_encoding: capabilities.foveated_encoding,
                        encoder_high_profile: capabilities.encoder_high_profile,
                        encoder_10_bits: capabilities.encoder_10_bits,
                        encoder_av1: capabilities.encoder_av1,
                        prefer_10bit: capabilities.prefer_10bit,
                        preferred_encoding_gamma: capabilities.preferred_encoding_gamma,
                        prefer_hdr: capabilities.prefer_hdr,
                        ext_str: String::new(),
                    }
                    .with_ext(VideoStreamingCapabilitiesExt {}),
                ),
            },
        )))
        .to_con()?;
    let config_packet =
        proto_control_socket.recv::<StreamConfigPacket>(HANDSHAKE_ACTION_TIMEOUT)?;
    dbg_connection!("connection_pipeline: stream config received");

    let stream_config = config_packet.to_stream_config().to_con()?;

    let streaming_start_event = ClientCoreEvent::StreamingStarted(Box::new(stream_config.clone()));

    let settings = stream_config.settings;
    let negotiated_config = stream_config.negotiated_config;

    *ctx.max_prediction.write() = Duration::from_millis(settings.headset.max_prediction_ms);

    *ctx.statistics_manager.lock() = Some(StatisticsManager::new(
        settings.connection.statistics_history_size,
    ));

    let (mut control_sender, mut control_receiver) = proto_control_socket
        .split(STREAMING_RECV_TIMEOUT)
        .to_con()?;

    match control_receiver.recv(HANDSHAKE_ACTION_TIMEOUT) {
        Ok(ServerControlPacket::StartStream) => {
            info!("Stream starting");
            set_hud_message(&event_queue, STREAM_STARTING_MESSAGE);
        }
        Ok(ServerControlPacket::Restarting) => {
            info!("Server restarting");
            set_hud_message(&event_queue, SERVER_RESTART_MESSAGE);
            return Ok(());
        }
        Err(e) => {
            info!("Server disconnected. Cause: {e}");
            set_hud_message(&event_queue, SERVER_DISCONNECTED_MESSAGE);
            return Ok(());
        }
        _ => {
            info!("Unexpected packet");
            set_hud_message(&event_queue, "Unexpected packet");
            return Ok(());
        }
    }

    let stream_protocol = if negotiated_config.wired {
        SocketProtocol::Tcp
    } else {
        settings.connection.stream_protocol
    };

    dbg_connection!("connection_pipeline: create StreamSocket");
    let stream_socket_builder = StreamSocketBuilder::listen_for_server(
        Duration::from_secs(1),
        settings.connection.stream_port,
        stream_protocol,
        settings.connection.dscp,
        settings.connection.client_buffer_config,
    )
    .to_con()?;

    dbg_connection!("connection_pipeline: Send StreamReady");
    if let Err(e) = control_sender.send(&ClientControlPacket::StreamReady) {
        info!("Server disconnected. Cause: {e:?}");
        set_hud_message(&event_queue, SERVER_DISCONNECTED_MESSAGE);
        return Ok(());
    }

    dbg_connection!("connection_pipeline: accept connection");
    let mut stream_socket = stream_socket_builder.accept_from_server(
        server_ip,
        settings.connection.stream_port,
        settings.connection.packet_size as _,
        HANDSHAKE_ACTION_TIMEOUT,
    )?;

    info!("Connected to server");

    let mut video_receiver =
        stream_socket.subscribe_to_stream::<VideoPacketHeader>(VIDEO, MAX_UNREAD_PACKETS);
    let mut game_audio_receiver = stream_socket.subscribe_to_stream(AUDIO, MAX_UNREAD_PACKETS);
    let tracking_sender = stream_socket.request_stream(TRACKING);
    let mut haptics_receiver =
        stream_socket.subscribe_to_stream::<Haptics>(HAPTICS, MAX_UNREAD_PACKETS);
    let statistics_sender = stream_socket.request_stream(STATISTICS);

    let video_receive_thread = thread::spawn({
        let ctx = Arc::clone(&ctx);
        move || {
            let mut stream_corrupted = true;
            while is_streaming(&ctx) {
                let data = match video_receiver.recv(STREAMING_RECV_TIMEOUT) {
                    Ok(data) => data,
                    Err(ConnectionError::TryAgain(_)) => continue,
                    Err(ConnectionError::Other(_)) => return,
                };
                let Ok((header, nal)) = data.get() else {
                    return;
                };

                if let Some(stats) = &mut *ctx.statistics_manager.lock() {
                    stats.report_video_packet_received(header.timestamp);
                }

                if header.is_idr {
                    stream_corrupted = false;
                } else if data.had_packet_loss() {
                    stream_corrupted = true;
                    if let Some(sender) = &mut *ctx.control_sender.lock() {
                        sender.send(&ClientControlPacket::RequestIdr).ok();
                    }
                    warn!("Network dropped video packet");
                }

                if !stream_corrupted || !settings.connection.avoid_video_glitching {
                    // The view params must be enqueued before calling the decoder callback, there
                    // is no problem if the callback fails
                    {
                        let global_view_params_queue_lock =
                            &mut ctx.global_view_params_queue.lock();

                        global_view_params_queue_lock
                            .push_back((header.timestamp, header.global_view_params));

                        while global_view_params_queue_lock.len() > 128 {
                            global_view_params_queue_lock.pop_front();
                        }
                    }

                    let submitted = ctx
                        .decoder_callback
                        .lock()
                        .as_mut()
                        .is_some_and(|callback| callback(header.timestamp, nal));

                    if !submitted {
                        stream_corrupted = true;
                        if let Some(sender) = &mut *ctx.control_sender.lock() {
                            sender.send(&ClientControlPacket::RequestIdr).ok();
                        }
                        warn!("Dropped video packet. Reason: Decoder saturation")
                    }
                } else {
                    if let Some(sender) = &mut *ctx.control_sender.lock() {
                        sender.send(&ClientControlPacket::RequestIdr).ok();
                    }
                    warn!("Dropped video packet. Reason: Waiting for IDR frame")
                }
            }
        }
    });

    let game_audio_thread = if let Switch::Enabled(config) = settings.audio.game_audio {
        let device = alvr_audio::new_output(None).to_con()?;
        thread::spawn({
            let ctx = Arc::clone(&ctx);
            move || {
                while is_streaming(&ctx) {
                    alvr_common::show_err(audio::play_audio_loop(
                        || is_streaming(&ctx),
                        &device,
                        2,
                        negotiated_config.game_audio_sample_rate,
                        config.buffering.clone(),
                        &mut game_audio_receiver,
                    ));
                }
            }
        })
    } else {
        thread::spawn(|| ())
    };

    let microphone_thread = if matches!(settings.audio.microphone, Switch::Enabled(_)) {
        let device = alvr_audio::new_input(None).to_con()?;

        let microphone_sender = stream_socket.request_stream(AUDIO);

        thread::spawn({
            let ctx = Arc::clone(&ctx);
            move || {
                while is_streaming(&ctx) {
                    let ctx = Arc::clone(&ctx);
                    match audio::record_audio_blocking(
                        Arc::new(move || is_streaming(&ctx)),
                        microphone_sender.clone(),
                        &device,
                        1,
                        false,
                    ) {
                        Ok(()) => break,
                        Err(e) => {
                            error!("Audio record error: {e}");

                            continue;
                        }
                    }
                }
            }
        })
    } else {
        thread::spawn(|| ())
    };

    let haptics_receive_thread = thread::spawn({
        let ctx = Arc::clone(&ctx);
        let event_queue = Arc::clone(&event_queue);
        move || {
            while is_streaming(&ctx) {
                let data = match haptics_receiver.recv(STREAMING_RECV_TIMEOUT) {
                    Ok(packet) => packet,
                    Err(ConnectionError::TryAgain(_)) => continue,
                    Err(ConnectionError::Other(_)) => return,
                };
                let Ok(haptics) = data.get_header() else {
                    return;
                };

                event_queue.lock().push_back(ClientCoreEvent::Haptics {
                    device_id: haptics.device_id,
                    duration: haptics.duration,
                    frequency: haptics.frequency,
                    amplitude: haptics.amplitude,
                });
            }
        }
    });

    let (log_channel_sender, log_channel_receiver) = mpsc::channel();

    let control_send_thread = thread::spawn({
        let ctx = Arc::clone(&ctx);
        let event_queue = Arc::clone(&event_queue);
        let disconnect_notif = Arc::clone(&disconnect_notif);
        move || {
            let mut keepalive_deadline = Instant::now();

            #[cfg(target_os = "android")]
            let mut battery_deadline = Instant::now();

            while is_streaming(&ctx) && *lifecycle_state.read() == LifecycleState::Resumed {
                if let Ok(packet) = log_channel_receiver.recv_timeout(STREAMING_RECV_TIMEOUT)
                    && let Some(sender) = &mut *ctx.control_sender.lock()
                    && let Err(e) = sender.send(&packet)
                {
                    info!("Server disconnected. Cause: {e:?}");
                    set_hud_message(&event_queue, SERVER_DISCONNECTED_MESSAGE);

                    break;
                }

                if Instant::now() > keepalive_deadline
                    && let Some(sender) = &mut *ctx.control_sender.lock()
                {
                    sender.send(&ClientControlPacket::KeepAlive).ok();

                    keepalive_deadline = Instant::now() + KEEPALIVE_INTERVAL;
                }

                #[cfg(target_os = "android")]
                if Instant::now() > battery_deadline {
                    let (gauge_value, is_plugged) = alvr_system_info::get_battery_status();
                    if let Some(sender) = &mut *ctx.control_sender.lock() {
                        sender
                            .send(&ClientControlPacket::Battery(crate::BatteryInfo {
                                device_id: *alvr_common::HEAD_ID,
                                gauge_value,
                                is_plugged,
                            }))
                            .ok();
                    }

                    battery_deadline = Instant::now() + Duration::from_secs(5);
                }
            }

            disconnect_notif.notify_one();
        }
    });

    let control_receive_thread = thread::spawn({
        let ctx = Arc::clone(&ctx);
        let event_queue = Arc::clone(&event_queue);
        let disconnect_notif = Arc::clone(&disconnect_notif);
        move || {
            let mut disconnection_deadline = Instant::now() + KEEPALIVE_TIMEOUT;
            while is_streaming(&ctx) {
                let maybe_packet = control_receiver.recv(STREAMING_RECV_TIMEOUT);

                match maybe_packet {
                    Ok(ServerControlPacket::DecoderConfig(config)) => {
                        event_queue
                            .lock()
                            .push_back(ClientCoreEvent::DecoderConfig {
                                codec: config.codec,
                                config_nal: config.config_buffer,
                            });
                    }
                    Ok(ServerControlPacket::Restarting) => {
                        info!("{SERVER_RESTART_MESSAGE}");
                        set_hud_message(&event_queue, SERVER_RESTART_MESSAGE);
                        disconnect_notif.notify_one();
                    }
                    Ok(ServerControlPacket::RealTimeConfig(config)) => {
                        event_queue
                            .lock()
                            .push_back(ClientCoreEvent::RealTimeConfig(config));
                    }
                    Ok(ServerControlPacket::StartStream) => {
                        error!("Unexpected StartStream paceket");
                    }
                    Ok(ServerControlPacket::KeepAlive) => (),
                    Ok(
                        ServerControlPacket::Reserved(_) | ServerControlPacket::ReservedBuffer(_),
                    ) => {}
                    Err(ConnectionError::TryAgain(_)) => {
                        if Instant::now() > disconnection_deadline {
                            info!("{CONNECTION_TIMEOUT_MESSAGE}");
                            set_hud_message(&event_queue, CONNECTION_TIMEOUT_MESSAGE);
                            disconnect_notif.notify_one();
                        } else {
                            continue;
                        }
                    }
                    Err(e) => {
                        info!("{SERVER_DISCONNECTED_MESSAGE} Cause: {e}");
                        set_hud_message(&event_queue, SERVER_DISCONNECTED_MESSAGE);
                        disconnect_notif.notify_one();
                    }
                }

                disconnection_deadline = Instant::now() + KEEPALIVE_TIMEOUT;
            }
        }
    });

    let stream_receive_thread = thread::spawn({
        let ctx = Arc::clone(&ctx);
        let event_queue = Arc::clone(&event_queue);
        let disconnect_notif = Arc::clone(&disconnect_notif);
        move || {
            while is_streaming(&ctx) {
                match stream_socket.recv() {
                    Ok(()) => (),
                    Err(ConnectionError::TryAgain(_)) => continue,
                    Err(e) => {
                        info!("Client disconnected. Cause: {e}");
                        set_hud_message(&event_queue, SERVER_DISCONNECTED_MESSAGE);
                        disconnect_notif.notify_one();
                    }
                }
            }
        }
    });

    *ctx.control_sender.lock() = Some(control_sender);
    *ctx.tracking_sender.lock() = Some(tracking_sender);
    *ctx.statistics_sender.lock() = Some(statistics_sender);
    if let Switch::Enabled(filter_level) = settings.extra.logging.client_log_report_level {
        *LOG_CHANNEL_SENDER.lock() = Some(LogMirrorData {
            sender: log_channel_sender,
            filter_level,
            debug_groups_config: settings.extra.logging.debug_groups,
        });
    }
    event_queue.lock().push_back(streaming_start_event);

    *connection_state_lock = ConnectionState::Streaming;

    dbg_connection!("connection_pipeline: Unlock streams");

    // Unlock CONNECTION_STATE and block thread
    wait_rwlock(&disconnect_notif, &mut connection_state_lock);

    *connection_state_lock = ConnectionState::Disconnecting;

    *ctx.control_sender.lock() = None;
    *ctx.tracking_sender.lock() = None;
    *ctx.statistics_sender.lock() = None;
    *LOG_CHANNEL_SENDER.lock() = None;

    event_queue
        .lock()
        .push_back(ClientCoreEvent::StreamingStopped);

    // Remove lock to allow threads to properly exit:
    drop(connection_state_lock);

    dbg_connection!("connection_pipeline: Destroying streams");

    video_receive_thread.join().ok();
    game_audio_thread.join().ok();
    microphone_thread.join().ok();
    haptics_receive_thread.join().ok();
    control_send_thread.join().ok();
    control_receive_thread.join().ok();
    stream_receive_thread.join().ok();

    dbg_connection!("connection_pipeline: End");

    Ok(())
}


================================================
FILE: alvr/client_core/src/lib.rs
================================================
#![allow(
    non_upper_case_globals,
    non_snake_case,
    clippy::missing_safety_doc,
    clippy::unseparated_literal_suffix
)]

mod c_api;
mod connection;
mod logging_backend;
mod sockets;
mod statistics;
mod storage;

#[cfg(target_os = "android")]
mod audio;

pub mod video_decoder;

use alvr_common::{
    ConnectionState, LifecycleState, ViewParams, dbg_client_core, error,
    glam::{UVec2, Vec2},
    parking_lot::{Mutex, RwLock},
    warn,
};
use alvr_packets::{
    BatteryInfo, ButtonEntry, ClientControlPacket, RealTimeConfig, StreamConfig, TrackingData,
};
use alvr_session::CodecType;
use alvr_system_info::Platform;
use connection::{ConnectionContext, DecoderCallback};
use std::{
    collections::{HashSet, VecDeque},
    sync::Arc,
    thread::{self, JoinHandle},
    time::Duration,
};
use storage::Config;

pub use logging_backend::init_logging;

pub enum ClientCoreEvent {
    UpdateHudMessage(String),
    StreamingStarted(Box<StreamConfig>),
    StreamingStopped,
    Haptics {
        device_id: u64,
        duration: Duration,
        frequency: f32,
        amplitude: f32,
    },
    // Note: All subsequent DecoderConfig events should be ignored until reconnection
    DecoderConfig {
        codec: CodecType,
        config_nal: Vec<u8>,
    },
    RealTimeConfig(RealTimeConfig),
}

// Note: this struct may change without breaking network protocol changes
#[derive(Clone)]
pub struct ClientCapabilities {
    pub platform: Platform,
    pub default_view_resolution: UVec2,
    pub max_view_resolution: UVec2,
    pub refresh_rates: Vec<f32>,
    pub foveated_encoding: bool,
    pub encoder_high_profile: bool,
    pub encoder_10_bits: bool,
    pub encoder_av1: bool,
    pub prefer_10bit: bool,
    pub preferred_encoding_gamma: f32,
    pub prefer_hdr: bool,
}

pub struct ClientCoreContext {
    platform: Platform,
    lifecycle_state: Arc<RwLock<LifecycleState>>,
    event_queue: Arc<Mutex<VecDeque<ClientCoreEvent>>>,
    connection_context: Arc<ConnectionContext>,
    connection_thread: Arc<Mutex<Option<JoinHandle<()>>>>,
    last_good_global_view_params: Mutex<[ViewParams; 2]>,
}

impl ClientCoreContext {
    pub fn new(capabilities: ClientCapabilities) -> Self {
        dbg_client_core!("Create");

        // Make sure to reset config in case of version compat mismatch.
        if Config::load().protocol_id != alvr_common::protocol_id() {
            // NB: Config::default() sets the current protocol ID
            Config::default().store();
        }

        #[cfg(target_os = "android")]
        {
            dbg_client_core!("Getting permissions");
            alvr_system_info::try_get_permission(alvr_system_info::MICROPHONE_PERMISSION);
            alvr_system_info::set_wifi_lock(true);
        }

        let platform = capabilities.platform;

        let lifecycle_state = Arc::new(RwLock::new(LifecycleState::Idle));
        let event_queue = Arc::new(Mutex::new(VecDeque::new()));
        let connection_context = Arc::new(ConnectionContext::default());
        let connection_thread = thread::spawn({
            let lifecycle_state = Arc::clone(&lifecycle_state);
            let connection_context = Arc::clone(&connection_context);
            let event_queue = Arc::clone(&event_queue);
            move || {
                connection::connection_lifecycle_loop(
                    capabilities,
                    connection_context,
                    lifecycle_state,
                    event_queue,
                )
            }
        });

        Self {
            platform,
            lifecycle_state,
            event_queue,
            connection_context,
            connection_thread: Arc::new(Mutex::new(Some(connection_thread))),
            last_good_global_view_params: Mutex::new([ViewParams::DUMMY; 2]),
        }
    }

    pub fn resume(&self) {
        dbg_client_core!("resume");

        *self.lifecycle_state.write() = LifecycleState::Resumed;
    }

    pub fn pause(&self) {
        dbg_client_core!("pause");

        let mut connection_state_lock = self.connection_context.state.write();

        *self.lifecycle_state.write() = LifecycleState::Idle;

        // We want to shutdown streaming when pausing.
        if *connection_state_lock != ConnectionState::Disconnected {
            alvr_common::wait_rwlock(
                &self.connection_context.disconnected_notif,
                &mut connection_state_lock,
            );
        }
    }

    pub fn poll_event(&self) -> Option<ClientCoreEvent> {
        dbg_client_core!("poll_event");

        self.event_queue.lock().pop_front()
    }

    pub fn send_battery(&self, device_id: u64, gauge_value: f32, is_plugged: bool) {
        dbg_client_core!("send_battery");

        if let Some(sender) = &mut *self.connection_context.control_sender.lock() {
            sender
                .send(&ClientControlPacket::Battery(BatteryInfo {
                    device_id,
                    gauge_value,
                    is_plugged,
                }))
                .ok();
        }
    }

    pub fn send_playspace(&self, area: Option<Vec2>) {
        dbg_client_core!("send_playspace");

        if let Some(sender) = &mut *self.connection_context.control_sender.lock() {
            sender.send(&ClientControlPacket::PlayspaceSync(area)).ok();
        }
    }

    pub fn send_active_interaction_profile(
        &self,
        device_id: u64,
        profile_id: u64,
        input_ids: HashSet<u64>,
    ) {
        dbg_client_core!("send_active_interaction_profile");

        if let Some(sender) = &mut *self.connection_context.control_sender.lock() {
            sender
                .send(&ClientControlPacket::ActiveInteractionProfile {
                    device_id,
                    profile_id,
                    input_ids,
                })
                .ok();
        }
    }

    pub fn send_buttons(&self, entries: Vec<ButtonEntry>) {
        dbg_client_core!("send_buttons");

        if let Some(sender) = &mut *self.connection_context.control_sender.lock() {
            sender.send(&ClientControlPacket::Buttons(entries)).ok();
        }
    }

    // These must be in its local space, as if the head pose is in the origin.
    pub fn send_view_params(&self, views: [ViewParams; 2]) {
        dbg_client_core!("send_view_params");

        if let Some(sender) = &mut *self.connection_context.control_sender.lock() {
            sender
                .send(&ClientControlPacket::LocalViewParams(views))
                .ok();
        }
    }

    pub fn send_tracking(&self, data: TrackingData) {
        dbg_client_core!("send_tracking");

        if let Some(sender) = &mut *self.connection_context.tracking_sender.lock() {
            sender.send_header(&data).ok();

            if let Some(stats) = &mut *self.connection_context.statistics_manager.lock() {
                stats.report_input_acquired(data.poll_timestamp);
            }
        }
    }

    pub fn send_proximity_state(&self, headset_is_worn: bool) {
        if let Some(sender) = &mut *self.connection_context.control_sender.lock() {
            sender
                .send(&ClientControlPacket::ProximityState(headset_is_worn))
                .ok();
        }
    }

    pub fn get_total_prediction_offset(&self) -> Duration {
        dbg_client_core!("get_total_prediction_offset");

        if let Some(stats) = &*self.connection_context.statistics_manager.lock() {
            Duration::min(
                stats.average_total_pipeline_latency(),
                *self.connection_context.max_prediction.read(),
            )
        } else {
            Duration::ZERO
        }
    }

    /// The callback should return true if the frame was successfully submitted to the decoder
    pub fn set_decoder_input_callback(&self, callback: Box<DecoderCallback>) {
        dbg_client_core!("set_decoder_input_callback");

        *self.connection_context.decoder_callback.lock() = Some(callback);

        if let Some(sender) = &mut *self.connection_context.control_sender.lock() {
            sender.send(&ClientControlPacket::RequestIdr).ok();
        }
    }

    pub fn report_frame_decoded(&self, timestamp: Duration) {
        dbg_client_core!("report_frame_decoded");

        if let Some(stats) = &mut *self.connection_context.statistics_manager.lock() {
            stats.report_frame_decoded(timestamp);
        }
    }

    pub fn report_fatal_decoder_error(&self, error: &str) {
        error!("Fatal decoder error, restarting connection: {error}");

        // The connection loop observes changes on this value
        *self.connection_context.state.write() = ConnectionState::Disconnecting;
    }

    pub fn report_compositor_start(&self, timestamp: Duration) -> [ViewParams; 2] {
        dbg_client_core!("report_compositor_start");

        if let Some(stats) = &mut *self.connection_context.statistics_manager.lock() {
            stats.report_compositor_start(timestamp);
        }

        let global_view_params_lock = &mut *self.last_good_global_view_params.lock();
        for (ts, params) in &*self.connection_context.global_view_params_queue.lock() {
            if *ts == timestamp {
                *global_view_params_lock = *params;
                break;
            }
        }

        *global_view_params_lock
    }

    pub fn report_submit(&self, timestamp: Duration, vsync_queue: Duration) {
        dbg_client_core!("report_submit");

        if let Some(stats) = &mut *self.connection_context.statistics_manager.lock() {
            stats.report_submit(timestamp, vsync_queue);

            if let Some(sender) = &mut *self.connection_context.statistics_sender.lock() {
                if let Some(stats) = stats.summary(timestamp) {
                    sender.send_header(&stats).ok();
                } else {
                    warn!("Statistics summary not ready!");
                }
            }
        }
    }

    pub fn platform(&self) -> Platform {
        self.platform
    }
}

impl Drop for ClientCoreContext {
    fn drop(&mut self) {
        dbg_client_core!("Drop");

        *self.lifecycle_state.write() = LifecycleState::ShuttingDown;

        if let Some(thread) = self.connection_thread.lock().take() {
            thread.join().ok();
        }

        #[cfg(target_os = "android")]
        alvr_system_info::set_wifi_lock(false);
    }
}


================================================
FILE: alvr/client_core/src/logging_backend.rs
================================================
use alvr_common::{
    DebugGroupsConfig, LogSeverity,
    log::{Level, Record},
    parking_lot::Mutex,
};
use alvr_packets::ClientControlPacket;
use std::{
    sync::{LazyLock, mpsc},
    time::{Duration, Instant},
};

const LOG_REPEAT_TIMEOUT: Duration = Duration::from_secs(1);

pub struct LogMirrorData {
    pub sender: mpsc::Sender<ClientControlPacket>,
    pub filter_level: LogSeverity,
    pub debug_groups_config: DebugGroupsConfig,
}

pub static LOG_CHANNEL_SENDER: Mutex<Option<LogMirrorData>> = Mutex::new(None);

struct RepeatedLogEvent {
    message: String,
    repetition_times: usize,
    initial_timestamp: Instant,
}

static LAST_LOG_EVENT: LazyLock<Mutex<RepeatedLogEvent>> = LazyLock::new(|| {
    Mutex::new(RepeatedLogEvent {
        message: "".into(),
        repetition_times: 0,
        initial_timestamp: Instant::now(),
    })
});

pub fn init_logging() {
    fn send_log(record: &Record) -> bool {
        let Some(data) = &*LOG_CHANNEL_SENDER.lock() else {
            // if channel has not been setup, always print everything to stdout
            // todo: the client debug groups settings should be moved client side when feasible
            return true;
        };

        let level = match record.level() {
            Level::Error => LogSeverity::Error,
            Level::Warn => LogSeverity::Warning,
            Level::Info => LogSeverity::Info,
            Level::Debug | Level::Trace => LogSeverity::Debug,
        };
        if level < data.filter_level {
            return false;
        }

        let message = format!("{}", record.args());

        if !alvr_common::filter_debug_groups(&message, &data.debug_groups_config) {
            return false;
        }

        let mut last_log_event_lock = LAST_LOG_EVENT.lock();

        if last_log_event_lock.message == message
            && last_log_event_lock.initial_timestamp + LOG_REPEAT_TIMEOUT > Instant::now()
        {
            last_log_event_lock.repetition_times += 1;
        } else {
            if last_log_event_lock.repetition_times > 1 {
                data.sender
                    .send(ClientControlPacket::Log {
                        level: LogSeverity::Info,
                        message: format!(
                            "Last log line repeated {} times",
                            last_log_event_lock.repetition_times
                        ),
                    })
                    .ok();
            }

            *last_log_event_lock = RepeatedLogEvent {
                message: message.clone(),
                repetition_times: 1,
                initial_timestamp: Instant::now(),
            };

            data.sender
                .send(ClientControlPacket::Log { level, message })
                .ok();
        }

        true
    }

    #[cfg(target_os = "android")]
    {
        android_logger::init_once(
            android_logger::Config::default()
                .with_tag("[ALVR NATIVE-RUST]")
                .format(|f, record| {
                    if send_log(record) {
                        writeln!(f, "{}", record.args())
                    } else {
                        Ok(())
                    }
                })
                .with_max_level(alvr_common::log::LevelFilter::Info),
        );
    }
    #[cfg(not(target_os = "android"))]
    {
        use std::io::Write;
        env_logger::builder()
            .format(|f, record| {
                if send_log(record) {
                    writeln!(f, "{}", record.args())
                } else {
                    Ok(())
                }
            })
            .try_init()
            .ok();
    }

    alvr_common::set_panic_hook();
}


================================================
FILE: alvr/client_core/src/sockets.rs
================================================
use alvr_common::anyhow::{Result, bail};
use mdns_sd::{ServiceDaemon, ServiceInfo};

pub struct AnnouncerSocket {
    hostname: String,
    daemon: ServiceDaemon,
}

impl AnnouncerSocket {
    pub fn new(hostname: &str) -> Result<Self> {
        let daemon = ServiceDaemon::new()?;

        Ok(Self {
            daemon,
            hostname: hostname.to_owned(),
        })
    }

    pub fn announce(&self) -> Result<()> {
        let local_ip = alvr_system_info::local_ip();
        if local_ip.is_unspecified() {
            bail!("IP is unspecified");
        }

        self.daemon.register(ServiceInfo::new(
            alvr_sockets::MDNS_SERVICE_TYPE,
            &format!("alvr{}", rand::random::<u16>()),
            &self.hostname,
            local_ip,
            5353,
            &[(
                alvr_sockets::MDNS_PROTOCOL_KEY,
                alvr_common::protocol_id().as_str(),
            )][..],
        )?)?;

        Ok(())
    }
}


================================================
FILE: alvr/client_core/src/statistics.rs
================================================
use alvr_common::SlidingWindowAverage;
use alvr_packets::ClientStatistics;
use std::{
    collections::VecDeque,
    time::{Duration, Instant},
};

struct HistoryFrame {
    input_acquired: Instant,
    video_packet_received: Instant,
    client_stats: ClientStatistics,
}

pub struct StatisticsManager {
    history_buffer: VecDeque<HistoryFrame>,
    max_history_size: usize,
    prev_vsync: Instant,
    total_pipeline_latency_average: SlidingWindowAverage<Duration>,
}

impl StatisticsManager {
    pub fn new(max_history_size: usize) -> Self {
        Self {
            max_history_size,
            history_buffer: VecDeque::new(),
            prev_vsync: Instant::now(),
            total_pipeline_latency_average: SlidingWindowAverage::new(
                Duration::ZERO,
                max_history_size,
            ),
        }
    }

    pub fn report_input_acquired(&mut self, target_timestamp: Duration) {
        if !self
            .history_buffer
            .iter()
            .any(|frame| frame.client_stats.target_timestamp == target_timestamp)
        {
            self.history_buffer.push_front(HistoryFrame {
                input_acquired: Instant::now(),
                // this is just a placeholder because Instant does not have a default value
                video_packet_received: Instant::now(),
                client_stats: ClientStatistics {
                    target_timestamp,
                    ..Default::default()
                },
            });
        }

        if self.history_buffer.len() > self.max_history_size {
            self.history_buffer.pop_back();
        }
    }

    pub fn report_video_packet_received(&mut self, target_timestamp: Duration) {
        if let Some(frame) = self
            .history_buffer
            .iter_mut()
            .find(|frame| frame.client_stats.target_timestamp == target_timestamp)
        {
            frame.video_packet_received = Instant::now();
        }
    }

    pub fn report_frame_decoded(&mut self, target_timestamp: Duration) {
        if let Some(frame) = self
            .history_buffer
            .iter_mut()
            .find(|frame| frame.client_stats.target_timestamp == target_timestamp)
        {
            frame.client_stats.video_decode =
                Instant::now().saturating_duration_since(frame.video_packet_received);
        }
    }

    pub fn report_compositor_start(&mut self, target_timestamp: Duration) {
        if let Some(frame) = self
            .history_buffer
            .iter_mut()
            .find(|frame| frame.client_stats.target_timestamp == target_timestamp)
        {
            frame.client_stats.video_decoder_queue = Instant::now().saturating_duration_since(
                frame.video_packet_received + frame.client_stats.video_decode,
            );
        }
    }

    // vsync_queue is the latency between this call and the vsync. it cannot be measured by ALVR and
    // should be reported by the VR runtime
    pub fn report_submit(&mut self, target_timestamp: Duration, vsync_queue: Duration) {
        let now = Instant::now();

        if let Some(frame) = self
            .history_buffer
            .iter_mut()
            .find(|frame| frame.client_stats.target_timestamp == target_timestamp)
        {
            frame.client_stats.rendering = now.saturating_duration_since(
                frame.video_packet_received
                    + frame.client_stats.video_decode
                    + frame.client_stats.video_decoder_queue,
            );
            frame.client_stats.vsync_queue = vsync_queue;
            frame.client_stats.total_pipeline_latency =
                now.saturating_duration_since(frame.input_acquired) + vsync_queue;
            self.total_pipeline_latency_average
                .submit_sample(frame.client_stats.total_pipeline_latency);

            let vsync = now + vsync_queue;
            frame.client_stats.frame_interval = vsync.saturating_duration_since(self.prev_vsync);
            self.prev_vsync = vsync;
        }
    }

    pub fn summary(&self, target_timestamp: Duration) -> Option<ClientStatistics> {
        self.history_buffer
            .iter()
            .find(|frame| frame.client_stats.target_timestamp == target_timestamp)
            .map(|frame| frame.client_stats.clone())
    }

    // latency used for head prediction
    pub fn average_total_pipeline_latency(&self) -> Duration {
        self.total_pipeline_latency_average.get_average()
    }
}


================================================
FILE: alvr/client_core/src/storage.rs
================================================
use alvr_common::{error, info};
use app_dirs2::{AppDataType, AppInfo};
use rand::Rng;
use serde::{Deserialize, Serialize};
use std::{fs, path::PathBuf};

fn config_path() -> PathBuf {
    app_dirs2::app_root(
        AppDataType::UserConfig,
        &AppInfo {
            name: "ALVR Client",
            author: "ALVR",
        },
    )
    .unwrap()
    .join("session.json")
}

#[derive(Serialize, Deserialize)]
pub struct Config {
    pub hostname: String,
    pub protocol_id: String,
}

impl Default for Config {
    fn default() -> Self {
        let mut rng = rand::rng();

        Self {
            hostname: format!(
                "{}{}{}{}.client.local.",
                rng.random_range(0..10),
                rng.random_range(0..10),
                rng.random_range(0..10),
                rng.random_range(0..10),
            ),
            protocol_id: alvr_common::protocol_id(),
        }
    }
}

impl Config {
    pub fn load() -> Self {
        if let Ok(config_string) = fs::read_to_string(config_path()) {
            // Failure happens if the Config signature changed between versions.
            // todo: recover data from mismatched Config signature. low priority
            if let Ok(config) = serde_json::from_str(&config_string) {
                return config;
            } else {
                info!("Error parsing ALVR config. Using default");
            }
        } else {
            info!("Error reading ALVR config. Using default");
        }

        let config = Config::default();
        config.store();

        config
    }

    pub fn store(&self) {
        let config_string = serde_json::to_string(self).unwrap();
        if let Err(e) = fs::write(config_path(), config_string) {
            error!("Error writing ALVR config: {e}")
        }
    }
}


================================================
FILE: alvr/client_core/src/video_decoder/android.rs
================================================
use super::VideoDecoderConfig;
use alvr_common::{
    RelaxedAtomic, ToAny,
    anyhow::{Context, Result, anyhow, bail},
    error, info,
    parking_lot::{Condvar, Mutex},
    warn,
};
use alvr_session::{CodecType, MediacodecPropType};
use ndk::{
    hardware_buffer::HardwareBufferUsage,
    media::{
        image_reader::{AcquireResult, Image, ImageFormat, ImageReader},
        media_codec::{
            DequeuedInputBufferResult, DequeuedOutputBufferInfoResult, MediaCodec,
            MediaCodecDirection, MediaFormat,
        },
    },
};
use std::{
    collections::VecDeque,
    ffi::c_void,
    ops::Deref,
    ptr,
    sync::{Arc, Weak},
    thread::{self, JoinHandle},
    time::Duration,
};

struct FakeThreadSafe<T>(T);
unsafe impl<T> Send for FakeThreadSafe<T> {}
unsafe impl<T> Sync for FakeThreadSafe<T> {}

impl<T> Deref for FakeThreadSafe<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

type SharedMediaCodec = Arc<FakeThreadSafe<MediaCodec>>;

pub struct VideoDecoderSink {
    inner: Arc<Mutex<Option<SharedMediaCodec>>>,
}

unsafe impl Send for VideoDecoderSink {}

impl VideoDecoderSink {
    // Block until the buffer has been written or timeout is reached. Returns false if timeout.
    pub fn push_frame_nal(&mut self, timestamp: Duration, data: &[u8]) -> Result<bool> {
        let Some(decoder) = &*self.inner.lock() else {
            // This might happen only during destruction
            return Ok(false);
        };

        match decoder.dequeue_input_buffer(Duration::ZERO) {
            Ok(DequeuedInputBufferResult::Buffer(mut buffer)) => {
                unsafe {
                    ptr::copy_nonoverlapping(
                        data.as_ptr(),
                        buffer.buffer_mut().as_mut_ptr().cast(),
                        data.len(),
                    )
                };

                // NB: the function expects the timestamp in micros, but nanos is used to have
                // complete precision, so when converted back to Duration it can compare correctly
                // to other Durations
                decoder.queue_input_buffer(buffer, 0, data.len(), timestamp.as_nanos() as _, 0)?;

                Ok(true)
            }
            Ok(DequeuedInputBufferResult::TryAgainLater) => Ok(false),
            Err(e) => bail!("{e}"),
        }
    }
}

struct QueuedImage {
    timestamp: Duration,
    image: Image,
    in_use: bool,
}
unsafe impl Send for QueuedImage {}

// Access the image queue synchronously.
pub struct VideoDecoderSource {
    running: Arc<RelaxedAtomic>,
    dequeue_thread: Option<JoinHandle<()>>,
    image_queue: Arc<Mutex<VecDeque<QueuedImage>>>,
    config: VideoDecoderConfig,
    buffering_running_average: f32,
}

unsafe impl Send for VideoDecoderSource {}

impl VideoDecoderSource {
    // The application MUST finish using the returned buffer before calling this function again
    pub fn dequeue_frame(&mut self) -> Option<(Duration, *mut c_void)> {
        let mut image_queue_lock = self.image_queue.lock();

        if let Some(queued_image) = image_queue_lock.front()
            && queued_image.in_use
        {
            // image is released and ready to be reused by the decoder
            image_queue_lock.pop_front();
        }

        // use running average to give more weight to recent samples
        self.buffering_running_average = self.buffering_running_average
            * self.config.buffering_history_weight
            + image_queue_lock.len() as f32 * (1. - self.config.buffering_history_weight);
        if self.buffering_running_average > self.config.max_buffering_frames as f32 {
            image_queue_lock.pop_front();
        }

        if let Some(queued_image) = image_queue_lock.front_mut() {
            queued_image.in_use = true;

            Some((
                queued_image.timestamp,
                queued_image
                    .image
                    .hardware_buffer()
                    .unwrap()
                    .as_ptr()
                    .cast(),
            ))
        } else {
            // TODO: add back when implementing proper phase sync
            //warn!("Video frame queue underflow!");
            None
        }
    }
}

impl Drop for VideoDecoderSource {
    fn drop(&mut self) {
        self.running.set(false);

        // Destruction of decoder, buffered images and ImageReader
        self.dequeue_thread.take().map(|t| t.join());
    }
}

fn mime_for_codec(codec: CodecType) -> &'static str {
    match codec {
        CodecType::H264 => "video/avc",
        CodecType::Hevc => "video/hevc",
        CodecType::AV1 => "video/av01",
    }
}

// Attempts to create a MediaCodec, and then configure and start it.
fn decoder_attempt_setup(
    codec_type: CodecType,
    is_software: bool,
    format: &MediaFormat,
    image_reader: &ImageReader,
) -> Result<MediaCodec> {
    let decoder = if is_software {
        let sw_codec_name = match codec_type {
            CodecType::H264 => "OMX.google.h264.decoder",
            CodecType::Hevc => "OMX.google.hevc.decoder",
            CodecType::AV1 => bail!("AV1 is not supported for software decoding"),
        };
        MediaCodec::from_codec_name(&sw_codec_name)
            .ok_or(anyhow!("no such codec: {}", &sw_codec_name))?
    } else {
        let mime = mime_for_codec(codec_type);
        MediaCodec::from_decoder_type(&mime)
            .ok_or(anyhow!("unable to find decoder for mime type: {}", &mime))?
    };
    decoder
        .configure(
            &format,
            Some(&image_reader.window()?),
            MediaCodecDirection::Decoder,
        )
        .with_context(|| format!("failed to configure decoder"))?;

    decoder
        .start()
        .with_context(|| format!("failed to start decoder"))?;

    Ok(decoder)
}

// Since we leak the ImageReader, and we pass frame_result_callback to it which contains a reference
// to ClientCoreContext, to avoid circular references we need to use a Weak reference.
fn decoder_lifecycle(
    config: VideoDecoderConfig,
    csd_0: Vec<u8>,
    frame_result_callback: Weak<impl Fn(Result<Duration>) + Send + Sync + 'static>,
    running: Arc<RelaxedAtomic>,
    decoder_sink: Arc<Mutex<Option<SharedMediaCodec>>>,
    decoder_ready_notifier: Arc<Condvar>,
    image_queue: Arc<Mutex<VecDeque<QueuedImage>>>,
    image_reader: &mut ImageReader,
) -> Result<()> {
    // 2x: keep the target buffering in the middle of the max amount of queuable frames
    let available_buffering_frames = (2. * config.max_buffering_frames).ceil() as usize;

    image_reader.set_image_listener(Box::new({
        let image_queue = Arc::clone(&image_queue);
        move |image_reader| {
            let mut image_queue_lock = image_queue.lock();

            if image_queue_lock.len() > available_buffering_frames {
                warn!("Video frame queue overflow!");
                image_queue_lock.pop_front();
            }

            match image_reader.acquire_next_image() {
                Ok(AcquireResult::Image(image)) => {
                    let timestamp = Duration::from_nanos(image.timestamp().unwrap() as u64);

                    if let Some(callback) = frame_result_callback.upgrade() {
                        callback(Ok(timestamp));
                    }

                    image_queue_lock.push_back(QueuedImage {
                        timestamp,
                        image,
                        in_use: false,
                    });
                }
                Ok(e) => {
                    error!("ImageReader error: {e:?}");

                    image_queue_lock.pop_front();
                }
                Err(e) => {
                    error!("ImageReader error: {e}");

                    image_queue_lock.clear();
                }
            }
        }
    }))?;

    // Documentation says that this call is necessary to properly dispose acquired buffers.
    // todo: find out how to use it and avoid leaking the ImageReader
    image_reader.set_buffer_removed_listener(Box::new(|_, _| ()))?;

    let mime = mime_for_codec(config.codec);

    let mut format = MediaFormat::new();
    format.set_str("mime", mime);
    // Given https://github.com/alvr-org/ALVR/pull/1933#discussion_r1431902906 - change at own risk.
    // It might be harmless, it might not be, but it's definitely a risk.
    format.set_i32("width", 512);
    format.set_i32("height", 1024);
    format.set_buffer("csd-0", &csd_0);

    for (key, prop) in &config.options {
        let maybe_error = match prop.ty {
            MediacodecPropType::Float => prop
                .value
                .parse()
                .map(|value| format.set_f32(key, value))
                .to_any(),
            MediacodecPropType::Int32 => prop
                .value
                .parse()
                .map(|value| format.set_i32(key, value))
                .to_any(),
            MediacodecPropType::Int64 => prop
                .value
                .parse()
                .map(|value| format.set_i64(key, value))
                .to_any(),
            MediacodecPropType::String => Ok(format.set_str(key, &prop.value)),
        };

        if let Err(e) = maybe_error {
            error!("Failed to set property {key} to {}: {e}", prop.value);
        }
    }

    info!("Using AMediaCodec format:{} ", format);

    let decoder = if config.force_software_decoder {
        decoder_attempt_setup(config.codec, true, &format, &image_reader)?
    } else {
        // Hardware decoders sometimes fail at the CSD-0.
        // May as well fall back if this occurs.
        match decoder_attempt_setup(config.codec, false, &format, &image_reader) {
            Ok(d) => d,
            Err(e) => {
                // would be "warn!" but this is a severe caveat and a pretty major error.
                error!("Attempting software fallback due to error in default decoder: {e:#}");

                decoder_attempt_setup(config.codec, true, &format, &image_reader)?
            }
        }
    };

    let decoder = Arc::new(FakeThreadSafe(decoder));

    {
        let mut decoder_lock = decoder_sink.lock();

        *decoder_lock = Some(Arc::clone(&decoder));

        decoder_ready_notifier.notify_one();
    }

    let mut error_counter = 0;
    while running.value() {
        match decoder.dequeue_output_buffer(Duration::from_millis(1)) {
            Ok(DequeuedOutputBufferInfoResult::Buffer(buffer)) => {
                // The buffer timestamp is actually nanoseconds
                let presentation_time_ns = buffer.info().presentation_time_us();

                if let Err(e) = decoder.release_output_buffer_at_time(buffer, presentation_time_ns)
                {
                    error!("Decoder dequeue error: {e}");
                }
            }
            Ok(DequeuedOutputBufferInfoResult::TryAgainLater) => continue,
            Ok(i) => info!("Decoder dequeue event: {i:?}"),
            Err(e) => {
                error!("Decoder dequeue error: {e}");

                error_counter += 1;
                if error_counter > 10 {
                    bail!("Too many decoder errors: {e}");
                }

                // lessen logcat flood (just in case)
                thread::sleep(Duration::from_millis(50));

                continue;
            }
        }

        error_counter = 0;
    }

    // Destroy all resources
    decoder_sink.lock().take(); // Make sure the shared ref is deleted first
    decoder.stop()?;
    drop(decoder);

    Ok(())
}

// Create a sink/source pair
pub fn video_decoder_split(
    config: VideoDecoderConfig,
    csd_0: Vec<u8>,
    frame_result_callback: impl Fn(Result<Duration>) + Send + Sync + 'static,
) -> Result<(VideoDecoderSink, VideoDecoderSource)> {
    let running = Arc::new(RelaxedAtomic::new(true));
    let decoder_sink = Arc::new(Mutex::new(None::<SharedMediaCodec>));
    let decoder_ready_notifier = Arc::new(Condvar::new());
    let image_queue = Arc::new(Mutex::new(VecDeque::<QueuedImage>::new()));

    let dequeue_thread = thread::spawn({
        let config = config.clone();
        let running = Arc::clone(&running);
        let decoder_sink = Arc::clone(&decoder_sink);
        let decoder_ready_notifier = Arc::clone(&decoder_ready_notifier);
        let image_queue = Arc::clone(&image_queue);
        move || {
            const MAX_BUFFERING_FRAMES: usize = 10;
            let mut image_reader = match ImageReader::new_with_usage(
                1,
                1,
                ImageFormat::PRIVATE,
                HardwareBufferUsage::GPU_SAMPLED_IMAGE,
                MAX_BUFFERING_FRAMES as i32,
            ) {
                Ok(reader) => reader,
                Err(e) => {
                    frame_result_callback(Err(anyhow!("{e}")));
                    return;
                }
            };

            let frame_result_callback = Arc::new(frame_result_callback);

            if let Err(e) = decoder_lifecycle(
                config,
                csd_0,
                Arc::downgrade(&frame_result_callback),
                running,
                decoder_sink,
     
Download .txt
gitextract_unk25vpb/

├── .cargo/
│   └── config.toml
├── .clang-format
├── .editorconfig
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   └── bug_report.md
│   ├── dependabot.yml
│   └── workflows/
│       ├── prepare-release.yml
│       ├── queue.yml
│       ├── rust.yml
│       ├── stale.yml
│       └── wiki.yml
├── .gitignore
├── .gitmodules
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Cargo.toml
├── LICENSE
├── README.md
├── about.toml
├── alvr/
│   ├── adb/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── commands.rs
│   │       ├── lib.rs
│   │       └── parse.rs
│   ├── audio/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── lib.rs
│   │       ├── linux.rs
│   │       └── windows.rs
│   ├── client_core/
│   │   ├── Cargo.toml
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── build.rs
│   │   ├── cbindgen.toml
│   │   └── src/
│   │       ├── audio.rs
│   │       ├── c_api.rs
│   │       ├── connection.rs
│   │       ├── lib.rs
│   │       ├── logging_backend.rs
│   │       ├── sockets.rs
│   │       ├── statistics.rs
│   │       ├── storage.rs
│   │       └── video_decoder/
│   │           ├── android.rs
│   │           └── mod.rs
│   ├── client_mock/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── main.rs
│   ├── client_openxr/
│   │   ├── Cargo.toml
│   │   ├── cbindgen.toml
│   │   ├── resources/
│   │   │   ├── drawable/
│   │   │   │   └── ic_launcher_foreground.xml
│   │   │   ├── mipmap-anydpi-v26/
│   │   │   │   └── ic_launcher.xml
│   │   │   └── values/
│   │   │       └── ic_launcher_background.xml
│   │   └── src/
│   │       ├── c_api.rs
│   │       ├── extra_extensions/
│   │       │   ├── body_tracking_bd.rs
│   │       │   ├── body_tracking_fb.rs
│   │       │   ├── eye_gaze_interaction.rs
│   │       │   ├── eye_tracking_social.rs
│   │       │   ├── face_tracking2_fb.rs
│   │       │   ├── face_tracking_pico.rs
│   │       │   ├── facial_tracking_htc.rs
│   │       │   ├── mod.rs
│   │       │   ├── motion_tracking_bd.rs
│   │       │   ├── multimodal_input.rs
│   │       │   ├── passthrough_fb.rs
│   │       │   └── passthrough_htc.rs
│   │       ├── graphics.rs
│   │       ├── interaction.rs
│   │       ├── lib.rs
│   │       ├── lobby.rs
│   │       ├── passthrough.rs
│   │       └── stream.rs
│   ├── common/
│   │   ├── Cargo.toml
│   │   ├── LICENSE
│   │   ├── README.md
│   │   └── src/
│   │       ├── average.rs
│   │       ├── c_api.rs
│   │       ├── connection_result.rs
│   │       ├── inputs.rs
│   │       ├── lib.rs
│   │       ├── logging.rs
│   │       ├── primitives.rs
│   │       └── version.rs
│   ├── dashboard/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── build.rs
│   │   └── src/
│   │       ├── dashboard/
│   │       │   ├── components/
│   │       │   │   ├── about.rs
│   │       │   │   ├── debug.rs
│   │       │   │   ├── devices.rs
│   │       │   │   ├── installation.rs
│   │       │   │   ├── logs.rs
│   │       │   │   ├── mod.rs
│   │       │   │   ├── new_version_popup.rs
│   │       │   │   ├── notifications.rs
│   │       │   │   ├── settings.rs
│   │       │   │   ├── settings_controls/
│   │       │   │   │   ├── array.rs
│   │       │   │   │   ├── boolean.rs
│   │       │   │   │   ├── choice.rs
│   │       │   │   │   ├── collapsible.rs
│   │       │   │   │   ├── dictionary.rs
│   │       │   │   │   ├── mod.rs
│   │       │   │   │   ├── notice.rs
│   │       │   │   │   ├── number.rs
│   │       │   │   │   ├── optional.rs
│   │       │   │   │   ├── presets/
│   │       │   │   │   │   ├── builtin_schema.rs
│   │       │   │   │   │   ├── higher_order_choice.rs
│   │       │   │   │   │   ├── mirror.rs
│   │       │   │   │   │   ├── mod.rs
│   │       │   │   │   │   └── schema.rs
│   │       │   │   │   ├── reset.rs
│   │       │   │   │   ├── section.rs
│   │       │   │   │   ├── switch.rs
│   │       │   │   │   ├── text.rs
│   │       │   │   │   ├── up_down.rs
│   │       │   │   │   └── vector.rs
│   │       │   │   ├── setup_wizard.rs
│   │       │   │   └── statistics.rs
│   │       │   └── mod.rs
│   │       ├── data_sources.rs
│   │       ├── data_sources_wasm.rs
│   │       ├── linux_checks.rs
│   │       ├── logging_backend.rs
│   │       ├── main.rs
│   │       └── steamvr_launcher/
│   │           ├── linux_steamvr.rs
│   │           ├── mod.rs
│   │           └── windows_steamvr.rs
│   ├── events/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── lib.rs
│   ├── filesystem/
│   │   ├── Cargo.toml
│   │   ├── build.rs
│   │   └── src/
│   │       └── lib.rs
│   ├── graphics/
│   │   ├── Cargo.toml
│   │   ├── resources/
│   │   │   ├── lobby_line.wgsl
│   │   │   ├── lobby_quad.wgsl
│   │   │   ├── staging_fragment.glsl
│   │   │   ├── staging_vertex.glsl
│   │   │   └── stream.wgsl
│   │   └── src/
│   │       ├── lib.rs
│   │       ├── lobby.rs
│   │       ├── staging.rs
│   │       └── stream.rs
│   ├── gui_common/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── basic_components/
│   │       │   ├── button_group.rs
│   │       │   ├── mod.rs
│   │       │   ├── modal.rs
│   │       │   └── switch.rs
│   │       ├── lib.rs
│   │       └── theme.rs
│   ├── launcher/
│   │   ├── Cargo.toml
│   │   ├── build.rs
│   │   └── src/
│   │       ├── actions.rs
│   │       ├── main.rs
│   │       └── ui.rs
│   ├── packets/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── lib.rs
│   ├── server_core/
│   │   ├── Cargo.toml
│   │   ├── cbindgen.toml
│   │   └── src/
│   │       ├── bitrate.rs
│   │       ├── c_api.rs
│   │       ├── connection.rs
│   │       ├── hand_gestures.rs
│   │       ├── haptics.rs
│   │       ├── input_mapping.rs
│   │       ├── lib.rs
│   │       ├── logging_backend.rs
│   │       ├── sockets.rs
│   │       ├── statistics.rs
│   │       ├── tracking/
│   │       │   ├── body.rs
│   │       │   ├── face.rs
│   │       │   ├── mod.rs
│   │       │   └── vmc.rs
│   │       └── web_server.rs
│   ├── server_io/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   └── src/
│   │       ├── firewall.rs
│   │       ├── lib.rs
│   │       ├── openvr_drivers.rs
│   │       └── openvrpaths.rs
│   ├── server_openvr/
│   │   ├── Cargo.toml
│   │   ├── LICENSE
│   │   ├── LICENSE-Valve
│   │   ├── build.rs
│   │   ├── cpp/
│   │   │   ├── ALVR-common/
│   │   │   │   ├── common-utils.cpp
│   │   │   │   ├── common-utils.h
│   │   │   │   ├── exception.cpp
│   │   │   │   ├── exception.h
│   │   │   │   └── packet_types.h
│   │   │   ├── alvr_server/
│   │   │   │   ├── ChaperoneUpdater.cpp
│   │   │   │   ├── Controller.cpp
│   │   │   │   ├── Controller.h
│   │   │   │   ├── FakeViveTracker.cpp
│   │   │   │   ├── FakeViveTracker.h
│   │   │   │   ├── HMD.cpp
│   │   │   │   ├── HMD.h
│   │   │   │   ├── IDRScheduler.cpp
│   │   │   │   ├── IDRScheduler.h
│   │   │   │   ├── Logger.cpp
│   │   │   │   ├── Logger.h
│   │   │   │   ├── NalParsing.cpp
│   │   │   │   ├── Paths.cpp
│   │   │   │   ├── Paths.h
│   │   │   │   ├── PoseHistory.cpp
│   │   │   │   ├── PoseHistory.h
│   │   │   │   ├── Settings.cpp
│   │   │   │   ├── Settings.h
│   │   │   │   ├── TrackedDevice.cpp
│   │   │   │   ├── TrackedDevice.h
│   │   │   │   ├── Utils.h
│   │   │   │   ├── ViveTrackerProxy.cpp
│   │   │   │   ├── ViveTrackerProxy.h
│   │   │   │   ├── alvr_server.cpp
│   │   │   │   ├── bindings.h
│   │   │   │   ├── driverlog.cpp
│   │   │   │   ├── driverlog.h
│   │   │   │   ├── include/
│   │   │   │   │   ├── openvr_math.h
│   │   │   │   │   └── picojson.h
│   │   │   │   ├── nvEncodeAPI.h
│   │   │   │   ├── openvr_driver_wrap.h
│   │   │   │   └── shader/
│   │   │   │       ├── ColorCorrectionPixelShader.hlsl
│   │   │   │       ├── CompressAxisAlignedPixelShader.hlsl
│   │   │   │       ├── FoveatedRendering.hlsli
│   │   │   │       ├── FrameRender.fx
│   │   │   │       ├── FrameRenderPS.hlsl
│   │   │   │       ├── FrameRenderVS.hlsl
│   │   │   │       └── rgbtoyuv420.hlsl
│   │   │   ├── platform/
│   │   │   │   ├── linux/
│   │   │   │   │   ├── CEncoder.cpp
│   │   │   │   │   ├── CEncoder.h
│   │   │   │   │   ├── CrashHandler.cpp
│   │   │   │   │   ├── EncodePipeline.cpp
│   │   │   │   │   ├── EncodePipeline.h
│   │   │   │   │   ├── EncodePipelineNvEnc.cpp
│   │   │   │   │   ├── EncodePipelineNvEnc.h
│   │   │   │   │   ├── EncodePipelineSW.cpp
│   │   │   │   │   ├── EncodePipelineSW.h
│   │   │   │   │   ├── EncodePipelineVAAPI.cpp
│   │   │   │   │   ├── EncodePipelineVAAPI.h
│   │   │   │   │   ├── FormatConverter.cpp
│   │   │   │   │   ├── FormatConverter.h
│   │   │   │   │   ├── FrameRender.cpp
│   │   │   │   │   ├── FrameRender.h
│   │   │   │   │   ├── Renderer.cpp
│   │   │   │   │   ├── Renderer.h
│   │   │   │   │   ├── ffmpeg_helper.cpp
│   │   │   │   │   ├── ffmpeg_helper.h
│   │   │   │   │   ├── protocol.h
│   │   │   │   │   └── shader/
│   │   │   │   │       ├── color.comp
│   │   │   │   │       ├── color.comp.spv
│   │   │   │   │       ├── ffr.comp
│   │   │   │   │       ├── ffr.comp.spv
│   │   │   │   │       ├── quad.comp
│   │   │   │   │       ├── quad.comp.spv
│   │   │   │   │       ├── rgbtoyuv420.comp
│   │   │   │   │       └── rgbtoyuv420.comp.spv
│   │   │   │   ├── macos/
│   │   │   │   │   ├── CEncoder.h
│   │   │   │   │   └── CrashHandler.cpp
│   │   │   │   └── win32/
│   │   │   │       ├── CEncoder.cpp
│   │   │   │       ├── CEncoder.h
│   │   │   │       ├── ColorCorrectionPixelShader.cso
│   │   │   │       ├── CompressAxisAlignedPixelShader.cso
│   │   │   │       ├── CrashHandler.cpp
│   │   │   │       ├── FFR.cpp
│   │   │   │       ├── FFR.h
│   │   │   │       ├── FrameRender.cpp
│   │   │   │       ├── FrameRender.h
│   │   │   │       ├── FrameRenderPS.cso
│   │   │   │       ├── FrameRenderVS.cso
│   │   │   │       ├── NvCodecUtils.h
│   │   │   │       ├── NvEncoder.cpp
│   │   │   │       ├── NvEncoder.h
│   │   │   │       ├── NvEncoderD3D11.cpp
│   │   │   │       ├── NvEncoderD3D11.h
│   │   │   │       ├── OvrDirectModeComponent.cpp
│   │   │   │       ├── OvrDirectModeComponent.h
│   │   │   │       ├── QuadVertexShader.cso
│   │   │   │       ├── VideoEncoder.cpp
│   │   │   │       ├── VideoEncoder.h
│   │   │   │       ├── VideoEncoderAMF.cpp
│   │   │   │       ├── VideoEncoderAMF.h
│   │   │   │       ├── VideoEncoderNVENC.cpp
│   │   │   │       ├── VideoEncoderNVENC.h
│   │   │   │       ├── VideoEncoderSW.cpp
│   │   │   │       ├── VideoEncoderSW.h
│   │   │   │       ├── VideoEncoderVPL.cpp
│   │   │   │       ├── VideoEncoderVPL.h
│   │   │   │       ├── d3d-render-utils/
│   │   │   │       │   ├── QuadVertexShader.hlsl
│   │   │   │       │   ├── RenderPipeline.cpp
│   │   │   │       │   ├── RenderPipeline.h
│   │   │   │       │   ├── RenderPipelineYUV.cpp
│   │   │   │       │   ├── RenderPipelineYUV.h
│   │   │   │       │   ├── RenderUtils.cpp
│   │   │   │       │   └── RenderUtils.h
│   │   │   │       ├── rgbtoyuv420.cso
│   │   │   │       └── shared/
│   │   │   │           ├── d3drender.cpp
│   │   │   │           └── d3drender.h
│   │   │   └── shared/
│   │   │       ├── amf/
│   │   │       │   └── public/
│   │   │       │       ├── common/
│   │   │       │       │   ├── AMFFactory.cpp
│   │   │       │       │   ├── AMFFactory.h
│   │   │       │       │   ├── AMFMath.h
│   │   │       │       │   ├── AMFSTL.cpp
│   │   │       │       │   ├── AMFSTL.h
│   │   │       │       │   ├── ByteArray.h
│   │   │       │       │   ├── CPUCaps.h
│   │   │       │       │   ├── CurrentTimeImpl.cpp
│   │   │       │       │   ├── CurrentTimeImpl.h
│   │   │       │       │   ├── DataStream.h
│   │   │       │       │   ├── DataStreamFactory.cpp
│   │   │       │       │   ├── DataStreamFile.cpp
│   │   │       │       │   ├── DataStreamFile.h
│   │   │       │       │   ├── DataStreamMemory.cpp
│   │   │       │       │   ├── DataStreamMemory.h
│   │   │       │       │   ├── IOCapsImpl.cpp
│   │   │       │       │   ├── IOCapsImpl.h
│   │   │       │       │   ├── InterfaceImpl.h
│   │   │       │       │   ├── ObservableImpl.h
│   │   │       │       │   ├── PropertyStorageExImpl.cpp
│   │   │       │       │   ├── PropertyStorageExImpl.h
│   │   │       │       │   ├── PropertyStorageImpl.h
│   │   │       │       │   ├── Thread.cpp
│   │   │       │       │   ├── Thread.h
│   │   │       │       │   ├── TraceAdapter.cpp
│   │   │       │       │   ├── TraceAdapter.h
│   │   │       │       │   └── Windows/
│   │   │       │       │       └── ThreadWindows.cpp
│   │   │       │       └── include/
│   │   │       │           ├── components/
│   │   │       │           │   ├── Ambisonic2SRenderer.h
│   │   │       │           │   ├── AudioCapture.h
│   │   │       │           │   ├── Capture.h
│   │   │       │           │   ├── ChromaKey.h
│   │   │       │           │   ├── ColorSpace.h
│   │   │       │           │   ├── Component.h
│   │   │       │           │   ├── ComponentCaps.h
│   │   │       │           │   ├── CursorCapture.h
│   │   │       │           │   ├── DisplayCapture.h
│   │   │       │           │   ├── FFMPEGAudioConverter.h
│   │   │       │           │   ├── FFMPEGAudioDecoder.h
│   │   │       │           │   ├── FFMPEGAudioEncoder.h
│   │   │       │           │   ├── FFMPEGComponents.h
│   │   │       │           │   ├── FFMPEGEncoderAV1.h
│   │   │       │           │   ├── FFMPEGEncoderH264.h
│   │   │       │           │   ├── FFMPEGEncoderHEVC.h
│   │   │       │           │   ├── FFMPEGFileDemuxer.h
│   │   │       │           │   ├── FFMPEGFileMuxer.h
│   │   │       │           │   ├── FFMPEGVideoDecoder.h
│   │   │       │           │   ├── FRC.h
│   │   │       │           │   ├── HQScaler.h
│   │   │       │           │   ├── MediaSource.h
│   │   │       │           │   ├── PreAnalysis.h
│   │   │       │           │   ├── PreProcessing.h
│   │   │       │           │   ├── SupportedCodecs.h
│   │   │       │           │   ├── VQEnhancer.h
│   │   │       │           │   ├── VideoCapture.h
│   │   │       │           │   ├── VideoConverter.h
│   │   │       │           │   ├── VideoDecoderUVD.h
│   │   │       │           │   ├── VideoEncoderAV1.h
│   │   │       │           │   ├── VideoEncoderHEVC.h
│   │   │       │           │   ├── VideoEncoderVCE.h
│   │   │       │           │   ├── VideoStitch.h
│   │   │       │           │   └── ZCamLiveStream.h
│   │   │       │           └── core/
│   │   │       │               ├── AudioBuffer.h
│   │   │       │               ├── Buffer.h
│   │   │       │               ├── Compute.h
│   │   │       │               ├── ComputeFactory.h
│   │   │       │               ├── Context.h
│   │   │       │               ├── CurrentTime.h
│   │   │       │               ├── D3D12AMF.h
│   │   │       │               ├── Data.h
│   │   │       │               ├── Debug.h
│   │   │       │               ├── Dump.h
│   │   │       │               ├── Factory.h
│   │   │       │               ├── Interface.h
│   │   │       │               ├── Plane.h
│   │   │       │               ├── Platform.h
│   │   │       │               ├── PropertyStorage.h
│   │   │       │               ├── PropertyStorageEx.h
│   │   │       │               ├── Result.h
│   │   │       │               ├── Surface.h
│   │   │       │               ├── Trace.h
│   │   │       │               ├── Variant.h
│   │   │       │               ├── Version.h
│   │   │       │               └── VulkanAMF.h
│   │   │       ├── backward.cpp
│   │   │       ├── backward.hpp
│   │   │       ├── threadtools.cpp
│   │   │       └── threadtools.h
│   │   └── src/
│   │       ├── graphics.rs
│   │       ├── lib.rs
│   │       ├── props.rs
│   │       └── tracking.rs
│   ├── session/
│   │   ├── Cargo.toml
│   │   ├── build.rs
│   │   └── src/
│   │       ├── lib.rs
│   │       └── settings.rs
│   ├── sockets/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── control_socket.rs
│   │       ├── lib.rs
│   │       └── stream_socket/
│   │           ├── mod.rs
│   │           ├── tcp.rs
│   │           └── udp.rs
│   ├── system_info/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── android.rs
│   │       └── lib.rs
│   ├── vrcompositor_wrapper/
│   │   ├── Cargo.toml
│   │   ├── build.rs
│   │   ├── drm-lease-shim.cpp
│   │   └── src/
│   │       └── main.rs
│   ├── vulkan_layer/
│   │   ├── .gitignore
│   │   ├── Cargo.toml
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── build.rs
│   │   ├── layer/
│   │   │   ├── alvr_x86_64.json
│   │   │   ├── device_api.cpp
│   │   │   ├── device_api.hpp
│   │   │   ├── layer.cpp
│   │   │   ├── layer.h
│   │   │   ├── private_data.cpp
│   │   │   ├── private_data.hpp
│   │   │   ├── settings.cpp
│   │   │   ├── settings.h
│   │   │   ├── surface_api.cpp
│   │   │   ├── surface_api.hpp
│   │   │   ├── swapchain_api.cpp
│   │   │   └── swapchain_api.hpp
│   │   ├── src/
│   │   │   └── lib.rs
│   │   ├── util/
│   │   │   ├── custom_allocator.cpp
│   │   │   ├── custom_allocator.hpp
│   │   │   ├── extension_list.cpp
│   │   │   ├── extension_list.hpp
│   │   │   ├── logger.cpp
│   │   │   ├── logger.h
│   │   │   ├── platform_set.hpp
│   │   │   ├── pose.cpp
│   │   │   ├── pose.hpp
│   │   │   ├── timed_semaphore.cpp
│   │   │   └── timed_semaphore.hpp
│   │   └── wsi/
│   │       ├── display.cpp
│   │       ├── display.hpp
│   │       ├── headless/
│   │       │   ├── surface_properties.cpp
│   │       │   ├── surface_properties.hpp
│   │       │   ├── swapchain.cpp
│   │       │   └── swapchain.hpp
│   │       ├── surface_properties.hpp
│   │       ├── swapchain_base.cpp
│   │       ├── swapchain_base.hpp
│   │       ├── wsi_factory.cpp
│   │       └── wsi_factory.hpp
│   └── xtask/
│       ├── Cargo.toml
│       ├── LICENSE
│       ├── README.md
│       ├── build.rs
│       ├── firewall/
│       │   ├── alvr-firewalld.xml
│       │   ├── alvr_fw_config.sh
│       │   └── ufw-alvr
│       ├── flatpak/
│       │   ├── README.md
│       │   ├── build_and_install.sh
│       │   ├── com.valvesoftware.Steam.Utility.alvr.desktop
│       │   ├── com.valvesoftware.Steam.Utility.alvr.json
│       │   ├── run_with_adb_keys.sh
│       │   └── setup_xdg_shortcut.sh
│       ├── licenses_template.hbs
│       ├── patches/
│       │   ├── 0001-Add-AV_VAAPI_DRIVER_QUIRK_HEVC_ENCODER_ALIGN_64_16-f.patch
│       │   ├── 0001-av1-encode-backport.patch
│       │   ├── 0001-clip-constants-used-with-shift-instr.patch
│       │   ├── 0001-guid-conftest.patch
│       │   ├── 0001-lavu-hwcontext_vulkan-Fix-importing-RGBx-frames-to-C.patch
│       │   ├── 0001-update-rc-modes.patch
│       │   ├── 0001-vaapi_encode-Add-filler_data-option.patch
│       │   ├── 0001-vaapi_encode-Allow-to-dynamically-change-bitrate-and.patch
│       │   ├── 0001-vaapi_encode-Enable-global-header.patch
│       │   └── 0001-vaapi_encode_h265-Set-vui_parameters_present_flag.patch
│       ├── resources/
│       │   ├── alvr.desktop
│       │   └── driver.vrdrivermanifest
│       └── src/
│           ├── build.rs
│           ├── ci.rs
│           ├── command.rs
│           ├── dependencies.rs
│           ├── format.rs
│           ├── main.rs
│           ├── packaging.rs
│           └── version.rs
└── wiki/
    ├── ALVR-Checklist.md
    ├── ALVR-wired-setup-(ALVR-over-USB).md
    ├── Building-From-Source.md
    ├── Controller-latency.md
    ├── FFmpeg-Hardware-Encoding-Testing.md
    ├── Fixed-Foveated-Rendering-(FFR).md
    ├── Hand-tracking-controller-bindings.md
    ├── Headset-and-ALVR-streamer-on-separate-networks.md
    ├── Home.md
    ├── How-ALVR-works.md
    ├── Information-and-Recommendations.md
    ├── Installation-guide.md
    ├── Installing-ALVR-and-using-SteamVR-on-Linux-through-Flatpak.md
    ├── Linux-Troubleshooting.md
    ├── My-game-is-not-working-properly!-Help!.md
    ├── Other-resources.md
    ├── Real-time-video-upscaling-experiments.md
    ├── Roadmap.md
    ├── Settings-tutorial.md
    ├── Troubleshooting.md
    └── _Sidebar.md
Download .txt
Showing preview only (398K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2819 symbols across 317 files)

FILE: alvr/adb/src/commands.rs
  constant PLATFORM_TOOLS_VERSION (line 22) | const PLATFORM_TOOLS_VERSION: &str = "-latest";
  constant PLATFORM_TOOLS_OS (line 25) | const PLATFORM_TOOLS_OS: &str = "linux";
  constant PLATFORM_TOOLS_OS (line 27) | const PLATFORM_TOOLS_OS: &str = "darwin";
  constant PLATFORM_TOOLS_OS (line 29) | const PLATFORM_TOOLS_OS: &str = "windows";
  constant REQUEST_TIMEOUT (line 31) | const REQUEST_TIMEOUT: Duration = Duration::from_secs(5);
  function get_command (line 33) | fn get_command(adb_path: &str, args: &[&str]) -> Command {
  function download (line 43) | pub fn download(url: &str, progress_callback: impl Fn(usize, Option<usiz...
  function get_process_id (line 74) | pub fn get_process_id(
  function is_activity_resumed (line 96) | pub fn is_activity_resumed(
  function require_adb (line 139) | pub fn require_adb(
  function install_adb (line 151) | fn install_adb(
  function download_adb (line 161) | fn download_adb(progress_callback: impl Fn(usize, Option<usize>)) -> Res...
  function get_platform_tools_url (line 167) | fn get_platform_tools_url() -> String {
  function start_application (line 176) | pub fn start_application(adb_path: &str, device_serial: &str, applicatio...
  function list_devices (line 198) | pub fn list_devices(adb_path: &str) -> Result<Vec<Device>> {
  function install_package (line 215) | pub fn install_package(adb_path: &str, device_serial: &str, apk_path: &s...
  function is_package_installed (line 223) | pub fn is_package_installed(
  function uninstall_package (line 237) | pub fn uninstall_package(adb_path: &str, device_serial: &str, applicatio...
  function list_installed_packages (line 248) | pub fn list_installed_packages(adb_path: &str, device_serial: &str) -> R...
  function get_adb_path (line 265) | pub fn get_adb_path(layout: &afs::Layout) -> Option<String> {
  function get_uptime (line 283) | pub fn get_uptime(adb_path: &str, device_serial: &str) -> Result<Duratio...
  function list_forwarded_ports (line 306) | pub fn list_forwarded_ports(adb_path: &str, device_serial: &str) -> Resu...
  function forward_port (line 321) | pub fn forward_port(adb_path: &str, device_serial: &str, port: u16) -> R...
  function kill_server (line 343) | pub fn kill_server(adb_path: &str) -> Result<()> {

FILE: alvr/adb/src/lib.rs
  type WiredConnectionStatus (line 13) | pub enum WiredConnectionStatus {
  type WiredConnection (line 18) | pub struct WiredConnection {
    method new (line 23) | pub fn new(
    method setup (line 32) | pub fn setup(
  method drop (line 107) | fn drop(&mut self) {
  function get_process_name (line 115) | pub fn get_process_name(

FILE: alvr/adb/src/parse.rs
  constant SERIAL_NUMBER_COLUMN_LENGTH (line 3) | const SERIAL_NUMBER_COLUMN_LENGTH: usize = 22;
  type ConnectionState (line 7) | pub enum ConnectionState {
  function parse_connection_state (line 22) | pub fn parse_connection_state(value: &str) -> Option<ConnectionState> {
  function parse_pair (line 39) | fn parse_pair(pair: &str) -> Option<String> {
  type TransportType (line 48) | pub enum TransportType {
  function parse_transport_type (line 55) | pub fn parse_transport_type(pair: &str) -> Option<TransportType> {
  type Device (line 74) | pub struct Device {
  function parse_device (line 83) | pub fn parse_device(line: &str) -> Option<Device> {
  type ForwardedPorts (line 124) | pub struct ForwardedPorts {
  function parse_forwarded_ports (line 130) | pub fn parse_forwarded_ports(line: &str) -> Option<ForwardedPorts> {
  function parse_port (line 150) | fn parse_port(value: &str) -> Option<u16> {

FILE: alvr/audio/src/lib.rs
  function device_from_custom_config (line 27) | fn device_from_custom_config(
  function new_output (line 54) | pub fn new_output(config: Option<&CustomAudioDeviceConfig>) -> Result<De...
  function new_input (line 67) | pub fn new_input(config: Option<CustomAudioDeviceConfig>) -> Result<Devi...
  function new_virtual_microphone_pair (line 81) | pub fn new_virtual_microphone_pair(config: MicrophoneDevicesConfig) -> R...
  function input_sample_rate (line 132) | pub fn input_sample_rate(dev: &Device) -> Result<u32> {
  type AudioRecordState (line 141) | pub enum AudioRecordState {
  type AudioChannel (line 147) | pub enum AudioChannel {
  function downmix_channels (line 164) | fn downmix_channels(channels: &[AudioChannel], data: &[u8], out_channels...
  function downmix_audio (line 200) | fn downmix_audio(data: Vec<u8>, in_channels: u16, out_channels: u16) -> ...
  function record_audio_blocking (line 248) | pub fn record_audio_blocking(
  function get_next_frame_batch (line 345) | pub fn get_next_frame_batch(
  function receive_samples_loop (line 376) | pub fn receive_samples_loop(
  type StreamingSource (line 477) | struct StreamingSource {
  method current_span_len (line 487) | fn current_span_len(&self) -> Option<usize> {
  method channels (line 491) | fn channels(&self) -> u16 {
  method sample_rate (line 495) | fn sample_rate(&self) -> u32 {
  method total_duration (line 499) | fn total_duration(&self) -> Option<std::time::Duration> {
  type Item (line 505) | type Item = f32;
  method next (line 508) | fn next(&mut self) -> Option<f32> {
  function play_audio_loop (line 526) | pub fn play_audio_loop(

FILE: alvr/audio/src/linux.rs
  function try_load_pipewire (line 33) | pub fn try_load_pipewire() -> Result<()> {
  function probe_pipewire (line 61) | fn probe_pipewire() -> Result<(), pipewire::Error> {
  type AudioInfo (line 69) | pub struct AudioInfo {
  type Terminate (line 74) | struct Terminate;
  function audio_loop (line 81) | pub fn audio_loop(
  function pw_main_loop (line 154) | fn pw_main_loop(
  function audio_info_to_vec (line 202) | fn audio_info_to_vec(audio_info: AudioInfoRaw) -> Vec<u8> {
  function create_speaker_stream (line 216) | fn create_speaker_stream(
  function create_mic_stream (line 267) | fn create_mic_stream(
  function fill_pw_buf (line 317) | fn fill_pw_buf(

FILE: alvr/audio/src/windows.rs
  function get_windows_device (line 16) | fn get_windows_device(device: &Device) -> Result<IMMDevice> {
  function get_windows_device_id (line 51) | pub fn get_windows_device_id(device: &Device) -> Result<String> {
  function set_mute_windows_device (line 64) | pub fn set_mute_windows_device(device: &Device, mute: bool) -> Result<()> {
  function is_same_device (line 76) | pub fn is_same_device(device1: &Device, device2: &Device) -> bool {

FILE: alvr/client_core/build.rs
  function main (line 1) | fn main() {

FILE: alvr/client_core/src/audio.rs
  constant INPUT_SAMPLES_MAX_BUFFER_COUNT (line 19) | const INPUT_SAMPLES_MAX_BUFFER_COUNT: usize = 20;
  constant INPUT_RECV_TIMEOUT (line 20) | const INPUT_RECV_TIMEOUT: Duration = Duration::from_millis(20);
  function record_audio_blocking (line 23) | pub fn record_audio_blocking(
  function play_audio_loop (line 94) | pub fn play_audio_loop(

FILE: alvr/client_core/src/c_api.rs
  type AlvrClientCapabilities (line 42) | pub struct AlvrClientCapabilities {
  type AlvrEvent (line 59) | pub enum AlvrEvent {
  type AlvrVideoFrameData (line 85) | pub struct AlvrVideoFrameData {
  type AlvrDeviceMotion (line 94) | pub struct AlvrDeviceMotion {
  type AlvrButtonValue (line 103) | pub enum AlvrButtonValue {
  type AlvrLogLevel (line 110) | pub enum AlvrLogLevel {
  function alvr_initialize_logging (line 118) | pub extern "C" fn alvr_initialize_logging() {
  function alvr_path_string_to_id (line 123) | pub extern "C" fn alvr_path_string_to_id(path: *const c_char) -> u64 {
  function alvr_log (line 128) | pub extern "C" fn alvr_log(level: AlvrLogLevel, message: *const c_char) {
  function alvr_dbg_client_impl (line 140) | pub extern "C" fn alvr_dbg_client_impl(message: *const c_char) {
  function alvr_dbg_decoder (line 146) | pub extern "C" fn alvr_dbg_decoder(message: *const c_char) {
  function alvr_log_time (line 151) | pub extern "C" fn alvr_log_time(tag: *const c_char) {
  function string_to_c_str (line 156) | fn string_to_c_str(buffer: *mut c_char, value: &str) -> u64 {
  function alvr_mdns_service (line 168) | pub extern "C" fn alvr_mdns_service(service_buffer: *mut c_char) -> u64 {
  function alvr_hostname (line 174) | pub extern "C" fn alvr_hostname(hostname_buffer: *mut c_char) -> u64 {
  function alvr_protocol_id (line 180) | pub extern "C" fn alvr_protocol_id(protocol_buffer: *mut c_char) -> u64 {
  function alvr_try_get_permission (line 186) | pub extern "C" fn alvr_try_get_permission(permission: *const c_char) {
  function alvr_initialize_android_context (line 193) | pub extern "C" fn alvr_initialize_android_context(java_vm: *mut c_void, ...
  function alvr_initialize (line 199) | pub extern "C" fn alvr_initialize(capabilities: AlvrClientCapabilities) {
  function alvr_destroy (line 232) | pub extern "C" fn alvr_destroy() {
  function alvr_resume (line 242) | pub extern "C" fn alvr_resume() {
  function alvr_pause (line 249) | pub extern "C" fn alvr_pause() {
  function alvr_poll_event (line 257) | pub extern "C" fn alvr_poll_event(out_event: *mut AlvrEvent) -> bool {
  function alvr_hud_message (line 318) | pub extern "C" fn alvr_hud_message(message_buffer: *mut c_char) -> u64 {
  function alvr_get_settings_json (line 335) | pub extern "C" fn alvr_get_settings_json(out_buffer: *mut c_char) -> u64 {
  function alvr_get_server_version (line 341) | pub extern "C" fn alvr_get_server_version(out_buffer: *mut c_char) -> u64 {
  function alvr_get_decoder_config (line 347) | pub extern "C" fn alvr_get_decoder_config(out_buffer: *mut c_char) -> u64 {
  function alvr_send_battery (line 360) | pub extern "C" fn alvr_send_battery(device_id: u64, gauge_value: f32, is...
  function alvr_send_playspace (line 367) | pub extern "C" fn alvr_send_playspace(width: f32, height: f32) {
  function alvr_send_active_interaction_profile (line 374) | pub extern "C" fn alvr_send_active_interaction_profile(
  function alvr_send_button (line 396) | pub extern "C" fn alvr_send_button(path_id: u64, value: AlvrButtonValue) {
  function alvr_send_view_params (line 411) | pub extern "C" fn alvr_send_view_params(view_params: *const AlvrViewPara...
  function alvr_send_tracking (line 428) | pub extern "C" fn alvr_send_tracking(
  function alvr_set_decoder_input_callback (line 507) | pub extern "C" fn alvr_set_decoder_input_callback(
  function alvr_report_frame_decoded (line 533) | pub extern "C" fn alvr_report_frame_decoded(target_timestamp_ns: u64) {
  function alvr_report_fatal_decoder_error (line 540) | pub extern "C" fn alvr_report_fatal_decoder_error(message: *const c_char) {
  function alvr_report_compositor_start (line 549) | pub extern "C" fn alvr_report_compositor_start(
  function alvr_report_submit (line 565) | pub extern "C" fn alvr_report_submit(target_timestamp_ns: u64, vsync_que...
  type AlvrLobbyViewParams (line 583) | pub struct AlvrLobbyViewParams {
  type AlvrStreamViewParams (line 589) | pub struct AlvrStreamViewParams {
  type AlvrStreamConfig (line 596) | pub struct AlvrStreamConfig {
  function alvr_initialize_opengl (line 616) | pub extern "C" fn alvr_initialize_opengl() {
  function alvr_destroy_opengl (line 621) | pub extern "C" fn alvr_destroy_opengl() {
  function convert_swapchain_array (line 625) | fn convert_swapchain_array(
  function alvr_resume_opengl (line 651) | pub extern "C" fn alvr_resume_opengl(
  function alvr_pause_opengl (line 666) | pub extern "C" fn alvr_pause_opengl() {
  function alvr_update_hud_message_opengl (line 672) | pub extern "C" fn alvr_update_hud_message_opengl(message: *const c_char) {
  function alvr_start_stream_opengl (line 681) | pub extern "C" fn alvr_start_stream_opengl(config: AlvrStreamConfig) {
  function alvr_render_lobby_opengl (line 717) | pub extern "C" fn alvr_render_lobby_opengl(
  function alvr_render_stream_opengl (line 763) | pub extern "C" fn alvr_render_stream_opengl(
  type AlvrMediacodecPropType (line 818) | pub enum AlvrMediacodecPropType {
  type AlvrMediacodecOption (line 834) | pub struct AlvrMediacodecOption {
  type AlvrDecoderConfig (line 841) | pub struct AlvrDecoderConfig {
  function alvr_create_decoder (line 854) | pub extern "C" fn alvr_create_decoder(config: AlvrDecoderConfig) {
  function alvr_destroy_decoder (line 924) | pub extern "C" fn alvr_destroy_decoder() {
  function alvr_get_frame (line 930) | pub extern "C" fn alvr_get_frame(
  function alvr_rotation_delta (line 949) | pub extern "C" fn alvr_rotation_delta(source: AlvrQuat, destination: Alv...

FILE: alvr/client_core/src/connection.rs
  constant INITIAL_MESSAGE (line 38) | const INITIAL_MESSAGE: &str = concat!(
  constant SUCCESS_CONNECT_MESSAGE (line 43) | const SUCCESS_CONNECT_MESSAGE: &str = "Successful connection!\nPlease wa...
  constant STREAM_STARTING_MESSAGE (line 44) | const STREAM_STARTING_MESSAGE: &str = "The stream will begin soon\nPleas...
  constant SERVER_RESTART_MESSAGE (line 45) | const SERVER_RESTART_MESSAGE: &str = "The streamer is restarting\nPlease...
  constant SERVER_DISCONNECTED_MESSAGE (line 46) | const SERVER_DISCONNECTED_MESSAGE: &str = "The streamer has disconnected.";
  constant CONNECTION_TIMEOUT_MESSAGE (line 47) | const CONNECTION_TIMEOUT_MESSAGE: &str = "Connection timeout.";
  constant SOCKET_INIT_RETRY_INTERVAL (line 49) | const SOCKET_INIT_RETRY_INTERVAL: Duration = Duration::from_millis(500);
  constant CONNECTION_RETRY_INTERVAL (line 50) | const CONNECTION_RETRY_INTERVAL: Duration = Duration::from_secs(1);
  constant HANDSHAKE_ACTION_TIMEOUT (line 51) | const HANDSHAKE_ACTION_TIMEOUT: Duration = Duration::from_secs(2);
  constant STREAMING_RECV_TIMEOUT (line 52) | const STREAMING_RECV_TIMEOUT: Duration = Duration::from_millis(500);
  constant MAX_UNREAD_PACKETS (line 54) | const MAX_UNREAD_PACKETS: usize = 10;
  type DecoderCallback (line 56) | pub type DecoderCallback = dyn FnMut(Duration, &[u8]) -> bool + Send;
  type ConnectionContext (line 59) | pub struct ConnectionContext {
  function set_hud_message (line 71) | fn set_hud_message(event_queue: &Mutex<VecDeque<ClientCoreEvent>>, messa...
  function is_streaming (line 84) | fn is_streaming(ctx: &ConnectionContext) -> bool {
  function connection_lifecycle_loop (line 88) | pub fn connection_lifecycle_loop(
  function connection_pipeline (line 123) | fn connection_pipeline(

FILE: alvr/client_core/src/lib.rs
  type ClientCoreEvent (line 42) | pub enum ClientCoreEvent {
  type ClientCapabilities (line 62) | pub struct ClientCapabilities {
  type ClientCoreContext (line 76) | pub struct ClientCoreContext {
    method new (line 86) | pub fn new(capabilities: ClientCapabilities) -> Self {
    method resume (line 131) | pub fn resume(&self) {
    method pause (line 137) | pub fn pause(&self) {
    method poll_event (line 153) | pub fn poll_event(&self) -> Option<ClientCoreEvent> {
    method send_battery (line 159) | pub fn send_battery(&self, device_id: u64, gauge_value: f32, is_plugge...
    method send_playspace (line 173) | pub fn send_playspace(&self, area: Option<Vec2>) {
    method send_active_interaction_profile (line 181) | pub fn send_active_interaction_profile(
    method send_buttons (line 200) | pub fn send_buttons(&self, entries: Vec<ButtonEntry>) {
    method send_view_params (line 209) | pub fn send_view_params(&self, views: [ViewParams; 2]) {
    method send_tracking (line 219) | pub fn send_tracking(&self, data: TrackingData) {
    method send_proximity_state (line 231) | pub fn send_proximity_state(&self, headset_is_worn: bool) {
    method get_total_prediction_offset (line 239) | pub fn get_total_prediction_offset(&self) -> Duration {
    method set_decoder_input_callback (line 253) | pub fn set_decoder_input_callback(&self, callback: Box<DecoderCallback...
    method report_frame_decoded (line 263) | pub fn report_frame_decoded(&self, timestamp: Duration) {
    method report_fatal_decoder_error (line 271) | pub fn report_fatal_decoder_error(&self, error: &str) {
    method report_compositor_start (line 278) | pub fn report_compositor_start(&self, timestamp: Duration) -> [ViewPar...
    method report_submit (line 296) | pub fn report_submit(&self, timestamp: Duration, vsync_queue: Duration) {
    method platform (line 312) | pub fn platform(&self) -> Platform {
  method drop (line 318) | fn drop(&mut self) {

FILE: alvr/client_core/src/logging_backend.rs
  constant LOG_REPEAT_TIMEOUT (line 12) | const LOG_REPEAT_TIMEOUT: Duration = Duration::from_secs(1);
  type LogMirrorData (line 14) | pub struct LogMirrorData {
  type RepeatedLogEvent (line 22) | struct RepeatedLogEvent {
  function init_logging (line 36) | pub fn init_logging() {

FILE: alvr/client_core/src/sockets.rs
  type AnnouncerSocket (line 4) | pub struct AnnouncerSocket {
    method new (line 10) | pub fn new(hostname: &str) -> Result<Self> {
    method announce (line 19) | pub fn announce(&self) -> Result<()> {

FILE: alvr/client_core/src/statistics.rs
  type HistoryFrame (line 8) | struct HistoryFrame {
  type StatisticsManager (line 14) | pub struct StatisticsManager {
    method new (line 22) | pub fn new(max_history_size: usize) -> Self {
    method report_input_acquired (line 34) | pub fn report_input_acquired(&mut self, target_timestamp: Duration) {
    method report_video_packet_received (line 56) | pub fn report_video_packet_received(&mut self, target_timestamp: Durat...
    method report_frame_decoded (line 66) | pub fn report_frame_decoded(&mut self, target_timestamp: Duration) {
    method report_compositor_start (line 77) | pub fn report_compositor_start(&mut self, target_timestamp: Duration) {
    method report_submit (line 91) | pub fn report_submit(&mut self, target_timestamp: Duration, vsync_queu...
    method summary (line 116) | pub fn summary(&self, target_timestamp: Duration) -> Option<ClientStat...
    method average_total_pipeline_latency (line 124) | pub fn average_total_pipeline_latency(&self) -> Duration {

FILE: alvr/client_core/src/storage.rs
  function config_path (line 7) | fn config_path() -> PathBuf {
  type Config (line 20) | pub struct Config {
    method load (line 43) | pub fn load() -> Self {
    method store (line 62) | pub fn store(&self) {
  method default (line 26) | fn default() -> Self {

FILE: alvr/client_core/src/video_decoder/android.rs
  type FakeThreadSafe (line 30) | struct FakeThreadSafe<T>(T);
  type Target (line 35) | type Target = T;
  method deref (line 37) | fn deref(&self) -> &T {
  type SharedMediaCodec (line 42) | type SharedMediaCodec = Arc<FakeThreadSafe<MediaCodec>>;
  type VideoDecoderSink (line 44) | pub struct VideoDecoderSink {
    method push_frame_nal (line 52) | pub fn push_frame_nal(&mut self, timestamp: Duration, data: &[u8]) -> ...
  type QueuedImage (line 81) | struct QueuedImage {
  type VideoDecoderSource (line 89) | pub struct VideoDecoderSource {
    method dequeue_frame (line 101) | pub fn dequeue_frame(&mut self) -> Option<(Duration, *mut c_void)> {
  method drop (line 140) | fn drop(&mut self) {
  function mime_for_codec (line 148) | fn mime_for_codec(codec: CodecType) -> &'static str {
  function decoder_attempt_setup (line 157) | fn decoder_attempt_setup(
  function decoder_lifecycle (line 193) | fn decoder_lifecycle(
  function video_decoder_split (line 352) | pub fn video_decoder_split(

FILE: alvr/client_core/src/video_decoder/mod.rs
  type VideoDecoderConfig (line 9) | pub struct VideoDecoderConfig {
  type VideoDecoderSink (line 18) | pub struct VideoDecoderSink {
    method push_nal (line 26) | pub fn push_nal(&mut self, timestamp: Duration, nal: &[u8]) -> bool {
  type VideoDecoderSource (line 36) | pub struct VideoDecoderSource {
    method get_frame (line 43) | pub fn get_frame(&mut self) -> Option<(Duration, *mut std::ffi::c_void...
  function create_decoder (line 55) | pub fn create_decoder(

FILE: alvr/client_mock/src/main.rs
  type WindowInput (line 24) | struct WindowInput {
  method default (line 35) | fn default() -> Self {
  type WindowOutput (line 49) | struct WindowOutput {
  method default (line 59) | fn default() -> Self {
  type Window (line 71) | pub struct Window {
    method new (line 79) | fn new(
    method update (line 93) | fn update(&mut self, context: &Context, _: &mut Frame) {
  function tracking_thread (line 141) | fn tracking_thread(
  function client_thread (line 188) | fn client_thread(
  function main (line 301) | fn main() {

FILE: alvr/client_openxr/src/c_api.rs
  function alvr_entry_point (line 3) | pub extern "C" fn alvr_entry_point(java_vm: *mut std::ffi::c_void, conte...

FILE: alvr/client_openxr/src/extra_extensions/body_tracking_bd.rs
  constant BD_BODY_TRACKING_EXTENSION_NAME (line 9) | pub const BD_BODY_TRACKING_EXTENSION_NAME: &str = "XR_BD_body_tracking";
  constant BODY_JOINT_COUNT_BD (line 20) | pub const BODY_JOINT_COUNT_BD: usize = 24;
  type XrBodyTrackerBD (line 24) | pub struct XrBodyTrackerBD(u64);
  type BodyJointSetBD (line 28) | pub struct BodyJointSetBD(i32);
    constant BODY_WITHOUT_ARM (line 30) | pub const BODY_WITHOUT_ARM: BodyJointSetBD = Self(1i32);
    constant FULL_BODY_JOINTS (line 31) | pub const FULL_BODY_JOINTS: BodyJointSetBD = Self(2i32);
  type BodyTrackingStatusCodeBD (line 36) | pub struct BodyTrackingStatusCodeBD(i32);
    constant INVALID (line 38) | pub const INVALID: BodyTrackingStatusCodeBD = Self(0i32);
  type BodyTrackingErrorCodeBD (line 43) | pub struct BodyTrackingErrorCodeBD(i32);
    constant INNER_EXCEPTION (line 45) | pub const INNER_EXCEPTION: BodyTrackingErrorCodeBD = Self(0i32);
    constant TRACKER_NOT_CALIBRATED (line 46) | pub const TRACKER_NOT_CALIBRATED: BodyTrackingErrorCodeBD = Self(1i32);
  type CalibAppFlagBD (line 51) | pub struct CalibAppFlagBD(i32);
    constant MOTION_TRACKER_2 (line 53) | pub const MOTION_TRACKER_2: CalibAppFlagBD = Self(1i32);
  type BodyTrackerCreateInfoBD (line 57) | struct BodyTrackerCreateInfoBD {
  type BodyJointsLocateInfoBD (line 64) | struct BodyJointsLocateInfoBD {
  type BodyJointLocationBD (line 72) | pub struct BodyJointLocationBD {
  type BodyJointLocationsBD (line 79) | struct BodyJointLocationsBD {
  type SystemBodyTrackingPropertiesBD (line 88) | struct SystemBodyTrackingPropertiesBD {
  type CreateBodyTrackerBD (line 94) | type CreateBodyTrackerBD = unsafe extern "system" fn(
  type DestroyBodyTrackerBD (line 100) | type DestroyBodyTrackerBD = unsafe extern "system" fn(XrBodyTrackerBD) -...
  type LocateBodyJointsBD (line 102) | type LocateBodyJointsBD = unsafe extern "system" fn(
  type StartBodyTrackingCalibAppBD (line 108) | type StartBodyTrackingCalibAppBD =
  type GetBodyTrackingStateBD (line 111) | type GetBodyTrackingStateBD = unsafe extern "system" fn(
  type BodyTrackerBD (line 117) | pub struct BodyTrackerBD {
    method new (line 126) | pub fn new<G>(
    method locate_body_joints (line 206) | pub fn locate_body_joints(
  method drop (line 263) | fn drop(&mut self) {

FILE: alvr/client_openxr/src/extra_extensions/body_tracking_fb.rs
  constant META_BODY_TRACKING_FULL_BODY_EXTENSION_NAME (line 10) | pub const META_BODY_TRACKING_FULL_BODY_EXTENSION_NAME: &str = "XR_META_b...
  constant META_BODY_TRACKING_FIDELITY_EXTENSION_NAME (line 13) | pub const META_BODY_TRACKING_FIDELITY_EXTENSION_NAME: &str = "XR_META_bo...
  constant FULL_BODY_JOINT_COUNT_META (line 16) | pub const FULL_BODY_JOINT_COUNT_META: usize = 84;
  type SystemPropertiesBodyTrackingFullBodyMETA (line 19) | struct SystemPropertiesBodyTrackingFullBodyMETA {
  type BodyTrackerFB (line 25) | pub struct BodyTrackerFB {
    method new (line 47) | pub fn new<G>(
    method locate_body_joints (line 100) | pub fn locate_body_joints(
  type SystemPropertiesBodyTrackingFidelityMETA (line 31) | struct SystemPropertiesBodyTrackingFidelityMETA {
  type BodyTrackingFidelityMode (line 38) | enum BodyTrackingFidelityMode {
  type RequestBodyTrackingFidelityMETA (line 43) | type RequestBodyTrackingFidelityMETA =
  method drop (line 142) | fn drop(&mut self) {

FILE: alvr/client_openxr/src/extra_extensions/eye_gaze_interaction.rs
  function supports_eye_gaze_interaction (line 4) | pub fn supports_eye_gaze_interaction<G>(session: &xr::Session<G>, system...

FILE: alvr/client_openxr/src/extra_extensions/eye_tracking_social.rs
  type EyeTrackerSocial (line 7) | pub struct EyeTrackerSocial {
    method new (line 13) | pub fn new<G>(session: &xr::Session<G>) -> xr::Result<Self> {
    method get_eye_gazes (line 36) | pub fn get_eye_gazes(
  method drop (line 71) | fn drop(&mut self) {

FILE: alvr/client_openxr/src/extra_extensions/face_tracking2_fb.rs
  type FaceTracker2FB (line 7) | pub struct FaceTracker2FB {
    method new (line 15) | pub fn new<G>(session: xr::Session<G>, visual: bool, audio: bool) -> x...
    method get_face_expression_weights (line 53) | pub fn get_face_expression_weights(&self, time: xr::Time) -> xr::Resul...
  method drop (line 98) | fn drop(&mut self) {

FILE: alvr/client_openxr/src/extra_extensions/face_tracking_pico.rs
  constant TRACKING_MODE_FACE_BIT (line 4) | const TRACKING_MODE_FACE_BIT: u64 = 0x00000008;
  constant PICO_FACE_EXPRESSION_COUNT (line 5) | const PICO_FACE_EXPRESSION_COUNT: usize = 52;
  type FaceTrackingDataPICO (line 8) | struct FaceTrackingDataPICO {
  type StartEyeTrackingPICO (line 17) | type StartEyeTrackingPICO = unsafe extern "system" fn(sys::Session) -> s...
  type StopEyeTrackingPICO (line 19) | type StopEyeTrackingPICO = unsafe extern "system" fn(sys::Session, u64) ...
  type SetTrackingModePICO (line 21) | type SetTrackingModePICO = unsafe extern "system" fn(sys::Session, u64) ...
  type GetFaceTrackingDataPICO (line 23) | type GetFaceTrackingDataPICO = unsafe extern "system" fn(
  type FaceTrackerPico (line 30) | pub struct FaceTrackerPico {
    method new (line 39) | pub fn new<G>(session: xr::Session<G>) -> xr::Result<Self> {
    method get_face_tracking_data (line 60) | pub fn get_face_tracking_data(&self, time: xr::Time) -> xr::Result<Opt...
    method start_face_tracking (line 89) | pub fn start_face_tracking(&self) -> xr::Result<()> {
    method stop_face_tracking (line 99) | pub fn stop_face_tracking(&self) -> xr::Result<()> {

FILE: alvr/client_openxr/src/extra_extensions/facial_tracking_htc.rs
  type FacialTrackerHTC (line 7) | pub struct FacialTrackerHTC {
    method new (line 16) | pub fn new<G>(
    method get_facial_expressions (line 72) | pub fn get_facial_expressions(&self, time: xr::Time) -> xr::Result<Opt...
  method drop (line 102) | fn drop(&mut self) {

FILE: alvr/client_openxr/src/extra_extensions/mod.rs
  function xr_res (line 29) | fn xr_res(result: sys::Result) -> xr::Result<()> {
  function get_props (line 37) | fn get_props<G, T>(
  function get_instance_proc (line 57) | fn get_instance_proc<G, FnTy>(session: &xr::Session<G>, method_name: &st...

FILE: alvr/client_openxr/src/extra_extensions/motion_tracking_bd.rs
  constant BD_MOTION_TRACKING_EXTENSION_NAME (line 5) | pub const BD_MOTION_TRACKING_EXTENSION_NAME: &str = "XR_BD_motion_tracki...
  constant PICO_CONFIGURATION_EXTENSION_NAME (line 6) | pub const PICO_CONFIGURATION_EXTENSION_NAME: &str = "XR_PICO_configurati...
  type MotionTrackerConnectStateBD (line 10) | struct MotionTrackerConnectStateBD {
  type MotionTrackerSerialBD (line 17) | pub struct MotionTrackerSerialBD {
  type MotionTrackerConfidenceBD (line 23) | pub struct MotionTrackerConfidenceBD(i32);
  type MotionTrackerLocationBD (line 26) | pub struct MotionTrackerLocationBD {
  type MotionTrackerLocationsBD (line 35) | pub struct MotionTrackerLocationsBD {
  type GetMotionTrackerConnectStateBD (line 42) | type GetMotionTrackerConnectStateBD =
  type GetMotionTrackerLocationsBD (line 45) | type GetMotionTrackerLocationsBD = unsafe extern "system" fn(
  type SetConfigPICO (line 52) | type SetConfigPICO = unsafe extern "system" fn(sys::Session, i32, *const...
  type MotionTrackerBD (line 54) | pub struct MotionTrackerBD {
    method new (line 61) | pub fn new<G>(session: xr::Session<G>, extra_extensions: &[String]) ->...
    method locate_motion_trackers (line 88) | pub fn locate_motion_trackers(

FILE: alvr/client_openxr/src/extra_extensions/multimodal_input.rs
  constant META_SIMULTANEOUS_HANDS_AND_CONTROLLERS_EXTENSION_NAME (line 11) | pub const META_SIMULTANEOUS_HANDS_AND_CONTROLLERS_EXTENSION_NAME: &str =
  constant META_DETACHED_CONTROLLERS_EXTENSION_NAME (line 13) | pub const META_DETACHED_CONTROLLERS_EXTENSION_NAME: &str = "XR_META_deta...
  type SystemSymultaneousHandsAndControllersPropertiesMETA (line 25) | struct SystemSymultaneousHandsAndControllersPropertiesMETA {
  type SimultaneousHandsAndControllersTrackingResumeInfoMETA (line 32) | struct SimultaneousHandsAndControllersTrackingResumeInfoMETA {
  type SimultaneousHandsAndControllersTrackingPauseInfoMETA (line 37) | struct SimultaneousHandsAndControllersTrackingPauseInfoMETA {
  type ResumeSimultaneousHandsAndControllersTrackingMETA (line 42) | type ResumeSimultaneousHandsAndControllersTrackingMETA = unsafe extern "...
  type PauseSimultaneousHandsAndControllersTrackingMETA (line 46) | type PauseSimultaneousHandsAndControllersTrackingMETA = unsafe extern "s...
  type MultimodalMeta (line 51) | pub struct MultimodalMeta {
    method new (line 60) | pub fn new<G>(
    method resume (line 102) | pub fn resume(&self) -> xr::Result<()> {
    method pause (line 116) | pub fn pause(&self) -> xr::Result<()> {

FILE: alvr/client_openxr/src/extra_extensions/passthrough_fb.rs
  type PassthroughFB (line 8) | pub struct PassthroughFB {
    method new (line 16) | pub fn new(session: &xr::Session<xr::OpenGlEs>, platform: Platform) ->...
    method layer (line 75) | pub fn layer(&self) -> &sys::CompositionLayerPassthroughFB {
  method drop (line 81) | fn drop(&mut self) {

FILE: alvr/client_openxr/src/extra_extensions/passthrough_htc.rs
  type PassthroughHTC (line 7) | pub struct PassthroughHTC {
    method new (line 14) | pub fn new(session: &xr::Session<xr::OpenGlEs>) -> xr::Result<Self> {
    method layer (line 56) | pub fn layer(&self) -> &sys::CompositionLayerPassthroughHTC {
  method drop (line 62) | fn drop(&mut self) {

FILE: alvr/client_openxr/src/graphics.rs
  function session_create_info (line 8) | pub fn session_create_info(ctx: &GraphicsContext) -> xr::opengles::Sessi...
  function swapchain_format (line 21) | pub fn swapchain_format(
  function create_swapchain (line 33) | pub fn create_swapchain(
  type ProjectionLayerAlphaConfig (line 57) | pub struct ProjectionLayerAlphaConfig {
  type ProjectionLayerBuilder (line 64) | pub struct ProjectionLayerBuilder<'a> {
  function new (line 72) | pub fn new(
  function build (line 98) | pub fn build(&self) -> xr::CompositionLayerProjection<'_, xr::OpenGlEs> {

FILE: alvr/client_openxr/src/interaction.rs
  constant IPD_CHANGE_EPS (line 23) | const IPD_CHANGE_EPS: f32 = 0.001;
  function get_controller_offset (line 32) | fn get_controller_offset(platform: Platform, is_right_hand: bool) -> Pose {
  function check_ext_object (line 79) | fn check_ext_object<T>(name: &str, result: xr::Result<T>) -> Option<T> {
  type ButtonAction (line 94) | pub enum ButtonAction {
  type HandInteraction (line 99) | pub struct HandInteraction {
  type FaceExpressionsTracker (line 119) | pub enum FaceExpressionsTracker {
  type FaceSources (line 128) | pub struct FaceSources {
  type BodyTracker (line 134) | pub enum BodyTracker {
  type InteractionSourcesConfig (line 144) | pub struct InteractionSourcesConfig {
    method new (line 151) | pub fn new(config: &StreamConfig) -> Self {
  type InteractionContext (line 175) | pub struct InteractionContext {
    method new (line 190) | pub fn new(
    method select_sources (line 503) | pub fn select_sources(&mut self, config: &InteractionSourcesConfig) {
  function get_reference_space (line 674) | pub fn get_reference_space(
  function get_head_data (line 683) | pub fn get_head_data(
  function get_hand_data (line 794) | pub fn get_hand_data(
  function update_buttons (line 939) | pub fn update_buttons(
  function get_face_data (line 977) | pub fn get_face_data(
  function get_body_skeleton (line 1044) | pub fn get_body_skeleton(
  function get_bd_motion_trackers (line 1107) | pub fn get_bd_motion_trackers(source: &BodyTracker, time: Duration) -> V...

FILE: alvr/client_openxr/src/lib.rs
  function from_xr_vec3 (line 33) | fn from_xr_vec3(v: xr::Vector3f) -> Vec3 {
  function to_xr_vec3 (line 37) | fn to_xr_vec3(v: Vec3) -> xr::Vector3f {
  function from_xr_quat (line 45) | fn from_xr_quat(q: xr::Quaternionf) -> Quat {
  function to_xr_quat (line 49) | fn to_xr_quat(q: Quat) -> xr::Quaternionf {
  function from_xr_pose (line 58) | fn from_xr_pose(p: xr::Posef) -> Pose {
  function to_xr_pose (line 65) | fn to_xr_pose(p: Pose) -> xr::Posef {
  function from_xr_fov (line 72) | fn from_xr_fov(f: xr::Fovf) -> Fov {
  function to_xr_fov (line 81) | fn to_xr_fov(f: Fov) -> xr::Fovf {
  function from_xr_time (line 90) | fn from_xr_time(timestamp: xr::Time) -> Duration {
  function to_xr_time (line 94) | fn to_xr_time(timestamp: Duration) -> xr::Time {
  function to_perf_settings_level (line 98) | fn to_perf_settings_level(level: PerformanceLevel) -> xr::PerfSettingsLe...
  function set_performance_level (line 107) | fn set_performance_level(
  function default_view (line 124) | fn default_view() -> xr::View {
  function create_session (line 145) | fn create_session(
  function entry_point (line 162) | pub fn entry_point() {
  function xr_runtime_now (line 637) | fn xr_runtime_now(xr_instance: &xr::Instance) -> Option<xr::Time> {
  function android_main (line 646) | fn android_main(app: android_activity::AndroidApp) {

FILE: alvr/client_openxr/src/lobby.rs
  type Lobby (line 12) | pub struct Lobby {
    method new (line 24) | pub fn new(
    method update_reference_space (line 79) | pub fn update_reference_space(&mut self) {
    method update_hud_message (line 84) | pub fn update_hud_message(&self, message: &str) {
    method render (line 88) | pub fn render(&mut self, vsync_time: Duration) -> ProjectionLayerBuild...

FILE: alvr/client_openxr/src/passthrough.rs
  type PassthroughLayer (line 7) | pub struct PassthroughLayer<'a> {
  function new (line 14) | pub fn new(session: &xr::Session<xr::OpenGlEs>, platform: Platform) -> R...
  type Target (line 36) | type Target = xr::CompositionLayerBase<'a, xr::OpenGlEs>;
  method deref (line 38) | fn deref(&self) -> &Self::Target {

FILE: alvr/client_openxr/src/stream.rs
  constant DECODER_MAX_TIMEOUT_MULTIPLIER (line 33) | const DECODER_MAX_TIMEOUT_MULTIPLIER: f32 = 0.8;
  type ParsedStreamConfig (line 35) | pub struct ParsedStreamConfig {
    method new (line 53) | pub fn new(config: &StreamConfig) -> Self {
  type StreamContext (line 87) | pub struct StreamContext {
    method new (line 105) | pub fn new(
    method uses_passthrough (line 253) | pub fn uses_passthrough(&self) -> bool {
    method update_reference_space (line 257) | pub fn update_reference_space(&mut self) {
    method maybe_initialize_decoder (line 304) | pub fn maybe_initialize_decoder(&mut self, codec: CodecType, config_na...
    method update_real_time_config (line 336) | pub fn update_real_time_config(&mut self, config: &RealTimeConfig) {
    method render (line 341) | pub fn render(
  method drop (line 511) | fn drop(&mut self) {
  function stream_input_loop (line 517) | fn stream_input_loop(

FILE: alvr/common/src/average.rs
  type SlidingWindowAverage (line 3) | pub struct SlidingWindowAverage<T> {
  function new (line 9) | pub fn new(initial_value: T, max_history_size: usize) -> Self {
  function submit_sample (line 16) | pub fn submit_sample(&mut self, sample: T) {
  function retain (line 24) | pub fn retain(&mut self, count: usize) {
  function get_average (line 31) | pub fn get_average(&self) -> f32 {
  function get_average (line 37) | pub fn get_average(&self) -> Duration {

FILE: alvr/common/src/c_api.rs
  type AlvrFov (line 6) | pub struct AlvrFov {
  type AlvrQuat (line 19) | pub struct AlvrQuat {
  type AlvrPose (line 28) | pub struct AlvrPose {
  type AlvrViewParams (line 34) | pub struct AlvrViewParams {
  type AlvrCodecType (line 40) | pub enum AlvrCodecType {
  function to_capi_fov (line 46) | pub fn to_capi_fov(fov: &Fov) -> AlvrFov {
  function from_capi_fov (line 55) | pub fn from_capi_fov(fov: &AlvrFov) -> Fov {
  function from_capi_quat (line 64) | pub fn from_capi_quat(quat: &AlvrQuat) -> Quat {
  function to_capi_quat (line 68) | pub fn to_capi_quat(quat: &Quat) -> AlvrQuat {
  function to_capi_pose (line 77) | pub fn to_capi_pose(pose: &Pose) -> AlvrPose {
  function from_capi_pose (line 84) | pub fn from_capi_pose(pose: &AlvrPose) -> Pose {
  function to_capi_view_params (line 91) | pub fn to_capi_view_params(view_params: &ViewParams) -> AlvrViewParams {
  function from_capi_view_params (line 98) | pub fn from_capi_view_params(view_params: &AlvrViewParams) -> ViewParams {

FILE: alvr/common/src/connection_result.rs
  type ConnectionError (line 9) | pub enum ConnectionError {
  method fmt (line 15) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  type ConResult (line 21) | pub type ConResult<T = ()> = Result<T, ConnectionError>;
  function try_again (line 23) | pub fn try_again<T>() -> ConResult<T> {
  type ToCon (line 34) | pub trait ToCon<T> {
    method to_con (line 36) | fn to_con(self) -> ConResult<T>;
  function to_con (line 40) | fn to_con(self) -> ConResult<T> {
  function to_con (line 46) | fn to_con(self) -> ConResult<T> {
  type AnyhowToCon (line 51) | pub trait AnyhowToCon<T> {
    method to_con (line 52) | fn to_con(self) -> ConResult<T>;
  function to_con (line 56) | fn to_con(self) -> ConResult<T> {
  type HandleTryAgain (line 61) | pub trait HandleTryAgain<T> {
    method handle_try_again (line 62) | fn handle_try_again(self) -> ConResult<T>;
  function handle_try_again (line 66) | fn handle_try_again(self) -> ConResult<T> {
  function handle_try_again (line 82) | fn handle_try_again(self) -> ConResult<T> {
  function handle_try_again (line 91) | fn handle_try_again(self) -> ConResult<T> {

FILE: alvr/common/src/inputs.rs
  type ButtonType (line 69) | pub enum ButtonType {
  type ButtonInfo (line 74) | pub struct ButtonInfo {
  type InteractionProfileInfo (line 153) | pub struct InteractionProfileInfo {

FILE: alvr/common/src/lib.rs
  constant ALVR_NAME (line 29) | pub const ALVR_NAME: &str = "ALVR";
  type RelaxedAtomic (line 34) | pub struct RelaxedAtomic(AtomicBool);
    method new (line 37) | pub const fn new(initial_value: bool) -> Self {
    method value (line 41) | pub fn value(&self) -> bool {
    method set (line 45) | pub fn set(&self, value: bool) {
  type LifecycleState (line 51) | pub enum LifecycleState {
  type ConnectionState (line 59) | pub enum ConnectionState {
  function wait_rwlock (line 68) | pub fn wait_rwlock<T>(condvar: &Condvar, guard: &mut RwLockWriteGuard<'_...

FILE: alvr/common/src/logging.rs
  constant SERVER_IMPL_DBG_LABEL (line 8) | pub const SERVER_IMPL_DBG_LABEL: &str = "SERVER IMPL";
  constant CLIENT_IMPL_DBG_LABEL (line 9) | pub const CLIENT_IMPL_DBG_LABEL: &str = "CLIENT IMPL";
  constant SERVER_CORE_DBG_LABEL (line 10) | pub const SERVER_CORE_DBG_LABEL: &str = "SERVER CORE";
  constant CLIENT_CORE_DBG_LABEL (line 11) | pub const CLIENT_CORE_DBG_LABEL: &str = "CLIENT CORE";
  constant CONNECTION_DBG_LABEL (line 12) | pub const CONNECTION_DBG_LABEL: &str = "CONNECTION";
  constant SOCKETS_DBG_LABEL (line 13) | pub const SOCKETS_DBG_LABEL: &str = "SOCKETS";
  constant SERVER_GFX_DBG_LABEL (line 14) | pub const SERVER_GFX_DBG_LABEL: &str = "SERVER GFX";
  constant CLIENT_GFX_DBG_LABEL (line 15) | pub const CLIENT_GFX_DBG_LABEL: &str = "CLIENT GFX";
  constant ENCODER_DBG_LABEL (line 16) | pub const ENCODER_DBG_LABEL: &str = "ENCODER";
  constant DECODER_DBG_LABEL (line 17) | pub const DECODER_DBG_LABEL: &str = "DECODER";
  type DebugGroupsConfig (line 102) | pub struct DebugGroupsConfig {
  function filter_debug_groups (line 125) | pub fn filter_debug_groups(target: &str, config: &DebugGroupsConfig) -> ...
  function is_enabled_debug_group (line 141) | pub fn is_enabled_debug_group(target: &str, config: &DebugGroupsConfig) ...
  type LogSeverity (line 157) | pub enum LogSeverity {
    method from_log_level (line 165) | pub fn from_log_level(level: log::Level) -> Self {
    method into_log_level (line 174) | pub fn into_log_level(self) -> log::Level {
  type LogEntry (line 185) | pub struct LogEntry {
  function set_popup_callback (line 191) | pub fn set_popup_callback(callback: fn(&str, &str, LogSeverity)) {
  function set_panic_hook (line 195) | pub fn set_panic_hook() {
  function show_w (line 215) | pub fn show_w<W: Display + Send + 'static>(w: W) {
  function show_warn (line 225) | pub fn show_warn<T, E: Display + Send + 'static>(res: Result<T, E>) -> O...
  function show_e_block (line 229) | fn show_e_block<E: Display>(e: E, blocking: bool) {
  function show_e (line 259) | pub fn show_e<E: Display>(e: E) {
  function show_e_dbg (line 263) | pub fn show_e_dbg<E: std::fmt::Debug>(e: E) {
  function show_e_blocking (line 267) | pub fn show_e_blocking<E: Display>(e: E) {
  function show_err (line 271) | pub fn show_err<T, E: Display>(res: Result<T, E>) -> Option<T> {
  function show_err_blocking (line 275) | pub fn show_err_blocking<T, E: Display>(res: Result<T, E>) -> Option<T> {
  type ToAny (line 279) | pub trait ToAny<T> {
    method to_any (line 280) | fn to_any(self) -> Result<T>;
  function to_any (line 284) | fn to_any(self) -> Result<T> {
  function to_any (line 293) | fn to_any(self) -> Result<T> {

FILE: alvr/common/src/primitives.rs
  type Fov (line 7) | pub struct Fov {
    constant DUMMY (line 15) | pub const DUMMY: Self = Fov {
  type Pose (line 24) | pub struct Pose {
    constant IDENTITY (line 30) | pub const IDENTITY: Self = Pose {
    method inverse (line 35) | pub fn inverse(&self) -> Pose {
    type Output (line 45) | type Output = Pose;
    method mul (line 47) | fn mul(self, rhs: Pose) -> Pose {
    type Output (line 63) | type Output = DeviceMotion;
    method mul (line 65) | fn mul(self, rhs: DeviceMotion) -> DeviceMotion {
  type DeviceMotion (line 56) | pub struct DeviceMotion {
    constant IDENTITY (line 80) | pub const IDENTITY: Self = DeviceMotion {
    method predict (line 86) | pub fn predict(&self, from_timestamp: Duration, to_timestamp: Duration...
  function difference_seconds (line 75) | fn difference_seconds(from: Duration, to: Duration) -> f32 {
  type ViewParams (line 105) | pub struct ViewParams {
    constant DUMMY (line 111) | pub const DUMMY: Self = ViewParams {
  type BodySkeletonFb (line 118) | pub struct BodySkeletonFb {
  type BodySkeletonBd (line 124) | pub struct BodySkeletonBd(pub [Option<Pose>; 24]);
  type BodySkeleton (line 127) | pub enum BodySkeleton {

FILE: alvr/common/src/version.rs
  function hash_string (line 12) | pub fn hash_string(string: &str) -> u64 {
  function is_nightly (line 18) | pub fn is_nightly() -> bool {
  function is_stable (line 22) | pub fn is_stable() -> bool {
  function protocol_id (line 29) | pub fn protocol_id() -> String {
  function protocol_id_u64 (line 37) | pub fn protocol_id_u64() -> u64 {
  function is_version_compatible (line 42) | pub fn is_version_compatible(other_version: &Version) -> bool {

FILE: alvr/dashboard/build.rs
  function main (line 2) | fn main() {
  function main (line 9) | fn main() {}

FILE: alvr/dashboard/src/dashboard/components/about.rs
  function about_tab_ui (line 5) | pub fn about_tab_ui(ui: &mut Ui) {

FILE: alvr/dashboard/src/dashboard/components/debug.rs
  function debug_tab_ui (line 4) | pub fn debug_tab_ui(ui: &mut Ui) -> Option<ServerRequest> {

FILE: alvr/dashboard/src/dashboard/components/devices.rs
  type EditPopupState (line 13) | struct EditPopupState {
  type DevicesTab (line 19) | pub struct DevicesTab {
    method new (line 27) | pub fn new() -> Self {
    method update_client_list (line 36) | pub fn update_client_list(&mut self, session: &SessionConfig) {
    method update_adb_download_progress (line 48) | pub fn update_adb_download_progress(&mut self, progress: f32) {
    method ui (line 52) | pub fn ui(&mut self, ui: &mut Ui, connected_to_server: bool) -> Vec<Se...
  function wired_client_section (line 189) | fn wired_client_section(
  function new_clients_section (line 258) | fn new_clients_section(
  function trusted_clients_section (line 306) | fn trusted_clients_section(
  function connection_label (line 384) | fn connection_label(ui: &mut Ui, connection_state: &ConnectionState) {

FILE: alvr/dashboard/src/dashboard/components/installation.rs
  constant DRIVER_UPDATE_INTERVAL (line 9) | const DRIVER_UPDATE_INTERVAL: Duration = Duration::from_secs(1);
  type InstallationTabRequest (line 11) | pub enum InstallationTabRequest {
  type InstallationTab (line 16) | pub struct InstallationTab {
    method new (line 22) | pub fn new() -> Self {
    method update_drivers (line 29) | pub fn update_drivers(&mut self, list: Vec<PathBuf>) {
    method ui (line 33) | pub fn ui(&mut self, ui: &mut Ui) -> Vec<InstallationTabRequest> {

FILE: alvr/dashboard/src/dashboard/components/logs.rs
  type Entry (line 12) | struct Entry {
  type LogsTab (line 19) | pub struct LogsTab {
    method new (line 26) | pub fn new() -> Self {
    method update_settings (line 36) | pub fn update_settings(&mut self, settings: &Settings) {
    method push_event (line 40) | pub fn push_event(&mut self, event: Event) {
    method ui (line 75) | pub fn ui(&mut self, ui: &mut Ui) {

FILE: alvr/dashboard/src/dashboard/components/new_version_popup.rs
  type CloseAction (line 7) | pub enum CloseAction {
  type NewVersionPopup (line 12) | pub struct NewVersionPopup {
    method new (line 19) | pub fn new(version: String, message: String) -> Self {
    method ui (line 36) | pub fn ui(&self, context: &Context, shutdown_alvr_cb: impl Fn()) -> Op...

FILE: alvr/dashboard/src/dashboard/components/notifications.rs
  constant TIMEOUT (line 17) | const TIMEOUT: Duration = Duration::from_secs(5);
  constant NO_NOTIFICATIONS_MESSAGE (line 18) | const NO_NOTIFICATIONS_MESSAGE: &str = "No new notifications";
  constant NOTIFICATION_TIPS (line 19) | const NOTIFICATION_TIPS: &[&str] = &[
  type NotificationBar (line 50) | pub struct NotificationBar {
    method new (line 60) | pub fn new() -> Self {
    method update_settings (line 71) | pub fn update_settings(&mut self, settings: &Settings) {
    method push_notification (line 85) | pub fn push_notification(&mut self, event: LogEntry, from_dashboard: b...
    method ui (line 106) | pub fn ui(&mut self, context: &egui::Context) {

FILE: alvr/dashboard/src/dashboard/components/settings.rs
  constant DATA_UPDATE_INTERVAL (line 17) | const DATA_UPDATE_INTERVAL: Duration = Duration::from_secs(1);
  constant MIN_COLUMN_SIZE (line 18) | const MIN_COLUMN_SIZE: f32 = 300.0;
  type TopLevelEntry (line 20) | struct TopLevelEntry {
  type SettingsTab (line 25) | pub struct SettingsTab {
    method new (line 42) | pub fn new() -> Self {
    method update_session (line 89) | pub fn update_session(&mut self, session_settings: &SessionSettings) {
    method ui (line 112) | pub fn ui(&mut self, ui: &mut Ui) -> Vec<ServerRequest> {

FILE: alvr/dashboard/src/dashboard/components/settings_controls/array.rs
  type Control (line 7) | pub struct Control {
    method new (line 13) | pub fn new(nesting_info: NestingInfo, schema_array: Vec<SchemaNode>) -...
    method ui (line 32) | pub fn ui(

FILE: alvr/dashboard/src/dashboard/components/settings_controls/boolean.rs
  type Control (line 9) | pub struct Control {
    method new (line 16) | pub fn new(nesting_info: NestingInfo, default: bool) -> Self {
    method ui (line 26) | pub fn ui(

FILE: alvr/dashboard/src/dashboard/components/settings_controls/choice.rs
  function get_display_name (line 12) | fn get_display_name(id: &str, strings: &HashMap<String, String>) -> Stri...
  type Control (line 31) | pub struct Control {
    method new (line 43) | pub fn new(
    method ui (line 101) | pub fn ui(

FILE: alvr/dashboard/src/dashboard/components/settings_controls/collapsible.rs
  function collapsible_button (line 6) | pub fn collapsible_button(

FILE: alvr/dashboard/src/dashboard/components/settings_controls/dictionary.rs
  type Entry (line 14) | struct Entry {
  type Control (line 19) | pub struct Control {
    method new (line 28) | pub fn new(
    method ui (line 46) | pub fn ui(

FILE: alvr/dashboard/src/dashboard/components/settings_controls/mod.rs
  constant INDENTATION_STEP (line 23) | pub const INDENTATION_STEP: f32 = 20.0;
  function get_single_value (line 25) | fn get_single_value(
  function grid_flow_inline (line 39) | fn grid_flow_inline(ui: &mut Ui, allow_inline: bool) {
  function get_display_name (line 46) | pub fn get_display_name(id: &str, strings: &HashMap<String, String>) -> ...
  function f64_eq (line 54) | pub fn f64_eq(f1: f64, f2: f64) -> bool {
  function json_values_eq (line 60) | pub fn json_values_eq(a: &serde_json::Value, b: &serde_json::Value) -> b...
  type NestingInfo (line 75) | pub struct NestingInfo {
  type SettingControl (line 80) | pub enum SettingControl {
    method new (line 95) | pub fn new(nesting_info: NestingInfo, schema: SchemaNode) -> Self {
    method ui (line 158) | pub fn ui(

FILE: alvr/dashboard/src/dashboard/components/settings_controls/notice.rs
  function notice (line 7) | pub fn notice(ui: &mut Ui, text: &str) {

FILE: alvr/dashboard/src/dashboard/components/settings_controls/number.rs
  function to_json_value (line 13) | fn to_json_value(number: f64, ty: NumberType) -> json::Value {
  type Control (line 21) | pub struct Control {
    method new (line 32) | pub fn new(
    method ui (line 52) | pub fn ui(

FILE: alvr/dashboard/src/dashboard/components/settings_controls/optional.rs
  type Control (line 10) | pub struct Control {
    method new (line 18) | pub fn new(nesting_info: NestingInfo, default_set: bool, schema_conten...
    method ui (line 40) | pub fn ui(

FILE: alvr/dashboard/src/dashboard/components/settings_controls/presets/builtin_schema.rs
  function string_modifier (line 11) | fn string_modifier(target_path: &str, value: &str) -> PresetModifier {
  function num_modifier (line 17) | fn num_modifier(target_path: &str, value: &str) -> PresetModifier {
  function bool_modifier (line 25) | fn bool_modifier(target_path: &str, value: bool) -> PresetModifier {
  function resolution_schema (line 32) | pub fn resolution_schema() -> PresetSchemaNode {
  function framerate_schema (line 89) | pub fn framerate_schema() -> PresetSchemaNode {
  function codec_preset_schema (line 112) | pub fn codec_preset_schema() -> PresetSchemaNode {
  function encoder_preset_schema (line 145) | pub fn encoder_preset_schema() -> PresetSchemaNode {
  function foveation_preset_schema (line 183) | pub fn foveation_preset_schema() -> PresetSchemaNode {
  function game_audio_schema (line 238) | pub fn game_audio_schema() -> PresetSchemaNode {
  function microphone_schema (line 269) | pub fn microphone_schema() -> PresetSchemaNode {
  function game_audio_schema (line 300) | pub fn game_audio_schema() -> PresetSchemaNode {
  function microphone_schema (line 340) | pub fn microphone_schema() -> PresetSchemaNode {
  function hand_tracking_interaction_schema (line 383) | pub fn hand_tracking_interaction_schema() -> PresetSchemaNode {
  function eye_face_tracking_schema (line 447) | pub fn eye_face_tracking_schema() -> PresetSchemaNode {

FILE: alvr/dashboard/src/dashboard/components/settings_controls/presets/higher_order_choice.rs
  type Control (line 9) | pub struct Control {
    method new (line 17) | pub fn new(schema: HigherOrderChoiceSchema) -> Self {
    method update_session_settings (line 90) | pub fn update_session_settings(&mut self, session_setting_json: &json:...
    method ui (line 132) | pub fn ui(&mut self, ui: &mut Ui) -> Vec<PathValuePair> {

FILE: alvr/dashboard/src/dashboard/components/settings_controls/presets/mod.rs
  type PresetControl (line 12) | pub enum PresetControl {
    method new (line 18) | pub fn new(schema: PresetSchemaNode) -> Self {
    method update_session_settings (line 27) | pub fn update_session_settings(&mut self, session_settings_json: &json...
    method ui (line 35) | pub fn ui(&mut self, ui: &mut Ui) -> Vec<PathValuePair> {

FILE: alvr/dashboard/src/dashboard/components/settings_controls/presets/schema.rs
  type PresetModifierOperation (line 7) | pub enum PresetModifierOperation {
  type PresetModifier (line 12) | pub struct PresetModifier {
  type HigherOrderChoiceOption (line 19) | pub struct HigherOrderChoiceOption {
  type HigherOrderChoiceSchema (line 26) | pub struct HigherOrderChoiceSchema {
  type PresetSchemaNode (line 36) | pub enum PresetSchemaNode {

FILE: alvr/dashboard/src/dashboard/components/settings_controls/reset.rs
  function reset_button (line 6) | pub fn reset_button(ui: &mut Ui, enabled: bool, default_str: &str) -> Re...

FILE: alvr/dashboard/src/dashboard/components/settings_controls/section.rs
  type Entry (line 14) | struct Entry {
  type Control (line 24) | pub struct Control {
    method new (line 31) | pub fn new(
    method ui (line 71) | pub fn ui(

FILE: alvr/dashboard/src/dashboard/components/settings_controls/switch.rs
  type Control (line 10) | pub struct Control {
    method new (line 18) | pub fn new(
    method ui (line 44) | pub fn ui(

FILE: alvr/dashboard/src/dashboard/components/settings_controls/text.rs
  type Control (line 9) | pub struct Control {
    method new (line 17) | pub fn new(nesting_info: NestingInfo, default: String) -> Self {
    method ui (line 28) | pub fn ui(

FILE: alvr/dashboard/src/dashboard/components/settings_controls/up_down.rs
  type UpDownResult (line 7) | pub enum UpDownResult {
  function up_down_buttons (line 13) | pub fn up_down_buttons(ui: &mut Ui, index: usize, count: usize) -> UpDow...

FILE: alvr/dashboard/src/dashboard/components/settings_controls/vector.rs
  type Control (line 14) | pub struct Control {
    method new (line 22) | pub fn new(
    method ui (line 35) | pub fn ui(

FILE: alvr/dashboard/src/dashboard/components/setup_wizard.rs
  type SetupWizardRequest (line 7) | pub enum SetupWizardRequest {
  type Page (line 13) | enum Page {
  function index_to_page (line 23) | fn index_to_page(index: usize) -> Page {
  function page_content (line 36) | fn page_content(
  type SetupWizard (line 57) | pub struct SetupWizard {
    method new (line 62) | pub fn new() -> Self {
    method ui (line 68) | pub fn ui(&mut self, ui: &mut Ui) -> Option<SetupWizardRequest> {

FILE: alvr/dashboard/src/dashboard/components/statistics.rs
  constant GRAPH_HISTORY_SIZE (line 15) | const GRAPH_HISTORY_SIZE: usize = 1000;
  constant UPPER_QUANTILE (line 16) | const UPPER_QUANTILE: f64 = 0.90;
  function draw_lines (line 18) | fn draw_lines(painter: &Painter, points: Vec<Pos2>, color: Color32) {
  type StatisticsTab (line 22) | pub struct StatisticsTab {
    method new (line 28) | pub fn new() -> Self {
    method update_statistics (line 37) | pub fn update_statistics(&mut self, statistics: StatisticsSummary) {
    method update_graph_statistics (line 41) | pub fn update_graph_statistics(&mut self, statistics: GraphStatistics) {
    method ui (line 46) | pub fn ui(&self, ui: &mut Ui) -> Option<ServerRequest> {
    method draw_graph (line 65) | fn draw_graph(
    method draw_latency_graph (line 126) | fn draw_latency_graph(&self, ui: &mut Ui, available_width: f32) {
    method draw_fps_graph (line 217) | fn draw_fps_graph(&self, ui: &mut Ui, available_width: f32) {
    method draw_bitrate_graph (line 265) | fn draw_bitrate_graph(&self, ui: &mut Ui, available_width: f32) {
    method draw_statistics_overview (line 435) | fn draw_statistics_overview(&self, ui: &mut Ui, statistics: &Statistic...

FILE: alvr/dashboard/src/dashboard/mod.rs
  type ServerRequest (line 25) | pub enum ServerRequest {
  type Tab (line 48) | enum Tab {
  type Dashboard (line 59) | pub struct Dashboard {
    method new (line 80) | pub fn new(creation_context: &eframe::CreationContext<'_>, data_source...
    method restart_steamvr (line 118) | fn restart_steamvr(&self, requests: &mut Vec<ServerRequest>) {
    method update (line 145) | fn update(&mut self, context: &egui::Context, _: &mut eframe::Frame) {

FILE: alvr/dashboard/src/data_sources.rs
  constant LOCAL_REQUEST_TIMEOUT (line 26) | const LOCAL_REQUEST_TIMEOUT: Duration = Duration::from_millis(200);
  constant REMOTE_REQUEST_TIMEOUT (line 27) | const REMOTE_REQUEST_TIMEOUT: Duration = Duration::from_secs(2);
  type SessionSource (line 29) | enum SessionSource {
  function get_local_session_source (line 34) | fn get_local_session_source() -> ServerSessionManager {
  function clean_session (line 39) | pub fn clean_session() {
  function get_read_only_local_session (line 79) | pub fn get_read_only_local_session() -> Arc<ServerSessionManager> {
  function report_event_local (line 83) | fn report_event_local(
  function report_session_local (line 100) | fn report_session_local(
  type PolledEvent (line 112) | pub struct PolledEvent {
  type DataSources (line 117) | pub struct DataSources {
    method new (line 129) | pub fn new(
    method request (line 529) | pub fn request(&self, request: ServerRequest) {
    method poll_event (line 533) | pub fn poll_event(&self) -> Option<PolledEvent> {
    method server_connected (line 537) | pub fn server_connected(&self) -> bool {
  method drop (line 543) | fn drop(&mut self) {

FILE: alvr/dashboard/src/data_sources_wasm.rs
  type DataSources (line 7) | pub struct DataSources {
    method new (line 13) | pub fn new(context: egui::Context) -> Self {
    method request (line 20) | pub fn request(&self, request: ServerRequest) {
    method poll_event (line 34) | pub fn poll_event(&mut self) -> Option<Event> {
    method server_connected (line 64) | pub fn server_connected(&self) -> bool {

FILE: alvr/dashboard/src/linux_checks.rs
  function audio_check (line 1) | pub fn audio_check() {

FILE: alvr/dashboard/src/logging_backend.rs
  function init_logging (line 9) | pub fn init_logging(event_sender: mpsc::Sender<PolledEvent>) {

FILE: alvr/dashboard/src/main.rs
  function get_filesystem_layout (line 26) | fn get_filesystem_layout() -> afs::Layout {
  function main (line 31) | fn main() {
  function main (line 117) | fn main() {

FILE: alvr/dashboard/src/steamvr_launcher/linux_steamvr.rs
  function launch_steamvr_with_steam (line 9) | pub fn launch_steamvr_with_steam() {
  function terminate_process (line 16) | pub fn terminate_process(process: &Process) {
  function maybe_wrap_vrcompositor_launcher (line 20) | pub fn maybe_wrap_vrcompositor_launcher() -> alvr_common::anyhow::Result...
  type DeviceInfo (line 58) | enum DeviceInfo {
  function linux_hardware_checks (line 65) | pub fn linux_hardware_checks() {
  function linux_gpu_checks (line 96) | fn linux_gpu_checks(device_infos: &[(&wgpu::Adapter, DeviceInfo)]) {
  function linux_encoder_checks (line 215) | fn linux_encoder_checks(device_infos: &[(&wgpu::Adapter, DeviceInfo)]) {
  function probe_nvenc_encoder_profile (line 294) | fn probe_nvenc_encoder_profile(
  function probe_libva_encoder_profile (line 315) | fn probe_libva_encoder_profile(

FILE: alvr/dashboard/src/steamvr_launcher/mod.rs
  constant SHUTDOWN_TIMEOUT (line 27) | const SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(10);
  constant DRIVER_KEY (line 28) | const DRIVER_KEY: &str = "driver_alvr_server";
  constant BLOCKED_KEY (line 29) | const BLOCKED_KEY: &str = "blocked_by_safe_mode";
  function is_steamvr_running (line 31) | pub fn is_steamvr_running() -> bool {
  function maybe_kill_steamvr (line 38) | pub fn maybe_kill_steamvr() {
  function unblock_alvr_driver (line 68) | fn unblock_alvr_driver() -> Result<()> {
  function unblock_alvr_driver_within_vrsettings (line 84) | fn unblock_alvr_driver_within_vrsettings(text: &str) -> Result<String> {
  type Launcher (line 111) | pub struct Launcher {
    method launch_steamvr (line 116) | pub fn launch_steamvr(&self) {
    method ensure_steamvr_shutdown (line 203) | pub fn ensure_steamvr_shutdown(&self) {
    method restart_steamvr (line 213) | pub fn restart_steamvr(&self) {

FILE: alvr/dashboard/src/steamvr_launcher/windows_steamvr.rs
  constant CREATE_NO_WINDOW (line 4) | const CREATE_NO_WINDOW: u32 = 0x0800_0000;
  function launch_steamvr_with_steam (line 6) | pub fn launch_steamvr_with_steam() {
  function kill_process (line 14) | pub fn kill_process(pid: u32) {

FILE: alvr/events/src/lib.rs
  type StatisticsSummary (line 8) | pub struct StatisticsSummary {
  type BitrateDirectives (line 25) | pub struct BitrateDirectives {
  type GraphStatistics (line 36) | pub struct GraphStatistics {
  type TrackingEvent (line 54) | pub struct TrackingEvent {
  type ButtonEvent (line 61) | pub struct ButtonEvent {
  type HapticsEvent (line 67) | pub struct HapticsEvent {
  type AdbEvent (line 75) | pub struct AdbEvent {
  type EventType (line 81) | pub enum EventType {
  type Event (line 97) | pub struct Event {
    method event_type_string (line 103) | pub fn event_type_string(&self) -> String {
    method message (line 125) | pub fn message(&self) -> String {
  function send_event (line 142) | pub fn send_event(event_type: EventType) {

FILE: alvr/filesystem/build.rs
  function main (line 2) | fn main() {}

FILE: alvr/filesystem/src/lib.rs
  function exec_fname (line 9) | pub fn exec_fname(name: &str) -> String {
  function dynlib_fname (line 13) | pub fn dynlib_fname(name: &str) -> String {
  function target_dir (line 17) | pub fn target_dir() -> PathBuf {
  function workspace_dir (line 31) | pub fn workspace_dir() -> PathBuf {
  function crate_dir (line 40) | pub fn crate_dir(name: &str) -> PathBuf {
  function deps_dir (line 47) | pub fn deps_dir() -> PathBuf {
  function build_dir (line 51) | pub fn build_dir() -> PathBuf {
  function streamer_build_dir (line 55) | pub fn streamer_build_dir() -> PathBuf {
  function launcher_fname (line 59) | pub fn launcher_fname() -> String {
  function launcher_build_dir (line 63) | pub fn launcher_build_dir() -> PathBuf {
  function launcher_build_exe_path (line 67) | pub fn launcher_build_exe_path() -> PathBuf {
  function installer_path (line 71) | pub fn installer_path() -> PathBuf {
  function dashboard_fname (line 75) | pub fn dashboard_fname() -> &'static str {
  type Layout (line 85) | pub struct Layout {
    method new (line 112) | pub fn new(root: &Path) -> Self {
    method dashboard_exe (line 176) | pub fn dashboard_exe(&self) -> PathBuf {
    method local_adb_exe (line 180) | pub fn local_adb_exe(&self) -> PathBuf {
    method resources_dir (line 186) | pub fn resources_dir(&self) -> PathBuf {
    method dashboard_dir (line 190) | pub fn dashboard_dir(&self) -> PathBuf {
    method presets_dir (line 194) | pub fn presets_dir(&self) -> PathBuf {
    method session (line 198) | pub fn session(&self) -> PathBuf {
    method session_log (line 202) | pub fn session_log(&self) -> PathBuf {
    method server_start_script (line 210) | pub fn server_start_script(&self) -> PathBuf {
    method connect_script (line 218) | pub fn connect_script(&self) -> PathBuf {
    method disconnect_script (line 226) | pub fn disconnect_script(&self) -> PathBuf {
    method crash_log (line 234) | pub fn crash_log(&self) -> PathBuf {
    method openvr_driver_lib_dir (line 238) | pub fn openvr_driver_lib_dir(&self) -> PathBuf {
    method openvr_driver_lib (line 253) | pub fn openvr_driver_lib(&self) -> PathBuf {
    method openvr_driver_manifest (line 259) | pub fn openvr_driver_manifest(&self) -> PathBuf {
    method vrcompositor_wrapper (line 263) | pub fn vrcompositor_wrapper(&self) -> PathBuf {
    method drm_lease_shim (line 267) | pub fn drm_lease_shim(&self) -> PathBuf {
    method vulkan_layer (line 271) | pub fn vulkan_layer(&self) -> PathBuf {
    method firewall_script (line 275) | pub fn firewall_script(&self) -> PathBuf {
    method firewalld_config (line 279) | pub fn firewalld_config(&self) -> PathBuf {
    method ufw_config (line 283) | pub fn ufw_config(&self) -> PathBuf {
    method vulkan_layer_manifest (line 287) | pub fn vulkan_layer_manifest(&self) -> PathBuf {
    method launcher_exe (line 291) | pub fn launcher_exe(&self) -> Option<PathBuf> {
  function layout_from_env (line 298) | fn layout_from_env() -> Option<Layout> {
  function filesystem_layout_from_dashboard_exe (line 304) | pub fn filesystem_layout_from_dashboard_exe(path: &Path) -> Option<Layou...
  function filesystem_layout_from_openvr_driver_root_dir (line 318) | pub fn filesystem_layout_from_openvr_driver_root_dir(dir: &Path) -> Opti...
  function filesystem_layout_invalid (line 334) | pub fn filesystem_layout_invalid() -> Layout {

FILE: alvr/graphics/src/lib.rs
  constant SDR_FORMAT (line 20) | pub const SDR_FORMAT: TextureFormat = TextureFormat::Rgba8Unorm;
  constant SDR_FORMAT_GL (line 21) | pub const SDR_FORMAT_GL: u32 = gl::RGBA8;
  constant GL_TEXTURE_EXTERNAL_OES (line 22) | pub const GL_TEXTURE_EXTERNAL_OES: u32 = 0x8D65;
  constant MAX_PUSH_CONSTANTS_SIZE (line 23) | pub const MAX_PUSH_CONSTANTS_SIZE: u32 = 128;
  type CreateImageFn (line 25) | type CreateImageFn = unsafe extern "C" fn(
  type DestroyImageFn (line 32) | type DestroyImageFn = unsafe extern "C" fn(egl::EGLDisplay, egl::EGLImag...
  type GetNativeClientBufferFn (line 33) | type GetNativeClientBufferFn = unsafe extern "C" fn(*const c_void) -> eg...
  type ImageTargetTexture2DFn (line 34) | type ImageTargetTexture2DFn = unsafe extern "C" fn(egl::Enum, egl::EGLIm...
  type HandData (line 36) | pub struct HandData {
  function check_error (line 42) | pub fn check_error(gl: &gl::Context, message_context: &str) {
  function projection_from_fov (line 62) | fn projection_from_fov(fov: Fov) -> Mat4 {
  function choose_swapchain_format (line 85) | pub fn choose_swapchain_format(supported_formats: &[u32], enable_hdr: bo...
  function gl_format_to_wgpu (line 105) | pub fn gl_format_to_wgpu(format: u32) -> TextureFormat {
  function create_texture (line 114) | pub fn create_texture(device: &Device, resolution: UVec2, format: Textur...
  function create_texture_from_gles (line 132) | fn create_texture_from_gles(
  function create_texture_from_gles (line 186) | fn create_texture_from_gles(_: &Device, _: u32, _: UVec2, _: TextureForm...
  function create_gl_swapchain (line 191) | pub fn create_gl_swapchain(
  type GraphicsContext (line 206) | pub struct GraphicsContext {
    method new_gl (line 230) | pub fn new_gl() -> Self {
    method new_gl (line 351) | pub fn new_gl() -> Self {
    method make_current (line 355) | pub fn make_current(&self) {
    method render_ahardwarebuffer_using_texture (line 381) | pub unsafe fn render_ahardwarebuffer_using_texture(
  method default (line 423) | fn default() -> Self {

FILE: alvr/graphics/src/lobby.rs
  constant TRANSFORM_CONST_SIZE (line 24) | const TRANSFORM_CONST_SIZE: u32 = mem::size_of::<Mat4>() as u32;
  constant OBJECT_TYPE_CONST_SIZE (line 25) | const OBJECT_TYPE_CONST_SIZE: u32 = mem::size_of::<u32>() as u32;
  constant FLOOR_SIDE_CONST_SIZE (line 26) | const FLOOR_SIDE_CONST_SIZE: u32 = mem::size_of::<f32>() as u32;
  constant COLOR_CONST_SIZE (line 27) | const COLOR_CONST_SIZE: u32 = mem::size_of::<u32>() as u32;
  constant QUAD_PUSH_CONTANTS_SIZE (line 29) | const QUAD_PUSH_CONTANTS_SIZE: u32 =
  constant LINE_PUSH_CONTANTS_SIZE (line 31) | const LINE_PUSH_CONTANTS_SIZE: u32 = TRANSFORM_CONST_SIZE + COLOR_CONST_...
  constant _ (line 32) | const _: () = assert!(
  constant TRANSFORM_CONST_OFFSET (line 38) | const TRANSFORM_CONST_OFFSET: u32 = 0;
  constant OBJECT_TYPE_CONST_OFFSET (line 39) | const OBJECT_TYPE_CONST_OFFSET: u32 = TRANSFORM_CONST_SIZE;
  constant FLOOR_SIDE_CONST_OFFSET (line 40) | const FLOOR_SIDE_CONST_OFFSET: u32 = OBJECT_TYPE_CONST_OFFSET + OBJECT_T...
  constant COLOR_CONST_OFFSET (line 41) | const COLOR_CONST_OFFSET: u32 = TRANSFORM_CONST_SIZE;
  constant FLOOR_SIDE (line 43) | const FLOOR_SIDE: f32 = 300.0;
  constant HUD_DIST (line 44) | const HUD_DIST: f32 = 5.0;
  constant HUD_SIDE (line 45) | const HUD_SIDE: f32 = 3.5;
  constant HUD_TEXTURE_SIDE (line 46) | const HUD_TEXTURE_SIDE: usize = 1024;
  constant FONT_SIZE (line 47) | const FONT_SIZE: f32 = 50.0;
  constant FAST_BORDER_OFFSETS (line 49) | const FAST_BORDER_OFFSETS: [IVec2; 8] = [
  constant MAX_BORDER_OFFSET (line 59) | const MAX_BORDER_OFFSET: i32 = 3;
  constant HAND_SKELETON_BONES (line 61) | const HAND_SKELETON_BONES: [(usize, usize); 19] = [
  constant BODY_JOINT_RELATIONS_FB (line 88) | const BODY_JOINT_RELATIONS_FB: [(usize, usize); 30] = [
  constant BODY_JOINT_RELATIONS_BD (line 126) | const BODY_JOINT_RELATIONS_BD: [(usize, usize); 23] = [
  function create_pipeline (line 157) | fn create_pipeline(
  type LobbyViewParams (line 215) | pub struct LobbyViewParams {
  type LobbyRenderer (line 220) | pub struct LobbyRenderer {
    method new (line 230) | pub fn new(
    method update_hud_message (line 323) | pub fn update_hud_message(&self, message: &str) {
    method render (line 403) | pub fn render(

FILE: alvr/graphics/src/staging.rs
  function create_program (line 7) | fn create_program(
  type StagingRenderer (line 51) | pub struct StagingRenderer {
    method new (line 61) | pub fn new(
    method render (line 120) | pub fn render(&self, hardware_buffer: *mut c_void) {
  method drop (line 151) | fn drop(&mut self) {

FILE: alvr/graphics/src/stream.rs
  constant FLOAT_SIZE (line 18) | const FLOAT_SIZE: u32 = mem::size_of::<f32>() as u32;
  constant U32_SIZE (line 19) | const U32_SIZE: u32 = mem::size_of::<u32>() as u32;
  constant VEC4_SIZE (line 20) | const VEC4_SIZE: u32 = mem::size_of::<Vec4>() as u32;
  constant TRANSFORM_SIZE (line 21) | const TRANSFORM_SIZE: u32 = mem::size_of::<Mat4>() as u32;
  constant TRANSFORM_CONST_OFFSET (line 23) | const TRANSFORM_CONST_OFFSET: u32 = 0;
  constant VIEW_INDEX_CONST_OFFSET (line 24) | const VIEW_INDEX_CONST_OFFSET: u32 = TRANSFORM_SIZE;
  constant PASSTHROUGH_MODE_OFFSET (line 25) | const PASSTHROUGH_MODE_OFFSET: u32 = VIEW_INDEX_CONST_OFFSET + U32_SIZE;
  constant ALPHA_CONST_OFFSET (line 26) | const ALPHA_CONST_OFFSET: u32 = PASSTHROUGH_MODE_OFFSET + U32_SIZE;
  constant CK_CHANNEL0_CONST_OFFSET (line 27) | const CK_CHANNEL0_CONST_OFFSET: u32 = ALPHA_CONST_OFFSET + FLOAT_SIZE + ...
  constant CK_CHANNEL1_CONST_OFFSET (line 28) | const CK_CHANNEL1_CONST_OFFSET: u32 = CK_CHANNEL0_CONST_OFFSET + VEC4_SIZE;
  constant CK_CHANNEL2_CONST_OFFSET (line 29) | const CK_CHANNEL2_CONST_OFFSET: u32 = CK_CHANNEL1_CONST_OFFSET + VEC4_SIZE;
  constant PUSH_CONSTANTS_SIZE (line 30) | const PUSH_CONSTANTS_SIZE: u32 = CK_CHANNEL2_CONST_OFFSET + VEC4_SIZE;
  constant _ (line 32) | const _: () = assert!(
  type StreamViewParams (line 37) | pub struct StreamViewParams {
  type ViewObjects (line 44) | struct ViewObjects {
  type StreamRenderer (line 49) | pub struct StreamRenderer {
    method new (line 59) | pub fn new(
    method render (line 246) | pub fn render(
  function set_passthrough_push_constants (line 337) | fn set_passthrough_push_constants(render_pass: &mut RenderPass, config: ...
  function foveated_encoding_shader_constants (line 440) | pub fn foveated_encoding_shader_constants(
  function compute_target_view_resolution (line 520) | pub fn compute_target_view_resolution(

FILE: alvr/gui_common/src/basic_components/button_group.rs
  function button_group_clicked (line 5) | pub fn button_group_clicked(

FILE: alvr/gui_common/src/basic_components/modal.rs
  type ModalButton (line 5) | pub enum ModalButton {
  method fmt (line 13) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  function modal (line 23) | pub fn modal(

FILE: alvr/gui_common/src/basic_components/switch.rs
  function switch (line 4) | pub fn switch(ui: &mut Ui, on: &mut bool) -> Response {

FILE: alvr/gui_common/src/lib.rs
  function get_id (line 8) | pub fn get_id() -> usize {
  type DisplayString (line 15) | pub struct DisplayString {
    method from (line 21) | fn from((id, display): (String, String)) -> Self {
  type Target (line 27) | type Target = String;
  method deref (line 29) | fn deref(&self) -> &String {

FILE: alvr/gui_common/src/theme.rs
  constant ACCENT (line 3) | pub const ACCENT: Color32 = Color32::from_rgb(0, 76, 176);
  constant BG (line 4) | pub const BG: Color32 = Color32::from_rgb(30, 30, 30);
  constant LIGHTER_BG (line 5) | pub const LIGHTER_BG: Color32 = Color32::from_rgb(36, 36, 36);
  constant SECTION_BG (line 6) | pub const SECTION_BG: Color32 = Color32::from_rgb(36, 36, 36);
  constant DARKER_BG (line 7) | pub const DARKER_BG: Color32 = Color32::from_rgb(26, 26, 26);
  constant SEPARATOR_BG (line 8) | pub const SEPARATOR_BG: Color32 = Color32::from_rgb(69, 69, 69);
  constant FG (line 9) | pub const FG: Color32 = Color32::from_rgb(250, 250, 250);
  constant SCROLLBAR_DOT_DIAMETER (line 10) | pub const SCROLLBAR_DOT_DIAMETER: f32 = 20.0;
  constant SWITCH_DOT_DIAMETER (line 11) | pub const SWITCH_DOT_DIAMETER: f32 = SCROLLBAR_DOT_DIAMETER;
  constant FRAME_PADDING (line 12) | pub const FRAME_PADDING: f32 = 10.0;
  constant CORNER_RADIUS (line 13) | pub const CORNER_RADIUS: u8 = 10;
  constant FRAME_TEXT_SPACING (line 14) | pub const FRAME_TEXT_SPACING: f32 = 5.0;
  constant OK_GREEN (line 16) | pub const OK_GREEN: Color32 = Color32::GREEN;
  constant KO_RED (line 17) | pub const KO_RED: Color32 = Color32::RED;
  constant ERROR_LIGHT (line 22) | pub const ERROR_LIGHT: Color32 = Color32::from_rgb(255, 50, 50);
  constant WARNING_LIGHT (line 23) | pub const WARNING_LIGHT: Color32 = Color32::from_rgb(205, 147, 9);
  constant INFO_LIGHT (line 24) | pub const INFO_LIGHT: Color32 = Color32::from_rgb(134, 171, 241);
  constant DEBUG_LIGHT (line 25) | pub const DEBUG_LIGHT: Color32 = Color32::LIGHT_GRAY;
  constant EVENT_LIGHT (line 26) | pub const EVENT_LIGHT: Color32 = Color32::GRAY;
  constant RENDER_EXTERNAL (line 34) | pub const RENDER_EXTERNAL: Color32 = Color32::from_rgb(64, 64, 64);
  constant RENDER_EXTERNAL_LABEL (line 35) | pub const RENDER_EXTERNAL_LABEL: Color32 = Color32::GRAY;
  constant RENDER (line 36) | pub const RENDER: Color32 = Color32::RED;
  constant IDLE (line 37) | pub const IDLE: Color32 = Color32::from_rgb(255, 217, 61);
  constant TRANSCODE (line 38) | pub const TRANSCODE: Color32 = Color32::from_rgb(107, 203, 119);
  constant NETWORK (line 39) | pub const NETWORK: Color32 = Color32::from_rgb(77, 150, 255);
  constant SERVER_FPS (line 41) | pub const SERVER_FPS: Color32 = Color32::LIGHT_BLUE;
  constant CLIENT_FPS (line 42) | pub const CLIENT_FPS: Color32 = Color32::KHAKI;
  constant INITIAL_CALCULATED_THROUGHPUT (line 44) | pub const INITIAL_CALCULATED_THROUGHPUT: Color32 = Color32::GRAY;
  constant ENCODER_DECODER_LATENCY_LIMITER (line 45) | pub const ENCODER_DECODER_LATENCY_LIMITER: Color32 = TRANSCODE;
  constant NETWORK_LATENCY_LIMITER (line 46) | pub const NETWORK_LATENCY_LIMITER: Color32 = NETWORK;
  constant MIN_MAX_LATENCY_THROUGHPUT (line 47) | pub const MIN_MAX_LATENCY_THROUGHPUT: Color32 = Color32::RED;
  constant REQUESTED_BITRATE (line 48) | pub const REQUESTED_BITRATE: Color32 = Color32::GREEN;
  constant RECORDED_THROUGHPUT (line 49) | pub const RECORDED_THROUGHPUT: Color32 = Color32::KHAKI;
  constant RECORDED_BITRATE (line 50) | pub const RECORDED_BITRATE: Color32 = super::FG;
  function set_theme (line 53) | pub fn set_theme(ctx: &Context) {

FILE: alvr/launcher/build.rs
  function main (line 2) | fn main() {
  function main (line 9) | fn main() {}

FILE: alvr/launcher/src/actions.rs
  constant APK_NAME (line 17) | const APK_NAME: &str = "client.apk";
  function installations_dir (line 19) | pub fn installations_dir() -> PathBuf {
  function worker (line 23) | pub fn worker(
  function fetch_all_releases (line 78) | async fn fetch_all_releases(client: &reqwest::Client) -> Result<ReleaseC...
  function fetch_releases_for_repo (line 93) | async fn fetch_releases_for_repo(client: &reqwest::Client, url: &str) ->...
  function get_release (line 116) | pub fn get_release(
  function install_and_launch_apk (line 134) | fn install_and_launch_apk(
  function download (line 212) | async fn download(
  function install_server (line 242) | async fn install_server(
  function data_dir (line 312) | pub fn data_dir() -> PathBuf {
  function get_installations (line 325) | pub fn get_installations() -> Vec<InstallationInfo> {
  function launch_dashboard (line 366) | pub fn launch_dashboard(version: &str) -> Result<()> {
  function delete_installation (line 382) | pub fn delete_installation(version: &str) -> Result<()> {

FILE: alvr/launcher/src/main.rs
  type ReleaseChannelsInfo (line 9) | pub struct ReleaseChannelsInfo {
  type Progress (line 14) | pub struct Progress {
  type WorkerMessage (line 19) | pub enum WorkerMessage {
  type ReleaseInfo (line 27) | pub struct ReleaseInfo {
  type UiMessage (line 32) | pub enum UiMessage {
  type InstallationInfo (line 41) | pub struct InstallationInfo {
  function main (line 47) | fn main() {

FILE: alvr/launcher/src/ui.rs
  type State (line 16) | enum State {
  type PopupType (line 23) | enum PopupType {
  type ReleaseChannelType (line 35) | enum ReleaseChannelType {
  type Version (line 41) | struct Version {
  type Launcher (line 46) | pub struct Launcher {
    method new (line 56) | pub fn new(
    method version_popup (line 73) | fn version_popup(
    method edit_popup (line 223) | fn edit_popup(&self, ctx: &Context, version: String) -> PopupType {
    method delete_popup (line 246) | fn delete_popup(&mut self, ctx: &Context, version: String) -> PopupType {
    method update (line 282) | fn update(&mut self, ctx: &Context, _: &mut eframe::Frame) {

FILE: alvr/packets/src/lib.rs
  constant TRACKING (line 20) | pub const TRACKING: u16 = 0;
  constant HAPTICS (line 21) | pub const HAPTICS: u16 = 1;
  constant AUDIO (line 22) | pub const AUDIO: u16 = 2;
  constant VIDEO (line 23) | pub const VIDEO: u16 = 3;
  constant STATISTICS (line 24) | pub const STATISTICS: u16 = 4;
  type VideoStreamingCapabilitiesExt (line 27) | pub struct VideoStreamingCapabilitiesExt {
  type VideoStreamingCapabilities (line 32) | pub struct VideoStreamingCapabilities {
    method with_ext (line 48) | pub fn with_ext(self, ext: VideoStreamingCapabilitiesExt) -> Self {
    method ext (line 55) | pub fn ext(&self) -> Result<VideoStreamingCapabilitiesExt> {
  type ConnectionAcceptedInfo (line 65) | pub struct ConnectionAcceptedInfo {
  type ClientConnectionResult (line 73) | pub enum ClientConnectionResult {
  type NegotiatedStreamingConfigExt (line 79) | pub struct NegotiatedStreamingConfigExt {
  type NegotiatedStreamingConfig (line 84) | pub struct NegotiatedStreamingConfig {
    method with_ext (line 96) | pub fn with_ext(self, ext: NegotiatedStreamingConfigExt) -> Self {
    method ext (line 103) | pub fn ext(&self) -> Result<NegotiatedStreamingConfigExt> {
  type StreamConfigPacket (line 113) | pub struct StreamConfigPacket {
    method new (line 126) | pub fn new(session: &SessionConfig, negotiated: NegotiatedStreamingCon...
    method to_stream_config (line 133) | pub fn to_stream_config(self) -> Result<StreamConfig> {
  type StreamConfig (line 119) | pub struct StreamConfig {
  type DecoderInitializationConfig (line 147) | pub struct DecoderInitializationConfig {
  type ServerControlPacket (line 154) | pub enum ServerControlPacket {
  type BatteryInfo (line 165) | pub struct BatteryInfo {
  type ButtonValue (line 172) | pub enum ButtonValue {
  type ButtonEntry (line 178) | pub struct ButtonEntry {
  type ClientControlPacket (line 184) | pub enum ClientControlPacket {
  type FaceExpressions (line 207) | pub enum FaceExpressions {
  type FaceData (line 217) | pub struct FaceData {
  type TrackingData (line 227) | pub struct TrackingData {
  type VideoPacketHeader (line 236) | pub struct VideoPacketHeader {
  type Haptics (line 243) | pub struct Haptics {
  type PathSegment (line 251) | pub enum PathSegment {
    method from (line 266) | fn from(value: &str) -> Self {
    method from (line 272) | fn from(value: String) -> Self {
    method from (line 278) | fn from(value: usize) -> Self {
  method fmt (line 257) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  function parse_path (line 284) | pub fn parse_path(path: &str) -> Vec<PathSegment> {
  type ClientConnectionsAction (line 289) | pub enum ClientConnectionsAction {
  type ClientStatistics (line 303) | pub struct ClientStatistics {
  type PathValuePair (line 314) | pub struct PathValuePair {
  type FirewallRulesAction (line 320) | pub enum FirewallRulesAction {
  type RealTimeConfig (line 328) | pub struct RealTimeConfig {
    method from_settings (line 337) | pub fn from_settings(settings: &Settings) -> Self {

FILE: alvr/server_core/src/bitrate.rs
  constant UPDATE_INTERVAL (line 11) | const UPDATE_INTERVAL: Duration = Duration::from_secs(1);
  type DynamicEncoderParams (line 13) | pub struct DynamicEncoderParams {
  type BitrateManager (line 18) | pub struct BitrateManager {
    method new (line 36) | pub fn new(max_history_size: usize, initial_framerate: f32) -> Self {
    method report_frame_present (line 64) | pub fn report_frame_present(&mut self, config: &Switch<BitrateAdaptive...
    method report_frame_encoded (line 86) | pub fn report_frame_encoded(
    method report_frame_latencies (line 99) | pub fn report_frame_latencies(
    method get_encoder_params (line 148) | pub fn get_encoder_params(

FILE: alvr/server_core/src/c_api.rs
  type AlvrDeviceMotion (line 28) | pub struct AlvrDeviceMotion {
  type AlvrHandType (line 35) | pub enum AlvrHandType {
  type AlvrButtonEntry (line 48) | pub struct AlvrButtonEntry {
  type AlvrBatteryInfo (line 54) | pub struct AlvrBatteryInfo {
  type AlvrEvent (line 62) | pub enum AlvrEvent {
  type AlvrTargetConfig (line 78) | pub struct AlvrTargetConfig {
  type AlvrDeviceConfig (line 86) | pub struct AlvrDeviceConfig {
  type AlvrDynamicEncoderParams (line 92) | pub struct AlvrDynamicEncoderParams {
  function string_to_c_str (line 97) | fn string_to_c_str(buffer: *mut c_char, value: &str) -> u64 {
  function alvr_get_time_ns (line 111) | pub extern "C" fn alvr_get_time_ns() -> u64 {
  function alvr_path_to_id (line 118) | pub unsafe extern "C" fn alvr_path_to_id(path_string: *const c_char) -> ...
  function alvr_error (line 123) | pub unsafe extern "C" fn alvr_error(string_ptr: *const c_char) {
  function log (line 127) | pub unsafe fn log(level: log::Level, string_ptr: *const c_char) {
  function alvr_warn (line 136) | pub unsafe extern "C" fn alvr_warn(string_ptr: *const c_char) {
  function alvr_info (line 141) | pub unsafe extern "C" fn alvr_info(string_ptr: *const c_char) {
  function alvr_dbg_server_impl (line 146) | pub unsafe extern "C" fn alvr_dbg_server_impl(string_ptr: *const c_char) {
  function alvr_dbg_encoder (line 154) | pub unsafe extern "C" fn alvr_dbg_encoder(string_ptr: *const c_char) {
  function alvr_log_periodically (line 163) | pub unsafe extern "C" fn alvr_log_periodically(tag_ptr: *const c_char, m...
  function alvr_get_settings_json (line 183) | pub extern "C" fn alvr_get_settings_json(buffer: *mut c_char) -> u64 {
  function alvr_initialize_environment (line 189) | pub unsafe extern "C" fn alvr_initialize_environment(
  function alvr_initialize_logging (line 207) | pub unsafe extern "C" fn alvr_initialize_logging(
  function alvr_initialize (line 227) | pub extern "C" fn alvr_initialize() -> AlvrTargetConfig {
  function alvr_start_connection (line 244) | pub extern "C" fn alvr_start_connection() {
  function alvr_poll_event (line 251) | pub unsafe extern "C" fn alvr_poll_event(out_event: *mut AlvrEvent, time...
  function alvr_get_device_motion (line 310) | pub unsafe extern "C" fn alvr_get_device_motion(
  function alvr_get_hand_skeleton (line 336) | pub unsafe extern "C" fn alvr_get_hand_skeleton(
  function alvr_get_buttons (line 363) | pub unsafe extern "C" fn alvr_get_buttons(out_entries: *mut AlvrButtonEn...
  function alvr_send_haptics (line 387) | pub extern "C" fn alvr_send_haptics(
  function alvr_set_video_config_nals (line 406) | pub unsafe extern "C" fn alvr_set_video_config_nals(
  function alvr_send_video_nal (line 428) | pub unsafe extern "C" fn alvr_send_video_nal(
  function alvr_get_dynamic_encoder_params (line 456) | pub unsafe extern "C" fn alvr_get_dynamic_encoder_params(
  function alvr_report_composed (line 474) | pub extern "C" fn alvr_report_composed(timestamp_ns: u64, offset_ns: u64) {
  function alvr_report_present (line 484) | pub extern "C" fn alvr_report_present(timestamp_ns: u64, offset_ns: u64) {
  function alvr_duration_until_next_vsync (line 495) | pub unsafe extern "C" fn alvr_duration_until_next_vsync(out_ns: *mut u64...
  function alvr_restart (line 508) | pub extern "C" fn alvr_restart() {
  function alvr_shutdown (line 515) | pub extern "C" fn alvr_shutdown() {

FILE: alvr/server_core/src/connection.rs
  constant RETRY_CONNECT_MIN_INTERVAL (line 43) | const RETRY_CONNECT_MIN_INTERVAL: Duration = Duration::from_secs(1);
  constant HANDSHAKE_ACTION_TIMEOUT (line 44) | const HANDSHAKE_ACTION_TIMEOUT: Duration = Duration::from_secs(2);
  constant STREAMING_RECV_TIMEOUT (line 45) | pub const STREAMING_RECV_TIMEOUT: Duration = Duration::from_millis(500);
  constant REAL_TIME_UPDATE_INTERVAL (line 46) | const REAL_TIME_UPDATE_INTERVAL: Duration = Duration::from_secs(1);
  constant MAX_UNREAD_PACKETS (line 48) | const MAX_UNREAD_PACKETS: usize = 10;
  type VideoPacket (line 50) | pub struct VideoPacket {
  function align32 (line 55) | fn align32(value: f32) -> u32 {
  function is_streaming (line 59) | fn is_streaming(client_hostname: &str) -> bool {
  function contruct_openvr_config (line 67) | pub fn contruct_openvr_config(session: &SessionConfig) -> OpenvrConfig {
  function handshake_loop (line 241) | pub fn handshake_loop(ctx: Arc<ConnectionContext>, lifecycle_state: Arc<...
  function try_connect (line 457) | fn try_connect(
  function connection_pipeline (line 506) | fn connection_pipeline(

FILE: alvr/server_core/src/hand_gestures.rs
  function lerp_pose (line 15) | fn lerp_pose(a: Pose, b: Pose, fac: f32) -> Pose {
  type HandGesture (line 51) | pub struct HandGesture {
  type GestureAction (line 59) | pub struct GestureAction {
  type HandGestureId (line 71) | pub enum HandGestureId {
  type HandGestureManager (line 89) | pub struct HandGestureManager {
    method new (line 95) | pub fn new() -> Self {
    method get_active_gestures (line 102) | pub fn get_active_gestures(
    method is_gesture_active (line 366) | fn is_gesture_active(
    method test_gesture_dist (line 450) | fn test_gesture_dist(
    method get_gesture_hover (line 462) | fn get_gesture_hover(
    method get_joystick_values (line 480) | fn get_joystick_values(
  function get_click_bind_for_gesture (line 501) | fn get_click_bind_for_gesture(device_id: u64, gesture_id: HandGestureId)...
  function get_touch_bind_for_gesture (line 524) | fn get_touch_bind_for_gesture(device_id: u64, gesture_id: HandGestureId)...
  function get_hover_bind_for_gesture (line 544) | fn get_hover_bind_for_gesture(device_id: u64, gesture_id: HandGestureId)...
  function trigger_hand_gesture_actions (line 564) | pub fn trigger_hand_gesture_actions(

FILE: alvr/server_core/src/haptics.rs
  function map_haptics (line 5) | pub fn map_haptics(config: &HapticsConfig, haptics: Haptics) -> Haptics {

FILE: alvr/server_core/src/input_mapping.rs
  function registered_button_set (line 9) | pub fn registered_button_set(
  type BindingTarget (line 50) | pub struct BindingTarget {
  type ButtonInputs (line 58) | pub struct ButtonInputs {
  function click (line 65) | fn click(click: u64) -> ButtonInputs {
  function ct (line 74) | fn ct(set: &HashSet<u64>, click: u64, touch: u64) -> ButtonInputs {
  function value (line 83) | fn value(value: u64) -> ButtonInputs {
  function ctv (line 92) | fn ctv(set: &HashSet<u64>, click: u64, touch: u64, value: u64) -> Button...
  function ctvf (line 101) | fn ctvf(set: &HashSet<u64>, click: u64, touch: u64, value: u64, force: u...
  function passthrough (line 110) | fn passthrough(target: u64) -> BindingTarget {
  function binary_to_scalar (line 118) | fn binary_to_scalar(target: u64, map: BinaryToScalarStates) -> BindingTa...
  function hysteresis_threshold (line 126) | fn hysteresis_threshold(target: u64, map: HysteresisThreshold) -> Bindin...
  function remap (line 134) | fn remap(target: u64, map: Range) -> BindingTarget {
  function map_button_pair_automatic (line 143) | fn map_button_pair_automatic(
  function automatic_bindings (line 243) | pub fn automatic_bindings(
  type ButtonMappingManager (line 561) | pub struct ButtonMappingManager {
    method new_automatic (line 568) | pub fn new_automatic(
    method new_manual (line 581) | pub fn new_manual(mappings: &[(String, Vec<ButtonBindingTarget>)]) -> ...
    method map_button (line 611) | pub fn map_button(&mut self, source_button: &ButtonEntry) -> Vec<Butto...

FILE: alvr/server_core/src/lib.rs
  function initialize_environment (line 66) | pub fn initialize_environment(layout: afs::Layout) {
  type ServerCoreEvent (line 73) | pub enum ServerCoreEvent {
  type ConnectionContext (line 95) | pub struct ConnectionContext {
  function create_recording_file (line 109) | pub fn create_recording_file(connection_context: &ConnectionContext, set...
  function notify_restart_driver (line 141) | pub fn notify_restart_driver() {
  function settings (line 153) | pub fn settings() -> Settings {
  function registered_button_set (line 157) | pub fn registered_button_set() -> HashSet<u64> {
  type ServerCoreContext (line 166) | pub struct ServerCoreContext {
    method new (line 175) | pub fn new() -> (Self, mpsc::Receiver<ServerCoreEvent>) {
    method start_connection (line 239) | pub fn start_connection(&self) {
    method get_device_motion (line 252) | pub fn get_device_motion(
    method get_hand_skeleton (line 265) | pub fn get_hand_skeleton(
    method get_motion_to_photon_latency (line 279) | pub fn get_motion_to_photon_latency(&self) -> Duration {
    method get_tracker_pose_time_offset (line 302) | pub fn get_tracker_pose_time_offset(&self) -> Duration {
    method send_haptics (line 313) | pub fn send_haptics(&self, haptics: Haptics) {
    method set_video_config_nals (line 349) | pub fn set_video_config_nals(&self, config_buffer: Vec<u8>, codec: Cod...
    method send_video_nal (line 367) | pub fn send_video_nal(
    method get_dynamic_encoder_params (line 457) | pub fn get_dynamic_encoder_params(&self) -> Option<DynamicEncoderParam...
    method report_composed (line 479) | pub fn report_composed(&self, target_timestamp: Duration, offset: Dura...
    method report_present (line 487) | pub fn report_present(&self, target_timestamp: Duration, offset: Durat...
    method duration_until_next_vsync (line 507) | pub fn duration_until_next_vsync(&self) -> Option<Duration> {
    method restart (line 517) | pub fn restart(self) {
  method drop (line 527) | fn drop(&mut self) {

FILE: alvr/server_core/src/logging_backend.rs
  function init_logging (line 13) | pub fn init_logging(session_log_path: Option<PathBuf>, crash_log_path: O...

FILE: alvr/server_core/src/sockets.rs
  type WelcomeSocket (line 10) | pub struct WelcomeSocket {
    method new (line 15) | pub fn new() -> Result<Self> {
    method recv_all (line 22) | pub fn recv_all(&self) -> Result<HashMap<String, IpAddr>> {

FILE: alvr/server_core/src/statistics.rs
  constant FULL_REPORT_INTERVAL (line 9) | const FULL_REPORT_INTERVAL: Duration = Duration::from_millis(500);
  constant EPS_INTERVAL (line 10) | const EPS_INTERVAL: Duration = Duration::from_micros(1);
  type HistoryFrame (line 12) | pub struct HistoryFrame {
  method default (line 23) | fn default() -> Self {
  type BatteryData (line 38) | struct BatteryData {
  type StatisticsManager (line 43) | pub struct StatisticsManager {
    method new (line 63) | pub fn new(
    method report_tracking_received (line 92) | pub fn report_tracking_received(&mut self, target_timestamp: Duration) {
    method report_frame_present (line 110) | pub fn report_frame_present(&mut self, target_timestamp: Duration, off...
    method report_frame_composed (line 126) | pub fn report_frame_composed(&mut self, target_timestamp: Duration, of...
    method report_frame_encoded (line 137) | pub fn report_frame_encoded(
    method report_battery (line 164) | pub fn report_battery(&mut self, device_id: u64, gauge_value: f32, is_...
    method report_throughput_stats (line 171) | pub fn report_throughput_stats(&mut self, stats: BitrateDirectives) {
    method report_statistics (line 177) | pub fn report_statistics(&mut self, client_stats: ClientStatistics) ->...
    method motion_to_photon_latency_average (line 290) | pub fn motion_to_photon_latency_average(&self) -> Duration {
    method tracker_pose_time_offset (line 294) | pub fn tracker_pose_time_offset(&self) -> Duration {
    method duration_until_next_vsync (line 300) | pub fn duration_until_next_vsync(&mut self) -> Duration {

FILE: alvr/server_core/src/tracking/body.rs
  constant CHEST_FB (line 11) | const CHEST_FB: usize = 5;
  constant HIPS_FB (line 12) | const HIPS_FB: usize = 1;
  constant LEFT_ARM_LOWER_FB (line 13) | const LEFT_ARM_LOWER_FB: usize = 11;
  constant RIGHT_ARM_LOWER_FB (line 14) | const RIGHT_ARM_LOWER_FB: usize = 16;
  constant LEFT_LOWER_LEG_META (line 15) | const LEFT_LOWER_LEG_META: usize = 1;
  constant LEFT_FOOT_BALL_META (line 16) | const LEFT_FOOT_BALL_META: usize = 6;
  constant RIGHT_LOWER_LEG_META (line 17) | const RIGHT_LOWER_LEG_META: usize = 8;
  constant RIGHT_FOOT_BALL_META (line 18) | const RIGHT_FOOT_BALL_META: usize = 13;
  constant PELVIS_BD (line 19) | const PELVIS_BD: usize = 0;
  constant LEFT_KNEE_BD (line 20) | const LEFT_KNEE_BD: usize = 4;
  constant RIGHT_KNEE_BD (line 21) | const RIGHT_KNEE_BD: usize = 5;
  constant SPINE3_BD (line 22) | const SPINE3_BD: usize = 9;
  constant LEFT_FOOT_BD (line 23) | const LEFT_FOOT_BD: usize = 10;
  constant RIGHT_FOOT_BD (line 24) | const RIGHT_FOOT_BD: usize = 11;
  constant LEFT_ELBOW_BD (line 25) | const LEFT_ELBOW_BD: usize = 18;
  constant RIGHT_ELBOW_BD (line 26) | const RIGHT_ELBOW_BD: usize = 19;
  type BodyTrackingSink (line 42) | pub struct BodyTrackingSink {
    method new (line 48) | pub fn new(config: BodyTrackingSinkConfig, local_osc_port: u16) -> Res...
    method send_osc_message (line 66) | fn send_osc_message(&self, path: &str, args: Vec<OscType>) {
    method send_tracking (line 80) | pub fn send_tracking(&self, device_motions: &[(u64, DeviceMotion)]) {
  function get_default_body_trackers_from_detached_controllers (line 108) | pub fn get_default_body_trackers_from_detached_controllers(
  function get_default_body_trackers_from_motion_trackers_bd (line 124) | pub fn get_default_body_trackers_from_motion_trackers_bd(
  function extract_default_trackers (line 143) | pub fn extract_default_trackers(skeleton: &BodySkeleton) -> Vec<(u64, De...

FILE: alvr/server_core/src/tracking/face.rs
  constant RAD_TO_DEG (line 7) | const RAD_TO_DEG: f32 = 180.0 / PI;
  constant VRCFT_PORT (line 9) | const VRCFT_PORT: u16 = 0xA1F7;
  type FaceTrackingSink (line 11) | pub struct FaceTrackingSink {
    method new (line 18) | pub fn new(config: FaceTrackingSinkConfig, local_osc_port: u16) -> Res...
    method send_osc_message (line 34) | fn send_osc_message(&self, path: &str, args: Vec<OscType>) {
    method append_packet_vrcft (line 46) | fn append_packet_vrcft(&mut self, prefix: [u8; 8], data: &[f32]) {
    method send_tracking (line 54) | pub fn send_tracking(&mut self, face_data: &FaceData) {

FILE: alvr/server_core/src/tracking/mod.rs
  constant DEG_TO_RAD (line 37) | const DEG_TO_RAD: f32 = PI / 180.0;
  type HandType (line 40) | pub enum HandType {
  type MotionConfig (line 47) | struct MotionConfig {
  type TrackingManager (line 54) | pub struct TrackingManager {
    method new (line 63) | pub fn new(max_history_size: usize) -> TrackingManager {
    method recenter (line 73) | pub fn recenter(
    method recenter_pose (line 112) | pub fn recenter_pose(&self, pose: Pose) -> Pose {
    method recenter_motion (line 116) | pub fn recenter_motion(&self, motion: DeviceMotion) -> DeviceMotion {
    method report_device_motions (line 121) | pub fn report_device_motions(
    method get_device_motion (line 199) | pub fn get_device_motion(
    method report_hand_skeleton (line 234) | pub fn report_hand_skeleton(
    method get_hand_skeleton (line 253) | pub fn get_hand_skeleton(
    method unrecenter_view_params (line 264) | pub fn unrecenter_view_params(&self, view_params: &mut [ViewParams; 2]) {
  function tracking_loop (line 271) | pub fn tracking_loop(

FILE: alvr/server_core/src/tracking/vmc.rs
  type VMCSink (line 80) | pub struct VMCSink {
    method new (line 85) | pub fn new(config: VMCConfig) -> Result<Self> {
    method send_osc_message (line 94) | fn send_osc_message(&self, path: &str, args: Vec<OscType>) {
    method send_hand_tracking (line 108) | pub fn send_hand_tracking(
    method send_tracking (line 144) | pub fn send_tracking(

FILE: alvr/server_core/src/web_server.rs
  constant X_ALVR (line 28) | const X_ALVR: &str = "X-ALVR";
  function ensure_preflight (line 36) | async fn ensure_preflight(request: Request, next: middleware::Next) -> R...
  function web_server (line 47) | pub async fn web_server(connection_context: Arc<ConnectionContext>) -> R...
  function events_websocket (line 133) | async fn events_websocket(ws: WebSocketUpgrade) -> Response {
  function set_log (line 155) | async fn set_log(Json(entry): Json<LogEntry>) {
  function get_session (line 160) | async fn get_session() {
  function update_session (line 166) | async fn update_session(Json(config): Json<SessionConfig>) {
  function set_session_values (line 170) | async fn set_session_values(Json(descs): Json<Vec<PathValuePair>>) {
  function update_client_connections (line 174) | async fn update_client_connections(
  function insert_idr (line 191) | async fn insert_idr(State(ctx): State<Arc<ConnectionContext>>) {
  function capture_frame (line 195) | async fn capture_frame(State(ctx): State<Arc<ConnectionContext>>) {
  function start_recording (line 199) | async fn start_recording(State(ctx): State<Arc<ConnectionContext>>) {
  function stop_recording (line 203) | async fn stop_recording(State(ctx): State<Arc<ConnectionContext>>) {
  function add_firewall_rules (line 207) | async fn add_firewall_rules() {
  function remove_firewall_rules (line 217) | async fn remove_firewall_rules() {
  function get_driver_list (line 228) | async fn get_driver_list() {
  function register_alvr_driver (line 234) | async fn register_alvr_driver() {
  function unregister_driver (line 250) | async fn unregister_driver(Json(path): Json<PathBuf>) {
  function restart_steamvr (line 258) | async fn restart_steamvr(State(ctx): State<Arc<ConnectionContext>>) {
  function shutdown_steamvr (line 262) | async fn shutdown_steamvr(State(ctx): State<Arc<ConnectionContext>>) {
  function set_buttons (line 268) | async fn set_buttons(

FILE: alvr/server_io/src/firewall.rs
  function netsh_add_rule_command_string (line 9) | fn netsh_add_rule_command_string(rule_name: &str, program_path: &Path) -...
  function netsh_delete_rule_command_string (line 17) | fn netsh_delete_rule_command_string(rule_name: &str) -> String {
  function firewall_rules (line 25) | pub fn firewall_rules(

FILE: alvr/server_io/src/lib.rs
  function save_session (line 26) | fn save_session(session: &SessionConfig, path: &Path) -> Result<()> {
  type SessionLock (line 33) | pub struct SessionLock<'a> {
  type Target (line 40) | type Target = SessionConfig;
  method deref (line 41) | fn deref(&self) -> &SessionConfig {
  method deref_mut (line 47) | fn deref_mut(&mut self) -> &mut SessionConfig {
  method drop (line 53) | fn drop(&mut self) {
  type ServerSessionManager (line 68) | pub struct ServerSessionManager {
    method new (line 75) | pub fn new(session_path: Option<PathBuf>) -> Self {
    method load_session (line 91) | fn load_session(session_path: &Path, config_dir: &Path) -> SessionConf...
    method session (line 139) | pub fn session(&self) -> &SessionConfig {
    method session_mut (line 143) | pub fn session_mut(&mut self) -> SessionLock<'_> {
    method settings (line 151) | pub fn settings(&self) -> &Settings {
    method set_session_values (line 156) | pub fn set_session_values(&mut self, descs: Vec<PathValuePair>) -> Res...
    method client_list (line 195) | pub fn client_list(&self) -> &HashMap<String, ClientConnectionConfig> {
    method update_client_connections (line 199) | pub fn update_client_connections(&mut self, hostname: String, action: ...
    method client_hostnames (line 281) | pub fn client_hostnames(&self) -> Vec<String> {
    method clean_client_list (line 290) | pub fn clean_client_list(&mut self) {
  method fmt (line 313) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

FILE: alvr/server_io/src/openvr_drivers.rs
  function get_registered_drivers (line 13) | pub fn get_registered_drivers() -> Result<Vec<PathBuf>> {
  function driver_registration (line 21) | pub fn driver_registration(driver_paths: &[PathBuf], register: bool) -> ...
  function get_driver_dir_from_registered (line 44) | pub fn get_driver_dir_from_registered() -> Result<PathBuf> {

FILE: alvr/server_io/src/openvrpaths.rs
  function openvr_source_file_path (line 13) | fn openvr_source_file_path() -> Result<PathBuf> {
  function steamvr_settings_file_path (line 29) | pub fn steamvr_settings_file_path() -> Result<PathBuf> {
  function load_openvr_paths_json (line 47) | pub fn load_openvr_paths_json() -> Result<json::Value> {
  function save_openvr_paths_json (line 58) | pub fn save_openvr_paths_json(openvr_paths: &json::Value) -> Result<()> {
  function from_openvr_paths (line 66) | pub fn from_openvr_paths(paths: &json::Value) -> Vec<std::path::PathBuf> {
  function to_openvr_paths (line 78) | pub fn to_openvr_paths(paths: &[PathBuf]) -> json::Value {
  function get_single_openvr_path (line 88) | fn get_single_openvr_path(path_type: &str) -> Result<PathBuf> {
  function steamvr_root_dir (line 94) | pub fn steamvr_root_dir() -> Result<PathBuf> {

FILE: alvr/server_openvr/build.rs
  function get_ffmpeg_path (line 3) | fn get_ffmpeg_path() -> PathBuf {
  function get_linux_x264_path (line 20) | fn get_linux_x264_path() -> PathBuf {
  function main (line 24) | fn main() {

FILE: alvr/server_openvr/cpp/ALVR-common/common-utils.cpp
  function ToWstring (line 6) | std::wstring ToWstring(const std::string& src) {
  function ToUTF8 (line 12) | std::string ToUTF8(const std::wstring& src) {

FILE: alvr/server_openvr/cpp/ALVR-common/exception.cpp
  function Exception (line 6) | Exception FormatExceptionV(const char* format, va_list args) {
  function Exception (line 12) | Exception FormatException(const char* format, ...) {

FILE: alvr/server_openvr/cpp/ALVR-common/exception.h
  function class (line 6) | class Exception : public std::exception {

FILE: alvr/server_openvr/cpp/ALVR-common/packet_types.h
  type ALVR_CODEC (line 7) | enum ALVR_CODEC {
  type ALVR_H264_PROFILE (line 13) | enum ALVR_H264_PROFILE {
  type ALVR_RATE_CONTROL_METHOD (line 19) | enum ALVR_RATE_CONTROL_METHOD {
  type ALVR_ENTROPY_CODING (line 24) | enum ALVR_ENTROPY_CODING {
  type ALVR_ENCODER_QUALITY_PRESET (line 29) | enum ALVR_ENCODER_QUALITY_PRESET { ALVR_QUALITY = 0, ALVR_BALANCED = 1, ...
  type ALVR_INPUT (line 31) | enum ALVR_INPUT {

FILE: alvr/server_openvr/cpp/alvr_server/ChaperoneUpdater.cpp
  type alvr_chaperone (line 9) | namespace alvr_chaperone {
  function InitOpenvrClient (line 19) | void InitOpenvrClient() {
  function ShutdownOpenvrClient (line 41) | void ShutdownOpenvrClient() {
  function IsOpenvrClientReady (line 56) | bool IsOpenvrClientReady() { return isOpenvrInit; }
  function _SetChaperoneArea (line 58) | void _SetChaperoneArea(float areaWidth, float areaHeight) {
  function GetInvZeroPose (line 103) | std::unique_ptr<vr::HmdMatrix34_t> GetInvZeroPose() {

FILE: alvr/server_openvr/cpp/alvr_server/Controller.cpp
  function GetThumbBoneTransform (line 430) | void GetThumbBoneTransform(
  function GetTriggerBoneTransform (line 492) | void GetTriggerBoneTransform(
  function GetGripClickBoneTransform (line 1027) | void GetGripClickBoneTransform(

FILE: alvr/server_openvr/cpp/alvr_server/Controller.h
  function class (line 8) | class Controller : public TrackedDevice {

FILE: alvr/server_openvr/cpp/alvr_server/FakeViveTracker.h
  function class (line 7) | class FakeViveTracker : public TrackedDevice {

FILE: alvr/server_openvr/cpp/alvr_server/HMD.h
  function virtual (line 64) | virtual bool activate() final;

FILE: alvr/server_openvr/cpp/alvr_server/IDRScheduler.h
  function class (line 7) | class IDRScheduler {

FILE: alvr/server_openvr/cpp/alvr_server/Logger.cpp
  function _log (line 8) | void _log(const char* format, va_list args, void (*logFn)(const char*), ...
  function Exception (line 22) | Exception MakeException(const char* format, ...) {
  function Error (line 31) | void Error(const char* format, ...) {
  function Warn (line 38) | void Warn(const char* format, ...) {
  function Info (line 45) | void Info(const char* format, ...) {
  function Debug (line 53) | void Debug(const char* format, ...) {
  function LogPeriod (line 64) | void LogPeriod(const char* tag, const char* format, ...) {

FILE: alvr/server_openvr/cpp/alvr_server/NalParsing.cpp
  function getNalPrefixSize (line 18) | int8_t getNalPrefixSize(unsigned char* buf) {
  function sendHeaders (line 33) | void sendHeaders(int codec, unsigned char*& buf, int& len, int nalNum) {
  function processH264Nals (line 69) | void processH264Nals(unsigned char*& buf, int& len) {
  function processHevcNals (line 84) | void processHevcNals(unsigned char*& buf, int& len) {
  function ParseFrameNals (line 99) | void ParseFrameNals(

FILE: alvr/server_openvr/cpp/alvr_server/Paths.cpp
  function init_paths (line 42) | void init_paths() {

FILE: alvr/server_openvr/cpp/alvr_server/Paths.h
  function ButtonType (line 47) | enum class ButtonType {

FILE: alvr/server_openvr/cpp/alvr_server/PoseHistory.h
  function class (line 10) | class PoseHistory {

FILE: alvr/server_openvr/cpp/alvr_server/Settings.h
  function class (line 6) | class Settings {

FILE: alvr/server_openvr/cpp/alvr_server/TrackedDevice.h
  function ActivationState (line 10) | enum class ActivationState {

FILE: alvr/server_openvr/cpp/alvr_server/Utils.h
  function GetTimestampUs (line 33) | inline uint64_t GetTimestampUs() {

FILE: alvr/server_openvr/cpp/alvr_server/ViveTrackerProxy.h
  function virtual (line 21) | virtual inline void Deactivate() override { m_unObjectId = vr::k_unTrack...
  function virtual (line 23) | virtual inline void EnterStandby() override { }
  function virtual (line 24) | virtual inline void* GetComponent(const char* /*pchComponentNameAndVersi...
  function virtual (line 29) | virtual inline void DebugRequest(

FILE: alvr/server_openvr/cpp/alvr_server/alvr_server.cpp
  function GetRawZeroPose (line 30) | std::unique_ptr<vr::HmdMatrix34_t> GetRawZeroPose() {
  function load_debug_privilege (line 45) | static void load_debug_privilege(void) {
  class DriverProvider (line 80) | class DriverProvider : public vr::IServerTrackedDeviceProvider {
    method Init (line 93) | virtual vr::EVRInitError Init(vr::IVRDriverContext* pContext) override {
    method Cleanup (line 110) | virtual void Cleanup() override {
    method RunFrame (line 128) | virtual void RunFrame() override {
    method ShouldBlockStandbyMode (line 172) | virtual bool ShouldBlockStandbyMode() override { return false; }
    method EnterStandby (line 173) | virtual void EnterStandby() override { Debug("DriverProvider::EnterSta...
    method LeaveStandby (line 174) | virtual void LeaveStandby() override { Debug("DriverProvider::LeaveSta...
  function CppInit (line 224) | void CppInit(bool earlyHmdInitialization) {
  function InitializeStreaming (line 247) | bool InitializeStreaming() {
  function DeinitializeStreaming (line 374) | void DeinitializeStreaming() {
  function SendVSync (line 380) | void SendVSync() { vr::VRServerDriverHost()->VsyncEvent(0.0); }
  function RequestIDR (line 382) | void RequestIDR() {
  function SetTracking (line 388) | void SetTracking(
  function RequestDriverResync (line 445) | void RequestDriverResync() {
  function ShutdownSteamvr (line 453) | void ShutdownSteamvr() {
  function SetOpenvrProperty (line 461) | void SetOpenvrProperty(void* instancePtr, FfiOpenvrProperty prop) {
  function SetOpenvrPropByDeviceID (line 465) | void SetOpenvrPropByDeviceID(unsigned long long deviceID, FfiOpenvrPrope...
  function RegisterButton (line 473) | void RegisterButton(void* instancePtr, unsigned long long buttonID) {
  function SetLocalViewParams (line 478) | void SetLocalViewParams(const FfiViewParams params[2]) {
  function SetBattery (line 484) | void SetBattery(unsigned long long deviceID, float gauge_value, bool is_...
  function SetButton (line 497) | void SetButton(unsigned long long buttonID, FfiButtonValue value) {
  function SetProximityState (line 516) | void SetProximityState(bool headset_is_worn) {
  function SetChaperoneArea (line 522) | void SetChaperoneArea(float areaWidth, float areaHeight) {
  function CaptureFrame (line 526) | void CaptureFrame() {

FILE: alvr/server_openvr/cpp/alvr_server/bindings.h
  type FfiFov (line 3) | struct FfiFov {
  type FfiQuat (line 10) | struct FfiQuat {
  type FfiPose (line 17) | struct FfiPose {
  type FfiDeviceMotion (line 22) | struct FfiDeviceMotion {
  type FfiViewParams (line 29) | struct FfiViewParams {
  type FfiHandSkeleton (line 34) | struct FfiHandSkeleton {
  type FfiHandData (line 39) | struct FfiHandData {
  type FfiOpenvrPropertyType (line 46) | enum FfiOpenvrPropertyType {
  type FfiOpenvrProperty (line 66) | struct FfiOpenvrProperty {
  type FfiButtonType (line 72) | enum FfiButtonType {
  type FfiButtonValue (line 77) | struct FfiButtonValue {
  type FfiDynamicEncoderParams (line 85) | struct FfiDynamicEncoderParams {

FILE: alvr/server_openvr/cpp/alvr_server/driverlog.cpp
  function InitDriverLog (line 14) | bool InitDriverLog(vr::IVRDriverLog* pDriverLog) {
  function CleanupDriverLog (line 21) | void CleanupDriverLog() { s_pLogFile = NULL; }
  function DriverLogVarArgs (line 23) | void DriverLogVarArgs(const char* pMsgFormat, va_list args) {
  function DriverLog (line 31) | void DriverLog(const char* pMsgFormat, ...) {
  function DebugDriverLog (line 40) | void DebugDriverLog(const char* pMsgFormat, ...) {

FILE: alvr/server_openvr/cpp/alvr_server/include/openvr_math.h
  function vr (line 26) | inline vr::HmdQuaternion_t operator*(const vr::HmdQuaternion_t& lhs, con...
  function vr (line 69) | inline vr::HmdVector3d_t operator*(const vr::HmdVector3d_t& lhs, const d...
  function vr (line 137) | inline vr::HmdQuaternion_t quaternionFromRotationMatrix(const vr::HmdMat...
  function vr (line 174) | inline vr::HmdQuaternion_t quaternionConjugate(const vr::HmdQuaternion_t...
  function vr (line 231) | inline vr::HmdMatrix34_t matMul33(const vr::HmdMatrix34_t& a, const vr::...
  function vr (line 244) | inline vr::HmdVector3_t matMul33(const vr::HmdMatrix34_t& a, const vr::H...
  function vr (line 255) | inline vr::HmdVector3d_t matMul33(const vr::HmdMatrix34_t& a, const vr::...
  function vr (line 266) | inline vr::HmdVector3_t matMul33(const vr::HmdVector3_t& a, const vr::Hm...
  function vr (line 277) | inline vr::HmdVector3d_t matMul33(const vr::HmdVector3d_t& a, const vr::...
  function vr (line 288) | inline vr::HmdMatrix34_t transposeMul33(const vr::HmdMatrix34_t& a) {
  function vr (line 301) | inline vr::HmdMatrix34_t matInv33(vr::HmdMatrix34_t matrix) {

FILE: alvr/server_openvr/cpp/alvr_server/include/picojson.h
  function namespace (line 111) | namespace picojson {
  function class (line 923) | class deny_parse_context {
  function parse_array_stop (line 998) | bool parse_array_stop(size_t) {
  function parse_object_start (line 1001) | bool parse_object_start() {
  function set_null (line 1026) | bool set_null() {
  function set_bool (line 1029) | bool set_bool(bool) {
  function set_int64 (line 1033) | bool set_int64(int64_t) {
  function set_number (line 1037) | bool set_number(double) {
  function parse_array_start (line 1044) | bool parse_array_start() {
  function parse_array_stop (line 1050) | bool parse_array_stop(size_t) {
  function parse_object_start (line 1053) | bool parse_object_start() {
  function std (line 1095) | inline std::string parse(value &out, const std::string &s) {
  function std (line 1101) | inline std::string parse(value &out, std::istream &is) {
  function set_last_error (line 1110) | inline void set_last_error(const std::string &s) {
  function std (line 1114) | inline const std::string &get_last_error() {
  function namespace (line 1143) | namespace std {

FILE: alvr/server_openvr/cpp/alvr_server/nvEncodeAPI.h
  type __int32 (line 48) | typedef __int32 int32_t;
  type __int64 (line 50) | typedef __int64 int64_t;
  type RECT (line 72) | typedef RECT NVENC_RECT;
  type GUID (line 83) | typedef struct _GUID {
  type NVENC_RECT (line 97) | typedef struct _NVENC_RECT {
  type NV_ENC_PARAMS_FRAME_FIELD_MODE (line 286) | typedef enum _NV_ENC_PARAMS_FRAME_FIELD_MODE {
  type NV_ENC_PARAMS_RC_MODE (line 295) | typedef enum _NV_ENC_PARAMS_RC_MODE {
  type NV_ENC_MULTI_PASS (line 313) | typedef enum _NV_ENC_MULTI_PASS {
  type NV_ENC_EMPHASIS_MAP_LEVEL (line 324) | typedef enum _NV_ENC_EMPHASIS_MAP_LEVEL {
  type NV_ENC_QP_MAP_MODE (line 336) | typedef enum _NV_ENC_QP_MAP_MODE {
  type NV_ENC_PIC_STRUCT (line 355) | typedef enum _NV_ENC_PIC_STRUCT {
  type NV_ENC_DISPLAY_PIC_STRUCT (line 366) | typedef enum _NV_ENC_DISPLAY_PIC_STRUCT {
  type NV_ENC_PIC_TYPE (line 377) | typedef enum _NV_ENC_PIC_TYPE {
  type NV_ENC_MV_PRECISION (line 392) | typedef enum _NV_ENC_MV_PRECISION {
  type NV_ENC_BUFFER_FORMAT (line 403) | typedef enum _NV_ENC_BUFFER_FORMAT {
  type NV_ENC_LEVEL (line 458) | typedef enum _NV_ENC_LEVEL {
  type NVENCSTATUS (line 532) | typedef enum _NVENCSTATUS {
  type NV_ENC_PIC_FLAGS (line 703) | typedef enum _NV_ENC_PIC_FLAGS {
  type NV_ENC_MEMORY_HEAP (line 717) | typedef enum _NV_ENC_MEMORY_HEAP {
  type NV_ENC_BFRAME_REF_MODE (line 728) | typedef enum _NV_ENC_BFRAME_REF_MODE {
  type NV_ENC_H264_ENTROPY_CODING_MODE (line 738) | typedef enum _NV_ENC_H264_ENTROPY_CODING_MODE {
  type NV_ENC_H264_BDIRECT_MODE (line 748) | typedef enum _NV_ENC_H264_BDIRECT_MODE {
  type NV_ENC_H264_FMO_MODE (line 759) | typedef enum _NV_ENC_H264_FMO_MODE {
  type NV_ENC_H264_ADAPTIVE_TRANSFORM_MODE (line 768) | typedef enum _NV_ENC_H264_ADAPTIVE_TRANSFORM_MODE {
  type NV_ENC_STEREO_PACKING_MODE (line 778) | typedef enum _NV_ENC_STEREO_PACKING_MODE {
  type NV_ENC_INPUT_RESOURCE_TYPE (line 795) | typedef enum _NV_ENC_INPUT_RESOURCE_TYPE {
  type NV_ENC_BUFFER_USAGE (line 809) | typedef enum _NV_ENC_BUFFER_USAGE {
  type NV_ENC_DEVICE_TYPE (line 821) | typedef enum _NV_ENC_DEVICE_TYPE {
  type NV_ENC_NUM_REF_FRAMES (line 831) | typedef enum _NV_ENC_NUM_REF_FRAMES {
  type NV_ENC_CAPS (line 846) | typedef enum _NV_ENC_CAPS {
  type NV_ENC_HEVC_CUSIZE (line 1205) | typedef enum _NV_ENC_HEVC_CUSIZE {
  type NV_ENC_AV1_PART_SIZE (line 1216) | typedef enum _NV_ENC_AV1_PART_SIZE {
  type NV_ENC_VUI_VIDEO_FORMAT (line 1228) | typedef enum _NV_ENC_VUI_VIDEO_FORMAT {
  type NV_ENC_VUI_COLOR_PRIMARIES (line 1237) | typedef enum _NV_ENC_VUI_COLOR_PRIMARIES {
  type NV_ENC_VUI_TRANSFER_CHARACTERISTIC (line 1254) | typedef enum _NV_ENC_VUI_TRANSFER_CHARACTERISTIC {
  type NV_ENC_VUI_MATRIX_COEFFS (line 1276) | typedef enum _NV_ENC_VUI_MATRIX_COEFFS {
  type NV_ENC_CAPS_PARAM (line 1294) | typedef struct _NV_ENC_CAPS_PARAM {
  type NV_ENC_ENCODE_OUT_PARAMS (line 1307) | typedef struct _NV_ENC_ENCODE_OUT_PARAMS {
  type NV_ENC_CREATE_INPUT_BUFFER (line 1319) | typedef struct _NV_ENC_CREATE_INPUT_BUFFER {
  type NV_ENC_CREATE_BITSTREAM_BUFFER (line 1338) | typedef struct _NV_ENC_CREATE_BITSTREAM_BUFFER {
  type NV_ENC_MVECTOR (line 1356) | typedef struct _NV_ENC_MVECTOR {
  type NV_ENC_H264_MV_DATA (line 1364) | typedef struct _NV_ENC_H264_MV_DATA {
  type NV_ENC_HEVC_MV_DATA (line 1376) | typedef struct _NV_ENC_HEVC_MV_DATA {
  type NV_ENC_CREATE_MV_BUFFER (line 1389) | typedef struct _NV_ENC_CREATE_MV_BUFFER {
  type NV_ENC_QP (line 1402) | typedef struct _NV_ENC_QP {
  type NV_ENC_RC_PARAMS (line 1420) | typedef struct _NV_ENC_RC_PARAMS {
  type NV_ENC_CLOCK_TIMESTAMP_SET (line 1550) | typedef struct _NV_ENC_CLOCK_TIMESTAMP_SET {
  type NV_ENC_TIME_CODE (line 1562) | typedef struct _NV_ENC_TIME_CODE {
  type NV_ENC_CONFIG_H264_VUI_PARAMETERS (line 1571) | typedef struct _NV_ENC_CONFIG_H264_VUI_PARAMETERS {
  type NV_ENC_CONFIG_H264_VUI_PARAMETERS (line 1616) | typedef NV_ENC_CONFIG_H264_VUI_PARAMETERS NV_ENC_CONFIG_HEVC_VUI_PARAMET...
  type NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE (line 1623) | typedef struct _NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE {
  type NVENC_EXTERNAL_ME_HINT (line 1642) | typedef struct _NVENC_EXTERNAL_ME_HINT {
  type NVENC_EXTERNAL_ME_SB_HINT (line 1661) | typedef struct _NVENC_EXTERNAL_ME_SB_HINT {
  type NV_ENC_CONFIG_H264 (line 1686) | typedef struct _NV_ENC_CONFIG_H264 {
  type NV_ENC_CONFIG_HEVC (line 1872) | typedef struct _NV_ENC_CONFIG_HEVC {
  type NV_ENC_FILM_GRAIN_PARAMS_AV1 (line 2011) | typedef struct _NV_ENC_FILM_GRAIN_PARAMS_AV1 {
  type NV_ENC_CONFIG_AV1 (line 2071) | typedef struct _NV_ENC_CONFIG_AV1 {
  type NV_ENC_CONFIG_H264_MEONLY (line 2189) | typedef struct _NV_ENC_CONFIG_H264_MEONLY {
  type NV_ENC_CONFIG_HEVC_MEONLY (line 2207) | typedef struct _NV_ENC_CONFIG_HEVC_MEONLY {
  type NV_ENC_CODEC_CONFIG (line 2216) | typedef union _NV_ENC_CODEC_CONFIG {
  type NV_ENC_CONFIG (line 2231) | typedef struct _NV_ENC_CONFIG {
  type NV_ENC_TUNING_INFO (line 2267) | typedef enum NV_ENC_TUNING_INFO {
  type NV_ENC_INITIALIZE_PARAMS (line 2280) | typedef struct _NV_ENC_INITIALIZE_PARAMS {
  type NV_ENC_RECONFIGURE_PARAMS (line 2386) | typedef struct _NV_ENC_RECONFIGURE_PARAMS {
  type NV_ENC_PRESET_CONFIG (line 2422) | typedef struct _NV_ENC_PRESET_CONFIG {
  type NV_ENC_PIC_PARAMS_MVC (line 2437) | typedef struct _NV_ENC_PIC_PARAMS_MVC {
  type NV_ENC_PIC_PARAMS_H264_EXT (line 2455) | typedef union _NV_ENC_PIC_PARAMS_H264_EXT {
  type NV_ENC_SEI_PAYLOAD (line 2464) | typedef struct _NV_ENC_SEI_PAYLOAD {
  type NV_ENC_PIC_PARAMS_H264 (line 2478) | typedef struct _NV_ENC_PIC_PARAMS_H264 {
  type NV_ENC_PIC_PARAMS_HEVC (line 2552) | typedef struct _NV_ENC_PIC_PARAMS_HEVC {
  type NV_ENC_PIC_PARAMS_AV1 (line 2626) | typedef struct _NV_ENC_PIC_PARAMS_AV1 {
  type NV_ENC_CODEC_PIC_PARAMS (line 2718) | typedef union _NV_ENC_CODEC_PIC_PARAMS {
  type NV_ENC_PIC_PARAMS (line 2729) | typedef struct _NV_ENC_PIC_PARAMS {
  type NV_ENC_MEONLY_PARAMS (line 2851) | typedef struct _NV_ENC_MEONLY_PARAMS {
  type NV_ENC_LOCK_BITSTREAM (line 2909) | typedef struct _NV_ENC_LOCK_BITSTREAM {
  type NV_ENC_LOCK_INPUT_BUFFER (line 2980) | typedef struct _NV_ENC_LOCK_INPUT_BUFFER {
  type NV_ENC_MAP_INPUT_RESOURCE (line 3003) | typedef struct _NV_ENC_MAP_INPUT_RESOURCE {
  type NV_ENC_INPUT_RESOURCE_OPENGL_TEX (line 3029) | typedef struct _NV_ENC_INPUT_RESOURCE_OPENGL_TEX {
  type NV_ENC_FENCE_POINT_D3D12 (line 3037) | typedef struct _NV_ENC_FENCE_POINT_D3D12 {
  type NV_ENC_INPUT_RESOURCE_D3D12 (line 3059) | typedef struct _NV_ENC_INPUT_RESOURCE_D3D12 {
  type NV_ENC_OUTPUT_RESOURCE_D3D12 (line 3080) | typedef struct _NV_ENC_OUTPUT_RESOURCE_D3D12 {
  type NV_ENC_REGISTER_RESOURCE (line 3100) | typedef struct _NV_ENC_REGISTER_RESOURCE {
  type NV_ENC_STAT (line 3152) | typedef struct _NV_ENC_STAT {
  type NV_ENC_SEQUENCE_PARAM_PAYLOAD (line 3182) | typedef struct _NV_ENC_SEQUENCE_PARAM_PAYLOAD {
  type NV_ENC_EVENT_PARAMS (line 3204) | typedef struct _NV_ENC_EVENT_PARAMS {
  type NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS (line 3219) | typedef struct _NV_ENC_OPEN_ENCODE_SESSIONEX_PARAMS {
  type NV_ENCODE_API_FUNCTION_LIST (line 4913) | typedef struct _NV_ENCODE_API_FUNCTION_LIST {

FILE: alvr/server_openvr/cpp/platform/linux/CEncoder.cpp
  function read_exactly (line 38) | void read_exactly(pollfd pollfds, char* out, size_t size, std::atomic_bo...
  function read_latest (line 57) | void read_latest(pollfd pollfds, char* out, size_t size, std::atomic_boo...
  function accept_timeout (line 69) | int accept_timeout(pollfd socket, std::atomic_bool& exiting) {
  function av_logfn (line 83) | void av_logfn(void*, int level, const char* data, va_list va) {
  type msghdr (line 104) | struct msghdr
  type cmsghdr (line 105) | struct cmsghdr
  type cmsghdr (line 107) | struct cmsghdr
  type cmsghdr (line 108) | struct cmsghdr
  type iovec (line 110) | struct iovec
  type sockaddr_un (line 152) | struct sockaddr_un
  type sockaddr (line 162) | struct sockaddr
  type pollfd (line 175) | struct pollfd

FILE: alvr/server_openvr/cpp/platform/linux/CEncoder.h
  function class (line 12) | class CEncoder : public CThread {

FILE: alvr/server_openvr/cpp/platform/linux/CrashHandler.cpp
  function HookCrashHandler (line 3) | void HookCrashHandler() { }

FILE: alvr/server_openvr/cpp/platform/linux/EncodePipeline.h
  type AVCodecContext (line 8) | struct AVCodecContext
  type AVPacket (line 9) | struct AVPacket
  function namespace (line 13) | namespace alvr {

FILE: alvr/server_openvr/cpp/platform/linux/EncodePipelineNvEnc.cpp
  function set_hwframe_ctx (line 28) | void set_hwframe_ctx(AVCodecContext* ctx, AVBufferRef* hw_device_ctx) {

FILE: alvr/server_openvr/cpp/platform/linux/EncodePipelineNvEnc.h
  type AVBufferRef (line 7) | struct AVBufferRef
  type AVCodecContext (line 8) | struct AVCodecContext
  type AVFrame (line 9) | struct AVFrame
  function namespace (line 13) | namespace alvr {

FILE: alvr/server_openvr/cpp/platform/linux/EncodePipelineSW.cpp
  function x264_log (line 11) | void x264_log(void*, int level, const char* fmt, va_list args) {

FILE: alvr/server_openvr/cpp/platform/linux/EncodePipelineSW.h
  function namespace (line 9) | namespace alvr {

FILE: alvr/server_openvr/cpp/platform/linux/EncodePipelineVAAPI.cpp
  function set_hwframe_ctx (line 31) | void set_hwframe_ctx(AVCodecContext* ctx, AVBufferRef* hw_device_ctx) {
  function AVFrame (line 61) | AVFrame*
  function AVFrame (line 101) | AVFrame* import_frame(AVBufferRef* hw_frames_ref, DrmImage& drm) {

FILE: alvr/server_openvr/cpp/platform/linux/EncodePipelineVAAPI.h
  type AVBufferRef (line 5) | struct AVBufferRef
  type AVCodecContext (line 6) | struct AVCodecContext
  type AVFilterContext (line 7) | struct AVFilterContext
  type AVFilterGraph (line 8) | struct AVFilterGraph
  type AVFrame (line 9) | struct AVFrame
  function namespace (line 13) | namespace alvr {

FILE: alvr/server_openvr/cpp/platform/linux/FormatConverter.h
  function class (line 5) | class FormatConverter {
  function class (line 56) | class RgbToYuv420 : public FormatConverter {

FILE: alvr/server_openvr/cpp/platform/linux/FrameRender.h
  function class (line 7) | class FrameRender : public Renderer {

FILE: alvr/server_openvr/cpp/platform/linux/Renderer.cpp
  type Vertex (line 27) | struct Vertex {
  function to_drm_format (line 31) | static uint32_t to_drm_format(VkFormat format) {
  function filter_modifier (line 43) | static bool filter_modifier(uint64_t modifier) {

FILE: alvr/server_openvr/cpp/platform/linux/Renderer.h
  type DrmImage (line 22) | struct DrmImage {
  function class (line 33) | class Renderer {
  function class (line 155) | class RenderPipeline {

FILE: alvr/server_openvr/cpp/platform/linux/ffmpeg_helper.cpp
  function AVPixelFormat (line 20) | AVPixelFormat vk_format_to_av_format(vk::Format vk_fmt) {
  type stat (line 197) | struct stat

FILE: alvr/server_openvr/cpp/platform/linux/ffmpeg_helper.h
  function namespace (line 26) | namespace alvr {

FILE: alvr/server_openvr/cpp/platform/linux/protocol.h
  type present_packet (line 11) | struct present_packet {
  type init_packet (line 18) | struct init_packet {

FILE: alvr/server_openvr/cpp/platform/macos/CEncoder.h
  function class (line 5) | class CEncoder : public CThread {

FILE: alvr/server_openvr/cpp/platform/macos/CrashHandler.cpp
  function HookCrashHandler (line 3) | void HookCrashHandler() { }

FILE: alvr/server_openvr/cpp/platform/win32/CEncoder.h
  function class (line 30) | class CEncoder : public CThread {

FILE: alvr/server_openvr/cpp/platform/win32/CrashHandler.cpp
  function LONG (line 8) | static LONG WINAPI handler(PEXCEPTION_POINTERS ptrs) {
  function HookCrashHandler (line 23) | void HookCrashHandler() { SetUnhandledExceptionFilter(handler); }

FILE: alvr/server_openvr/cpp/platform/win32/FFR.cpp
  type FoveationVars (line 12) | struct FoveationVars {
  function FoveationVars (line 29) | FoveationVars CalculateFoveationVars() {
  function ID3D11Texture2D (line 136) | ID3D11Texture2D* FFR::GetOutputTexture() { return mOptimizedTexture.Get(...

FILE: alvr/server_openvr/cpp/platform/win32/FFR.h
  function class (line 5) | class FFR {

FILE: alvr/server_openvr/cpp/platform/win32/FrameRender.cpp
  function HmdMatrix_AsDxMat (line 15) | static DirectX::XMMATRIX HmdMatrix_AsDxMat(const vr::HmdMatrix34_t& m) {
  function HmdMatrix_AsDxMatOrientOnly (line 38) | static DirectX::XMMATRIX HmdMatrix_AsDxMatOrientOnly(vr::HmdMatrix34_t& ...
  function HmdMatrix_AsDxMatPosOnly (line 61) | static DirectX::XMMATRIX HmdMatrix_AsDxMatPosOnly(const vr::HmdMatrix34_...
  type FrameRenderBuffer (line 254) | struct FrameRenderBuffer {
  type ColorCorrection (line 410) | struct ColorCorrection {
  type YUVParams (line 463) | struct YUVParams {

FILE: alvr/server_openvr/cpp/platform/win32/FrameRender.h
  function class (line 42) | class FrameRender {

FILE: alvr/server_openvr/cpp/platform/win32/NvCodecUtils.h
  function check (line 36) | inline bool check(CUresult e, int iLine, const char *szFile) {
  function check (line 48) | inline bool check(cudaError_t e, int iLine, const char *szFile) {
  function check (line 58) | inline bool check(NVENCSTATUS e, int iLine, const char *szFile) {
  function check (line 96) | inline bool check(HRESULT e, int iLine, const char *szFile) {
  function check (line 108) | inline bool check(GLenum e, int iLine, const char *szFile) {
  function check (line 117) | inline bool check(int e, int iLine, const char *szFile) {
  function class (line 133) | class NvThread
  function class (line 180) | class BufferedFileReader {
  function GetBuffer (line 226) | bool GetBuffer(uint8_t **ppBuf, uint64_t *pnSize) {
  function class (line 317) | class IVFUtils {
  function WriteFrameHeader (line 340) | void WriteFrameHeader(std::vector<uint8_t> &vPacket,  size_t nFrameSize,...
  function mem_put_le16 (line 360) | static inline void mem_put_le16(void *vmem, int val)
  function class (line 372) | class StopWatch {
  function Stop (line 377) | double Stop() {
  function maxSize (line 391) | ConcurrentQueue(size_t size) : maxSize(size) {}
  function setSize (line 395) | void setSize(size_t s) {
  function push_back (line 399) | void push_back(const T& value) {
  function T (line 418) | T pop_front() {
  function T (line 436) | T front() {
  function size (line 446) | size_t size() {
  function empty (line 451) | bool empty() {
  function clear (line 455) | void clear() {
  function CheckInputFile (line 474) | inline void CheckInputFile(const char *szInFilePath) {
  function ValidateResolution (line 483) | inline void ValidateResolution(int nWidth, int nHeight) {

FILE: alvr/server_openvr/cpp/platform/win32/NvEncoder.cpp
  function NvEncInputFrame (line 443) | const NvEncInputFrame* NvEncoder::GetNextInputFrame()
  function NvEncInputFrame (line 449) | const NvEncInputFrame* NvEncoder::GetNextReferenceFrame()
  function NVENCSTATUS (line 543) | NVENCSTATUS NvEncoder::DoEncode(NV_ENC_INPUT_PTR inputBuffer, NV_ENC_OUT...
  function NV_ENC_REGISTERED_PTR (line 651) | NV_ENC_REGISTERED_PTR NvEncoder::RegisterResource(void *pBuffer, NV_ENC_...
  function NVENCSTATUS (line 1046) | NVENCSTATUS NvEncoder::DoMotionEstimation(NV_ENC_INPUT_PTR inputBuffer, ...

FILE: alvr/server_openvr/cpp/platform/win32/NvEncoder.h
  function class (line 27) | class NVENCException : public std::exception
  function NVENCException (line 44) | inline NVENCException NVENCException::makeNVENCException(const std::stri...
  type NvEncInputFrame (line 72) | struct NvEncInputFrame
  function class (line 86) | class NvEncoder

FILE: alvr/server_openvr/cpp/platform/win32/NvEncoderD3D11.cpp
  function DXGI_FORMAT (line 22) | DXGI_FORMAT GetD3D11Format(NV_ENC_BUFFER_FORMAT eBufferFormat)

FILE: alvr/server_openvr/cpp/platform/win32/NvEncoderD3D11.h
  function class (line 21) | class NvEncoderD3D11 : public NvEncoder

FILE: alvr/server_openvr/cpp/platform/win32/OvrDirectModeComponent.h
  function class (line 11) | class OvrDirectModeComponent : public vr::IVRDriverDirectModeComponent {

FILE: alvr/server_openvr/cpp/platform/win32/VideoEncoder.h
  function class (line 8) | class VideoEncoder {

FILE: alvr/server_openvr/cpp/platform/win32/VideoEncoderAMF.h
  type amf (line 13) | typedef amf::AMFData* AMFDataPtr;
  type std (line 14) | typedef std::function<void(AMFDataPtr)> AMFDataReceiver;
  function class (line 18) | class AMFPipe {
  type AMFPipe (line 30) | typedef AMFPipe* AMFPipePtr;
  function class (line 32) | class AMFSolidPipe : public AMFPipe {
  function class (line 42) | class AMFPipeline {
  type AMFPipeline (line 56) | typedef AMFPipeline* AMFPipelinePtr;
  function class (line 59) | class VideoEncoderAMF : public VideoEncoder {

FILE: alvr/server_openvr/cpp/platform/win32/VideoEncoderNVENC.h
  type AdaptiveQuantizationMode (line 8) | enum AdaptiveQuantizationMode { SpatialAQ = 1, TemporalAQ = 2 }
  function class (line 11) | class VideoEncoderNVENC : public VideoEncoder {

FILE: alvr/server_openvr/cpp/platform/win32/VideoEncoderSW.cpp
  function HRESULT (line 268) | HRESULT VideoEncoderSW::SetupStagingTexture(ID3D11Texture2D* pTexture) {
  function HRESULT (line 285) | HRESULT VideoEncoderSW::CopyTexture(ID3D11Texture2D* pTexture) {
  function AVCodecID (line 292) | AVCodecID VideoEncoderSW::ToFFMPEGCodec(ALVR_CODEC codec) {

FILE: alvr/server_openvr/cpp/platform/win32/VideoEncoderSW.h
  function class (line 21) | class VideoEncoderSW : public VideoEncoder {

FILE: alvr/server_openvr/cpp/platform/win32/VideoEncoderVPL.cpp
  function mfxFrameSurface1 (line 216) | mfxFrameSurface1* VideoEncoderVPL::VplImportTexture(ID3D11Texture2D* tex...

FILE: alvr/server_openvr/cpp/platform/win32/VideoEncoderVPL.h
  function class (line 19) | class VideoEncoderVPL : public VideoEncoder {

FILE: alvr/server_openvr/cpp/platform/win32/d3d-render-utils/RenderPipeline.cpp
  type d3d_render_utils (line 5) | namespace d3d_render_utils {

FILE: alvr/server_openvr/cpp/platform/win32/d3d-render-utils/RenderPipeline.h
  function namespace (line 5) | namespace d3d_render_utils {

FILE: alvr/server_openvr/cpp/platform/win32/d3d-render-utils/RenderPipelineYUV.cpp
  type d3d_render_utils (line 5) | namespace d3d_render_utils {

FILE: alvr/server_openvr/cpp/platform/win32/d3d-render-utils/RenderPipelineYUV.h
  function namespace (line 5) | namespace d3d_render_utils {

FILE: alvr/server_openvr/cpp/platform/win32/d3d-render-utils/RenderUtils.cpp
  type d3d_render_utils (line 8) | namespace d3d_render_utils {
    function GetAdapterInfo (line 10) | void GetAdapterInfo(ID3D11Device* d3dDevice, int32_t& adapterIndex, st...
    function ID3D11Device (line 45) | ID3D11Device* CreateDevice(IDXGIAdapter* dxgiAdapter) {
    function ID3D11Device (line 86) | ID3D11Device* CreateDevice(uint32_t adapterIndex) {
    function ID3D11Texture2D (line 99) | ID3D11Texture2D* CreateTexture(
    function ID3D11Buffer (line 129) | ID3D11Buffer*
    function UpdateBuffer (line 148) | void UpdateBuffer(ID3D11DeviceContext* context, ID3D11Buffer* buffer, ...
    function ID3D11VertexShader (line 152) | ID3D11VertexShader*
    function ID3D11PixelShader (line 164) | ID3D11PixelShader* CreatePixelShader(ID3D11Device* device, std::vector...
    function ID3D11Texture2D (line 173) | ID3D11Texture2D* GetTextureFromHandle(ID3D11Device* device, HANDLE han...
    function HANDLE (line 182) | HANDLE GetHandleFromTexture(ID3D11Texture2D* texture) {
    function KeyedMutexSync (line 194) | void KeyedMutexSync(

FILE: alvr/server_openvr/cpp/platform/win32/d3d-render-utils/RenderUtils.h
  function namespace (line 26) | namespace d3d_render_utils {

FILE: alvr/server_openvr/cpp/platform/win32/shared/d3drender.cpp
  function FindDXGIOutput (line 19) | bool FindDXGIOutput( IDXGIFactory *pFactory, int32_t nWidth, int32_t nHe...
  function CreateDevice (line 46) | bool CreateDevice( IDXGIAdapter *pDXGIAdapter, ID3D11Device **pD3D11Devi...
  class CEventHelper (line 88) | class CEventHelper
    method CEventHelper (line 91) | CEventHelper()
  function EventWriteString (line 106) | void EventWriteString( const wchar_t* pwchEvent )
  function ID3D11Texture2D (line 218) | ID3D11Texture2D *CD3DRender::GetSharedTexture( HANDLE hSharedTexture )

FILE: alvr/server_openvr/cpp/platform/win32/shared/d3drender.h
  function class (line 17) | class CD3DRender

FILE: alvr/server_openvr/cpp/shared/amf/public/common/AMFFactory.cpp
  function AMF_RESULT (line 71) | AMF_RESULT AMFFactoryHelper::Init(const wchar_t* dllName)
  function AMF_RESULT (line 128) | AMF_RESULT AMFFactoryHelper::Terminate()
  function amf_uint64 (line 161) | amf_uint64 AMFFactoryHelper::AMFQueryVersion()
  function AMF_RESULT (line 167) | AMF_RESULT  AMFFactoryHelper::LoadExternalComponent(amf::AMFContext* pCo...
  function AMF_RESULT (line 230) | AMF_RESULT  AMFFactoryHelper::UnLoadExternalComponent(const wchar_t* dll)

FILE: alvr/server_openvr/cpp/shared/amf/public/common/AMFFactory.h
  function amf_handle (line 62) | amf_handle    GetAMFDLLHandle() { return m_hDLLHandle; }
  type ComponentHolder (line 64) | struct ComponentHolder

FILE: alvr/server_openvr/cpp/shared/amf/public/common/AMFMath.h
  function namespace (line 38) | namespace amf
  function class (line 343) | class Quaternion : public Vector
  function FromEuler (line 351) | inline void FromEuler(float pitch, float yaw, float roll)
  function other (line 374) | inline bool operator==(const Quaternion& other) const
  function other (line 379) | inline bool operator!=(const Quaternion& other) const { return !operator...
  function Quaternion (line 392) | inline const Quaternion& RotateBy(const Quaternion& rotator)
  function Vector (line 398) | inline Vector ToEulerAngles() const
  function else (line 430) | else if (test < -0.499f*unit) { // singularity at south pole
  function Quaternion (line 475) | inline Quaternion Conjugate()  const
  function ScalarSinCos (line 498) | inline void ScalarSinCos(float* pSin, float* pCos, float  Value)
  function class (line 540) | class Matrix
  function Identity (line 562) | inline void Identity()
  function Matrix (line 582) | inline Matrix operator*=(const Matrix& other)
  function operator (line 588) | inline bool operator==(const Matrix& other) const
  function operator (line 592) | inline bool operator!=(const Matrix& other) const
  function MatrixAffineTransformation (line 611) | void MatrixAffineTransformation(const Vector &Scaling, const Vector &Rot...
  function MatrixScalingFromVector (line 626) | inline void MatrixScalingFromVector(const Vector& Scale)
  function MatrixRotationQuaternion (line 634) | void MatrixRotationQuaternion(const Vector& Quaternion)
  function LookToLH (line 665) | inline void LookToLH(const Vector& EyePosition, const Vector& EyeDirecti...
  function LookAtLH (line 711) | inline void LookAtLH(Vector& EyePosition, Vector& FocusPosition, Vector&...
  function PerspectiveFovLH (line 716) | inline void PerspectiveFovLH(float FovAngleY, float AspectRatio, float N...
  function RotationRollPitchYaw (line 746) | inline void RotationRollPitchYaw(float Pitch, float Yaw, float Roll)
  function Vector (line 752) | inline Vector Determinant()
  function amf (line 842) | inline amf::Quaternion ConvertMatrixToQuat()
  function DecomposeMatrix (line 894) | inline bool DecomposeMatrix(amf::Quaternion &q, amf::Vector &p, amf::Vec...
  function Matrix (line 984) | inline Matrix Inverse(Vector *pDeterminant)
  function class (line 1039) | class Pose
  function T (line 1166) | T Apply(T value)
  function T (line 1223) | T Apply(T value) const
  function class (line 1238) | class Derivative

FILE: alvr/server_openvr/cpp/shared/amf/public/common/AMFSTL.cpp
  function amf_string (line 92) | amf_string AMF_STD_CALL amf::amf_from_unicode_to_utf8(const amf_wstring&...
  function amf_wstring (line 160) | amf_wstring AMF_STD_CALL amf::amf_from_utf8_to_unicode(const amf_string&...
  function amf_string (line 244) | amf_string AMF_STD_CALL amf::amf_from_unicode_to_multibyte(const amf_wst...
  function amf_wstring (line 296) | amf_wstring AMF_STD_CALL amf::amf_from_multibyte_to_unicode(const amf_st...
  function amf_string (line 359) | amf_string AMF_STD_CALL amf::amf_from_string_to_hex_string(const amf_str...
  function amf_string (line 372) | amf_string AMF_STD_CALL amf::amf_from_hex_string_to_string(const amf_str...
  function amf_string (line 389) | amf_string AMF_STD_CALL amf::amf_string_to_lower(const amf_string& str)
  function amf_wstring (line 401) | amf_wstring AMF_STD_CALL amf::amf_string_to_lower(const amf_wstring& str)
  function amf_string (line 413) | amf_string AMF_STD_CALL amf::amf_string_to_upper(const amf_string& str)
  function amf_wstring (line 425) | amf_wstring AMF_STD_CALL amf::amf_string_to_upper(const amf_wstring& str)
  function amf_wstring (line 437) | amf_wstring AMF_STD_CALL amf::amf_convert_path_to_os_accepted_path(const...
  function amf_wstring (line 454) | amf_wstring AMF_STD_CALL amf::amf_convert_path_to_url_accepted_path(cons...
  function amf_string (line 472) | amf_string AMF_STD_CALL amf::amf_from_unicode_to_url_utf8(const amf_wstr...
  function amf_wstring (line 498) | amf_wstring AMF_STD_CALL amf::amf_from_url_utf8_to_unicode(const amf_str...
  function amf_size (line 531) | amf_size AMF_STD_CALL amf::amf_string_ci_find(const amf_wstring& left, c...
  function amf_size (line 538) | amf_size AMF_STD_CALL amf::amf_string_ci_rfind(const amf_wstring& left, ...
  function amf_int (line 545) | amf_int AMF_STD_CALL amf::amf_string_ci_compare(const amf_wstring& left,...
  function amf_int (line 552) | amf_int AMF_STD_CALL amf::amf_string_ci_compare(const amf_string& left, ...
  function amf_wstring (line 559) | amf_wstring AMF_STD_CALL amf::amf_string_format(const wchar_t* format, ...)
  function amf_string (line 569) | amf_string AMF_STD_CALL amf::amf_string_format(const char* format, ...)
  function amf_wstring (line 579) | amf_wstring AMF_STD_CALL amf::amf_string_formatVA(const wchar_t* format,...
  function amf_string (line 624) | amf_string AMF_STD_CALL amf::amf_string_formatVA(const char* format, va_...
  function vscprintf (line 643) | int vscprintf(const char* format, va_list argptr)
  function vscwprintf (line 661) | int vscwprintf(const wchar_t* format, va_list argptr)
  function isOneOf (line 715) | static bool isOneOf(CHAR_T p_ch, const CHAR_T* p_set)
  function processWidthAndPrecision (line 725) | static void processWidthAndPrecision(amf_string& p_fmt, va_list& p_args)
  function amf_wprintfCore (line 740) | static size_t amf_wprintfCore(outputStreamDelegateW p_outDelegate, void*...
  function amf_printfCore (line 974) | static size_t amf_printfCore(outputStreamDelegate p_outDelegate, void* p...
  function writeToMem (line 1216) | static size_t writeToMem(void* p_context, size_t p_offset, const wchar_t...
  function writeToFile (line 1227) | static size_t writeToFile(void* p_context, size_t, const wchar_t* p_stri...
  function vswprintf (line 1234) | int vswprintf(wchar_t* p_buf, size_t p_size, const wchar_t* p_fmt, va_li...
  function wsprintf (line 1242) | int wsprintf(wchar_t* p_buf, const wchar_t* p_fmt, ...)
  function swprintf (line 1249) | int swprintf(wchar_t* p_buf, size_t p_size, const wchar_t* p_fmt, ...)
  function vfwprintf (line 1256) | int vfwprintf(FILE* p_stream, const wchar_t* p_fmt, va_list p_args)
  function fwprintf (line 1261) | int fwprintf(FILE* p_stream, const wchar_t* p_fmt, ...)
  function vscwprintf (line 1269) | int vscwprintf(const wchar_t* p_fmt, va_list p_args)
  function vscprintf (line 1274) | int vscprintf(const char* p_fmt, va_list p_args)
  function _wcsicmp (line 1288) | int _wcsicmp(const wchar_t* s1, const wchar_t* s2)

FILE: alvr/server_openvr/cpp/shared/amf/public/common/AMFSTL.h
  type amf_allocator (line 93) | typedef amf_allocator<_Other> other;
  function deallocate (line 95) | void deallocate(_Ty* const _Ptr, const size_t _Count)
  function explicit (line 120) | explicit amf_vector(size_t _Count) : _base(_Count) {}
  function size_limit (line 158) | size_t size_limit()
  function set_size_limit (line 163) | void set_size_limit(size_t size_limit)
  function _Ty (line 172) | _Ty push_front(const _Ty& _Val)
  function push_front_ex (line 186) | void push_front_ex(const _Ty& _Val)
  function _Ty (line 191) | _Ty push_back(const _Ty& _Val)
  type std (line 245) | typedef std::vector<AMFInterfacePtr_TAdapted<_Interf>, amf_allocator<AMF...
  function reference (line 246) | reference operator[](size_t n)
  function amf_wstring (line 296) | struct std::hash<amf_wstring>
  function amf_string (line 305) | struct std::hash<amf_string>
  function namespace (line 313) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/common/ByteArray.h
  function class (line 43) | class AMFByteArray
  function virtual (line 61) | virtual ~AMFByteArray()
  function SetSize (line 68) | void  SetSize(amf_size num)
  function Copy (line 101) | void Copy(const AMFByteArray &old)
  function amf_uint8 (line 116) | amf_uint8    operator[] (amf_size iPos) const
  function amf_uint8 (line 133) | amf_uint8 *GetData() const { return m_pData; }

FILE: alvr/server_openvr/cpp/shared/amf/public/common/CPUCaps.h
  function class (line 46) | class InstructionSet
  function virtual (line 254) | virtual ~InstructionSet_Internal()

FILE: alvr/server_openvr/cpp/shared/amf/public/common/CurrentTimeImpl.cpp
  type amf (line 36) | namespace amf
    function amf_pts (line 52) | amf_pts AMF_STD_CALL AMFCurrentTimeImpl::Get()

FILE: alvr/server_openvr/cpp/shared/amf/public/common/CurrentTimeImpl.h
  function namespace (line 41) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/common/DataStream.h
  function namespace (line 45) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/common/DataStreamFactory.cpp
  function AMF_RESULT (line 43) | AMF_RESULT AMF_STD_CALL amf::AMFDataStream::OpenDataStream(const wchar_t...

FILE: alvr/server_openvr/cpp/shared/amf/public/common/DataStreamFile.cpp
  function AMF_RESULT (line 80) | AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::Close()
  function AMF_RESULT (line 95) | AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::Read(void* pData, amf_siz...
  function AMF_RESULT (line 117) | AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::Write(const void* pData, ...
  function AMF_RESULT (line 134) | AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::Seek(AMF_SEEK_ORIGIN eOri...
  function AMF_RESULT (line 168) | AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::GetPosition(amf_int64* pP...
  function AMF_RESULT (line 180) | AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::GetSize(amf_int64* pSize)
  function AMF_RESULT (line 196) | AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::Open(const wchar_t* pFile...

FILE: alvr/server_openvr/cpp/shared/amf/public/common/DataStreamFile.h
  function namespace (line 43) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/common/DataStreamMemory.cpp
  function AMF_RESULT (line 56) | AMF_RESULT AMF_STD_CALL AMFDataStreamMemoryImpl::Close()
  function AMF_RESULT (line 69) | AMF_RESULT AMFDataStreamMemoryImpl::Realloc(amf_size iSize)
  function AMF_RESULT (line 95) | AMF_RESULT AMF_STD_CALL AMFDataStreamMemoryImpl::Read(void* pData, amf_s...
  function AMF_RESULT (line 110) | AMF_RESULT AMF_STD_CALL AMFDataStreamMemoryImpl::Write(const void* pData...
  function AMF_RESULT (line 125) | AMF_RESULT AMF_STD_CALL AMFDataStreamMemoryImpl::Seek(AMF_SEEK_ORIGIN eO...
  function AMF_RESULT (line 153) | AMF_RESULT AMF_STD_CALL AMFDataStreamMemoryImpl::GetPosition(amf_int64* ...
  function AMF_RESULT (line 160) | AMF_RESULT AMF_STD_CALL AMFDataStreamMemoryImpl::GetSize(amf_int64* pSize)

FILE: alvr/server_openvr/cpp/shared/amf/public/common/DataStreamMemory.h
  function namespace (line 41) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/common/IOCapsImpl.cpp
  type amf (line 35) | namespace amf
    function amf_int32 (line 167) | amf_int32 AMF_STD_CALL AMFIOCapsImpl::GetVertAlign() const
    function amf_int32 (line 173) | amf_int32 AMF_STD_CALL AMFIOCapsImpl::GetNumOfFormats() const
    function AMF_RESULT (line 178) | AMF_RESULT AMF_STD_CALL AMFIOCapsImpl::GetFormatAt(amf_int32 index, AM...
    function amf_int32 (line 200) | amf_int32 AMF_STD_CALL AMFIOCapsImpl::GetNumOfMemoryTypes() const
    function AMF_RESULT (line 205) | AMF_RESULT AMF_STD_CALL AMFIOCapsImpl::GetMemoryTypeAt(amf_int32 index...
    function amf_bool (line 227) | amf_bool AMF_STD_CALL AMFIOCapsImpl::IsInterlacedSupported() const

FILE: alvr/server_openvr/cpp/shared/amf/public/common/IOCapsImpl.h
  type Resolution (line 77) | struct Resolution

FILE: alvr/server_openvr/cpp/shared/amf/public/common/InterfaceImpl.h
  function namespace (line 42) | namespace amf
  function AMF_STD_CALL (line 197) | AMF_STD_CALL Release()
  function AMF_STD_CALL (line 201) | AMF_STD_CALL RefCount()

FILE: alvr/server_openvr/cpp/shared/amf/public/common/ObservableImpl.h
  function namespace (line 46) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/common/PropertyStorageExImpl.cpp
  function AMF_RESULT (line 55) | AMF_RESULT amf::CastVariantToAMFProperty(amf::AMFVariantStruct* pDest, c...
  function AMFPropertyInfoImpl (line 423) | AMFPropertyInfoImpl& AMFPropertyInfoImpl::operator=(const AMFPropertyInf...

FILE: alvr/server_openvr/cpp/shared/amf/public/common/PropertyStorageExImpl.h
  function namespace (line 50) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/common/PropertyStorageImpl.h
  function namespace (line 46) | namespace amf
  function AMF_STD_CALL (line 78) | AMF_STD_CALL GetProperty(const wchar_t* pName, AMFVariantStruct* pValue)...
  function AMF_STD_CALL (line 93) | AMF_STD_CALL HasProperty(const wchar_t* pName) const
  function AMF_STD_CALL (line 104) | AMF_STD_CALL GetPropertyAt(amf_size index, wchar_t* pName, amf_size name...
  function AMF_STD_CALL (line 129) | AMF_STD_CALL Clear()
  function AMF_STD_CALL (line 135) | AMF_STD_CALL AddTo(AMFPropertyStorage* pDest, bool overwrite, bool /*dee...
  function AMF_STD_CALL (line 167) | AMF_STD_CALL CopyTo(AMFPropertyStorage* pDest, bool deep) const
  function AMF_STD_CALL (line 181) | AMF_STD_CALL OnPropertyChanged(const wchar_t* /*name*/) { }
  function AMF_STD_CALL (line 183) | AMF_STD_CALL AddObserver(AMFPropertyStorageObserver* pObserver) { AMFObs...
  function AMF_STD_CALL (line 185) | AMF_STD_CALL RemoveObserver(AMFPropertyStorageObserver* pObserver) { AMF...

FILE: alvr/server_openvr/cpp/shared/amf/public/common/Thread.cpp
  type amf (line 47) | namespace amf
    function m_hSyncObject (line 88) | bool bOpenExistent
    class AMFThreadObj (line 249) | class AMFThreadObj
      method Run (line 264) | virtual void Run() { m_pOwner->Run(); }
      method Init (line 265) | virtual bool Init(){ return m_pOwner->Init(); }
      method Terminate (line 266) | virtual bool Terminate(){ return m_pOwner->Terminate();}
      method Run (line 364) | virtual void Run()
      method Init (line 368) | virtual bool Init()
      method Terminate (line 372) | virtual bool Terminate()
      method Run (line 473) | virtual void Run() { m_pOwner->Run(); }
      method Init (line 474) | virtual bool Init(){ return m_pOwner->Init(); }
      method Terminate (line 475) | virtual bool Terminate(){ return m_pOwner->Terminate();}
    class AMFThreadObj (line 342) | class AMFThreadObj
      method Run (line 264) | virtual void Run() { m_pOwner->Run(); }
      method Init (line 265) | virtual bool Init(){ return m_pOwner->Init(); }
      method Terminate (line 266) | virtual bool Terminate(){ return m_pOwner->Terminate();}
      method Run (line 364) | virtual void Run()
      method Init (line 368) | virtual bool Init()
      method Terminate (line 372) | virtual bool Terminate()
      method Run (line 473) | virtual void Run() { m_pOwner->Run(); }
      method Init (line 474) | virtual bool Init(){ return m_pOwner->Init(); }
      method Terminate (line 475) | virtual bool Terminate(){ return m_pOwner->Terminate();}
    function ExitThread (line 453) | void ExitThread()
    class AMFThreadObj (line 460) | class AMFThreadObj
      method Run (line 264) | virtual void Run() { m_pOwner->Run(); }
      method Init (line 265) | virtual bool Init(){ return m_pOwner->Init(); }
      method Terminate (line 266) | virtual bool Terminate(){ return m_pOwner->Terminate();}
      method Run (line 364) | virtual void Run()
      method Init (line 368) | virtual bool Init()
      method Terminate (line 372) | virtual bool Terminate()
      method Run (line 473) | virtual void Run() { m_pOwner->Run(); }
      method Init (line 474) | virtual bool Init(){ return m_pOwner->Init(); }
      method Terminate (line 475) | virtual bool Terminate(){ return m_pOwner->Terminate();}
    function ExitThread (line 584) | void ExitThread()

FILE: alvr/server_openvr/cpp/shared/amf/public/common/Thread.h
  function class (line 123) | class AMF_NO_VTABLE AMFSyncBase
  function class (line 130) | class AMFEvent : public AMFSyncBase
  function class (line 150) | class AMFMutex : public AMFSyncBase

FILE: alvr/server_openvr/cpp/shared/amf/public/common/TraceAdapter.cpp
  function AMFTrace (line 54) | static AMFTrace *GetTrace()
  function AMFDebug (line 77) | static AMFDebug *GetDebug()
  function AMF_RESULT (line 98) | AMF_RESULT AMF_CDECL_CALL amf::AMFSetCustomDebugger(AMFDebug *pDebugger)
  function AMF_RESULT (line 104) | AMF_RESULT AMF_CDECL_CALL amf::AMFSetCustomTracer(AMFTrace *pTracer)
  function AMF_RESULT (line 110) | AMF_RESULT AMF_CDECL_CALL amf::AMFTraceEnableAsync(bool enable)
  function AMF_RESULT (line 115) | AMF_RESULT AMF_CDECL_CALL amf::AMFTraceFlush()
  function AMF_RESULT (line 138) | AMF_RESULT AMF_CDECL_CALL amf::AMFTraceSetPath(const wchar_t* path)
  function AMF_RESULT (line 143) | AMF_RESULT AMF_CDECL_CALL amf::AMFTraceGetPath(wchar_t* path, amf_size* ...
  function amf_int32 (line 158) | amf_int32 AMF_CDECL_CALL amf::AMFTraceSetGlobalLevel(amf_int32 level)
  function amf_int32 (line 163) | amf_int32 AMF_CDECL_CALL amf::AMFTraceGetGlobalLevel()
  function amf_int32 (line 168) | amf_int32 AMF_CDECL_CALL amf::AMFTraceSetWriterLevel(const wchar_t* writ...
  function amf_int32 (line 173) | amf_int32 AMF_CDECL_CALL amf::AMFTraceGetWriterLevel(const wchar_t* writ...
  function amf_int32 (line 178) | amf_int32 AMF_CDECL_CALL amf::AMFTraceSetWriterLevelForScope(const wchar...
  function amf_int32 (line 183) | amf_int32 AMF_CDECL_CALL amf::AMFTraceGetWriterLevelForScope(const wchar...
  function amf_uint32 (line 209) | amf_uint32 AMF_CDECL_CALL AMFTraceGetScopeDepth()
  function amf_wstring (line 227) | amf_wstring AMF_CDECL_CALL  amf::AMFFormatResult(AMF_RESULT result)
  function wchar_t (line 232) | const wchar_t* AMF_STD_CALL amf::AMFGetResultText(AMF_RESULT res)
  function wchar_t (line 236) | const wchar_t* AMF_STD_CALL amf::AMFSurfaceGetFormatName(const AMF_SURFA...
  function AMF_SURFACE_FORMAT (line 240) | AMF_SURFACE_FORMAT AMF_STD_CALL amf::AMFSurfaceGetFormatByName(const wch...
  function wchar_t (line 244) | const wchar_t* AMF_STD_CALL amf::AMFGetMemoryTypeName(const AMF_MEMORY_T...
  function AMF_MEMORY_TYPE (line 249) | AMF_MEMORY_TYPE AMF_STD_CALL amf::AMFGetMemoryTypeByName(const wchar_t* ...

FILE: alvr/server_openvr/cpp/shared/amf/public/common/TraceAdapter.h
  function namespace (line 72) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/common/Windows/ThreadWindows.cpp
  function amf_long (line 44) | amf_long AMF_CDECL_CALL amf_atomic_inc(amf_long* X)
  function amf_long (line 49) | amf_long AMF_CDECL_CALL amf_atomic_dec(amf_long* X)
  function amf_handle (line 54) | amf_handle AMF_CDECL_CALL amf_create_critical_section()
  function amf_handle (line 121) | amf_handle AMF_CDECL_CALL amf_create_event(bool bInitiallyOwned, bool bM...
  function amf_handle (line 192) | amf_handle AMF_CDECL_CALL amf_create_mutex(bool bInitiallyOwned, const w...
  function amf_handle (line 204) | amf_handle AMF_CDECL_CALL amf_open_mutex(const wchar_t* pName)
  function amf_handle (line 242) | amf_handle AMF_CDECL_CALL amf_create_semaphore(amf_long iInitCount, amf_...
  function amf_pts (line 299) | amf_pts AMF_CDECL_CALL amf_high_precision_clock()
  function amf_handle (line 395) | amf_handle  AMF_CDECL_CALL amf_load_library1(const wchar_t* filename, bo...
  function amf_handle (line 400) | amf_handle AMF_CDECL_CALL amf_load_library(const wchar_t* filename)
  function amf_int32 (line 438) | amf_int32 AMF_STD_CALL amf_get_cpu_cores()

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/Ambisonic2SRenderer.h
  type AMF_AMBISONIC2SRENDERER_MODE_ENUM (line 45) | enum AMF_AMBISONIC2SRENDERER_MODE_ENUM

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/Capture.h
  type AMF_CAPTURE_DEVICE_TYPE_ENUM (line 42) | typedef enum AMF_CAPTURE_DEVICE_TYPE_ENUM
  type AMFInterfacePtr_T (line 79) | typedef AMFInterfacePtr_T<AMFCaptureDevice> AMFCaptureDevicePtr;
  type AMFCaptureVtbl (line 84) | typedef struct AMFCaptureDeviceVtbl
  type AMFCapture (line 141) | struct AMFCapture
  type AMFInterfacePtr_T (line 164) | typedef AMFInterfacePtr_T<AMFCaptureManager> AMFCaptureManagerPtr;
  type AMFCaptureManagerVtbl (line 169) | typedef struct AMFCaptureManagerVtbl
  type AMFCaptureManager (line 184) | struct AMFCaptureManager

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/ColorSpace.h
  type AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM (line 43) | typedef enum AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM
  type AMF_COLOR_PRIMARIES_ENUM (line 61) | typedef enum AMF_COLOR_PRIMARIES_ENUM // as in VUI color_primaries AVC a...
  type AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM (line 80) | typedef enum AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM // as in VUI transfe...
  type AMF_COLOR_BIT_DEPTH_ENUM (line 103) | typedef enum AMF_COLOR_BIT_DEPTH_ENUM
  type AMFHDRMetadata (line 110) | typedef struct AMFHDRMetadata
  type AMF_COLOR_RANGE_ENUM (line 123) | typedef enum AMF_COLOR_RANGE_ENUM

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/Component.h
  type AMFInterfacePtr_T (line 69) | typedef AMFInterfacePtr_T<AMFDataAllocatorCB> AMFDataAllocatorCBPtr;
  type AMFDataAllocatorCB (line 72) | typedef struct AMFDataAllocatorCB AMFDataAllocatorCB;
  type AMFDataAllocatorCBVtbl (line 74) | typedef struct AMFDataAllocatorCBVtbl
  type AMFDataAllocatorCB (line 86) | struct AMFDataAllocatorCB
  function class (line 94) | class AMF_NO_VTABLE AMFComponentOptimizationCallback
  type AMFComponentOptimizationCallback (line 100) | typedef struct AMFComponentOptimizationCallback AMFComponentOptimization...
  type AMFComponentOptimizationCallbackVtbl (line 101) | typedef struct AMFComponentOptimizationCallbackVtbl
  type AMFComponentOptimizationCallback (line 107) | struct AMFComponentOptimizationCallback
  type AMFInterfacePtr_T (line 139) | typedef AMFInterfacePtr_T<AMFComponent> AMFComponentPtr;
  type AMFComponent (line 142) | typedef struct AMFComponent AMFComponent;
  type AMFComponentVtbl (line 144) | typedef struct AMFComponentVtbl
  type AMFComponent (line 187) | struct AMFComponent
  type AMFInterfacePtr_T (line 207) | typedef AMFInterfacePtr_T<AMFInput> AMFInputPtr;
  type AMFInput (line 210) | typedef struct AMFInput AMFInput;
  type AMFInputVtbl (line 212) | typedef struct AMFInputVtbl
  type AMFInput (line 243) | struct AMFInput
  type AMFInterfacePtr_T (line 263) | typedef AMFInterfacePtr_T<AMFOutput> AMFOutputPtr;
  type AMFOutput (line 266) | typedef struct AMFOutput AMFOutput;
  type AMFOutputVtbl (line 268) | typedef struct AMFOutputVtbl
  type AMFOutput (line 299) | struct AMFOutput
  type AMFInterfacePtr_T (line 324) | typedef AMFInterfacePtr_T<AMFComponentEx> AMFComponentExPtr;
  type AMFComponentEx (line 327) | typedef struct AMFComponentEx AMFComponentEx;
  type AMFComponentExVtbl (line 329) | typedef struct AMFComponentExVtbl
  type AMFComponentEx (line 382) | struct AMFComponentEx
  type AMF_STREAM_TYPE_ENUM (line 393) | typedef enum AMF_STREAM_TYPE_ENUM
  type AMF_STREAM_CODEC_ID_ENUM (line 401) | typedef enum AMF_STREAM_CODEC_ID_ENUM     // matched codecs from VideoDe...

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/ComponentCaps.h
  type AMF_ACCELERATION_TYPE (line 46) | typedef enum AMF_ACCELERATION_TYPE
  function AMF_STD_CALL (line 65) | AMF_STD_CALL GetVertAlign() const = 0;
  type AMFIOCaps (line 110) | struct AMFIOCaps
  type AMFInterfacePtr_T (line 131) | typedef AMFInterfacePtr_T<AMFCaps>  AMFCapsPtr;
  type AMFCaps (line 133) | typedef struct AMFCaps AMFCaps;
  type AMFCapsVtbl (line 135) | typedef struct AMFCapsVtbl
  type AMFCaps (line 161) | struct AMFCaps

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/CursorCapture.h
  function namespace (line 41) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/DisplayCapture.h
  type AMF_DISPLAYCAPTURE_MODE_ENUM (line 54) | typedef enum AMF_DISPLAYCAPTURE_MODE_ENUM

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/FRC.h
  type AMF_FRC_ENGINE (line 41) | enum AMF_FRC_ENGINE
  type AMF_FRC_MODE_TYPE (line 49) | enum AMF_FRC_MODE_TYPE
  type AMF_FRC_SNAPSHOT_MODE_TYPE (line 58) | enum AMF_FRC_SNAPSHOT_MODE_TYPE {
  type AMF_FRC_PROFILE (line 67) | enum AMF_FRC_PROFILE {
  type AMF_FRC_MV_SEARCH_MODE (line 74) | enum AMF_FRC_MV_SEARCH_MODE {

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/HQScaler.h
  type AMF_HQ_SCALER_ALGORITHM_ENUM (line 42) | enum  AMF_HQ_SCALER_ALGORITHM_ENUM

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/MediaSource.h
  function namespace (line 40) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/PreAnalysis.h
  type AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_ENUM (line 42) | enum  AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_ENUM
  type AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_ENUM (line 50) | enum  AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_ENUM
  type AMF_PA_ACTIVITY_TYPE_ENUM (line 58) | enum  AMF_PA_ACTIVITY_TYPE_ENUM
  type AMF_PA_CAQ_STRENGTH_ENUM (line 65) | enum  AMF_PA_CAQ_STRENGTH_ENUM
  type AMF_PA_PAQ_MODE_ENUM (line 73) | enum AMF_PA_PAQ_MODE_ENUM
  type AMF_PA_TAQ_MODE_ENUM (line 80) | enum  AMF_PA_TAQ_MODE_ENUM
  type AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE_ENUM (line 87) | enum AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE_ENUM

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/SupportedCodecs.h
  function namespace (line 47) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/VideoConverter.h
  type AMF_VIDEO_CONVERTER_SCALE_ENUM (line 45) | enum AMF_VIDEO_CONVERTER_SCALE_ENUM
  type AMF_VIDEO_CONVERTER_TONEMAPPING_ENUM (line 52) | enum AMF_VIDEO_CONVERTER_TONEMAPPING_ENUM

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/VideoDecoderUVD.h
  type AMF_VIDEO_DECODER_MODE_ENUM (line 58) | enum AMF_VIDEO_DECODER_MODE_ENUM
  type AMF_TIMESTAMP_MODE_ENUM (line 64) | enum AMF_TIMESTAMP_MODE_ENUM

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/VideoEncoderAV1.h
  type AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_ENUM (line 37) | enum AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_ENUM
  type AMF_VIDEO_ENCODER_AV1_USAGE_ENUM (line 45) | enum AMF_VIDEO_ENCODER_AV1_USAGE_ENUM
  type AMF_VIDEO_ENCODER_AV1_PROFILE_ENUM (line 55) | enum AMF_VIDEO_ENCODER_AV1_PROFILE_ENUM
  type AMF_VIDEO_ENCODER_AV1_LEVEL_ENUM (line 60) | enum AMF_VIDEO_ENCODER_AV1_LEVEL_ENUM
  type AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_ENUM (line 88) | enum AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_ENUM
  type AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_ENUM (line 100) | enum AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_ENUM
  type AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE_ENUM (line 107) | enum AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE_ENUM
  type AMF_VIDEO_ENCODER_AV1_OUTPUT_FRAME_TYPE_ENUM (line 116) | enum AMF_VIDEO_ENCODER_AV1_OUTPUT_FRAME_TYPE_ENUM
  type AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_ENUM (line 125) | enum AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_ENUM
  type AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_ENUM (line 133) | enum AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_ENUM
  type AMF_VIDEO_ENCODER_AV1_SWITCH_FRAME_INSERTION_MODE_ENUM (line 140) | enum AMF_VIDEO_ENCODER_AV1_SWITCH_FRAME_INSERTION_MODE_ENUM
  type AMF_VIDEO_ENCODER_AV1_CDEF_MODE_ENUM (line 146) | enum AMF_VIDEO_ENCODER_AV1_CDEF_MODE_ENUM
  type AMF_VIDEO_ENCODER_AV1_CDF_FRAME_END_UPDATE_MODE_ENUM (line 152) | enum AMF_VIDEO_ENCODER_AV1_CDF_FRAME_END_UPDATE_MODE_ENUM
  type AMF_VIDEO_ENCODER_AV1_AQ_MODE_ENUM (line 158) | enum AMF_VIDEO_ENCODER_AV1_AQ_MODE_ENUM
  type AMF_VIDEO_ENCODER_AV1_INTRA_REFRESH_MODE_ENUM (line 164) | enum AMF_VIDEO_ENCODER_AV1_INTRA_REFRESH_MODE_ENUM
  type AMF_VIDEO_ENCODER_AV1_LTR_MODE_ENUM (line 170) | enum AMF_VIDEO_ENCODER_AV1_LTR_MODE_ENUM
  type AMF_VIDEO_ENCODER_AV1_OUTPUT_MODE_ENUM (line 176) | enum AMF_VIDEO_ENCODER_AV1_OUTPUT_MODE_ENUM
  type AMF_VIDEO_ENCODER_AV1_OUTPUT_BUFFER_TYPE_ENUM (line 182) | enum AMF_VIDEO_ENCODER_AV1_OUTPUT_BUFFER_TYPE_ENUM

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/VideoEncoderHEVC.h
  type AMF_VIDEO_ENCODER_HEVC_USAGE_ENUM (line 37) | enum AMF_VIDEO_ENCODER_HEVC_USAGE_ENUM
  type AMF_VIDEO_ENCODER_HEVC_PROFILE_ENUM (line 48) | enum AMF_VIDEO_ENCODER_HEVC_PROFILE_ENUM
  type AMF_VIDEO_ENCODER_HEVC_TIER_ENUM (line 54) | enum AMF_VIDEO_ENCODER_HEVC_TIER_ENUM
  type AMF_VIDEO_ENCODER_LEVEL_ENUM (line 60) | enum AMF_VIDEO_ENCODER_LEVEL_ENUM
  type AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_ENUM (line 77) | enum AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_ENUM
  type AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_ENUM (line 89) | enum AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_ENUM
  type AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_ENUM (line 98) | enum AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_ENUM
  type AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_ENUM (line 105) | enum AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_ENUM
  type AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_ENUM (line 112) | enum AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_ENUM
  type AMF_VIDEO_ENCODER_HEVC_PICTURE_TRANSFER_MODE_ENUM (line 119) | enum AMF_VIDEO_ENCODER_HEVC_PICTURE_TRANSFER_MODE_ENUM
  type AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE (line 125) | enum AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE
  type AMF_VIDEO_ENCODER_HEVC_LTR_MODE_ENUM (line 131) | enum AMF_VIDEO_ENCODER_HEVC_LTR_MODE_ENUM
  type AMF_VIDEO_ENCODER_HEVC_OUTPUT_MODE_ENUM (line 137) | enum AMF_VIDEO_ENCODER_HEVC_OUTPUT_MODE_ENUM
  type AMF_VIDEO_ENCODER_HEVC_OUTPUT_BUFFER_TYPE_ENUM (line 143) | enum AMF_VIDEO_ENCODER_HEVC_OUTPUT_BUFFER_TYPE_ENUM

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/VideoEncoderVCE.h
  type AMF_VIDEO_ENCODER_USAGE_ENUM (line 48) | enum AMF_VIDEO_ENCODER_USAGE_ENUM
  type AMF_VIDEO_ENCODER_PROFILE_ENUM (line 59) | enum AMF_VIDEO_ENCODER_PROFILE_ENUM
  type AMF_VIDEO_ENCODER_H264_LEVEL_ENUM (line 69) | enum AMF_VIDEO_ENCODER_H264_LEVEL_ENUM
  type AMF_VIDEO_ENCODER_SCANTYPE_ENUM (line 92) | enum AMF_VIDEO_ENCODER_SCANTYPE_ENUM
  type AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_ENUM (line 98) | enum AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_ENUM
  type AMF_VIDEO_ENCODER_QUALITY_PRESET_ENUM (line 110) | enum AMF_VIDEO_ENCODER_QUALITY_PRESET_ENUM
  type AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_ENUM (line 117) | enum AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_ENUM
  type AMF_VIDEO_ENCODER_PICTURE_TYPE_ENUM (line 125) | enum AMF_VIDEO_ENCODER_PICTURE_TYPE_ENUM
  type AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_ENUM (line 135) | enum AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_ENUM
  type AMF_VIDEO_ENCODER_PREENCODE_MODE_ENUM (line 143) | enum AMF_VIDEO_ENCODER_PREENCODE_MODE_ENUM
  type AMF_VIDEO_ENCODER_CODING_ENUM (line 149) | enum AMF_VIDEO_ENCODER_CODING_ENUM
  type AMF_VIDEO_ENCODER_PICTURE_TRANSFER_MODE_ENUM (line 157) | enum AMF_VIDEO_ENCODER_PICTURE_TRANSFER_MODE_ENUM
  type AMF_VIDEO_ENCODER_LTR_MODE_ENUM (line 163) | enum AMF_VIDEO_ENCODER_LTR_MODE_ENUM
  type AMF_VIDEO_ENCODER_OUTPUT_MODE_ENUM (line 169) | enum AMF_VIDEO_ENCODER_OUTPUT_MODE_ENUM
  type AMF_VIDEO_ENCODER_OUTPUT_BUFFER_TYPE_ENUM (line 175) | enum AMF_VIDEO_ENCODER_OUTPUT_BUFFER_TYPE_ENUM

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/VideoStitch.h
  type AMF_VIDEO_STITCH_LENS_ENUM (line 91) | enum AMF_VIDEO_STITCH_LENS_ENUM
  type AMF_VIDEO_STITCH_OUTPUT_MODE_ENUM (line 99) | enum AMF_VIDEO_STITCH_OUTPUT_MODE_ENUM
  type AMF_VIDEO_STITCH_AUDIO_MODE_ENUM (line 108) | enum AMF_VIDEO_STITCH_AUDIO_MODE_ENUM

FILE: alvr/server_openvr/cpp/shared/amf/public/include/components/ZCamLiveStream.h
  type CAMLIVE_MODE_ENUM (line 56) | enum CAMLIVE_MODE_ENUM
  type CAM_AUDIO_MODE_ENUM (line 72) | enum CAM_AUDIO_MODE_ENUM

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/AudioBuffer.h
  function namespace (line 44) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Buffer.h
  function namespace (line 45) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Compute.h
  function namespace (line 47) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/ComputeFactory.h
  function namespace (line 40) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Context.h
  function namespace (line 44) | namespace amf
  type AMF_CONTEXT_DEVICETYPE_ENUM (line 780) | enum AMF_CONTEXT_DEVICETYPE_ENUM

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/CurrentTime.h
  function namespace (line 29) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Data.h
  function namespace (line 40) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Debug.h
  function namespace (line 41) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Dump.h
  function AMF_STD_CALL (line 56) | AMF_STD_CALL IsInputDumpEnabled() const = 0;
  type AMFDump (line 101) | struct AMFDump

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Factory.h
  function class (line 56) | class AMF_NO_VTABLE AMFFactory
  type AMFFactory (line 68) | typedef struct AMFFactory AMFFactory;
  type AMFFactoryVtbl (line 70) | typedef struct AMFFactoryVtbl
  type AMFFactory (line 81) | struct AMFFactory

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Interface.h
  function namespace (line 40) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Plane.h
  function namespace (line 40) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Platform.h
  type HRESULT (line 80) | typedef signed int HRESULT;
  type amf_int64 (line 155) | typedef     int64_t             amf_int64;
  type amf_int32 (line 156) | typedef     int32_t             amf_int32;
  type amf_int16 (line 157) | typedef     int16_t             amf_int16;
  type amf_int8 (line 158) | typedef     int8_t              amf_int8;
  type amf_uint64 (line 160) | typedef     uint64_t            amf_uint64;
  type amf_uint32 (line 161) | typedef     uint32_t            amf_uint32;
  type amf_uint16 (line 162) | typedef     uint16_t            amf_uint16;
  type amf_uint8 (line 163) | typedef     uint8_t             amf_uint8;
  type amf_size (line 164) | typedef     size_t              amf_size;
  type amf_double (line 167) | typedef     double              amf_double;
  type amf_float (line 168) | typedef     float               amf_float;
  type amf_void (line 170) | typedef     void                amf_void;
  type amf_bool (line 173) | typedef     bool                amf_bool;
  type amf_uint8 (line 175) | typedef     amf_uint8           amf_bool;
  type amf_long (line 180) | typedef     long                amf_long;
  type amf_int (line 181) | typedef     int                 amf_int;
  type amf_ulong (line 182) | typedef     unsigned long       amf_ulong;
  type amf_uint (line 183) | typedef     unsigned int        amf_uint;
  type amf_int64 (line 185) | typedef     amf_int64           amf_pts;
  type amf_uint32 (line 187) | typedef amf_uint32              amf_flags;
  type typedef (line 207) | typedef struct AMFRect
  type AMFSize (line 230) | struct AMFSize
  function AMFSize (line 243) | AMFSize AMFConstructSize(amf_int32 width, amf_int32 height)
  type AMFPoint (line 249) | typedef struct AMFPoint
  function AMFPoint (line 262) | AMFPoint AMFConstructPoint(amf_int32 x, amf_int32 y)
  type AMFFloatPoint2D (line 268) | typedef struct AMFFloatPoint2D
  function AMFFloatPoint2D (line 281) | AMFFloatPoint2D AMFConstructFloatPoint2D(amf_float x, amf_float y)
  type AMFFloatSize (line 286) | typedef struct AMFFloatSize
  function AMFFloatSize (line 299) | AMFFloatSize AMFConstructFloatSize(amf_float w, amf_float h)
  type AMFFloatPoint3D (line 306) | typedef struct AMFFloatPoint3D
  function AMFFloatPoint3D (line 320) | AMFFloatPoint3D AMFConstructFloatPoint3D(amf_float x, amf_float y, amf_f...
  type AMFFloatVector4D (line 326) | typedef struct AMFFloatVector4D
  function AMFFloatVector4D (line 341) | AMFFloatVector4D AMFConstructFloatVector4D(amf_float x, amf_float y, amf...
  type AMFRate (line 348) | typedef struct AMFRate
  function AMFRate (line 361) | AMFRate AMFConstructRate(amf_uint32 num, amf_uint32 den)
  type AMFRatio (line 367) | typedef struct AMFRatio
  function AMFRatio (line 380) | AMFRatio AMFConstructRatio(amf_uint32 num, amf_uint32 den)
  type AMFColor (line 393) | typedef struct AMFColor
  function AMFColor (line 420) | AMFColor AMFConstructColor(amf_uint8 r, amf_uint8 g, amf_uint8 b, amf_ui...
  function AMF_INLINE (line 438) | static AMF_INLINE void* AMF_CDECL_CALL amf_variant_alloc(amf_size count)
  function AMF_CDECL_CALL (line 442) | AMF_CDECL_CALL amf_variant_free(void* ptr)
  function AMF_INLINE (line 457) | static AMF_INLINE void* AMF_CDECL_CALL amf_variant_alloc(amf_size count)
  function AMF_CDECL_CALL (line 461) | AMF_CDECL_CALL amf_variant_free(void* ptr)
  type AMFGuid (line 475) | typedef struct AMFGuid
  function AMF_INLINE (line 525) | static AMF_INLINE bool AMFCompareGUIDs(const AMFGuid& guid1, const AMFGu...
  function AMF_INLINE (line 530) | static AMF_INLINE amf_bool AMFCompareGUIDs(const struct AMFGuid guid1, c...

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/PropertyStorage.h
  function class (line 48) | class AMF_NO_VTABLE AMFPropertyStorageObserver
  type AMFPropertyStorageObserver (line 54) | typedef struct AMFPropertyStorageObserver AMFPropertyStorageObserver;
  type AMFPropertyStorageObserverVtbl (line 55) | typedef struct AMFPropertyStorageObserverVtbl
  type AMFPropertyStorageObserver (line 60) | struct AMFPropertyStorageObserver
  type AMFPropertyStorage (line 106) | struct AMFPropertyStorage
  type AMFPropertyStorageVtbl (line 109) | struct AMFPropertyStorageVtbl
  type AMFPropertyStorage (line 130) | struct AMFPropertyStorage

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/PropertyStorageEx.h
  function namespace (line 40) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Result.h
  type AMF_RESULT (line 43) | typedef enum AMF_RESULT

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Surface.h
  function namespace (line 46) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Trace.h
  function namespace (line 43) | namespace amf

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/Variant.h
  function namespace (line 46) | namespace amf
  function AMF_CDECL_CALL (line 587) | AMF_CDECL_CALL AMFVariantInit(AMFVariantStruct* pVariant)
  function AMF_CDECL_CALL (line 594) | AMF_CDECL_CALL AMFVariantClear(AMFVariantStruct* pVariant)
  function AMF_CDECL_CALL (line 631) | AMF_CDECL_CALL AMFVariantCompare(const AMFVariantStruct* pFirst, const A...
  function AMF_CDECL_CALL (line 752) | AMF_CDECL_CALL AMFVariantCopy(AMFVariantStruct* pDest, const AMFVariantS...
  function AMF_CDECL_CALL (line 846) | AMF_CDECL_CALL AMFVariantAssignString(AMFVariantStruct* pDest, const AMF...
  function AMF_CDECL_CALL (line 850) | AMF_CDECL_CALL AMFVariantAssignWString(AMFVariantStruct* pDest, const AM...
  function AMF_INLINE (line 855) | static AMF_INLINE amf_bool AMFConvertEmptyToBool(void*, AMF_RESULT& res)...
  function AMF_INLINE (line 856) | static AMF_INLINE amf_int64 AMFConvertEmptyToInt64(void*, AMF_RESULT& re...
  function AMF_INLINE (line 857) | static AMF_INLINE amf_double AMFConvertEmptyToDouble(void*, AMF_RESULT& ...
  function AMF_INLINE (line 858) | static AMF_INLINE amf_float AMFConvertEmptyToFloat(void*, AMF_RESULT& re...
  function AMF_INLINE (line 861) | static AMF_INLINE AMFVariant::String AMFConvertEmptyToString(void*, AMF_...
  function AMF_INLINE (line 862) | static AMF_INLINE AMFVariant::WString AMFConvertEmptyToWString(void*, AM...
  function AMF_INLINE (line 863) | static AMF_INLINE amf_int64 AMFConvertBoolToInt64(bool value, AMF_RESULT...
  function AMF_INLINE (line 864) | static AMF_INLINE amf_double AMFConvertBoolToDouble(bool value, AMF_RESU...
  function AMF_INLINE (line 865) | static AMF_INLINE amf_float AMFConvertBoolToFloat(bool value, AMF_RESULT...
  function AMF_INLINE (line 866) | static AMF_INLINE AMFVariant::String AMFConvertBoolToString(bool value, ...
  function AMF_INLINE (line 867) | static AMF_INLINE AMFVariant::WString AMFConvertBoolToWString(bool value...
  function AMF_INLINE (line 868) | static AMF_INLINE bool AMFConvertInt64ToBool(amf_int64 value, AMF_RESULT...
  function AMF_INLINE (line 869) | static AMF_INLINE amf_double AMFConvertInt64ToDouble(amf_int64 value, AM...
  function AMF_INLINE (line 870) | static AMF_INLINE amf_float AMFConvertInt64ToFloat(amf_int64 value, AMF_...
  function AMF_INLINE (line 871) | static AMF_INLINE AMFVariant::String AMFConvertInt64ToString(amf_int64 v...
  function AMF_INLINE (line 878) | static AMF_INLINE AMFVariant::WString AMFConvertInt64ToWString(amf_int64...
  function AMF_INLINE (line 886) | static AMF_INLINE bool AMFConvertDoubleToBool(amf_double value, AMF_RESU...
  function AMF_INLINE (line 887) | static AMF_INLINE bool AMFConvertFloatToBool(amf_float value, AMF_RESULT...
  function AMF_INLINE (line 888) | static AMF_INLINE amf_int64 AMFConvertDoubleToInt64(amf_double value, AM...
  function AMF_INLINE (line 889) | static AMF_INLINE amf_int64 AMFConvertFloatToInt64(amf_float value, AMF_...
  function AMF_INLINE (line 890) | static AMF_INLINE AMFVariant::String AMFConvertDoubleToString(amf_double...
  function AMF_INLINE (line 897) | static AMF_INLINE AMFVariant::String AMFConvertFloatToString(amf_float v...
  function AMF_INLINE (line 904) | static AMF_INLINE AMFVariant::WString AMFConvertDoubleToWString(amf_doub...
  function AMF_INLINE (line 911) | static AMF_INLINE AMFVariant::WString AMFConvertFloatToWString(amf_float...
  function AMF_INLINE (line 919) | static AMF_INLINE bool AMFConvertStringToBool(const AMFVariant::String& ...
  function AMF_INLINE (line 938) | static AMF_INLINE amf_int64 AMFConvertStringToInt64(const AMFVariant::St...
  function AMF_INLINE (line 976) | static AMF_INLINE amf_float AMFConvertStringToFloat(const AMFVariant::St...
  function AMF_INLINE (line 993) | static AMF_INLINE AMFVariant::WString AMFConvertStringToWString(const AM...
  function AMF_INLINE (line 1072) | static AMF_INLINE AMFVariant::String AMFConvertWStringToString(const AMF...
  function AMF_INLINE (line 1138) | static AMF_INLINE bool AMFConvertWStringToBool(const AMFVariant::WString...
  function AMF_INLINE (line 1142) | static AMF_INLINE amf_int64 AMFConvertWStringToInt64(const AMFVariant::W...
  function AMF_INLINE (line 1150) | static AMF_INLINE amf_float AMFConvertWStringToFloat(const AMFVariant::W...
  function AMF_INLINE (line 1155) | static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertRectToString...
  function AMF_INLINE (line 1162) | static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertSizeToString...
  function AMF_INLINE (line 1169) | static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertPointToStrin...
  function AMF_INLINE (line 1176) | static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertFloatSizeToS...
  function AMF_INLINE (line 1183) | static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertFloatPoint2D...
  function AMF_INLINE (line 1190) | static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertFloatPoint3D...
  function AMF_INLINE (line 1197) | static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertFloatVector4...
  function AMF_INLINE (line 1204) | static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertRateToString...
  function AMF_INLINE (line 1211) | static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertRatioToStrin...
  function AMF_INLINE (line 1218) | static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertColorToStrin...
  function AMF_STD_CALL (line 1226) | AMF_STD_CALL AMFConvertStringToRect(const AMFVariant::String& value, AMF...
  function AMF_STD_CALL (line 1243) | AMF_STD_CALL AMFConvertStringToSize(const AMFVariant::String& value, AMF...
  function AMF_STD_CALL (line 1266) | AMF_STD_CALL AMFConvertStringToPoint(const AMFVariant::String& value, AM...
  function AMF_STD_CALL (line 1282) | AMF_STD_CALL AMFConvertStringToFloatSize(const AMFVariant::String& value...
  function AMF_STD_CALL (line 1298) | AMF_STD_CALL AMFConvertStringToFloatPoint2D(const AMFVariant::String& va...
  function AMF_STD_CALL (line 1314) | AMF_STD_CALL AMFConvertStringToFloatPoint3D(const AMFVariant::String& va...
  function AMF_STD_CALL (line 1330) | AMF_STD_CALL AMFConvertStringToFloatVector4D(const AMFVariant::String& v...
  function AMF_STD_CALL (line 1346) | AMF_STD_CALL AMFConvertStringToRate(const AMFVariant::String& value, AMF...
  function AMF_STD_CALL (line 1362) | AMF_STD_CALL AMFConvertStringToRatio(const AMFVariant::String& value, AM...
  function AMF_STD_CALL (line 1378) | AMF_STD_CALL AMFConvertStringToColor(const AMFVariant::String& value, AM...
  function AMF_INLINE (line 1398) | static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertRectToWStri...
  function AMF_INLINE (line 1402) | static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertSizeToWStri...
  function AMF_INLINE (line 1406) | static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertPointToWStr...
  function AMF_INLINE (line 1410) | static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertFloatSizeTo...
  function AMF_INLINE (line 1414) | static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertFloatPoint2...
  function AMF_INLINE (line 1418) | static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertFloatPoint3...
  function AMF_INLINE (line 1422) | static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertFloatVector...
  function AMF_INLINE (line 1426) | static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertRateToWStri...
  function AMF_INLINE (line 1430) | static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertRatioToWStr...
  function AMF_INLINE (line 1434) | static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertColorToWStr...
  function AMF_STD_CALL (line 1439) | AMF_STD_CALL AMFConvertWStringToRect(const AMFVariant::WString& value, A...
  function AMF_STD_CALL (line 1444) | AMF_STD_CALL AMFConvertWStringToSize(const AMFVariant::WString& value, A...
  function AMF_STD_CALL (line 1448) | AMF_STD_CALL AMFConvertWStringToPoint(const AMFVariant::WString& value, ...
  function AMF_STD_CALL (line 1452) | AMF_STD_CALL AMFConvertWStringToFloatSize(const AMFVariant::WString& val...
  function AMF_STD_CALL (line 1456) | AMF_STD_CALL AMFConvertWStringToFloatPoint2D(const AMFVariant::WString& ...
  function AMF_STD_CALL (line 1460) | AMF_STD_CALL AMFConvertWStringToFloatPoint3D(const AMFVariant::WString& ...
  function AMF_STD_CALL (line 1464) | AMF_STD_CALL AMFConvertWStringToFloatVector4D(const AMFVariant::WString&...
  function AMF_STD_CALL (line 1468) | AMF_STD_CALL AMFConvertWStringToRate(const AMFVariant::WString& value, A...
  function AMF_STD_CALL (line 1472) | AMF_STD_CALL AMFConvertWStringToRatio(const AMFVariant::WString& value, ...
  function AMF_STD_CALL (line 1476) | AMF_STD_CALL AMFConvertWStringToColor(const AMFVariant::WString& value, ...
  function AMF_CDECL_CALL (line 1490) | AMF_CDECL_CALL AMFVariantChangeType(AMFVariantStruct* pDest, const AMFVa...
  function AMF_CDECL_CALL (line 1587) | AMF_CDECL_CALL AMFVariantAssignBool(AMFVariantStruct* pDest, amf_bool va...
  function AMF_CDECL_CALL (line 1601) | AMF_CDECL_CALL AMFVariantAssignInt64(AMFVariantStruct* pDest, amf_int64 ...
  function AMF_CDECL_CALL (line 1615) | AMF_CDECL_CALL AMFVariantAssignDouble(AMFVariantStruct* pDest, amf_doubl...
  function AMF_CDECL_CALL (line 1629) | AMF_CDECL_CALL AMFVariantAssignFloat(AMFVariantStruct* pDest, amf_float ...
  function AMF_CDECL_CALL (line 1643) | AMF_CDECL_CALL AMFVariantAssignString(AMFVariantStruct* pDest, const cha...
  function AMF_CDECL_CALL (line 1667) | AMF_CDECL_CALL AMFVariantAssignWString(AMFVariantStruct* pDest, const wc...
  function AMF_CDECL_CALL (line 1691) | AMF_CDECL_CALL AMFVariantAssignInterface(AMFVariantStruct* pDest, AMFInt...
  function AMF_CDECL_CALL (line 1715) | AMF_CDECL_CALL AMFVariantAssignRect(AMFVariantStruct* pDest, const AMFRe...
  function AMF_CDECL_CALL (line 1721) | AMF_CDECL_CALL AMFVariantAssignRect (AMFVariantStruct* pDest, const AMFR...
  function AMF_CDECL_CALL (line 1737) | AMF_CDECL_CALL AMFVariantAssignSize (AMFVariantStruct* pDest, const AMFS...
  function AMF_CDECL_CALL (line 1743) | AMF_CDECL_CALL AMFVariantAssignSize (AMFVariantStruct* pDest, const AMFS...
  function AMF_CDECL_CALL (line 1759) | AMF_CDECL_CALL AMFVariantAssignPoint(AMFVariantStruct* pDest, const AMFP...
  function AMF_CDECL_CALL (line 1763) | AMF_CDECL_CALL AMFVariantAssignFloatSize(AMFVariantStruct* pDest, const ...
  function AMF_CDECL_CALL (line 1767) | AMF_CDECL_CALL AMFVariantAssignFloatPoint2D(AMFVariantStruct* pDest, con...
  function AMF_CDECL_CALL (line 1771) | AMF_CDECL_CALL AMFVariantAssignFloatPoint3D(AMFVariantStruct* pDest, con...
  function AMF_CDECL_CALL (line 1775) | AMF_CDECL_CALL AMFVariantAssignFloatVector4D(AMFVariantStruct* pDest, co...
  function AMF_CDECL_CALL (line 1781) | AMF_CDECL_CALL AMFVariantAssignPoint(AMFVariantStruct* pDest, const AMFP...
  function AMF_CDECL_CALL (line 1796) | AMF_CDECL_CALL AMFVariantAssignFloatSize(AMFVariantStruct* pDest, const ...
  function AMF_CDECL_CALL (line 1811) | AMF_CDECL_CALL AMFVariantAssignFloatPoint2D(AMFVariantStruct* pDest, con...
  function AMF_CDECL_CALL (line 1826) | AMF_CDECL_CALL AMFVariantAssignFloatPoint3D(AMFVariantStruct* pDest, con...
  function AMF_CDECL_CALL (line 1841) | AMF_CDECL_CALL AMFVariantAssignFloatVector4D(AMFVariantStruct* pDest, co...
  function AMF_CDECL_CALL (line 1857) | AMF_CDECL_CALL AMFVariantAssignRate (AMFVariantStruct* pDest, const AMFR...
  function AMF_CDECL_CALL (line 1863) | AMF_CDECL_CALL AMFVariantAssignRate (AMFVariantStruct* pDest, const AMFR...
  function AMF_CDECL_CALL (line 1879) | AMF_CDECL_CALL AMFVariantAssignRatio(AMFVariantStruct* pDest, const AMFR...
  function AMF_CDECL_CALL (line 1885) | AMF_CDECL_CALL AMFVariantAssignRatio(AMFVariantStruct* pDest, const AMFR...
  function AMF_CDECL_CALL (line 1901) | AMF_CDECL_CALL AMFVariantAssignColor(AMFVariantStruct* pDest, const AMFC...
  function AMF_CDECL_CALL (line 1907) | AMF_CDECL_CALL AMFVariantAssignColor(AMFVariantStruct* pDest, const AMFC...
  function AMF_INLINE (line 1922) | static AMF_INLINE char* AMF_CDECL_CALL AMFVariantDuplicateString(const c...
  function AMF_CDECL_CALL (line 1936) | AMF_CDECL_CALL AMFVariantFreeString(char* pFrom)
  function AMF_INLINE (line 1941) | static AMF_INLINE wchar_t* AMF_CDECL_CALL AMFVariantDuplicateWString(con...
  function AMF_CDECL_CALL (line 1955) | AMF_CDECL_CALL AMFVariantFreeWString(wchar_t* pFrom)
  function AMF_INLINE (line 1963) | AMF_INLINE AMFVariant::AMFVariant(const AMFVariantStruct* pOther)

FILE: alvr/server_openvr/cpp/shared/amf/public/include/core/VulkanAMF.h
  function namespace (line 41) | namespace amf

FILE: alvr/server_openvr/cpp/shared/backward.cpp
  type backward (line 38) | namespace backward {

FILE: alvr/server_openvr/cpp/shared/backward.hpp
  type backward (line 417) | namespace backward {
    type details (line 418) | namespace details {
      type hashtable (line 419) | struct hashtable {
      type hashtable (line 431) | struct hashtable {
      function T (line 434) | const T &move(const T &v) { return v; }
      function T (line 435) | T &move(T &v) { return v; }
      type rm_ptr (line 510) | struct rm_ptr { typedef T type; }
      type rm_ptr<T *> (line 512) | struct rm_ptr<T *> { typedef T type; }
      type rm_ptr<const T *> (line 514) | struct rm_ptr<const T *> { typedef const T type; }
      type deleter (line 516) | struct deleter {
      type default_delete (line 520) | struct default_delete {
      class handle (line 525) | class handle {
        type dummy (line 526) | struct dummy
        method handle (line 531) | handle(const handle &) = delete;
        method handle (line 532) | handle &operator=(const handle &) = delete;
        method handle (line 542) | explicit handle() : _val(), _empty(true) {}
        method handle (line 543) | explicit handle(T val) : _val(val), _empty(false) {
        method handle (line 549) | handle(handle &&from) : _empty(true) { swap(from); }
        method handle (line 550) | handle &operator=(handle &&from) {
        method handle (line 555) | explicit handle(const handle &from) : _empty(true) {
        method handle (line 559) | handle &operator=(const handle &from) {
        method reset (line 566) | void reset(T new_val) {
        method update (line 571) | void update(T new_val) {
        method T (line 582) | T get() { return _val; }
        method T (line 583) | T release() {
        method swap (line 587) | void swap(handle &b) {
        method T (line 594) | T &operator->() { return _val; }
        method T (line 595) | const T &operator->() const { return _val; }
        method ref_t (line 599) | ref_t operator*() { return *_val; }
        method const_ref_t (line 600) | const_ref_t operator*() const { return *_val; }
        method ref_t (line 601) | ref_t operator[](size_t idx) { return _val[idx]; }
        method T (line 604) | T *operator&() {
      type demangler_impl (line 611) | struct demangler_impl {
        method demangle (line 612) | static std::string demangle(const char *funcname) { return funcnam...
      type demangler_impl<system_tag::current_tag> (line 617) | struct demangler_impl<system_tag::current_tag> {
        method demangler_impl (line 618) | demangler_impl() : _demangle_buffer_length(0) {}
        method demangle (line 620) | std::string demangle(const char *funcname) {
      type demangler (line 638) | struct demangler : public demangler_impl<system_tag::current_tag> {}
      function split_source_prefixes (line 648) | inline std::vector<std::string> split_source_prefixes(const std::str...
      class Unwinder (line 807) | class Unwinder {
        method _Unwind_Reason_Code (line 827) | static _Unwind_Reason_Code backtrace_trampoline(_Unwind_Context *ctx,
        method _Unwind_Reason_Code (line 832) | _Unwind_Reason_Code backtrace(_Unwind_Context *ctx) {
      function unwind (line 859) | size_t unwind(F f, size_t depth) {
    type details (line 430) | namespace details {
      type hashtable (line 419) | struct hashtable {
      type hashtable (line 431) | struct hashtable {
      function T (line 434) | const T &move(const T &v) { return v; }
      function T (line 435) | T &move(T &v) { return v; }
      type rm_ptr (line 510) | struct rm_ptr { typedef T type; }
      type rm_ptr<T *> (line 512) | struct rm_ptr<T *> { typedef T type; }
      type rm_ptr<const T *> (line 514) | struct rm_ptr<const T *> { typedef const T type; }
      type deleter (line 516) | struct deleter {
      type default_delete (line 520) | struct default_delete {
      class handle (line 525) | class handle {
        type dummy (line 526) | struct dummy
        method handle (line 531) | handle(const handle &) = delete;
        method handle (line 532) | handle &operator=(const handle &) = delete;
        method handle (line 542) | explicit handle() : _val(), _empty(true) {}
        method handle (line 543) | explicit handle(T val) : _val(val), _empty(false) {
        method handle (line 549) | handle(handle &&from) : _empty(true) { swap(from); }
        method handle (line 550) | handle &operator=(handle &&from) {
        method handle (line 555) | explicit handle(const handle &from) : _empty(true) {
        method handle (line 559) | handle &operator=(const handle &from) {
        method reset (line 566) | void reset(T new_val) {
        method update (line 571) | void update(T new_val) {
        method T (line 582) | T get() { return _val; }
        method T (line 583) | T release() {
        method swap (line 587) | void swap(handle &b) {
        method T (line 594) | T &operator->() { return _val; }
        method T (line 595) | const T &operator->() const { return _val; }
        method ref_t (line 599) | ref_t operator*() { return *_val; }
        method const_ref_t (line 600) | const_ref_t operator*() const { return *_val; }
        method ref_t (line 601) | ref_t operator[](size_t idx) { return _val[idx]; }
        method T (line 604) | T *operator&() {
      type demangler_impl (line 611) | struct demangler_impl {
        method demangle (line 612) | static std::string demangle(const char *funcname) { return funcnam...
      type demangler_impl<system_tag::current_tag> (line 617) | struct demangler_impl<system_tag::current_tag> {
        method demangler_impl (line 618) | demangler_impl() : _demangle_buffer_length(0) {}
        method demangle (line 620) | std::string demangle(const char *funcname) {
      type demangler (line 638) | struct demangler : public demangler_impl<system_tag::current_tag> {}
      function split_source_prefixes (line 648) | inline std::vector<std::string> split_source_prefixes(const std::str...
      class Unwinder (line 807) | class Unwinder {
        method _Unwind_Reason_Code (line 827) | static _Unwind_Reason_Code backtrace_trampoline(_Unwind_Context *ctx,
        method _Unwind_Reason_Code (line 832) | _Unwind_Reason_Code backtrace(_Unwind_Context *ctx) {
      function unwind (line 859) | size_t unwind(F f, size_t depth) {
    type details (line 441) | namespace details {
      type hashtable (line 419) | struct hashtable {
      type hashtable (line 431) | struct hashtable {
      function T (line 434) | const T &move(const T &v) { return v; }
      function T (line 435) | T &move(T &v) { return v; }
      type rm_ptr (line 510) | struct rm_ptr { typedef T type; }
      type rm_ptr<T *> (line 512) | struct rm_ptr<T *> { typedef T type; }
      type rm_ptr<const T *> (line 514) | struct rm_ptr<const T *> { typedef const T type; }
      type deleter (line 516) | struct deleter {
      type default_delete (line 520) | struct default_delete {
      class handle (line 525) | class handle {
        type dummy (line 526) | struct dummy
        method handle (line 531) | handle(const handle &) = delete;
        method handle (line 532) | handle &operator=(const handle &) = delete;
        method handle (line 542) | explicit handle() : _val(), _empty(true) {}
        method handle (line 543) | explicit handle(T val) : _val(val), _empty(false) {
        method handle (line 549) | handle(handle &&from) : _empty(true) { swap(from); }
        method handle (line 550) | handle &operator=(handle &&from) {
        method handle (line 555) | explicit handle(const handle &from) : _empty(true) {
        method handle (line 559) | handle &operator=(const handle &from) {
        method reset (line 566) | void reset(T new_val) {
        method update (line 571) | void update(T new_val) {
        method T (line 582) | T get() { return _val; }
        method T (line 583) | T release() {
        method swap (line 587) | void swap(handle &b) {
        method T (line 594) | T &operator->() { return _val; }
        method T (line 595) | const T &operator->() const { return _val; }
        method ref_t (line 599) | ref_t operator*() { return *_val; }
        method const_ref_t (line 600) | const_ref_t operator*() const { return *_val; }
        method ref_t (line 601) | ref_t operator[](size_t idx) { return _val[idx]; }
        method T (line 604) | T *operator&() {
      type demangler_impl (line 611) | struct demangler_impl {
        method demangle (line 612) | static std::string demangle(const char *funcname) { return funcnam...
      type demangler_impl<system_tag::current_tag> (line 617) | struct demangler_impl<system_tag::current_tag> {
        method demangler_impl (line 618) | demangler_impl() : _demangle_buffer_length(0) {}
        method demangle (line 620) | std::string demangle(const char *funcname) {
      type demangler (line 638) | struct demangler : public demangler_impl<system_tag::current_tag> {}
      function split_source_prefixes (line 648) | inline std::vector<std::string> split_source_prefixes(const std::str...
      class Unwinder (line 807) | class Unwinder {
        method _Unwind_Reason_Code (line 827) | static _Unwind_Reason_Code backtrace_trampoline(_Unwind_Context *ctx,
        method _Unwind_Reason_Code (line 832) | _Unwind_Reason_Code backtrace(_Unwind_Context *ctx) {
      function unwind (line 859) | size_t unwind(F f, size_t depth) {
    type system_tag (line 452) | namespace system_tag {
      type linux_tag (line 453) | struct linux_tag
      type darwin_tag (line 455) | struct darwin_tag
      type windows_tag (line 456) | struct windows_tag
      type unknown_tag (line 457) | struct unknown_tag
    type trace_resolver_tag (line 472) | namespace trace_resolver_tag {
      type libdw (line 474) | struct libdw
      type libbfd (line 475) | struct libbfd
      type libdwarf (line 476) | struct libdwarf
      type backtrace_symbol (line 477) | struct backtrace_symbol
      type backtrace_symbol (line 491) | struct backtrace_symbol
      type pdb_symbol (line 499) | struct pdb_symbol
    type details (line 508) | namespace details {
      type hashtable (line 419) | struct hashtable {
      type hashtable (line 431) | struct hashtable {
      function T (line 434) | const T &move(const T &v) { return v; }
      function T (line 435) | T &move(T &v) { return v; }
      type rm_ptr (line 510) | struct rm_ptr { typedef T type; }
      type rm_ptr<T *> (line 512) | struct rm_ptr<T *> { typedef T type; }
      type rm_ptr<const T *> (line 514) | struct rm_ptr<const T *> { typedef const T type; }
      type deleter (line 516) | struct deleter {
      type default_delete (line 520) | struct default_delete {
      class handle (line 525) | class handle {
        type dummy (line 526) | struct dummy
        method handle (line 531) | handle(const handle &) = delete;
        method handle (line 532) | handle &operator=(const handle &) = delete;
        method handle (line 542) | explicit handle() : _val(), _empty(true) {}
        method handle (line 543) | explicit handle(T val) : _val(val), _empty(false) {
        method handle (line 549) | handle(handle &&from) : _empty(true) { swap(from); }
        method handle (line 550) | handle &operator=(handle &&from) {
        method handle (line 555) | explicit handle(const handle &from) : _empty(true) {
        method handle (line 559) | handle &operator=(const handle &from) {
        method reset (line 566) | void reset(T new_val) {
        method update (line 571) | void update(T new_val) {
        method T (line 582) | T get() { return _val; }
        method T (line 583) | T release() {
        method swap (line 587) | void swap(handle &b) {
        method T (line 594) | T &operator->() { return _val; }
        method T (line 595) | const T &operator->() const { return _val; }
        method ref_t (line 599) | ref_t operator*() { return *_val; }
        method const_ref_t (line 600) | const_ref_t operator*() const { return *_val; }
        method ref_t (line 601) | ref_t operator[](size_t idx) { return _val[idx]; }
        method T (line 604) | T *operator&() {
      type demangler_impl (line 611) | struct demangler_impl {
        method demangle (line 612) | static std::string demangle(const char *funcname) { return funcnam...
      type demangler_impl<system_tag::current_tag> (line 617) | struct demangler_impl<system_tag::current_tag> {
        method demangler_impl (line 618) | demangler_impl() : _demangle_buffer_length(0) {}
        method demangle (line 620) | std::string demangle(const char *funcname) {
      type demangler (line 638) | struct demangler : public demangler_impl<system_tag::current_tag> {}
      function split_source_prefixes (line 648) | inline std::vector<std::string> split_source_prefixes(const std::str...
      class Unwinder (line 807) | class Unwinder {
        method _Unwind_Reason_Code (line 827) | static _Unwind_Reason_Code backtrace_trampoline(_Unwind_Context *ctx,
        method _Unwind_Reason_Code (line 832) | _Unwind_Reason_Code backtrace(_Unwind_Context *ctx) {
      function unwind (line 859) | size_t unwind(F f, size_t depth) {
    type Trace (line 667) | struct Trace {
      method Trace (line 671) | Trace() : addr(nullptr), idx(0) {}
      method Trace (line 673) | explicit Trace(void *_addr, size_t _idx) : addr(_addr), idx(_idx) {}
    type ResolvedTrace (line 676) | struct ResolvedTrace : public Trace {
      type SourceLoc (line 678) | struct SourceLoc {
        method SourceLoc (line 684) | SourceLoc() : line(0), col(0) {}
      method ResolvedTrace (line 713) | ResolvedTrace() : Trace() {}
      method ResolvedTrace (line 714) | ResolvedTrace(const Trace &mini_trace) : Trace(mini_trace) {}
    class StackTraceImpl (line 720) | class StackTraceImpl {
      method size (line 722) | size_t size() const { return 0; }
      method Trace (line 723) | Trace operator[](size_t) const { return Trace(); }
      method load_here (line 724) | size_t load_here(size_t = 0) { return 0; }
      method load_from (line 725) | size_t load_from(void *, size_t = 0, void * = nullptr, void * = null...
      method thread_id (line 728) | size_t thread_id() const { return 0; }
      method skip_n_firsts (line 729) | void skip_n_firsts(size_t) {}
    class StackTraceImplBase (line 733) | class StackTraceImplBase {
      method StackTraceImplBase (line 735) | StackTraceImplBase()
      method thread_id (line 738) | size_t thread_id() const { return _thread_id; }
      method skip_n_firsts (line 740) | void skip_n_firsts(size_t n) { _skip = n; }
      method load_thread_info (line 743) | void load_thread_info() {
      method set_context (line 764) | void set_context(void *context) { _context = context; }
      metho
Condensed preview — 495 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,945K chars).
[
  {
    "path": ".cargo/config.toml",
    "chars": 121,
    "preview": "[alias]\nxtask = \"run -p alvr_xtask --\"\n\n[target.x86_64-pc-windows-msvc]\nrustflags = [\"-C\", \"target-feature=+crt-static\"]"
  },
  {
    "path": ".clang-format",
    "chars": 189,
    "preview": "BasedOnStyle:  WebKit\nIndentWidth: 4\nColumnLimit: 100\nBinPackArguments: false\nBinPackParameters: false\nAlignAfterOpenBra"
  },
  {
    "path": ".editorconfig",
    "chars": 303,
    "preview": "# Editor configuration, see https://editorconfig.org\n\n[*.{c,cpp,h,hpp}]\nindent_style = space\nindent_size = 4\ntab_width ="
  },
  {
    "path": ".gitattributes",
    "chars": 616,
    "preview": "* text=auto eol=lf\n\nalvr/server_openvr/cpp/alvr_server/include/** linguist-vendored\nalvr/server_openvr/cpp/alvr_server/n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 667,
    "preview": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [u"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 1418,
    "preview": "---\nname: Bug Report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n<!-- Note: If th"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 632,
    "preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
  },
  {
    "path": ".github/workflows/prepare-release.yml",
    "chars": 8319,
    "preview": "name: Create release\n\nenv:\n  CARGO_TERM_COLOR: always\n\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        descr"
  },
  {
    "path": ".github/workflows/queue.yml",
    "chars": 2820,
    "preview": "name: Merge queue only checks\n\n# Merge queue checks need to be selected as required for prs to actually run, so simply s"
  },
  {
    "path": ".github/workflows/rust.yml",
    "chars": 3088,
    "preview": "name: Rust\n\non:\n  pull_request:\n    branches: [master]\n  merge_group:\n\nenv:\n  CARGO_TERM_COLOR: always\n\njobs:\n  check-wi"
  },
  {
    "path": ".github/workflows/stale.yml",
    "chars": 479,
    "preview": "name: 'Close stale issues'\non:\n  schedule:\n    - cron: '0 0 * * *'\n\njobs:\n  stale:\n    runs-on: ubuntu-latest\n    steps:"
  },
  {
    "path": ".github/workflows/wiki.yml",
    "chars": 343,
    "preview": "name: Publish to GitHub Wiki\n\non:\n  push:\n    branches: [master]\n  workflow_dispatch:\n\njobs:\n  wiki:\n    runs-on: ubuntu"
  },
  {
    "path": ".gitignore",
    "chars": 1294,
    "preview": "Debug\nRelease\n*.opensdf\n*.sdf\n*.suo\n*.filters\n*.user\n*.dll\n*.exe\n*.mexw64\n*.aps\n\n# editor\n.vs/\n.idea/\n\n# NuGet Packages\n"
  },
  {
    "path": ".gitmodules",
    "chars": 103,
    "preview": "[submodule \"openvr\"]\n\tpath = openvr\n\turl = https://github.com/ValveSoftware/openvr.git\n\tshallow = true\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 11018,
    "preview": "# Changelog\n\n## v20.11.0\n\n* Add flatpak launcher (by @failboat78 #2207)\n* Fix Linux/Nvenc error popups (by @failboat78 #"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 5294,
    "preview": "# Style\n\nChecklist for code style. This is on top of common Rust styling rules. These rules are not mandatory but I migh"
  },
  {
    "path": "Cargo.toml",
    "chars": 904,
    "preview": "[workspace]\nresolver = \"2\"\nmembers = [\"alvr/*\"]\n\n[workspace.package]\nversion = \"21.0.0-dev12\"\nedition = \"2024\"\nrust-vers"
  },
  {
    "path": "LICENSE",
    "chars": 1093,
    "preview": "Copyright (c) 2018-2019 polygraphene\nCopyright (c) 2020-2024 alvr-org\n\nPermission is hereby granted, free of charge, to "
  },
  {
    "path": "README.md",
    "chars": 5361,
    "preview": "<p align=\"center\"> <img width=\"500\" src=\"resources/ALVR-Grey.svg\"/> </p>\n\n# ALVR - Air Light VR\n\n[![badge-discord][]][li"
  },
  {
    "path": "about.toml",
    "chars": 587,
    "preview": "accepted = [\n    \"MIT\",\n    \"Apache-2.0\",\n    \"Apache-2.0 WITH LLVM-exception\",\n    \"BSD-2-Clause\",\n    \"BSD-3-Clause\",\n"
  },
  {
    "path": "alvr/adb/Cargo.toml",
    "chars": 335,
    "preview": "[package]\nname = \"alvr_adb\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nauthors.work"
  },
  {
    "path": "alvr/adb/src/commands.rs",
    "chars": 9569,
    "preview": "// https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/docs/user/adb.1.md\n\nuse crate::parse"
  },
  {
    "path": "alvr/adb/src/lib.rs",
    "chars": 5080,
    "preview": "pub mod commands;\nmod parse;\n\nuse alvr_common::anyhow::Result;\nuse alvr_common::{dbg_connection, error, warn};\nuse alvr_"
  },
  {
    "path": "alvr/adb/src/parse.rs",
    "chars": 4911,
    "preview": "// https://cs.android.com/android/platform/superproject/main/+/7dbe542b9a93fb3cee6c528e16e2d02a26da7cc0:packages/modules"
  },
  {
    "path": "alvr/audio/Cargo.toml",
    "chars": 744,
    "preview": "[package]\nname = \"alvr_audio\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nauthors.wo"
  },
  {
    "path": "alvr/audio/src/lib.rs",
    "chars": 18704,
    "preview": "#[cfg(windows)]\nmod windows;\n\n#[cfg(target_os = \"linux\")]\npub mod linux;\n\n#[cfg(windows)]\npub use crate::windows::*;\n\nus"
  },
  {
    "path": "alvr/audio/src/linux.rs",
    "chars": 11188,
    "preview": "use alvr_common::{ConnectionError, anyhow::Result, debug, error, parking_lot::Mutex};\nuse alvr_session::AudioBufferingCo"
  },
  {
    "path": "alvr/audio/src/windows.rs",
    "chars": 2444,
    "preview": "use alvr_common::anyhow::{Result, bail};\nuse cpal::{Device, platform::DeviceInner};\nuse rodio::DeviceTrait;\nuse windows:"
  },
  {
    "path": "alvr/client_core/Cargo.toml",
    "chars": 837,
    "preview": "[package]\nname = \"alvr_client_core\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nauth"
  },
  {
    "path": "alvr/client_core/LICENSE",
    "chars": 1056,
    "preview": "Copyright (c) 2020-2024 alvr-org\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this s"
  },
  {
    "path": "alvr/client_core/README.md",
    "chars": 114,
    "preview": "# alvr_client_core\n\nRust crate containing all major components for an ALVR client except the XR-API-related code.\n"
  },
  {
    "path": "alvr/client_core/build.rs",
    "chars": 420,
    "preview": "fn main() {\n    let platform_name = std::env::var(\"CARGO_CFG_TARGET_OS\").unwrap();\n\n    if platform_name == \"android\" {\n"
  },
  {
    "path": "alvr/client_core/cbindgen.toml",
    "chars": 417,
    "preview": "language = \"C\"\nheader = \"/* ALVR is licensed under the MIT license. https://github.com/alvr-org/ALVR/blob/master/LICENSE"
  },
  {
    "path": "alvr/client_core/src/audio.rs",
    "chars": 5759,
    "preview": "use alvr_audio::Device;\nuse alvr_common::{\n    anyhow::{Result, bail},\n    parking_lot::Mutex,\n};\nuse alvr_session::Audi"
  },
  {
    "path": "alvr/client_core/src/c_api.rs",
    "chars": 30969,
    "preview": "#![expect(dead_code)]\n\nuse crate::{\n    ClientCapabilities, ClientCoreContext, ClientCoreEvent, storage,\n    video_decod"
  },
  {
    "path": "alvr/client_core/src/connection.rs",
    "chars": 22844,
    "preview": "#![allow(clippy::if_same_then_else)]\n\nuse crate::{\n    ClientCapabilities, ClientCoreEvent,\n    logging_backend::{LOG_CH"
  },
  {
    "path": "alvr/client_core/src/lib.rs",
    "chars": 10384,
    "preview": "#![allow(\n    non_upper_case_globals,\n    non_snake_case,\n    clippy::missing_safety_doc,\n    clippy::unseparated_litera"
  },
  {
    "path": "alvr/client_core/src/logging_backend.rs",
    "chars": 3688,
    "preview": "use alvr_common::{\n    DebugGroupsConfig, LogSeverity,\n    log::{Level, Record},\n    parking_lot::Mutex,\n};\nuse alvr_pac"
  },
  {
    "path": "alvr/client_core/src/sockets.rs",
    "chars": 959,
    "preview": "use alvr_common::anyhow::{Result, bail};\nuse mdns_sd::{ServiceDaemon, ServiceInfo};\n\npub struct AnnouncerSocket {\n    ho"
  },
  {
    "path": "alvr/client_core/src/statistics.rs",
    "chars": 4485,
    "preview": "use alvr_common::SlidingWindowAverage;\nuse alvr_packets::ClientStatistics;\nuse std::{\n    collections::VecDeque,\n    tim"
  },
  {
    "path": "alvr/client_core/src/storage.rs",
    "chars": 1808,
    "preview": "use alvr_common::{error, info};\nuse app_dirs2::{AppDataType, AppInfo};\nuse rand::Rng;\nuse serde::{Deserialize, Serialize"
  },
  {
    "path": "alvr/client_core/src/video_decoder/android.rs",
    "chars": 14139,
    "preview": "use super::VideoDecoderConfig;\nuse alvr_common::{\n    RelaxedAtomic, ToAny,\n    anyhow::{Context, Result, anyhow, bail},"
  },
  {
    "path": "alvr/client_core/src/video_decoder/mod.rs",
    "chars": 2117,
    "preview": "#[cfg(target_os = \"android\")]\nmod android;\n\nuse alvr_common::anyhow::Result;\nuse alvr_session::{CodecType, MediacodecPro"
  },
  {
    "path": "alvr/client_mock/Cargo.toml",
    "chars": 389,
    "preview": "[package]\nname = \"alvr_client_mock\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nauth"
  },
  {
    "path": "alvr/client_mock/src/main.rs",
    "chars": 9991,
    "preview": "use alvr_client_core::{ClientCapabilities, ClientCoreContext, ClientCoreEvent};\nuse alvr_common::{\n    DeviceMotion, HEA"
  },
  {
    "path": "alvr/client_openxr/Cargo.toml",
    "chars": 7914,
    "preview": "[package]\nname = \"alvr_client_openxr\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nau"
  },
  {
    "path": "alvr/client_openxr/cbindgen.toml",
    "chars": 363,
    "preview": "language = \"C\"\nheader = \"/* ALVR is licensed under the MIT license. https://github.com/alvr-org/ALVR/blob/master/LICENSE"
  },
  {
    "path": "alvr/client_openxr/resources/drawable/ic_launcher_foreground.xml",
    "chars": 2487,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    "
  },
  {
    "path": "alvr/client_openxr/resources/mipmap-anydpi-v26/ic_launcher.xml",
    "chars": 337,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "alvr/client_openxr/resources/values/ic_launcher_background.xml",
    "chars": 120,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"ic_launcher_background\">#FFFFFF</color>\n</resources>"
  },
  {
    "path": "alvr/client_openxr/src/c_api.rs",
    "chars": 255,
    "preview": "#[cfg(target_os = \"android\")]\n#[unsafe(no_mangle)]\npub extern \"C\" fn alvr_entry_point(java_vm: *mut std::ffi::c_void, co"
  },
  {
    "path": "alvr/client_openxr/src/extra_extensions/body_tracking_bd.rs",
    "chars": 8268,
    "preview": "use crate::extra_extensions::get_instance_proc;\nuse openxr::{self as xr, AnyGraphics, sys};\nuse std::{\n    ffi::{CString"
  },
  {
    "path": "alvr/client_openxr/src/extra_extensions/body_tracking_fb.rs",
    "chars": 4725,
    "preview": "#![allow(dead_code)]\n\nuse crate::extra_extensions::get_instance_proc;\nuse openxr::{\n    self as xr, raw,\n    sys::{self,"
  },
  {
    "path": "alvr/client_openxr/src/extra_extensions/eye_gaze_interaction.rs",
    "chars": 609,
    "preview": "use openxr::{self as xr, sys};\nuse std::ptr;\n\npub fn supports_eye_gaze_interaction<G>(session: &xr::Session<G>, system: "
  },
  {
    "path": "alvr/client_openxr/src/extra_extensions/eye_tracking_social.rs",
    "chars": 1958,
    "preview": "use openxr::{\n    self as xr, raw,\n    sys::{self, Handle},\n};\nuse std::ptr;\n\npub struct EyeTrackerSocial {\n    handle: "
  },
  {
    "path": "alvr/client_openxr/src/extra_extensions/face_tracking2_fb.rs",
    "chars": 3316,
    "preview": "use openxr::{\n    self as xr, raw,\n    sys::{self, Handle},\n};\nuse std::ptr;\n\npub struct FaceTracker2FB {\n    // Keeping"
  },
  {
    "path": "alvr/client_openxr/src/extra_extensions/face_tracking_pico.rs",
    "chars": 3401,
    "preview": "use crate::extra_extensions::get_instance_proc;\nuse openxr::{self as xr, sys};\n\nconst TRACKING_MODE_FACE_BIT: u64 = 0x00"
  },
  {
    "path": "alvr/client_openxr/src/extra_extensions/facial_tracking_htc.rs",
    "chars": 3232,
    "preview": "use openxr::{\n    self as xr, raw,\n    sys::{self, Handle},\n};\nuse std::ptr;\n\npub struct FacialTrackerHTC {\n    // Keepi"
  },
  {
    "path": "alvr/client_openxr/src/extra_extensions/mod.rs",
    "chars": 1844,
    "preview": "mod body_tracking_bd;\nmod body_tracking_fb;\nmod eye_gaze_interaction;\nmod eye_tracking_social;\nmod face_tracking2_fb;\nmo"
  },
  {
    "path": "alvr/client_openxr/src/extra_extensions/motion_tracking_bd.rs",
    "chars": 4923,
    "preview": "use crate::extra_extensions::get_instance_proc;\nuse openxr::{self as xr, AnyGraphics, sys};\nuse std::ffi::{CString, c_ch"
  },
  {
    "path": "alvr/client_openxr/src/extra_extensions/multimodal_input.rs",
    "chars": 4708,
    "preview": "// Code taken from:\n// https://github.com/meta-quest/Meta-OpenXR-SDK/blob/main/OpenXR/meta_openxr_preview/meta_simultane"
  },
  {
    "path": "alvr/client_openxr/src/extra_extensions/passthrough_fb.rs",
    "chars": 2654,
    "preview": "use alvr_system_info::Platform;\nuse openxr::{\n    self as xr, raw,\n    sys::{self, Handle},\n};\nuse std::ptr;\n\npub struct"
  },
  {
    "path": "alvr/client_openxr/src/extra_extensions/passthrough_htc.rs",
    "chars": 1832,
    "preview": "use openxr::{\n    self as xr, raw,\n    sys::{self, Handle},\n};\nuse std::ptr;\n\npub struct PassthroughHTC {\n    handle: sy"
  },
  {
    "path": "alvr/client_openxr/src/graphics.rs",
    "chars": 4169,
    "preview": "use alvr_common::glam::UVec2;\nuse alvr_graphics::GraphicsContext;\nuse alvr_session::ClientsidePostProcessingConfig;\nuse "
  },
  {
    "path": "alvr/client_openxr/src/interaction.rs",
    "chars": 40110,
    "preview": "use crate::{\n    Platform,\n    extra_extensions::{\n        self, BODY_JOINT_SET_FULL_BODY_META, BodyJointSetBD, BodyTrac"
  },
  {
    "path": "alvr/client_openxr/src/lib.rs",
    "chars": 24002,
    "preview": "mod c_api;\nmod extra_extensions;\nmod graphics;\nmod interaction;\nmod lobby;\nmod passthrough;\nmod stream;\n\nuse crate::stre"
  },
  {
    "path": "alvr/client_openxr/src/lobby.rs",
    "chars": 7637,
    "preview": "use crate::{\n    graphics::{self, ProjectionLayerAlphaConfig, ProjectionLayerBuilder},\n    interaction::{self, Interacti"
  },
  {
    "path": "alvr/client_openxr/src/passthrough.rs",
    "chars": 1490,
    "preview": "use crate::extra_extensions::{PassthroughFB, PassthroughHTC};\nuse alvr_common::anyhow::{Result, bail};\nuse alvr_system_i"
  },
  {
    "path": "alvr/client_openxr/src/stream.rs",
    "chars": 24399,
    "preview": "use crate::{\n    graphics::{self, ProjectionLayerAlphaConfig, ProjectionLayerBuilder},\n    interaction::{self, Interacti"
  },
  {
    "path": "alvr/common/Cargo.toml",
    "chars": 615,
    "preview": "[package]\nname = \"alvr_common\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nauthors.w"
  },
  {
    "path": "alvr/common/LICENSE",
    "chars": 1056,
    "preview": "Copyright (c) 2020-2021 alvr-org\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this s"
  },
  {
    "path": "alvr/common/README.md",
    "chars": 213,
    "preview": "# alvr_common\n\nThis crate contains some basic functionality shared across all crates in the workspace. In particular it "
  },
  {
    "path": "alvr/common/src/average.rs",
    "chars": 1103,
    "preview": "use std::{collections::VecDeque, time::Duration};\n\npub struct SlidingWindowAverage<T> {\n    history_buffer: VecDeque<T>,"
  },
  {
    "path": "alvr/common/src/c_api.rs",
    "chars": 1996,
    "preview": "use glam::{Quat, Vec3};\n\nuse crate::{Fov, Pose, ViewParams};\n\n#[repr(C)]\npub struct AlvrFov {\n    /// Negative, radians\n"
  },
  {
    "path": "alvr/common/src/connection_result.rs",
    "chars": 2723,
    "preview": "use anyhow::{Result, anyhow};\nuse std::{\n    error::Error,\n    fmt::Display,\n    io,\n    sync::mpsc::{RecvTimeoutError, "
  },
  {
    "path": "alvr/common/src/inputs.rs",
    "chars": 22193,
    "preview": "use crate::hash_string;\nuse std::{\n    collections::{HashMap, HashSet},\n    sync::LazyLock,\n};\n\nmacro_rules! interaction"
  },
  {
    "path": "alvr/common/src/lib.rs",
    "chars": 1648,
    "preview": "mod average;\nmod c_api;\nmod connection_result;\nmod inputs;\nmod logging;\nmod primitives;\nmod version;\n\nuse parking_lot::{"
  },
  {
    "path": "alvr/common/src/logging.rs",
    "chars": 8735,
    "preview": "use anyhow::Result;\nuse backtrace::Backtrace;\nuse parking_lot::Mutex;\nuse serde::{Deserialize, Serialize};\nuse settings_"
  },
  {
    "path": "alvr/common/src/primitives.rs",
    "chars": 3363,
    "preview": "use glam::{Quat, Vec3};\nuse serde::{Deserialize, Serialize};\nuse std::{ops::Mul, time::Duration};\n\n// Field of view in r"
  },
  {
    "path": "alvr/common/src/version.rs",
    "chars": 1405,
    "preview": "use semver::Version;\nuse std::{\n    collections::hash_map::DefaultHasher,\n    hash::{Hash, Hasher},\n    sync::LazyLock,\n"
  },
  {
    "path": "alvr/dashboard/Cargo.toml",
    "chars": 1110,
    "preview": "[package]\nname = \"alvr_dashboard\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nauthor"
  },
  {
    "path": "alvr/dashboard/README.md",
    "chars": 78,
    "preview": "# alvr_gui\n\nCrate for GUI-related code. It needs a backend to display the UI.\n"
  },
  {
    "path": "alvr/dashboard/build.rs",
    "chars": 203,
    "preview": "#[cfg(windows)]\nfn main() {\n    let mut resource = winres::WindowsResource::new();\n    resource.set_icon(\"resources/dash"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/about.rs",
    "chars": 997,
    "preview": "use alvr_common::ALVR_VERSION;\nuse alvr_gui_common::theme;\nuse eframe::egui::{Frame, RichText, ScrollArea, Ui};\n\npub fn "
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/debug.rs",
    "chars": 887,
    "preview": "use crate::dashboard::ServerRequest;\nuse eframe::egui::Ui;\n\npub fn debug_tab_ui(ui: &mut Ui) -> Option<ServerRequest> {\n"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/devices.rs",
    "chars": 15939,
    "preview": "use crate::dashboard::ServerRequest;\nuse alvr_common::ConnectionState;\nuse alvr_gui_common::theme::{self, log_colors};\nu"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/installation.rs",
    "chars": 3311,
    "preview": "use crate::dashboard::ServerRequest;\nuse alvr_gui_common::theme;\nuse eframe::egui::{Frame, Grid, RichText, ScrollArea, U"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/logs.rs",
    "chars": 4181,
    "preview": "use alvr_common::LogSeverity;\nuse alvr_events::{Event, EventType};\nuse alvr_gui_common::theme::log_colors;\nuse alvr_sess"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/mod.rs",
    "chars": 504,
    "preview": "mod about;\nmod debug;\nmod devices;\nmod logs;\nmod new_version_popup;\nmod notifications;\nmod settings;\nmod settings_contro"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/new_version_popup.rs",
    "chars": 3748,
    "preview": "use crate::dashboard::ServerRequest;\nuse alvr_gui_common::ModalButton;\nuse alvr_packets::PathValuePair;\nuse eframe::egui"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/notifications.rs",
    "chars": 8194,
    "preview": "use alvr_common::{LogEntry, LogSeverity};\nuse alvr_gui_common::theme::{self, log_colors};\nuse alvr_session::Settings;\nus"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings.rs",
    "chars": 8960,
    "preview": "use super::{\n    NestingInfo, SettingControl,\n    presets::{PresetControl, builtin_schema},\n};\nuse crate::dashboard::Ser"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/array.rs",
    "chars": 1611,
    "preview": "use super::{NestingInfo, SettingControl, collapsible};\nuse alvr_packets::PathValuePair;\nuse alvr_session::settings_schem"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/boolean.rs",
    "chars": 1585,
    "preview": "use super::{NestingInfo, reset};\nuse alvr_packets::PathValuePair;\nuse eframe::{\n    egui::{Layout, Ui},\n    emath::Align"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/choice.rs",
    "chars": 6182,
    "preview": "use super::{NestingInfo, SettingControl, reset};\nuse alvr_gui_common::DisplayString;\nuse alvr_packets::PathValuePair;\nus"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/collapsible.rs",
    "chars": 738,
    "preview": "use super::NestingInfo;\nuse alvr_packets::PathValuePair;\nuse eframe::egui::Ui;\nuse serde_json as json;\n\npub fn collapsib"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/dictionary.rs",
    "chars": 6609,
    "preview": "use super::{INDENTATION_STEP, NestingInfo, SettingControl, reset};\nuse crate::dashboard::components::{\n    collapsible,\n"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/mod.rs",
    "chars": 5799,
    "preview": "pub mod array;\npub mod boolean;\npub mod choice;\npub mod collapsible;\npub mod dictionary;\npub mod notice;\npub mod number;"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/notice.rs",
    "chars": 415,
    "preview": "use alvr_gui_common::theme::{self, log_colors};\nuse eframe::{\n    egui::{Frame, Label, RichText, Ui},\n    epaint::Color3"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/number.rs",
    "chars": 5185,
    "preview": "use super::{NestingInfo, reset};\nuse crate::dashboard::components::f64_eq;\nuse alvr_gui_common::theme::SCROLLBAR_DOT_DIA"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/optional.rs",
    "chars": 2378,
    "preview": "use super::{NestingInfo, SettingControl, reset};\nuse alvr_packets::PathValuePair;\nuse alvr_session::settings_schema::Sch"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/presets/builtin_schema.rs",
    "chars": 17896,
    "preview": "use super::schema::{\n    HigherOrderChoiceOption, HigherOrderChoiceSchema, PresetModifier, PresetSchemaNode,\n};\nuse crat"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/presets/higher_order_choice.rs",
    "chars": 4888,
    "preview": "use super::schema::{HigherOrderChoiceSchema, PresetModifierOperation};\nuse crate::dashboard::components::{self, NestingI"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/presets/mirror.rs",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/presets/mod.rs",
    "chars": 1049,
    "preview": "mod higher_order_choice;\nmod mirror;\n\npub mod builtin_schema;\npub mod schema;\n\nuse self::schema::PresetSchemaNode;\nuse a"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/presets/schema.rs",
    "chars": 1052,
    "preview": "use serde::{Deserialize, Serialize};\nuse serde_json as json;\nuse settings_schema::ChoiceControlType;\nuse std::collection"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/reset.rs",
    "chars": 508,
    "preview": "use eframe::{\n    egui::{self, Button, Layout, Response, Ui},\n    emath::Align,\n};\n\npub fn reset_button(ui: &mut Ui, ena"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/section.rs",
    "chars": 4760,
    "preview": "use super::{INDENTATION_STEP, NestingInfo, SettingControl, collapsible, notice};\nuse alvr_gui_common::{\n    DisplayStrin"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/switch.rs",
    "chars": 2439,
    "preview": "use super::{NestingInfo, SettingControl, reset};\nuse alvr_packets::PathValuePair;\nuse alvr_session::settings_schema::Sch"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/text.rs",
    "chars": 2222,
    "preview": "use super::{NestingInfo, reset};\nuse alvr_packets::PathValuePair;\nuse eframe::{\n    egui::{Layout, TextEdit, Ui},\n    em"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/up_down.rs",
    "chars": 790,
    "preview": "use eframe::{\n    egui::{self, Button, Layout, Ui},\n    emath::Align,\n};\n\n#[derive(PartialEq, Eq)]\npub enum UpDownResult"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/settings_controls/vector.rs",
    "chars": 4401,
    "preview": "use super::{INDENTATION_STEP, NestingInfo, SettingControl, reset};\nuse crate::dashboard::components::{\n    collapsible,\n"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/setup_wizard.rs",
    "chars": 6334,
    "preview": "use crate::dashboard::ServerRequest;\nuse eframe::{\n    egui::{Button, Label, Layout, RichText, Ui},\n    emath::Align,\n};"
  },
  {
    "path": "alvr/dashboard/src/dashboard/components/statistics.rs",
    "chars": 19266,
    "preview": "use crate::dashboard::{ServerRequest, theme::graph_colors};\nuse alvr_events::{GraphStatistics, StatisticsSummary};\nuse a"
  },
  {
    "path": "alvr/dashboard/src/dashboard/mod.rs",
    "chars": 14315,
    "preview": "mod components;\n\nuse self::components::{\n    DevicesTab, LogsTab, NotificationBar, SettingsTab, SetupWizard, SetupWizard"
  },
  {
    "path": "alvr/dashboard/src/data_sources.rs",
    "chars": 23227,
    "preview": "use crate::dashboard::ServerRequest;\nuse alvr_common::{\n    ALVR_VERSION, RelaxedAtomic, debug, error, info,\n    parking"
  },
  {
    "path": "alvr/dashboard/src/data_sources_wasm.rs",
    "chars": 2007,
    "preview": "use alvr_events::Event;\nuse alvr_packets::ServerRequest;\nuse eframe::{egui, web_sys};\nuse ewebsock::{WsEvent, WsMessage,"
  },
  {
    "path": "alvr/dashboard/src/linux_checks.rs",
    "chars": 130,
    "preview": "pub fn audio_check() {\n    // No check for result, just show errors in logs\n    let _ = alvr_audio::linux::try_load_pipe"
  },
  {
    "path": "alvr/dashboard/src/logging_backend.rs",
    "chars": 1665,
    "preview": "use crate::data_sources::PolledEvent;\nuse alvr_common::{LogEntry, LogSeverity, log::LevelFilter, parking_lot::Mutex};\nus"
  },
  {
    "path": "alvr/dashboard/src/main.rs",
    "chars": 4168,
    "preview": "// hide console window on Windows in release\n#![cfg_attr(not(debug_assertions), windows_subsystem = \"windows\")]\n\nmod das"
  },
  {
    "path": "alvr/dashboard/src/steamvr_launcher/linux_steamvr.rs",
    "chars": 13280,
    "preview": "use std::fs;\nuse std::path::Path;\nuse std::process::Command;\n\nuse alvr_common::anyhow::bail;\nuse alvr_common::{debug, er"
  },
  {
    "path": "alvr/dashboard/src/steamvr_launcher/mod.rs",
    "chars": 7310,
    "preview": "#[cfg(target_os = \"linux\")]\nmod linux_steamvr;\n#[cfg(windows)]\nmod windows_steamvr;\n\nuse crate::data_sources;\nuse alvr_a"
  },
  {
    "path": "alvr/dashboard/src/steamvr_launcher/windows_steamvr.rs",
    "chars": 502,
    "preview": "use std::os::windows::process::CommandExt;\nuse std::process::Command;\n\nconst CREATE_NO_WINDOW: u32 = 0x0800_0000;\n\npub f"
  },
  {
    "path": "alvr/events/Cargo.toml",
    "chars": 333,
    "preview": "[package]\nname = \"alvr_events\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nauthors.w"
  },
  {
    "path": "alvr/events/src/lib.rs",
    "chars": 5117,
    "preview": "use alvr_common::{DeviceMotion, LogEntry, LogSeverity, Pose, info};\nuse alvr_packets::{ButtonValue, FaceData};\nuse alvr_"
  },
  {
    "path": "alvr/filesystem/Cargo.toml",
    "chars": 192,
    "preview": "[package]\nname = \"alvr_filesystem\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nautho"
  },
  {
    "path": "alvr/filesystem/build.rs",
    "chars": 84,
    "preview": "// This is needed so that `OUT_DIR` is set and `afs::target_dir` works\nfn main() {}\n"
  },
  {
    "path": "alvr/filesystem/src/lib.rs",
    "chars": 10456,
    "preview": "use std::{\n    env::{\n        self,\n        consts::{DLL_EXTENSION, DLL_PREFIX, DLL_SUFFIX, EXE_SUFFIX, OS},\n    },\n    "
  },
  {
    "path": "alvr/graphics/Cargo.toml",
    "chars": 365,
    "preview": "[package]\nname = \"alvr_graphics\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nauthors"
  },
  {
    "path": "alvr/graphics/resources/lobby_line.wgsl",
    "chars": 360,
    "preview": "struct PushConstant {\n    transform: mat4x4f,\n    color: u32,\n}\nvar<push_constant> pc: PushConstant;\n\n@vertex\nfn vertex_"
  },
  {
    "path": "alvr/graphics/resources/lobby_quad.wgsl",
    "chars": 2446,
    "preview": "struct PushConstant {\n    transform: mat4x4f,\n    object_type: u32,\n    floor_side: f32,\n}\nvar<push_constant> pc: PushCo"
  },
  {
    "path": "alvr/graphics/resources/staging_fragment.glsl",
    "chars": 468,
    "preview": "#version 300 es\n#extension GL_OES_EGL_image_external_essl3 : enable\n\nprecision mediump float;\n\nuniform samplerExternalOE"
  },
  {
    "path": "alvr/graphics/resources/staging_vertex.glsl",
    "chars": 255,
    "preview": "#version 300 es\n\nuniform int view_idx;\n\nout vec2 uv;\n\nvoid main() {\n    vec2 screen_uv = vec2(gl_VertexID & 1, gl_Vertex"
  },
  {
    "path": "alvr/graphics/resources/stream.wgsl",
    "chars": 13091,
    "preview": "const DIV12: f32 = 1.0 / 12.92;\nconst DIV1: f32 = 1.0 / 1.055;\nconst THRESHOLD: f32 = 0.04045;\nconst GAMMA: vec3f = vec3"
  },
  {
    "path": "alvr/graphics/src/lib.rs",
    "chars": 13567,
    "preview": "mod lobby;\nmod staging;\nmod stream;\n\npub use lobby::*;\npub use stream::*;\n\nuse alvr_common::{\n    DeviceMotion, Fov, Pos"
  },
  {
    "path": "alvr/graphics/src/lobby.rs",
    "chars": 22330,
    "preview": "use super::{GraphicsContext, MAX_PUSH_CONSTANTS_SIZE, SDR_FORMAT};\nuse crate::HandData;\nuse alvr_common::{\n    BodySkele"
  },
  {
    "path": "alvr/graphics/src/staging.rs",
    "chars": 5475,
    "preview": "use super::{GraphicsContext, ck};\nuse crate::GL_TEXTURE_EXTERNAL_OES;\nuse alvr_common::glam::{IVec2, UVec2};\nuse glow::{"
  },
  {
    "path": "alvr/graphics/src/stream.rs",
    "chars": 19828,
    "preview": "use super::{GraphicsContext, MAX_PUSH_CONSTANTS_SIZE, staging::StagingRenderer};\nuse alvr_common::{\n    ViewParams,\n    "
  },
  {
    "path": "alvr/gui_common/Cargo.toml",
    "chars": 225,
    "preview": "[package]\nname = \"alvr_gui_common\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nautho"
  },
  {
    "path": "alvr/gui_common/src/basic_components/button_group.rs",
    "chars": 499,
    "preview": "use crate::DisplayString;\nuse egui::Ui;\n\n// todo: use a custom widget\npub fn button_group_clicked(\n    ui: &mut Ui,\n    "
  },
  {
    "path": "alvr/gui_common/src/basic_components/mod.rs",
    "chars": 104,
    "preview": "mod button_group;\nmod modal;\nmod switch;\n\npub use button_group::*;\npub use modal::*;\npub use switch::*;\n"
  },
  {
    "path": "alvr/gui_common/src/basic_components/modal.rs",
    "chars": 1709,
    "preview": "use egui::{Align, Align2, Context, Layout, Ui, Window};\nuse std::fmt::{self, Display, Formatter};\n\n#[derive(Clone, Parti"
  },
  {
    "path": "alvr/gui_common/src/basic_components/switch.rs",
    "chars": 1088,
    "preview": "use crate::theme;\nuse egui::{self, Response, Sense, StrokeKind, Ui, WidgetInfo, WidgetType};\n\npub fn switch(ui: &mut Ui,"
  },
  {
    "path": "alvr/gui_common/src/lib.rs",
    "chars": 617,
    "preview": "mod basic_components;\npub mod theme;\n\npub use basic_components::*;\n\nuse std::{ops::Deref, sync::atomic::AtomicUsize};\n\np"
  },
  {
    "path": "alvr/gui_common/src/theme.rs",
    "chars": 3950,
    "preview": "use egui::{self, Color32, Context, CornerRadius, Stroke, TextStyle, ThemePreference, Visuals};\n\npub const ACCENT: Color3"
  },
  {
    "path": "alvr/launcher/Cargo.toml",
    "chars": 715,
    "preview": "[package]\nname = \"alvr_launcher\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nauthors"
  },
  {
    "path": "alvr/launcher/build.rs",
    "chars": 216,
    "preview": "#[cfg(windows)]\nfn main() {\n    let mut resource = winres::WindowsResource::new();\n    resource.set_icon(\"../dashboard/r"
  },
  {
    "path": "alvr/launcher/src/actions.rs",
    "chars": 12493,
    "preview": "use crate::{\n    InstallationInfo, Progress, ReleaseChannelsInfo, ReleaseInfo, UiMessage, WorkerMessage,\n};\nuse alvr_com"
  },
  {
    "path": "alvr/launcher/src/main.rs",
    "chars": 2383,
    "preview": "mod actions;\nmod ui;\n\nuse eframe::egui::{IconData, ViewportBuilder};\nuse ico::IconDir;\nuse std::{collections::BTreeMap, "
  },
  {
    "path": "alvr/launcher/src/ui.rs",
    "chars": 18616,
    "preview": "use crate::{InstallationInfo, Progress, ReleaseChannelsInfo, UiMessage, WorkerMessage, actions};\nuse alvr_gui_common::Mo"
  },
  {
    "path": "alvr/packets/Cargo.toml",
    "chars": 304,
    "preview": "[package]\nname = \"alvr_packets\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nauthors."
  },
  {
    "path": "alvr/packets/src/lib.rs",
    "chars": 9355,
    "preview": "use alvr_common::{\n    BodySkeleton, ConnectionState, DeviceMotion, LogSeverity, Pose, ViewParams,\n    anyhow::Result,\n "
  },
  {
    "path": "alvr/server_core/Cargo.toml",
    "chars": 1001,
    "preview": "[package]\nname = \"alvr_server_core\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nauth"
  },
  {
    "path": "alvr/server_core/cbindgen.toml",
    "chars": 416,
    "preview": "language = \"C\"\nheader = \"/* ALVR is licensed under the MIT license. https://github.com/alvr-org/ALVR/blob/master/LICENSE"
  },
  {
    "path": "alvr/server_core/src/bitrate.rs",
    "chars": 9813,
    "preview": "use alvr_common::SlidingWindowAverage;\nuse alvr_events::BitrateDirectives;\nuse alvr_session::{\n    BitrateAdaptiveFramer"
  },
  {
    "path": "alvr/server_core/src/c_api.rs",
    "chars": 15821,
    "preview": "#![allow(dead_code, unused_variables)]\n#![allow(clippy::missing_safety_doc)]\n\nuse crate::{\n    SESSION_MANAGER, ServerCo"
  },
  {
    "path": "alvr/server_core/src/connection.rs",
    "chars": 55602,
    "preview": "use crate::{\n    ConnectionContext, FILESYSTEM_LAYOUT, SESSION_MANAGER, ServerCoreEvent,\n    bitrate::BitrateManager,\n  "
  },
  {
    "path": "alvr/server_core/src/hand_gestures.rs",
    "chars": 20948,
    "preview": "use crate::input_mapping::ButtonMappingManager;\nuse alvr_common::{\n    glam::{Vec2, Vec3},\n    *,\n};\nuse alvr_packets::{"
  },
  {
    "path": "alvr/server_core/src/haptics.rs",
    "chars": 449,
    "preview": "use alvr_packets::Haptics;\nuse alvr_session::HapticsConfig;\nuse std::time::Duration;\n\npub fn map_haptics(config: &Haptic"
  },
  {
    "path": "alvr/server_core/src/input_mapping.rs",
    "chars": 23757,
    "preview": "use alvr_common::*;\nuse alvr_packets::{ButtonEntry, ButtonValue};\nuse alvr_session::{\n    AutomaticButtonMappingConfig, "
  },
  {
    "path": "alvr/server_core/src/lib.rs",
    "chars": 19339,
    "preview": "mod bitrate;\nmod c_api;\nmod connection;\nmod hand_gestures;\nmod haptics;\nmod input_mapping;\nmod logging_backend;\nmod sock"
  },
  {
    "path": "alvr/server_core/src/logging_backend.rs",
    "chars": 4241,
    "preview": "use crate::SESSION_MANAGER;\nuse alvr_common::{LogEntry, LogSeverity, log::LevelFilter};\nuse alvr_events::{Event, EventTy"
  },
  {
    "path": "alvr/server_core/src/sockets.rs",
    "chars": 2635,
    "preview": "use alvr_common::{\n    ToAny,\n    anyhow::{Result, bail},\n    warn,\n};\nuse flume::TryRecvError;\nuse mdns_sd::{Receiver, "
  },
  {
    "path": "alvr/server_core/src/statistics.rs",
    "chars": 11920,
    "preview": "use alvr_common::{HEAD_ID, SlidingWindowAverage};\nuse alvr_events::{BitrateDirectives, EventType, GraphStatistics, Stati"
  },
  {
    "path": "alvr/server_core/src/tracking/body.rs",
    "chars": 7877,
    "preview": "use alvr_common::{\n    BODY_CHEST_ID, BODY_HIPS_ID, BODY_LEFT_ELBOW_ID, BODY_LEFT_FOOT_ID, BODY_LEFT_KNEE_ID,\n    BODY_R"
  },
  {
    "path": "alvr/server_core/src/tracking/face.rs",
    "chars": 5328,
    "preview": "use alvr_common::{anyhow::Result, glam::EulerRot};\nuse alvr_packets::{FaceData, FaceExpressions};\nuse alvr_session::Face"
  },
  {
    "path": "alvr/server_core/src/tracking/mod.rs",
    "chars": 18707,
    "preview": "mod body;\nmod face;\nmod vmc;\n\npub use body::*;\npub use face::*;\npub use vmc::*;\n\nuse crate::{\n    ConnectionContext, SES"
  },
  {
    "path": "alvr/server_core/src/tracking/vmc.rs",
    "chars": 6217,
    "preview": "use crate::tracking::HandType;\nuse alvr_common::{\n    BODY_CHEST_ID, BODY_HIPS_ID, BODY_LEFT_ELBOW_ID, BODY_LEFT_FOOT_ID"
  },
  {
    "path": "alvr/server_core/src/web_server.rs",
    "chars": 9490,
    "preview": "use crate::{\n    ConnectionContext, FILESYSTEM_LAYOUT, SESSION_MANAGER, ServerCoreEvent,\n    logging_backend::EVENTS_SEN"
  },
  {
    "path": "alvr/server_io/Cargo.toml",
    "chars": 422,
    "preview": "[package]\nname = \"alvr_server_io\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nauthor"
  },
  {
    "path": "alvr/server_io/README.md",
    "chars": 133,
    "preview": "# alvr_server_io\n\nContains functionality for data storage and system info retrieval. Shared between server and dashboard"
  },
  {
    "path": "alvr/server_io/src/firewall.rs",
    "chars": 2721,
    "preview": "use crate::openvrpaths;\nuse alvr_packets::FirewallRulesAction;\nuse std::{\n    env, fs,\n    path::{Path, PathBuf},\n    pr"
  },
  {
    "path": "alvr/server_io/src/lib.rs",
    "chars": 10701,
    "preview": "mod firewall;\nmod openvr_drivers;\nmod openvrpaths;\n\npub use firewall::*;\npub use openvr_drivers::*;\npub use openvrpaths:"
  },
  {
    "path": "alvr/server_io/src/openvr_drivers.rs",
    "chars": 1807,
    "preview": "use crate::openvrpaths;\nuse alvr_common::{\n    ToAny,\n    anyhow::{Result, bail},\n};\nuse serde_json as json;\nuse std::{\n"
  },
  {
    "path": "alvr/server_io/src/openvrpaths.rs",
    "chars": 2581,
    "preview": "use alvr_common::{\n    ToAny,\n    anyhow::{Result, bail},\n};\nuse encoding_rs_io::DecodeReaderBytes;\nuse serde_json as js"
  },
  {
    "path": "alvr/server_openvr/Cargo.toml",
    "chars": 754,
    "preview": "[package]\nname = \"alvr_server_openvr\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nau"
  },
  {
    "path": "alvr/server_openvr/LICENSE",
    "chars": 1093,
    "preview": "Copyright (c) 2018-2019 polygraphene\nCopyright (c) 2020-2024 alvr-org\n\nPermission is hereby granted, free of charge, to "
  },
  {
    "path": "alvr/server_openvr/LICENSE-Valve",
    "chars": 1487,
    "preview": "Copyright (c) 2015, Valve Corporation\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or w"
  },
  {
    "path": "alvr/server_openvr/build.rs",
    "chars": 6945,
    "preview": "use std::{env, path::PathBuf};\n\nfn get_ffmpeg_path() -> PathBuf {\n    let ffmpeg_path = alvr_filesystem::deps_dir()\n    "
  },
  {
    "path": "alvr/server_openvr/cpp/ALVR-common/common-utils.cpp",
    "chars": 413,
    "preview": "#include \"common-utils.h\"\n\n#include <codecvt>\n#include <locale>\n\nstd::wstring ToWstring(const std::string& src) {\n    //"
  },
  {
    "path": "alvr/server_openvr/cpp/ALVR-common/common-utils.h",
    "chars": 126,
    "preview": "#pragma once\n\n#include <string>\n\nstd::wstring ToWstring(const std::string& src);\nstd::string ToUTF8(const std::wstring& "
  },
  {
    "path": "alvr/server_openvr/cpp/ALVR-common/exception.cpp",
    "chars": 419,
    "preview": "#include \"exception.h\"\n#include \"common-utils.h\"\n#include <stdarg.h>\n#include <wchar.h>\n\nException FormatExceptionV(cons"
  },
  {
    "path": "alvr/server_openvr/cpp/ALVR-common/exception.h",
    "chars": 410,
    "preview": "#pragma once\n\n#include <stdexcept>\n#include <string>\n\nclass Exception : public std::exception {\npublic:\n    Exception(st"
  },
  {
    "path": "alvr/server_openvr/cpp/ALVR-common/packet_types.h",
    "chars": 824,
    "preview": "#ifndef ALVRCLIENT_PACKETTYPES_H\n#define ALVRCLIENT_PACKETTYPES_H\n#include \"../alvr_server/bindings.h\"\n#include <assert."
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/ChaperoneUpdater.cpp",
    "chars": 3420,
    "preview": "#include \"ALVR-common/packet_types.h\"\n#include \"Logger.h\"\n#include \"bindings.h\"\n#include <memory>\n#include <mutex>\n\n#ifn"
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/Controller.cpp",
    "chars": 80424,
    "preview": "#include \"Controller.h\"\n#include \"Logger.h\"\n#include \"Paths.h\"\n#include \"Settings.h\"\n#include \"Utils.h\"\n#include \"includ"
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/Controller.h",
    "chars": 1575,
    "preview": "#pragma once\n\n#include \"ALVR-common/packet_types.h\"\n#include \"TrackedDevice.h\"\n#include \"openvr_driver_wrap.h\"\n#include "
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/FakeViveTracker.cpp",
    "chars": 9611,
    "preview": "#include \"FakeViveTracker.h\"\n\n#include \"Logger.h\"\n#include \"Paths.h\"\n#include \"Settings.h\"\n#include \"Utils.h\"\n#include \""
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/FakeViveTracker.h",
    "chars": 398,
    "preview": "#pragma once\n\n#include \"TrackedDevice.h\"\n#include \"bindings.h\"\n#include \"openvr_driver_wrap.h\"\n\nclass FakeViveTracker : "
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/HMD.cpp",
    "chars": 11573,
    "preview": "#include \"HMD.h\"\n\n#include \"Controller.h\"\n#include \"Logger.h\"\n#include \"Paths.h\"\n#include \"PoseHistory.h\"\n#include \"Sett"
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/HMD.h",
    "chars": 2167,
    "preview": "#pragma once\n\n#include \"ALVR-common/packet_types.h\"\n#include \"TrackedDevice.h\"\n#include \"openvr_driver_wrap.h\"\n#include "
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/IDRScheduler.cpp",
    "chars": 707,
    "preview": "#include \"IDRScheduler.h\"\n\n#include \"Utils.h\"\n#include <mutex>\n\nIDRScheduler::IDRScheduler() { }\n\nIDRScheduler::~IDRSche"
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/IDRScheduler.h",
    "chars": 464,
    "preview": "#pragma once\n\n#include \"Settings.h\"\n#include <mutex>\n#include <stdint.h>\n\nclass IDRScheduler {\npublic:\n    IDRScheduler("
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/Logger.cpp",
    "chars": 1745,
    "preview": "#include \"Logger.h\"\n\n#include <cstdarg>\n\n#include \"bindings.h\"\n#include \"driverlog.h\"\n\nvoid _log(const char* format, va_"
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/Logger.h",
    "chars": 305,
    "preview": "#pragma once\n\n#include \"ALVR-common/exception.h\"\n\nException MakeException(const char* format, ...);\n\nvoid Error(const ch"
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/NalParsing.cpp",
    "chars": 3547,
    "preview": "\n#include \"Logger.h\"\n#include \"Settings.h\"\n#include \"Utils.h\"\n#include \"bindings.h\"\n#include <mutex>\n#include <string.h>"
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/Paths.cpp",
    "chars": 17152,
    "preview": "#include \"Paths.h\"\n#include \"bindings.h\"\n\nuint64_t HEAD_ID;\nuint64_t HAND_LEFT_ID;\nuint64_t HAND_RIGHT_ID;\nuint64_t HAND"
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/Paths.h",
    "chars": 1892,
    "preview": "#pragma once\n\n#include <cstdint>\n#include <map>\n#include <set>\n#include <vector>\n\n#include \"openvr_driver_wrap.h\"\n\nexter"
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/PoseHistory.cpp",
    "chars": 3050,
    "preview": "#include \"PoseHistory.h\"\n#include \"Logger.h\"\n#include \"Utils.h\"\n#include \"include/openvr_math.h\"\n#include <mutex>\n#inclu"
  },
  {
    "path": "alvr/server_openvr/cpp/alvr_server/PoseHistory.h",
    "chars": 950,
    "preview": "#pragma once\n\n#include \"ALVR-common/packet_types.h\"\n#include \"openvr_driver_wrap.h\"\n\n#include <list>\n#include <mutex>\n#i"
  }
]

// ... and 295 more files (download for full content)

About this extraction

This page contains the full source code of the alvr-org/ALVR GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 495 files (3.6 MB), approximately 974.2k tokens, and a symbol index with 2819 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!