Introduction
In previous releases of Intel(R) Media Software Development Kit (Intel Media SDK) there were many cases where applications needed to run as root, especially with multiple sessions. Now Linux developers have more control over Media SDK process privileges with drmserver.
The Direct Rendering Manager (DRM) Authentication Server is a set of software components which provide DRM authentication capabilities. This is a workaround for graphics stack limitations which do not have a fix until future kernel versions. The drmserver performs the subset of operations which need to be executed as root. It registers multiple libdrm clients.
Adding drmserver to existing Media SDK for Linux Servers applications requires only a few steps.
Install drmserver and drmclient packages
Starting with Media SDK 2014 R2 for Linux Servers, a set of packages is available in the /opt/intel/mediasdk/tools/drmserver directory. These are distributed as .deb packages for Ubuntu and .rpm packages for SLES.
- drmserver: once installed, runs a service listening for registration requests. Source is also available for customization.
- drmclient: functions for applications to interact with drmserver. This is distributed as runtime and dev packages. Runtime is the core library and intended for redistribution, dev is include files, etc. for application development.
For more information, please see drmserver_release_notes.pdf.
Add drmclient to your application
With the following steps you can add drmserver support to the Media SDK tutorial code downloadable from the "tutorials" tab on the Intel Media Solutions Portal. The process is similar for the Media SDK samples or any other Media SDK for Linux Servers application.
The basic idea is to add a registration request before initializing the Media SDK display handle. For the Linux implementation of Media SDK all sessions require a display handle. This is perhaps the biggest of the short list of differences between the Windows and Linux implementations. In Windows a display handle is required only for sessions handling their own GPU memory surfaces.
For the tutorials, all changes are in common_vaaapi.cpp,
At the top of this file, add
#include "drmclient.h" #define DEFAULT_DRM_DEV "/dev/dri/card0"
Here we assume that there is only one GPU on the system. DRM could communicate with a number of cards via /dev/dri/card{N}. For systems with multiple discrete graphics cards the implementation would be more complex since the card associated with integrated graphics would need to be found as a separate step. However, for many scenarios there is only card0 and only Intel integrated graphics.
In the CreateVAEnvDRM function, update
m_fd = open("/dev/dri/card0", O_RDWR);
to
m_fd = open(DEFAULT_DRM_DEV, O_RDWR);
Optionally, additional diagnostics can be added close to this line to show what is happening. These are not required for general operation:
printf("drmclient_app: info: dev = %s\n", DEFAULT_DRM_DEV); printf("drmclient_app: info: socket = %s\n", drmc_get_auth_socket());
These lines simply display the DRM device and show that socket communication is working with the drmserver service.
The following lines actually do the authentication then verify that the handle is registered. These should be added after the open but before vaGetDisplayDRM:
if (DRMU_SUCCESS == drmc_authenticate_by_fd(m_fd)) { printf("drmclient_app: info: client authenticated\n"); printf("drmclient_app: info: verifying registration...\n"); if (drmu_is_pid_authenticated(m_fd, getpid())) { printf("drmclient_app: info: handle authenticated\n"); } else { fprintf(stderr, "drmclient_app: error: authentication error\n"); } }
For completeness a check can also be added before closing the handle. In the tutorials the close can be found in CleanupVAEnvDRM:
void CleanupVAEnvDRM() { if (m_va_dpy) { vaTerminate(m_va_dpy); } if (m_fd >= 0) { if (!drmu_is_pid_authenticated(m_fd, getpid())) { printf("drmclient_app: error: PID lost DRM authentication while opened file descriptors still present\n"); } close(m_fd); } }
Add drmclient to your makefile
Some simple changes are needed to let the compiler know where to find include files and libraries. For the tutorials, update these lines in the makefile for each example you want to build:
Original:
CFLAGS=-I/usr/local/include -I../common -I$(MFX_HOME)/include LFLAGS=-L$(MFX_HOME)/lib/lin_x64 -lmfx -lva -lva-drm -lpthread -lrt -ldl
Updated:
CFLAGS=-I/usr/local/include -I/usr/include/drmserver -I/usr/include/libdrm/ -I../common -I$(MFX_HOME)/include LFLAGS=-L$(MFX_HOME)/lib/lin_x64 -lmfx -lva -lva-drm -lpthread -lrt -ldl -ldrmclient
Testing operation
Because the source changes above are made to the common initialization code shared by all of the tutorial examples, this change enables drmserver for all of them. However, the makefile will need to be updated for each example you wish to compile.
The simplest starting point is simple_1_session. After compiling you will find a simple_session executable in the _build directory. When run output should look like this:
$ ./simple_session drmclient_app: info: dev = /dev/dri/card0 drmclient_app: info: socket = /var/run/drmserver/auth_socket drmclient: info: drm_magic = 11 drmclient: info: authentication granted drmclient_app: info: client authenticated drmclient_app: info: verifying registration... drmclient_app: info: handle authenticated libva info: VA-API version 0.34.0 libva info: va_getDriverName() returns 0 libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so libva info: Found init function __vaDriverInit_0_32 libva info: va_openDriver() returns 0 Implementation: HARDWARE API Version: 1.10
Conclusion
The drmserver tool is an important new feature of Media SDK 2014 R2 for Linux Servers. With it developers can quickly add additional privilege controls since running as root is not required. Any feedback on whether this fills needs or if there are additional gaps is very welcome. Please post feedback and any issue reports to the Intel Media SDK forum.