[VDPAU] [PATCHv3] Add VDPAU_DRIVER_PATH support

Emil Velikov emil.l.velikov at gmail.com
Thu Feb 20 14:37:45 PST 2014


Allow the user to specify the location of the backend driver,
via the VDPAU_DRIVER_PATH environment variable. This allows
easier testing of VDPAU backends without the need to rebuild
libvdpau.

Inspired by LIBGL_DRIVERS_PATH from mesa.

v2:
 - Fix compilation issues.
v3:
 - Transparently fallback to VDPAU_MODULEDIR if VDPAU_DRIVER_PATH
is not set and/or does not point to a suitable library.

Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
---

Decided to create second DRIVER_LIB_FORMAT as it simplifies
snprintf a bit and will result in the smallest library.

All the fallbacks seems to be working fine.

Thanks for the tips and patience guys.
Emil


 include/vdpau/vdpau_x11.h |  2 ++
 src/vdpau_wrapper.c       | 31 +++++++++++++++++++++++++------
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/include/vdpau/vdpau_x11.h b/include/vdpau/vdpau_x11.h
index ae5a377..1aa66fe 100644
--- a/include/vdpau/vdpau_x11.h
+++ b/include/vdpau/vdpau_x11.h
@@ -81,6 +81,8 @@ extern "C" {
  *   - \c /usr/lib/vdpau/libvdpau_nvidia.so.1
  *   - \c /usr/lib/vdpau/libvdpau_intel.so.1
  *   - \c /usr/lib/vdpau/libvdpau_ati.so.1
+ *   The library path can be overridden by the VDPAU_DRIVER_PATH
+ *   environment variable.
  *
  * The VDPAU wrapper library implements just one function; \ref
  * vdp_device_create_x11. The wrapper will implement this function
diff --git a/src/vdpau_wrapper.c b/src/vdpau_wrapper.c
index 9932937..d60cee6 100644
--- a/src/vdpau_wrapper.c
+++ b/src/vdpau_wrapper.c
@@ -30,6 +30,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 #include <vdpau/vdpau_x11.h>
 #if DRI2
 #include "mesa_dri2.h"
@@ -66,7 +67,8 @@ static void _vdp_wrapper_error_breakpoint(char const * file, int line, char cons
 
 #endif
 
-#define DRIVER_LIB_FORMAT "%slibvdpau_%s.so%s"
+#define DRIVER_FALLBACK_LIB_FORMAT "libvdpau_%s.so"
+#define DRIVER_LIB_FORMAT "%s/libvdpau_%s.so.1"
 
 static char * _vdp_get_driver_name_from_dri2(
     Display *             display,
@@ -107,6 +109,7 @@ static VdpStatus _vdp_open_driver(
 {
     char const * vdpau_driver;
     char * vdpau_driver_dri2 = NULL;
+    const char * vdpau_driver_path = NULL;
     char         vdpau_driver_lib[PATH_MAX];
     char const * vdpau_trace;
     char const * func_name;
@@ -120,8 +123,22 @@ static VdpStatus _vdp_open_driver(
         vdpau_driver = "nvidia";
     }
 
-    if (snprintf(vdpau_driver_lib, sizeof(vdpau_driver_lib), DRIVER_LIB_FORMAT,
-                 VDPAU_MODULEDIR "/", vdpau_driver, ".1") >=
+    if (geteuid() == getuid()) {
+        /* don't allow setuid apps to use VDPAU_DRIVER_PATH */
+        vdpau_driver_path = getenv("VDPAU_DRIVER_PATH");
+        if (vdpau_driver_path &&
+            snprintf(vdpau_driver_lib, sizeof(vdpau_driver_lib),
+                     DRIVER_LIB_FORMAT, vdpau_driver_path, vdpau_driver) <
+                sizeof(vdpau_driver_lib)) {
+            _vdp_driver_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
+        }
+    }
+
+    /* Fallback to VDPAU_MODULEDIR when VDPAU_DRIVER_PATH is not set,
+     * or if we fail to create the driver path/dlopen the library. */
+    if (!_vdp_driver_dll &&
+        snprintf(vdpau_driver_lib, sizeof(vdpau_driver_lib), DRIVER_LIB_FORMAT,
+                 VDPAU_MODULEDIR, vdpau_driver) >=
             sizeof(vdpau_driver_lib)) {
         fprintf(stderr, "Failed to construct driver path: path too long\n");
         if (vdpau_driver_dri2) {
@@ -132,12 +149,14 @@ static VdpStatus _vdp_open_driver(
         return VDP_STATUS_NO_IMPLEMENTATION;
     }
 
-    _vdp_driver_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
+    if (!_vdp_driver_dll) {
+        _vdp_driver_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
+    }
     if (!_vdp_driver_dll) {
         /* Try again using the old path, which is guaranteed to fit in PATH_MAX
          * if the complete path fit above. */
-        snprintf(vdpau_driver_lib, sizeof(vdpau_driver_lib), DRIVER_LIB_FORMAT,
-                 "", vdpau_driver, "");
+        snprintf(vdpau_driver_lib, sizeof(vdpau_driver_lib),
+                 DRIVER_FALLBACK_LIB_FORMAT, vdpau_driver);
         _vdp_driver_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
     }
 
-- 
1.9.0



More information about the VDPAU mailing list