Use GPUVideoSource for hardware-accelerated video decoding
Some checks are pending
GPU Worker CI/CD / test (push) Waiting to run
GPU Worker CI/CD / deploy (push) Blocked by required conditions

- CIDVideoSource now uses GPUVideoSource when GPU is available
- Enables CUDA hardware decoding for video sources
- Should significantly improve rendering performance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
giles
2026-02-04 01:03:16 +00:00
parent 0bd8ee71c7
commit ef4bc24eda
2 changed files with 53 additions and 13 deletions

View File

@@ -112,21 +112,22 @@
function initHls() {
if (Hls.isSupported()) {
hls = new Hls({
// Stability over low latency - buffer more for smoother playback
liveSyncDurationCount: 4, // Stay 4 segments behind live edge
liveMaxLatencyDurationCount: 8, // Max 8 segments behind
// Stay far behind live edge - rendering is slow (~0.1x speed)
// 10 segments = 40s of buffer before catching up
liveSyncDurationCount: 10, // Stay 10 segments behind live edge
liveMaxLatencyDurationCount: 20, // Allow up to 20 segments behind
liveDurationInfinity: true, // Treat as infinite live stream
// Large buffers to absorb rendering speed variations
maxBufferLength: 60, // Buffer up to 60s ahead
maxMaxBufferLength: 120, // Allow even more if needed
maxBufferSize: 60 * 1024 * 1024, // 60MB buffer
maxBufferLength: 120, // Buffer up to 120s ahead
maxMaxBufferLength: 180, // Allow even more if needed
maxBufferSize: 100 * 1024 * 1024, // 100MB buffer
maxBufferHole: 0.5, // Tolerate small gaps
// Back buffer for smooth seeking
backBufferLength: 30,
backBufferLength: 60,
// Playlist reload settings
// Playlist reload settings - check frequently for new segments
manifestLoadingTimeOut: 10000,
manifestLoadingMaxRetry: 4,
levelLoadingTimeOut: 10000,
@@ -202,9 +203,21 @@
}
});
// Handle video stalls
// Handle video stalls - check if we've caught up to live edge
video.addEventListener('waiting', function() {
statusEl.textContent = 'Buffering...';
// Check if we're near the live edge (within 2 segments)
if (hls && hls.liveSyncPosition) {
const liveEdge = hls.liveSyncPosition;
const currentTime = video.currentTime;
const behindLive = liveEdge - currentTime;
if (behindLive < 8) { // Less than 2 segments behind
statusEl.textContent = 'Waiting for rendering...';
} else {
statusEl.textContent = 'Buffering...';
}
} else {
statusEl.textContent = 'Buffering...';
}
statusEl.classList.remove('text-green-400');
statusEl.classList.add('text-yellow-400');
});
@@ -215,6 +228,24 @@
statusEl.classList.add('text-green-400');
});
// Periodic check for catching up to live edge
setInterval(function() {
if (hls && !video.paused && hls.levels && hls.levels.length > 0) {
const buffered = video.buffered;
if (buffered.length > 0) {
const bufferEnd = buffered.end(buffered.length - 1);
const currentTime = video.currentTime;
const bufferAhead = bufferEnd - currentTime;
// If less than 4 seconds buffered, show warning
if (bufferAhead < 4) {
statusEl.textContent = 'Waiting for rendering...';
statusEl.classList.remove('text-green-400');
statusEl.classList.add('text-yellow-400');
}
}
}
}, 1000);
hls.loadSource(hlsUrl);
hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {