Hey guys, I'm facing a pretty big problem when imp...
# ask-ai
b
Hey guys, I'm facing a pretty big problem when implementing LiveKit into my own setup. I am trying to stream some frames through livekit. These frames are generated a codebase that uses cuda. The issue is, whenever any call to Livekit happens (for example "rtc.LocalVideoTrack.create_video_track()" or anything else like that happens, my whole codebase breaks at the next cuda call. Specifically, the error that gets printed is "CUDA error: invalid device context". But this error is crashing my program, because it's happening not in the livekit internals (I see you see to ignore these errors in other threads), so it's a completely different and more serious issue. Digging into the livekit code, I can see that Livekit looks if CUDA is available and initializes a new context. This happens in the ffi codebase:
Copy code
bool NvidiaVideoEncoderFactory::IsSupported() {
  // Check if the CUDA context can be initialized.
  auto cu_context = std::make_unique<livekit::CudaContext>();
  if (!cu_context->Initialize()) {
    std::cout << "Failed to initialize CUDA context." << std::endl;
    return false;
  }

  std::cout << "Nvidia Encoder is supported." << std::endl;
  return true;
}
It's exactly when that "Nvidia Encoder is supported" line that gets printed, that all of my cuda related code crashes afterwards. And I am pretty sure it's livekit's fault doing something messy with the CUDA contexts, since if I remove livekit completely or perform all of my cuda calls before any of livekit causes a call to this code on the ffi server, it works perfectly. Another workaround that I found and that confirms this issue is "re-claiming" the context with
Copy code
dev = cuda.Device(0)
ctx = dev.retain_primary_context()
ctx.push()
However this breaks the code in other areas and also is not ideal to switch context after every call from livekit's encoder. So my final question (that I assume might be a workaround for this), is it possible to make Livekit not be so greedy with the CUDA context, or even easier to start the background ffi server without CUDA access?
t
Thanks for reaching out, Davide. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
I understand how dealing with CUDA context conflicts can be a bit tricky, but don’t worry—we can work through this together! Here are some steps you might find helpful: • Try wrapping your CUDA operations with
cuCtxPushCurrent
and
cuCtxPopCurrent
to manage the context switching more smoothly. • Consider initializing your own CUDA context using
cuCtxCreate
and then clean it up with
cuCtxDestroy
to avoid any surprises from implicit contexts. • If you're working with multiple threads, using
cuvidCtxLockCreate
along with a floating context can help make things thread-safe. • And if you’d prefer to stop LiveKit from initializing CUDA altogether, you might need to tweak the LiveKit code to skip CUDA initialization or start the background FFI server without CUDA access. Please feel free to reach out if you’d like me to walk you through any of these steps or if you have any other questions—I’m here to help! Sources: webrtc-sys/src/nvidia/implib/libcuda.so.tramp.S