Change:
<ins> diff --git a/sys/nvcodec/gstcudaloader.c b/sys/nvcodec/gstcudaloader.c index 4223ba1fbd..ca8bb5ceb1 100644 --- a/sys/nvcodec/gstcudaloader.c +++ b/sys/nvcodec/gstcudaloader.c @@ -135,6 +135,11 @@ gst_cuda_load_library (void) return TRUE; module = g_module_open (filename, G_MODULE_BIND_LAZY); + +  if (module == NULL) { +    module = g_module_open("@driverLink@/lib/" CUDA_LIBNAME, G_MODULE_BIND_LAZY); +  } + if (module == NULL) { GST_WARNING ("Could not open library %s, %s", filename, g_module_error ()); return FALSE; diff --git a/sys/nvcodec/gstcuvidloader.c b/sys/nvcodec/gstcuvidloader.c index 3c7505ca36..eeb376fa80 100644 --- a/sys/nvcodec/gstcuvidloader.c +++ b/sys/nvcodec/gstcuvidloader.c @@ -85,6 +85,11 @@ gst_cuvid_load_library (guint api_major_ver, guint api_minor_ver) return TRUE; module = g_module_open (filename, G_MODULE_BIND_LAZY); + +  if (module == NULL) { +    module = g_module_open ("@driverLink@/lib/" NVCUVID_LIBNAME, G_MODULE_BIND_LAZY); +  } + if (module == NULL) { GST_WARNING ("Could not open library %s, %s", filename, g_module_error ()); return FALSE; diff --git a/sys/nvcodec/gstnvenc.c b/sys/nvcodec/gstnvenc.c index 19637671ad..39858ccdee 100644 --- a/sys/nvcodec/gstnvenc.c +++ b/sys/nvcodec/gstnvenc.c @@ -874,6 +874,11 @@ gst_nvenc_load_library (guint * api_major_ver, guint * api_minor_ver) }; module = g_module_open (NVENC_LIBRARY_NAME, G_MODULE_BIND_LAZY); + +  if (module == NULL) { +    module = g_module_open ("@driverLink@/lib/" NVENC_LIBRARY_NAME, G_MODULE_BIND_LAZY); +  } + if (module == NULL) { GST_WARNING ("Could not open library %s, %s", NVENC_LIBRARY_NAME, g_module_error ()); </ins>

Discussion:
gst-plugins-bad cannot use nvcodec by default. This can be verified in one of two ways: use . make sure you delete each time before running 2. set to 4. it says and . Here is the full output: open , a gstreamer based video player, and find that is not in . However, if I set to : says . Full output is here: can uses to play videos I have tried to all libs of , but there is no difference and is still needed. who contribute to gst-plugins-bad who is one of cuda maintainers who is clapper's maintainer <!-- Please @ people who are in the list of the offending package or module. If in doubt, check for whoever last touched something. --Please run and paste the result.
You need to do so that the plugins reference system drivers, and add: to your , so that the cuda libraries exist on the system path (e.g. ) related:
I would recommend using if at all possible. If there are elements of CUDA required as well those are available in and can be included as . You can check out eg the derivation of jaxlib, pytorch, and others to see some examples!
I meant to mention the hook as well
Yes, but there will be times where software has optional nvidia capabilities, and we don't really want to add cuda to the build graph as it makes it: 1) unfree 2) bigger closure 3) only useful to nvidia users. I think enabling the impure route is the best compromise
Mmm, I see. What is your take on the current pattern of adding a build argument like which defaults to false but allows users to override? For ML packages, we have a pattern of keeping both eg and so that end users can choose between the smaller, non-CUDA version and the larger, unfree, CUDA-enabled version. Would that kind of pattern solve this problem?
I think if cuda availability is critical for a use case, then having a cuda variant makes sense. But for gstreamer plugins, it's not critical, but a big QoL win if nvidia is available.
I see... My hesitation with adding CUDA into is two-fold is a set of user-level libraries and utilities, so having it live next to drivers in a privileged directory is unusual.

Furthermore, Nix already has well-established patterns for linking against user-level libraries between packages. Any deviation from those patterns must come from some overwhelming raison d'être. two ways of accessing CUDA libraries -- one via standard nix derivation inputs, and a second via -- introduces complexity. In my experience, any time there are two ways to accomplish the same thing, there comes the inevitable ecosystem schism with some people choosing to do it one way, and others choosing to do it the other way. Inevitably, people start asking questions like "What is the correct way to do X?" and then we're stuck having to explain why multiple options exist and what the various tradeoffs are. I don't want to stand in the way of making this change if this truly is a life-changing improvement, but I feel obligated to bring up the challenges that may lie ahead with a two-acceptable-solutions state of the world.
I forget to mention that cuda is not necessary, only adding /run/opengl/lib to LDLIBRARYPATH is enough. cuda only adds two features which are not needed to decode videos. I do not think autoAddOpenGLRunpathHook will make a different result. Modifying runpath does not work in this case for some reason.
Ah, yea, to be completely honest, cuda is outside of my domain of expertise. But if just the nvidia drivers suffice then we should probably ensure that the gstreamer packages use the opengl path.
I tried to reproduce this, but on my machine gets loaded transitively by which already has the opengl path patched in. It does run into trouble finding however: Output:
I add this to : and add this to : After building the system, I run this: Here is the full log: The relevant part is: However, before and after this part, the runpath of does have .
I wonder if the binary is doing some weird hardcoding shenanigans that overrides RUNPATH... perhaps they only look in some set of "magic" locations on the user's system? Not entirely sure how they would accomplish such a thing, but that's the only thing I can think of atm...
while reviewing the DLDEBUG output, I noticed that the runpath is different every time a module is being loaded. I suspect that the runpath is actually coming from the file and we're just running into a runtime limitation of .

As a test, this is loading : And this is the rpath of : This leads me to believe that it might be fixable by changing the rpath of .
If you mean RUNPATH by rpath, then the answer is no. I when I all libs of gst-plugins-bad. The changes of RUNPATH in the log do look weird.
Google fished up which appears to be the exact same issue. It appears that the gmodule loading code really doesn't play very nice with RUNPATH patching and was historically fixed by changing the source code to open the absolute path, rather than the relative file.
It turns out that the problem is an incompatibility caused by wrappers. As an example, this is what happens for tells to load . Since it dynamically discovers the path by scanning it does not need to look for the library calls on the absolute path provided, dlopen loads the library and uses the of to load its declared dynamic dependencies. Where this goes wrong is how loads its dependencies: tells to load . Same as above calls same as above. As part of its initialization, tells to load . calls with the relative path . Since uses the runpath of its caller this results in a useless and a failure to load the library. If called directly this wouldn't be an issue. The end result is that tries to use like , but this results in an empty and a failure to find any library that hasn't already been loaded by another module beforehand. (This is why would always be found on my machine) Here is a patch that changes the relative lookups into fixed ones, but this will break non-nixos gstreamer users: A better solution might be to attempt to load first, and falling back to loading if that fails.
I suggest the reverse loading order, i.e. loading first and failing back to , which is useful if people want to use a different by setting . Do you think this is the right thing to do to solve this issue? If so, I can write a patch if no one is faster than me.
I was already in the process of making that change, its in the PR above
This should be fixed through the merging of
This issue will be automatically closed when that pr reaches the master branch.
It seems that pr has [reached][1] the master branch. Not sure why this issue is not automatically closed. Closing.