SDL2 "Couldn't find matching render driver" error on Raspberry Pi 3 model B with LibVLC

Hi, I am trying the simple libvlc demo with libsdl2 from https://wiki.videolan.org/LibVLC_SampleCode_SDL/ but I am having issues when running the compiled binary. I get a “Couldn’t find matching render driver” error from SDL_GetError() after SDL_CreateRenderer(). here is the source:

// libSDL and libVLC sample code.
// License: [http://en.wikipedia.org/wiki/WTFPL WTFPL]
 
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
 
#include <SDL2/SDL.h>
#include <SDL2/SDL_mutex.h>
 
#include <vlc/vlc.h>
 
#define WIDTH 640
#define HEIGHT 480
 
#define VIDEOWIDTH 320
#define VIDEOHEIGHT 240
 
typedef struct context {
    SDL_Renderer *renderer;
    SDL_Texture *texture;
    SDL_mutex *mutex;
    int n;
} context;
 
// VLC prepares to render a video frame.
static void *lock(void *data, void **p_pixels) {
 
    struct context *c = (context *)data;
 
    int pitch;
    SDL_LockMutex(c->mutex);
    SDL_LockTexture(c->texture, NULL, p_pixels, &pitch);
 
    return NULL; // Picture identifier, not needed here.
}
 
// VLC just rendered a video frame.
static void unlock(void *data, void *id, void *const *p_pixels) {
 
    struct context *c = (context *)data;
 
    uint16_t *pixels = (uint16_t *)*p_pixels;
 
    // We can also render stuff.
    int x, y;
    for(y = 10; y < 40; y++) {
        for(x = 10; x < 40; x++) {
            if(x < 13 || y < 13 || x > 36 || y > 36) {
                pixels[y * VIDEOWIDTH + x] = 0xffff;
            } else {
                // RV16 = 5+6+5 pixels per color, BGR.
                pixels[y * VIDEOWIDTH + x] = 0x02ff;
            }
        }
    }
 
    SDL_UnlockTexture(c->texture);
    SDL_UnlockMutex(c->mutex);
}
 
// VLC wants to display a video frame.
static void display(void *data, void *id) {
 
    struct context *c = (context *)data;
 
    SDL_Rect rect;
    rect.w = VIDEOWIDTH;
    rect.h = VIDEOHEIGHT;
    rect.x = (int)((1. + .5 * sin(0.03 * c->n)) * (WIDTH - VIDEOWIDTH) / 2);
    rect.y = (int)((1. + .5 * cos(0.03 * c->n)) * (HEIGHT - VIDEOHEIGHT) / 2);
 
    SDL_SetRenderDrawColor(c->renderer, 0, 80, 0, 255);
    SDL_RenderClear(c->renderer);
    SDL_RenderCopy(c->renderer, c->texture, NULL, &rect);
    SDL_RenderPresent(c->renderer);
}
 
static void quit(int c) {
    SDL_Quit();
    exit(c);
}
 
int main(int argc, char *argv[]) {
 
    libvlc_instance_t *libvlc;
    libvlc_media_t *m;
    libvlc_media_player_t *mp;
    char const *vlc_argv[] = {
 
        "--no-audio", // Don't play audio.
        "--no-xlib", // Don't use Xlib.
 
        // Apply a video filter.
        //"--video-filter", "sepia",
        //"--sepia-intensity=200"
    };
    int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);
 
    SDL_Event event;
    int done = 0, action = 0, pause = 0, n = 0;
 
    struct context context;
 
    if(argc < 2) {
        printf("Usage: %s <filename>\n", argv[0]);
        return EXIT_FAILURE;
    }
 
    // Initialise libSDL.
    if(SDL_Init(SDL_INIT_VIDEO) < 0) {
        printf("Could not initialize SDL: %s.\n", SDL_GetError());
        return EXIT_FAILURE;
    }
 
    // Create SDL graphics objects.
    SDL_Window * window = SDL_CreateWindow(
            "Fartplayer",
            SDL_WINDOWPOS_UNDEFINED,
            SDL_WINDOWPOS_UNDEFINED,
            WIDTH, HEIGHT,
            SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE);
    if (!window) {
        fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError());
        quit(3);
    }
 
    context.renderer = SDL_CreateRenderer(window, -1, 0);
    if (!context.renderer) {
        fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError());
        quit(4);
    }
 
    context.texture = SDL_CreateTexture(
            context.renderer,
            SDL_PIXELFORMAT_BGR565, SDL_TEXTUREACCESS_STREAMING,
            VIDEOWIDTH, VIDEOHEIGHT);
    if (!context.texture) {
        fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
        quit(5);
    }
 
    context.mutex = SDL_CreateMutex();
 
    // If you don't have this variable set you must have plugins directory
    // with the executable or libvlc_new() will not work!
    printf("VLC_PLUGIN_PATH=%s\n", getenv("VLC_PLUGIN_PATH"));
 
    // Initialise libVLC.
    libvlc = libvlc_new(vlc_argc, vlc_argv);
    if(NULL == libvlc) {
        printf("LibVLC initialization failure.\n");
        return EXIT_FAILURE;
    }
 
    m = libvlc_media_new_path(libvlc, argv[1]);
    mp = libvlc_media_player_new_from_media(m);
    libvlc_media_release(m);
 
    libvlc_video_set_callbacks(mp, lock, unlock, display, &context);
    libvlc_video_set_format(mp, "RV16", VIDEOWIDTH, VIDEOHEIGHT, VIDEOWIDTH*2);
    libvlc_media_player_play(mp);
 
    // Main loop.
    while(!done) {
 
        action = 0;
 
        // Keys: enter (fullscreen), space (pause), escape (quit).
        while( SDL_PollEvent( &event )) {
 
            switch(event.type) {
                case SDL_QUIT:
                    done = 1;
                    break;
                case SDL_KEYDOWN:
                    action = event.key.keysym.sym;
                    break;
            }
        }
 
        switch(action) {
            case SDLK_ESCAPE:
            case SDLK_q:
                done = 1;
                break;
            case ' ':
                printf("Pause toggle.\n");
                pause = !pause;
                break;
        }
 
        if(!pause) { context.n++; }
 
        SDL_Delay(1000/10);
    }
 
    // Stop stream and clean up libVLC.
    libvlc_media_player_stop(mp);
    libvlc_media_player_release(mp);
    libvlc_release(libvlc);
 
    // Close window and clean up libSDL.
    SDL_DestroyMutex(context.mutex);
    SDL_DestroyRenderer(context.renderer);
 
    quit(0);
 
    return 0;
}

I’ve only done a few modification to the code:

  • replace “SDL.h” by <SDL2/SDL.h>
  • replace struct context{}; by typedef struct context{}context;

I don’t know what the issue is but I am pretty sure it is SDL related. Also, to compile the SDL library I used.

hg clone https://hg.libsdl.org/SDL SDL
cd SDL
mkdir build
cd build
../configure
make
sudo make install

I did that like 3 days ago. So I guess I have the latest version of SDL (I also have the latest version of libvlc).

Also note that I am running everything on the Kano OS (some kind of fork of the Raspbian OS by Kano ).

Thanks in advance!

SDL2 is available pre-compiled from the Raspbian repository:

sudo apt-get install libsdl2-2.0-0

You might like to try that to see if it gives different results.

When I try to install it using the repository I get this message:

libsdl2-2.0.0 is already the newest version (2.0.6-2~kano1).
The following packages were automatically installed and are no longer required:

So perhaps you need to delete your local build to force your program to use the version from the repository? I’ve never built SDL2 on the Raspberry Pi, I’ve always used the repository version and it has always worked for me.

OK I did more than that. I re-install Kano OS and tried sudo apt-get install libsdl2-2.0-0. It is still telling me

libsdl2-2.0.0 is already the newest version (2.0.6-2~kano1).

Then I tried to compile a simple SDL code. Guess what! it didn’t work because having libsdl2-2.0.0 doesn’t mean I have libsdl2-dev and so I tried to install it and it failed stating:

Some packages could not be installed. This may mean that you have requested an impositble situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
libsdl2-dev : Depends: libsdl2-2.0-0 (= 2.0.5+dfsg1-2) but 2.0.6-2~kano1 is to be installed

So basically using the default libsdl2 is not gonna work since there is no compatible libsdl2-dev in the repository!

The (Raspbian Stretch) repository version of SDL was 2.0.5 when I installed it, and there was a compatible libsdl2-dev then. It sounds like the lib has been updated to 2.0.6 but the dev package hasn’t?

If the old repository version of SDL 2.0.5 is still available somewhere you may be able to install that first, then install libsdl2-dev, then update SDL to 2.0.6. Unless you are relying on any 2.0.6 headers, that may work.

Hopefully this mess is fixed in Raspbian Buster. I’ve successfully used the runtime libsdl from its repository, but not tried to build anything.