feat(nvenc): add support for explicit cuda streams - #2360
Conversation
|
Found one blocking concern: Avoid modifying an initialized FFmpeg device context — frame.py lines 89–105 ( Lines 89 to 105 in dbef919 av_hwdevice_ctx_create() returns an initialized context, after which the PR writes directly to AVCUDADeviceContext.stream. FFmpeg explicitly states that hwctx must not be modified after av_hwdevice_ctx_init(). Although current NVENC happens to read the stream later during setup, this relies on behavior outside FFmpeg’s API contract. The stream should be supplied through a supported pre-initialization/creation path. FFmpeg API documentation (https://www.ffmpeg.org/doxygen/8.0/structAVHWDeviceContext.html) |
|
You’re right. Sorry, I have little experience with ffmpeg av. |
|
The previous post-initialization mutation concern is resolved, but I found one remaining multi-GPU issue: The secondary CUDA device context created in Lines 116 to 139 in 0b8d386 In FFmpeg 8.1.2,
As written, |
|
Hmm, I wonder what would be best way to fix this one. The only solution I can see is to add a guard so it works for first gpu only. To be more specific: streams feature can be only used for device_id=0. The cleanest solution would be to improve ABI ffmpeg contract but I'm not sure if I want to go this route alone. |
|
In theory I could also push owner CUcontext, call cuCtxGetDevice and compare that device’s CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT with logical device 0. But I'm not sure if its any better. //edit |
|
Yes, please add the guard. Reject cuda_stream when device_id != 0, with an error explaining that users can expose the desired physical GPU as logical device 0 through CUDA_VISIBLE_DEVICES. I agree that modifying FFmpeg’s private struct or loading CUDA solely to reconstruct its private state would be too brittle. Supporting arbitrary device IDs cleanly should wait for an upstream FFmpeg API that accepts an external stream during device creation. |
…fore context init
|
done |
The performance gains probably depend on the specific pipeline.
In my case, I didn’t see any improvement with 1080p HEVC videos, but at 4K and 8K, the speed-up was around 13% and 25%, respectively (e2e wall time).
I haven’t looked into it too deeply, but my guess is that NVENC uses the default stream 0 and requires a full synchronization before encoding. At lower resolutions, that overhead doesn’t make much difference, but with 4K and 8K workloads, waiting for all the processing kernels to finish before encoding becomes more significant.