fix(deltacast): non-blocking write + 64MB FIFO + GPU runtime for capture container
This commit is contained in:
parent
13feb0a6a2
commit
ec1699907d
3 changed files with 34 additions and 4 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue