fix(deltacast): non-blocking write + 64MB FIFO + GPU runtime for capture container

This commit is contained in:
Zac Gaetano 2026-06-02 21:31:06 +00:00
parent 13feb0a6a2
commit ec1699907d
3 changed files with 34 additions and 4 deletions

View file

@ -16,6 +16,11 @@
# - Sets NVENC_ENABLED=true so the worker prioritises h264_nvenc/hevc_nvenc # - Sets NVENC_ENABLED=true so the worker prioritises h264_nvenc/hevc_nvenc
services: services:
capture:
runtime: nvidia
environment:
NVIDIA_VISIBLE_DEVICES: all
NVIDIA_DRIVER_CAPABILITIES: video,compute,utility
worker: worker:
build: build:
context: ./services/worker context: ./services/worker

View file

@ -104,6 +104,7 @@ services:
build: ./services/capture build: ./services/capture
profiles: [capture] profiles: [capture]
restart: unless-stopped restart: unless-stopped
runtime: nvidia
environment: environment:
REDIS_URL: ${REDIS_URL} REDIS_URL: ${REDIS_URL}
DATABASE_URL: ${DATABASE_URL} DATABASE_URL: ${DATABASE_URL}
@ -112,6 +113,8 @@ services:
S3_ACCESS_KEY: ${S3_ACCESS_KEY} S3_ACCESS_KEY: ${S3_ACCESS_KEY}
S3_SECRET_KEY: ${S3_SECRET_KEY} S3_SECRET_KEY: ${S3_SECRET_KEY}
CAPTURE_PORT: 3001 CAPTURE_PORT: 3001
NVIDIA_VISIBLE_DEVICES: all
NVIDIA_DRIVER_CAPABILITIES: video,compute,utility
devices: devices:
- ${BMD_DEVICE_0:-/dev/blackmagic/dv0}:/dev/blackmagic/dv0 - ${BMD_DEVICE_0:-/dev/blackmagic/dv0}:/dev/blackmagic/dv0
- ${BMD_DEVICE_1:-/dev/blackmagic/dv1}:/dev/blackmagic/dv1 - ${BMD_DEVICE_1:-/dev/blackmagic/dv1}:/dev/blackmagic/dv1

View file

@ -110,14 +110,33 @@ static VideoInfo video_info(VHD_VIDEOSTANDARD std, VHD_CLOCKDIVISOR div) {
} }
/* ── Write-all helper ─────────────────────────────────────────────────── */ /* ── Write-all helper ─────────────────────────────────────────────────── */
/* Writes all bytes to fd. Uses non-blocking I/O so the bridge never stalls
* waiting for a slow reader. Returns 0 on success, -1 on fatal error (EPIPE
* = reader closed the FIFO). EAGAIN / EWOULDBLOCK on a full pipe is NOT fatal
* the caller (video_thread) will retry on the next slot lock. */
static int write_all(int fd, const unsigned char *p, size_t len) { static int write_all(int fd, const unsigned char *p, size_t len) {
/* Make the fd non-blocking for the duration of this write */
int flags = fcntl(fd, F_GETFL, 0);
if (flags < 0) return -1;
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) return -1;
size_t off = 0; size_t off = 0;
while (off < len) { while (off < len) {
ssize_t n = write(fd, p + off, len - off); ssize_t n = write(fd, p + off, len - off);
if (n > 0) { off += (size_t)n; continue; } if (n > 0) { off += (size_t)n; continue; }
if (n < 0 && errno == EINTR) continue; if (n < 0 && errno == EINTR) continue;
if (n < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
/* Pipe full — brief yield then retry */
struct timespec ts = {0, 1000000L}; /* 1ms */
nanosleep(&ts, NULL);
continue;
}
/* EPIPE or other fatal error — restore flags and return */
fcntl(fd, F_SETFL, flags);
return -1; return -1;
} }
/* Restore blocking mode */
fcntl(fd, F_SETFL, flags);
return 0; return 0;
} }
@ -318,10 +337,13 @@ static void *video_thread(void *arg) {
#ifndef F_SETPIPE_SZ #ifndef F_SETPIPE_SZ
#define F_SETPIPE_SZ 1031 #define F_SETPIPE_SZ 1031
#endif #endif
if (fcntl(fd, F_SETPIPE_SZ, 8 * 1024 * 1024) < 0) { {
fprintf(stderr, "[video:%u] fcntl F_SETPIPE_SZ failed: %s\n", ps->port, strerror(errno)); int pipe_sz = 64 * 1024 * 1024; /* 64 MB — ~16 frames of 1080p UYVY */
} else { if (fcntl(fd, F_SETPIPE_SZ, pipe_sz) < 0) {
fprintf(stderr, "[video:%u] FIFO pipe size increased to 8MB\n", ps->port); fprintf(stderr, "[video:%u] fcntl F_SETPIPE_SZ failed: %s\n", ps->port, strerror(errno));
} else {
fprintf(stderr, "[video:%u] FIFO pipe size increased to %dMB\n", ps->port, pipe_sz / (1024*1024));
}
} }
HANDLE slot = NULL; HANDLE slot = NULL;