- C++ 59.2%
- C 38.3%
- Python 1.3%
- CMake 1.2%
| src | ||
| tools | ||
| .gitignore | ||
| CMakeLists.txt | ||
| CMakePresets.json | ||
| README.md | ||
| vcpkg.json | ||
DeckLink test apps
Two Windows apps (MSVC x64, vcpkg, Dear ImGui on D3D11) for a Blackmagic DeckLink card, plus two console tools.
| target | what |
|---|---|
decklink_rx |
Receiver: live video in a resizable, letterboxed window, audio monitoring, optional VU meter |
decklink_tx |
Signal generator: pick resolution / frame rate / audio channels and one of six generators |
decklink_list |
Console: lists devices and the input/output modes each supports |
decklink_selftest |
Console loopback check (see below) |
Build
set VCPKG_ROOT=C:\Users\Samuel\.vcpkg-clion\vcpkg
cmake --preset msvc-x64
cmake --build build --config Release
Binaries land in build\bin\<Config>. In CLion enable the vcpkg integration; vcpkg.json is the manifest
(imgui with the win32 + dx11 bindings, and miniaudio). The triplet is x64-windows-static-md, so there are
no DLLs to ship. Requires the Blackmagic Desktop Video driver.
DeckLink API header
No SDK download is needed. src/common/decklink_api.h is generated from the type library embedded in the
installed driver (tools/gen_decklink_api.py, currently driver 14.5), so the interface layouts match the driver.
To refresh it after a driver upgrade, compile a file containing
#import "DeckLinkAPI64.dll" raw_interfaces_only no_namespace named_guids and run
python tools/gen_decklink_api.py DeckLinkAPI64.tlh src/common/decklink_api.h.
The official SDK headers can be used instead by swapping the include.
Receiver (decklink_rx)
Command line: decklink_rx.exe [--device N] [--start] (N indexes the input devices in the list).
- Device / Format: pick an input, and either a fixed format or Auto-detect input format (cards that support it). Detected changes of mode or colour space are followed automatically.
- Video: UYVY (or BGRA for RGB sources) is uploaded to the GPU, converted to RGB (Rec.709 for height >= 720,
else Rec.601) and drawn letterboxed. The window is freely resizable and keeps updating while you drag it.
F11toggles fullscreen,Hhides the control panel. Keep last frame on signal loss holds the final picture instead of going black. - Audio: the card's embedded audio is captured (16 channels, falling back to 8 then 2) and one stereo pair is played on the default Windows output (Monitor selects the pair; volume / mute are provided).
- VU meter: one bar per captured channel, -60..0 dBFS, with peak hold. Optional checkbox.
Generator (decklink_tx)
Command line: decklink_tx.exe [--mode N] (index into the Mode dropdown).
Resolution and frame rate come from the display modes the selected device reports; audio is 48 kHz / 16-bit with 2, 8 or 16 channels. Mode can be switched while outputting (video immediately, audio within ~0.2 s); the Audio level slider and the pattern options are live too. The window shows frames scheduled, late / dropped counts and buffer depth.
| mode | output |
|---|---|
| Test pattern | Colour bars, grey ramp, sweeping line, bouncing square, timecode, frame counter, orange marker. Each second the picture flashes white while a 1 kHz blip starts on the same frame. Line / square / marker are individually switchable. |
| SDI check field (pathological) | SMPTE RP 198 (HD) / RP 178 (SD) stress signal: equaliser words (Cb/Cr 300h, Y 198h) and PLL words (Cb/Cr 200h, Y 110h), with the polarity-alternating word on every other frame. 10-bit v210 if the card supports it. Double-handle sliders set the vertical extent of each signal; uncovered lines are black. No audio. |
| Colour bars + 1 kHz tone | Static bars, continuous tone on all channels. |
| A/V sync flash + beep | Black with one white frame per second and a beep starting on that frame. |
| Audio channel identify | A 1 kHz beep on one channel at a time (0.5 s each) while the picture shows the channel number. |
| Black + silence |
How A/V sync is kept
Video frame n is scheduled at n * frameDuration; audio is a continuous stream where sample s is a pure
function of its index. A blip starts at the audio sample that coincides with the start of the flashing frame
(k * blipFrames * frameDuration * 48000 / timeScale), so both come from one timeline. Playback starts when the
first audio preroll callback fires.
Code map
src/common/decklink_api.h generated COM interfaces (subset)
src/common/decklink_util.* device/mode enumeration, FrameLock, callback IUnknown macro
src/common/d3d_app.* Win32 window + D3D11 swap chain + ImGui shell
src/rx/capture.* input capture, format-change handling, audio hand-off
src/rx/video_renderer.* YUV->RGB shader path and letterboxed draw
src/rx/audio_monitor.* miniaudio playback + peak levels
src/rx/main.cpp receiver UI
src/tx/generator.* scheduled playback, frame ring, audio timeline, generator modes
src/tx/pattern.* UYVY / v210 renderers (test pattern, bars, flash, channel id, check field)
src/tx/main.cpp generator UI
src/tools/ decklink_list, decklink_selftest
tools/gen_decklink_api.py regenerates decklink_api.h from the installed driver
Threading: DeckLink callbacks run on driver threads. Capture hands frames to the UI thread under a mutex;
Generator renders inside its completion callbacks and keeps live settings in atomics (the check-field ranges use
a small mutex).
Self test
decklink_selftest <tx-idx> <rx-idx> <secs> <mode> [capture|capture-fixed] [generator mode 0-5]
Plays a generator on one device while another device's input (cabled loopback) receives it. Without capture it
prints late/dropped frames, received frame spacing and the measured offset between flash and beep; with capture
it drives the receiver app's Capture class (including auto-detect) and prints received pixel words.