Skip to content

Instantly share code, notes, and snippets.

@gepatto
Last active February 13, 2021 09:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gepatto/986d2a020d9f139c73e0b04dd503f1c8 to your computer and use it in GitHub Desktop.
Save gepatto/986d2a020d9f139c73e0b04dd503f1c8 to your computer and use it in GitHub Desktop.
SDL VLC Pi test
// g++ -o sdlvlcpi sdl_vlc_pi.cpp `sdl2-config --cflags --libs` -l vlc
// libSDL and libVLC sample code.
// License: [http://en.wikipedia.org/wiki/WTFPL WTFPL]
//
// sdlvlcpi /path/to/video (default render)
// sdlvlcpi /path/to/video -t (render to texture)
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <string>
#include "SDL.h"
#include "SDL_mutex.h"
#include "vlc/vlc.h"
#define WIDTH 640
#define HEIGHT 480
#define VIDEOWIDTH 640
#define VIDEOHEIGHT 360
struct context {
SDL_Renderer *renderer;
SDL_Texture *texture;
SDL_mutex *mutex;
int n;
};
// 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 {
// 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;
}
static void quit(int c) {
SDL_Quit();
exit(c);
}
int main(int argc, char *argv[]) {
bool renderToTexture = false;
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.
};
int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);
SDL_Event event;
int done = 0, action = 0, pause = 0, n = 0;
struct context context;
printf("arg count %d \n",argc);
if(argc < 2) {
printf("Usage: %s <filename>\n", argv[0]);
return EXIT_FAILURE;
}
if(argc == 3){
renderToTexture = strcmp(argv[2],"-t")==0;
printf("Rendering to texture %s\n","");
}
// 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, SDL_RENDERER_SOFTWARE);
if (!context.renderer) {
fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError());
quit(4);
}
printf("TextureFormat: %s\n"," SDL_PIXELFORMAT_RGB888 ");
context.texture = SDL_CreateTexture(
context.renderer,
//SDL_PIXELFORMAT_BGR565, SDL_TEXTUREACCESS_STREAMING,
SDL_PIXELFORMAT_RGB888, 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);
if(renderToTexture){
libvlc_video_set_callbacks(mp, lock, unlock, display, &context);
}
libvlc_video_set_format(mp, "RV32", VIDEOWIDTH, VIDEOHEIGHT, VIDEOWIDTH*4);
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_Rect rect;
rect.w = VIDEOWIDTH;
rect.h = VIDEOHEIGHT;
rect.x = 0;
rect.y = 0;
SDL_SetRenderDrawColor(context.renderer, 0, 0, 0, 255);
SDL_LockMutex(context.mutex);
SDL_RenderClear(context.renderer);
SDL_RenderCopy(context.renderer, context.texture, NULL, &rect);
SDL_RenderPresent(context.renderer);
SDL_UnlockMutex(context.mutex);
SDL_Delay(5);
}
// 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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment