dragonflight/services/capture/patch_decklink.py
Zac Gaetano a8656fc1a8 capture: custom FFmpeg 7.1 build with DeckLink + D-Bus mounts + SDI deinterlace
Dockerfile is now a two-stage build that compiles FFmpeg from source with --enable-decklink against the Blackmagic SDK 16.x headers in services/capture/sdk/ (operator-supplied, gitignored). build-with-decklink.sh + patch_decklink.py drive the build.

docker-compose.yml mounts /dev/shm, /run/dbus, /run/systemd into mam-api, capture, web-ui so the BMD runtime can talk to the host.

capture-manager.js wraps SDI sources with -vf yadif=mode=1 (deinterlace).

recorders.html defaults to SDI source type now that we have a working DeckLink path.
2026-05-22 00:01:43 +00:00

51 lines
2 KiB
Python

import re
dec_path = '/ffmpeg/libavdevice/decklink_dec.cpp'
with open(dec_path) as f:
content = f.read()
# Fix 1: IDeckLinkMemoryAllocator -> IDeckLinkMemoryAllocator_v14_2_1
# SDK 16 removed the unversioned alias
for old, new in [
(': public IDeckLinkMemoryAllocator\n', ': public IDeckLinkMemoryAllocator_v14_2_1\n'),
('IDeckLinkMemoryAllocator *', 'IDeckLinkMemoryAllocator_v14_2_1 *'),
('IDeckLinkMemoryAllocator*', 'IDeckLinkMemoryAllocator_v14_2_1*'),
]:
content = content.replace(old, new)
print('Fix 1: IDeckLinkMemoryAllocator renamed')
# Fix 2: SetVideoInputFrameMemoryAllocator removed from IDeckLinkInput in SDK 16
content = re.sub(
r'ret = \(ctx->dli->SetVideoInputFrameMemoryAllocator\(allocator\)[^;]*;',
'ret = 0; /* SDK16: SetVideoInputFrameMemoryAllocator removed */',
content
)
print('Fix 2: SetVideoInputFrameMemoryAllocator patched')
# Fix 3: IDeckLinkVideoFrame::GetBytes removed in SDK 16 - moved to IDeckLinkVideoBuffer
# Replace: videoFrame->GetBytes(&frameBytes);
# With: { IDeckLinkVideoBuffer *vbuf = nullptr; videoFrame->QueryInterface(IID_IDeckLinkVideoBuffer, (void**)&vbuf); if (vbuf) { vbuf->GetBytes(&frameBytes); vbuf->Release(); } }
getbytes_replacement = (
'{ IDeckLinkVideoBuffer *_vbuf = nullptr; '
'videoFrame->QueryInterface(IID_IDeckLinkVideoBuffer, (void**)&_vbuf); '
'if (_vbuf) { _vbuf->GetBytes(&frameBytes); _vbuf->Release(); } }'
)
content = content.replace(
'videoFrame->GetBytes(&frameBytes);',
getbytes_replacement + ';'
)
print('Fix 3: videoFrame->GetBytes replaced with QueryInterface(IDeckLinkVideoBuffer)')
# Fix 4: Add include for versioned allocator header
if 'DeckLinkAPIMemoryAllocator_v14_2_1.h' not in content:
content = content.replace(
'#include "decklink_common.h"',
'#include "decklink_common.h"\n#include "DeckLinkAPIMemoryAllocator_v14_2_1.h"'
)
print('Fix 4: DeckLinkAPIMemoryAllocator_v14_2_1.h include added')
with open(dec_path, 'w') as f:
f.write(content)
print('All patches applied successfully')