Hi there,
I want a video texture on a OpenGL quad. I found this tutorial to read video on a SDL_Surface : http://wiki.videolan.org/LibVLC_SampleCode_SDL
It works fine.
I just want to add a OpenGL quad and to use the video as a texture. But the only thing I get is a white square.
Here’s my code :
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_mutex.h>
#include <GL/glu.h>
#include <vlc/vlc.h>
#define WIDTH 640
#define HEIGHT 480
#define VIDEO_FILE "/home/user/path/movie.avi"
struct ctx {
SDL_Surface *surf;
SDL_mutex *mutex;
};
static void catchEx (libvlc_exception_t *ex) {
if(libvlc_exception_raised(ex)) {
fprintf(stderr, "Exception libvlc : %s
", libvlc_exception_get_message(ex));
exit(EXIT_FAILURE);
}
libvlc_exception_clear(ex);
}
static void lock(struct ctx *ctx, void **pp_ret) {
SDL_LockMutex(ctx->mutex);
SDL_LockSurface(ctx->surf);
*pp_ret = ctx->surf->pixels;
}
static void unlock(struct ctx *ctx) {
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[] =
{
"--quiet",
"--ignore-config",
"--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;
SDL_Event event;
int done = 0, action = 0;
struct ctx ctx;
/*
* Init libSDL
*/
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD) == -1)
{
printf("cannot initialize SDL
");
return EXIT_FAILURE;
}
ctx.surf = SDL_CreateRGBSurface(SDL_SWSURFACE, WIDTH, HEIGHT, 16, 0xf800, 0x07e0, 0x001f, 0);
ctx.mutex = SDL_CreateMutex();
int options = SDL_ANYFORMAT | SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_OPENGL;
screen = SDL_SetVideoMode(1280, 800, 0, options);
if(!screen)
{
printf("cannot set video mode
");
return EXIT_FAILURE;
}
/* Get a texture id */
GLuint image;
glGenTextures(1, &image);
/*
* Init 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", WIDTH);
sprintf(height, "%i", HEIGHT);
sprintf(pitch, "%i", WIDTH * 2);
libvlc_exception_init(&ex);
libvlc = libvlc_new(vlc_argc, vlc_argv, &ex);
catchEx(&ex);
m = libvlc_media_new(libvlc, VIDEO_FILE, &ex);
catchEx(&ex);
mp = libvlc_media_player_new_from_media(m, &ex);
catchEx(&ex);
libvlc_media_release(m);
libvlc_media_player_play(mp, &ex);
catchEx(&ex);
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;
}
/* 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, NULL);
glBindTexture(GL_TEXTURE_2D, image);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ctx.surf->w, ctx.surf->h, 0, GL_RGB, GL_UNSIGNED_BYTE, ctx.surf->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBegin(GL_QUADS);
glTexCoord2d(0, 1);
glVertex2f(0, 0.9);
glTexCoord2d(1, 1);
glVertex2f(0.9, 0.9);
glTexCoord2d(1, 0);
glVertex2f(0.9, -0.9);
glTexCoord2d(0, 0);
glVertex2f(0, -0.9);
glEnd();
SDL_UnlockMutex(ctx.mutex);
//SDL_Flip(screen);
glFlush();
SDL_GL_SwapBuffers();
SDL_Delay(10);
}
/*
* Stop stream and clean up libVLC
*/
libvlc_media_player_stop(mp, &ex);
catchEx(&ex);
libvlc_media_player_release(mp);
libvlc_release(libvlc);
/*
* Close window and clean up libSDL
*/
SDL_DestroyMutex(ctx.mutex);
SDL_FreeSurface(ctx.surf);
SDL_Quit();
return 0;
}
So if someone has an idea to make this code working… :]
Thanks in advance.
Regards.
PS : g++ -otest main.o -lvlc -lSDL_image -lSDL -lGL