Skip to content

About

A client and server for streaming PC image to the Original XBox

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

4 Commits

Folders and files

Repository files navigation

xboxstreamer

Streams a PC's screen to an original Xbox, which displays it over RGB SCART. 640x480, 1:1, no rescaling, 60 fps, with audio.

The Xbox is the display endpoint, not a media player: its analog output is broadcast-spec, so a CRT that rejects PC timings will accept it.

Requirements

  • An original Xbox, softmodded or modchipped. Nothing here is signed.
  • RGB SCART to the television. Only sync timing matters — R, G and B are on separate pins, so PAL vs NTSC colour encoding is irrelevant, and the TV takes 60 Hz.
  • A wired LAN between PC and Xbox. The stream runs at up to ~67 Mbit/s.
  • Windows XP or Windows 10/11 on the capture side.
  • MSYS2 with the MinGW toolchains to build; nxdk to build the client.

Build

Server, from an MSYS2 shell — -mingw64 for Windows 10/11, -mingw32 for XP, where 32-bit is mandatory:

make -C pc-server

Hook DLLs, always from -mingw32 because the games are 32-bit:

make -C hook

Xbox client, from -mingw64 with NXDK_DIR pointing at your nxdk checkout:

bash client-xbox/build.sh

Run

Launch wsclient on the Xbox from your dashboard. It prints its own IP and waits. Then, from the PC:

pc-server/xboxstreamer-server.exe --scale --host <XBOX_IP>

--host is required and there is no default. A wrong address cannot be detected — UDP has nothing to reject against — so the server runs, reports frames, and the TV stays black.

--scale fits a larger source into 640x480 instead of cropping it to the top-left corner. Without it, a 4K desktop streams a 640x480 corner of itself.

docs/USAGE.md is the reference: every option, how to find the Xbox's address, how to install the client, and what each line of output means.

Fullscreen games

Desktop Duplication cannot capture an exclusive-fullscreen game — while a game owns the display, the desktop is not available to duplicate. Such games are captured from inside the process instead, by a proxy DLL placed next to the game's executable. Copy the one matching the API the game presents with, plus hook/xboxstreamer-hook.ini, into the game's folder, and run the server with --capture hook:

Game uses Drop in Confirmed against a real game
DirectDraw / D3D6-7 hook/ddraw.dll Yes
OpenGL hook/opengl32.dll Yes
Direct3D 8 hook/d3d8.dll No — passes its PC harness only
Direct3D 9 hook/d3d9.dll No — passes its PC harness only

Nothing is installed or registered; Windows searches the application directory before system32, so deleting the file undoes it. --capture hook is safe to leave on permanently — with no hooked game running it captures the desktop, and switches over when one starts.

How it works

PC ─ capture ─→ DXT1 encode ─→ block delta ─→ UDP ─→ Xbox ─→ NV2A ─→ SCART ─→ CRT
     0.4-7 ms    0.6-1.0 ms    changed          LAN    texture upload
                               blocks only             (DXT1 decoded free)

Four constraints shape it, each trading bandwidth for latency:

  • DXT1 is the codec. The NV2A decodes it in the texture unit at no cost: no decode time, no decode latency, a fixed 4:1 ratio, and no frame buffering anywhere. A real video codec would be far smaller on the wire and would reintroduce the delay this exists to avoid.
  • Only changed blocks are sent. Each frame is diffed against the last in 4x4 DXT1 blocks; a periodic keyframe bounds how long a lost packet can leave a block stale.
  • No retransmission. A lost packet leaves those blocks stale until their next update.
  • Input is not streamed. The controller plugs into the PC.

Audio is raw 48 kHz stereo PCM, ~1.5 Mbit/s, for the same reason. SCART carries it on the same cable as the picture.

Measured

Network ceiling 96 Mbit/s, zero loss — the Xbox saturates its 100 Mbit NIC
DXT1 encode 0.6-1.0 ms per frame, against a 16.7 ms budget
Capture 0.4 ms (Desktop Duplication), 4-7 ms (GDI on XP)
Idle desktop ~1.2 Mbit/s, almost all of it the periodic keyframe
Real motion 7-12.6 Mbit/s at 60 fps
A game, full screen 54-67 Mbit/s at 60 fps, no partial, late or dropped frames at the client

End-to-end latency is unmeasured. Every figure in the latency budget in docs/DESIGN.md is an estimate except the encode.

Layout

pc-server/ Capture backends, DXT1 encode, block delta, packetizer, UDP, audio
client-xbox/ lwIP receive, texture upload, fullscreen quad, AC97 audio
client-core/ Portable C99 stream reassembly, shared with the client, tested on the PC
hook/ The four proxy DLLs, and a fake game for each to test against
protocol/ Wire format
tests/ 340 checks

Tests

client-core has no platform calls, so the whole reassembly path is tested on the PC with no console involved:

make -C tests run

tests/check-portability.sh also compiles client-core with nxdk's clang, confirming it builds unmodified for the Xbox. make -C hook test runs all four proxy harnesses, each verifying the published pixels rather than merely that nothing crashed.

Documentation

docs/USAGE.md Building, running, every option, reading the output, troubleshooting
docs/DESIGN.md Architecture, bandwidth arithmetic, latency budget
docs/PROTOCOL.md Wire format, normative
docs/FINDINGS.md Measurements, and approaches that were tried and rejected

Known limitations

  • d3d8 and d3d9 have never run against a real game; both pass their PC harnesses. ddraw and opengl32 are confirmed on hardware.
  • End-to-end latency is unmeasured.
  • Audio dropouts on XP are not fully closed; the client overlay's underrun counter is the diagnostic.
  • --capture d3d9 is unusably slow on some drivers — see docs/USAGE.md.

License

MIT — see LICENSE.

About

A client and server for streaming PC image to the Original XBox

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages