Difference between revisions of "LibVLC SampleCode SDL"
Jump to navigation
Jump to search
Sam Hocevar (talk | contribs) (cool libSDL/libVLC example) |
Pdherbemont (talk | contribs) (convert to media and media player) |
||
Line 71: | Line 71: | ||
libvlc_exception_t ex; | libvlc_exception_t ex; | ||
libvlc_instance_t *libvlc; | libvlc_instance_t *libvlc; | ||
− | + | libvlc_media_t *m; | |
− | + | libvlc_media_player_t *mp; | |
char const *vlc_argv[] = | char const *vlc_argv[] = | ||
{ | { | ||
Line 140: | Line 140: | ||
libvlc = libvlc_new(vlc_argc, vlc_argv, &ex); | libvlc = libvlc_new(vlc_argc, vlc_argv, &ex); | ||
catch(&ex); | catch(&ex); | ||
− | + | m = libvlc_media_new(libvlc, argv[1], &ex); | |
catch(&ex); | catch(&ex); | ||
− | + | mp = libvlc_media_player_new_from_media(m, &ex); | |
catch(&ex); | catch(&ex); | ||
− | + | libvlc_media_release(m); | |
− | + | libvlc_media_player_play(mp, &ex); | |
catch(&ex); | catch(&ex); | ||
Line 208: | Line 208: | ||
* Stop stream and clean up libVLC | * Stop stream and clean up libVLC | ||
*/ | */ | ||
− | + | libvlc_media_player_stop(mp, &ex); | |
catch(&ex); | catch(&ex); | ||
− | + | libvlc_media_player_release(mp); | |
libvlc_release(libvlc); | libvlc_release(libvlc); | ||
Revision as of 01:16, 30 March 2008
This sample code will render a video into an SDL surface.
NOTE: this requires the "vmem" video output which was checked in on March 21st, 2008.
/* libSDL and libVLC sample code * Copyright © 2008 Sam Hocevar <sam@zoy.org> * license: [http://en.wikipedia.org/wiki/WTFPL WTFPL] */ #include <stdio.h> #include <stdint.h> #include <math.h> #include <stdlib.h> #include <SDL.h> #include <SDL_mutex.h> #include <vlc/libvlc.h> #define WIDTH 640 #define HEIGHT 480 #define VIDEOWIDTH 320 #define VIDEOHEIGHT 240 struct ctx { SDL_Surface *surf; SDL_mutex *mutex; }; static void catch (libvlc_exception_t *ex) { if(libvlc_exception_raised(ex)) { fprintf(stderr, "exception: %s\n", libvlc_exception_get_message(ex)); exit(1); } libvlc_exception_clear(ex); } static void * lock(struct ctx *ctx) { SDL_LockMutex(ctx->mutex); SDL_LockSurface(ctx->surf); return ctx->surf->pixels; } static void unlock(struct ctx *ctx) { /* VLC just rendered the video, but we can also render stuff */ uint16_t *pixels = (uint16_t *)ctx->surf->pixels; 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] = 0x0; SDL_UnlockSurface(ctx->surf); SDL_UnlockMutex(ctx->mutex); } int main(int argc, char *argv[]) { char clock[64], cunlock[64], cdata[64]; char width[32], height[32], pitch[32]; libvlc_exception_t ex; libvlc_instance_t *libvlc; libvlc_media_t *m; libvlc_media_player_t *mp; char const *vlc_argv[] = { "-q", //"-vvvvv", "--plugin-path", VLC_TREE "/modules", "--noaudio", "--vout", "vmem", "--vmem-width", width, "--vmem-height", height, "--vmem-pitch", pitch, "--vmem-chroma", "RV16", "--vmem-lock", clock, "--vmem-unlock", cunlock, "--vmem-data", cdata, }; int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); SDL_Surface *screen, *empty; SDL_Event event; SDL_Rect rect; int done = 0, action = 0, pause = 0, n = 0; struct ctx ctx; /* * Initialise libSDL */ if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD) == -1) { printf("cannot initialize SDL\n"); return EXIT_FAILURE; } empty = SDL_CreateRGBSurface(SDL_SWSURFACE, VIDEOWIDTH, VIDEOHEIGHT, 32, 0, 0, 0, 0); ctx.surf = SDL_CreateRGBSurface(SDL_SWSURFACE, VIDEOWIDTH, VIDEOHEIGHT, 16, 0x001f, 0x07e0, 0xf800, 0); ctx.mutex = SDL_CreateMutex(); int options = SDL_ANYFORMAT | SDL_HWSURFACE | SDL_DOUBLEBUF; screen = SDL_SetVideoMode(WIDTH, HEIGHT, 0, options); if(!screen) { printf("cannot set video mode\n"); return EXIT_FAILURE; } /* * Initialise libVLC */ sprintf(clock, "%lld", (long long int)(intptr_t)lock); sprintf(cunlock, "%lld", (long long int)(intptr_t)unlock); sprintf(cdata, "%lld", (long long int)(intptr_t)&ctx); sprintf(width, "%i", VIDEOWIDTH); sprintf(height, "%i", VIDEOHEIGHT); sprintf(pitch, "%i", VIDEOWIDTH * 2); if(argc < 2) { printf("too few arguments (MRL needed)\n"); return EXIT_FAILURE; } libvlc_exception_init(&ex); libvlc = libvlc_new(vlc_argc, vlc_argv, &ex); catch(&ex); m = libvlc_media_new(libvlc, argv[1], &ex); catch(&ex); mp = libvlc_media_player_new_from_media(m, &ex); catch(&ex); libvlc_media_release(m); libvlc_media_player_play(mp, &ex); catch(&ex); /* * Main loop */ rect.w = 0; rect.h = 0; 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: done = 1; break; case SDLK_RETURN: options ^= SDL_FULLSCREEN; screen = SDL_SetVideoMode(WIDTH, HEIGHT, 0, options); break; case ' ': pause = !pause; break; } rect.x = (int)((1. + .5 * sin(0.03 * n)) * (WIDTH - VIDEOWIDTH) / 2); rect.y = (int)((1. + .5 * cos(0.03 * n)) * (HEIGHT - VIDEOHEIGHT) / 2); if(!pause) n++; /* Blitting the surface does not prevent it from being locked and * written to by another thread, so we use this additional mutex. */ SDL_LockMutex(ctx.mutex); SDL_BlitSurface(ctx.surf, NULL, screen, &rect); SDL_UnlockMutex(ctx.mutex); SDL_Flip(screen); SDL_Delay(10); SDL_BlitSurface(empty, NULL, screen, &rect); } /* * Stop stream and clean up libVLC */ libvlc_media_player_stop(mp, &ex); catch(&ex); libvlc_media_player_release(mp); libvlc_release(libvlc); /* * Close window and clean up libSDL */ SDL_DestroyMutex(ctx.mutex); SDL_FreeSurface(ctx.surf); SDL_FreeSurface(empty); SDL_Quit(); return 0; }