In this presentation, we discuss how Parsec went about the process of building our own UDP protocol for cloud gaming. The goal for our protocol was to have the reliability of TCP while picking up many the benefits of UDP. This gave us high reliability with low latency video streaming at 1080p, 60fps, with no buffer. We hope this presentation can help other engineers build their own UDP protocols to solve their requirements.
1. Code Driven – Building A UDP Protocol For Cloud
Gaming
@ParsecTeam
Parsec.tv
2. PC GAMING IS EXPENSIVE, COMPLICATED, & RESTRICTIVE
PC gaming requires upfront investments, hardware knowledge to get started, and ties the gamer to
a desktop PC. This restricts the market for PC gaming and forces difficult decisions about investing
in hardware when we all just want to play our favorite games.
@ParsecTeam
3. PARSEC GIVES YOUACCESS TO GAMING MACHINES
Bring your gaming machine wherever you go with Parsec or access a gaming PC in the cloud.
@ParsecTeam
4. DELIVERING THE LOWEST LATENCY POSSIBLE
Capturing
Encoding
NetworkingDecoding
Rendering
Capturing
• Low latency desktop capture with zero-copy GPU pipeline to encoder
Encoding
• All hardware-specific encoding libraries implemented directly on
Windows (AMD, Intel, and NVIDIA) with library specific optimizations
Networking
• Low latency proprietary UDP protocol
• Ultra-responsive dynamic bitrate adjustment
• DTLS 1.2 with AES128 or AES256 cipher
• Secure per-connection tokens signed and authenticated with Parsec
• NAT traversal using UDP hole punching for peer-to-peer use cases
Decoding
• All hardware-specific decoding libraries implemented directly on Windows
(AMD, Intel, and NVIDIA) with library specific optimizations
• Hardware decoding on macOS
• Hardware decoding on Raspberry Pi via OpenMaxIL
• Hardware decoding on Android (available on request only right now)
Rendering
• Zero-copy OpenGL rendering pipeline from decoder
• Low level frame timing and synchronization optimizations
@ParsecTeam
6. TCP CAN’T HANDLE THE HEAT IN THE KITCHEN
TCP works very well when you have an amazing connection, but most people don’t have Gbps
connections with no loss (Spectrum – we’re looking at you).
@ParsecTeam
7. • TCP: Stream oriented
(abstracts IP packets), acks,
congestion, windows, state
all over the place
• UDP: Stateless, thin
abstraction over IP packets
Some Background
• Reliability & reordering
• Stream semantics
• Connection state &
handshaking
• Congestion control (dump
data to the network at will)
• Works everywhere
Some Benefits of TCP
• Linux kernel network source
(/source/net/ipv4)
- TCP code: 32 files, 724
KB
-UDP code: 6 files, 95 KB
Some Stats
UDP VS. TCP…ALWAYS TOGETHER, BUT NEVER CLOSE
@ParsecTeam
8. WHY WE’RE ROLLING WITH OUR OWN PROTOCOL
Benefits of TCP we need or want
-Reliability & reordering <-- yes
-Stream semantics <-- yes
-Connection state & handshaking <-- yes, via DTLS
-Congestion control <-- NO, we can control our bitrate
-Works everywhere < -- NO, assume minimum specs and buffers
Certain types of data can benefit by simpler or no congestion control
-Lossy compression can set bitrate on the fly
Hole punching! The bug becomes the feature
Control
-Optimize for a narrower use-case: latency / bandwidth
-Detailed loss and RTT metrics, can be hard to get with TCP
-Everything controlled in user space, no kernel options necessary
-Fine-grained drop vs. retransmit logic -- some data doesn't need to get there
@ParsecTeam
9. HOW WE BUILT BUD
-C -- everything you need, nothing you don't
-Wireshark -- the best program ever written
-Clumsy (windows), network conditioner (macos via xcode), tc (linux)
Tools
Packet headers (at minimum)
Read/write windows
ACK
Keepalive
Retransmit
Simplifying the interface: you’re going to need threads
@ParsecTeam
10. HOW WE BUILT BUD
-Sequence number
-Type
-Payload
Tools
Packet headers (at minimum)
Read/write windows
ACK
Keepalive
Retransmit
Simplifying the interface: you’re going to need threads
@ParsecTeam
11. HOW WE BUILT BUD
-Base pointer, head pointer (sequence numbers)
-Read data from base, add data to head
-Write data to head, send from base
Tools
Packet headers (at minimum)
Read/write windows
ACK
Keepalive
Retransmit
Simplifying the interface: you’re going to need threads
@ParsecTeam
12. 0 1 2 3 4 5 6
0 1 2 3 4 5 6
SENT UNACKED
EMPTY / ACKED
7 8
7 8
BASE
FULL
HEAD
BASE HEAD
READ/WRITE DETAILS
@ParsecTeam
13. HOW WE BUILT BUD
-Let the sender know we got the data
-Receiver sends read packet sn, head pointer
-Sender can calculate RTT
Tools
Packet headers (at minimum)
Read/write windows
ACK
Keepalive
Retransmit
Simplifying the interface: you’re going to need threads
@ParsecTeam
14. HOW WE BUILT BUD
-Need to send something if both sender and receiver are sleeping
-Receiver can send their head pointer
Tools
Packet headers (at minimum)
Read/write windows
ACK
Keepalive
Retransmit
Simplifying the interface: you’re going to need threads
@ParsecTeam
15. HOW WE BUILT BUD
-Fast retransmit based on out of order acks
-Most packets, if out of order, are only flipped
-Slow retransmit for failsafe (sent after certain multiple of the RTT)
Tools
Packet headers (at minimum)
Read/write windows
ACK
Keepalive
Retransmit
Simplifying the interface: you’re going to need threads
@ParsecTeam
17. HOW WE BUILT BUD
-Goal of the threading model is NOT to squeeze everything out of the CPU
-Always start with dumb "global" mutexes and get core logic solid... then get fancy
Tools
Packet headers (at minimum)
Read/write windows
ACK
Keepalive
Retransmit
Simplifying the interface: you’re going to need threads
@ParsecTeam
18. THE END RESULT
BUD is resilient even when you’re being chased by TIE fighters through the Asteroid Belt.
@ParsecTeam