Unity-Technologies / Unity-Technologies/com.unity.webrtc

[REQUEST]: Improve input latency for streaming from Unity camera to end users

Open
#803 18 comments 1 reaction 1 assignee View on GitHub

@karasusan is already working on this.

Since Sep 1, 2022.

enhancement issued
Dominant language
Assembly
Stars
852
Forks
238
PR merge metrics
No merged PRs in 30d

Description

Is your feature request related to a problem?

This is an approach to improve the latency with the current architecture of the plugin.

The goal is to get the frame encoded within 7ms of finishing rendering (https://parsec.app/blog/nvidia-nvenc-outperforms-amd-vce-on-h-264-encoding-latency-in-parsec-co-op-sessions-713b9e1e048a), which is pretty close to NvFBC / Moonlight.

Right now, due to the architecture of the plugin, the time between rendering finishing and encoding the frame is about

  • 7ms for NVIDIA to encode
  • 4-10ms to copy resources
  • 0-20ms due to frame rate control
  • 0-24ms due to WaitForEndOfFrame
    totalling about 11-61ms of input latency when networking RTT is 0.
Describe the solution you'd like
  • the plugin event call should be implemented as a custom pass in HDRP, a render feature in URP and the current method (end of frame) for the obsolete pipeline
  • Input System should queue events directly from the data channel's thread instead of using WebRTC.Sync. this will require a fix for Input System's memory leak with its input event buffers (https://forum.unity.com/threads/bug-memory-leaks-crash-when-queueing-events-from-threads-other-than-the-main-thread.1329837/)
  • video frame rate control should be turned off
  • avoiding copying:
    • the render texture passed to webrtc must be retained on c# side until webrtc reports it is done encoding it. or, the plugin can give unity the render texture it should blit into. resizing is essential and the C# side knows the size earlier than the plugin does, so the former is going to be easier to do.
    • gpu memory buffers should be created with a reference to the ITexture2D*. then, they should create the appropriate "texture view" for the hardware/software encoder on demand inside the encoder queue thread. this means handle() does the map step in the current implementation, and ToI420 gets the cpu texture. a map looks just as expensive as a CopyResourceNativeV though...
    • in order to avoid the expensive map on windows, there must be DX11 and DX12 NVEncoderImpl support, instead of using CUDA encoder for all platforms
Describe alternatives you've considered

No response

Additional context

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.