Created
January 2, 2017 09:44
-
-
Save croepha/4f6fedff15a77a588ff9337bab25b602 to your computer and use it in GitHub Desktop.
Lib vlc testing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <assert.h> | |
#include <SDL/SDL.h> | |
#include <SDL/SDL_mutex.h> | |
#include <epoxy/gl.h> | |
#include <epoxy/glx.h> | |
#include <vlc/vlc.h> | |
#define WIDTH 640 | |
#define HEIGHT 480 | |
// #define VIDEOWIDTH 320 | |
// #define VIDEOHEIGHT 240 | |
struct ctx | |
{ | |
SDL_mutex *mutex; | |
}; | |
void* tex_mem; | |
typedef unsigned int u32; | |
u32 VIDEOHEIGHT; | |
u32 VIDEOWIDTH; | |
#pragma clang diagnostic push | |
#pragma clang diagnostic ignored "-Wswitch" | |
void _check_gl_error(const char *file, int line) { | |
GLenum err = glGetError(); | |
while(err!=GL_NO_ERROR) { | |
const char *error; | |
switch(err) { | |
case GL_INVALID_OPERATION: error="INVALID_OPERATION"; break; | |
case GL_INVALID_ENUM: error="INVALID_ENUM"; break; | |
case GL_INVALID_VALUE: error="INVALID_VALUE"; break; | |
case GL_OUT_OF_MEMORY: error="OUT_OF_MEMORY"; break; | |
case GL_INVALID_FRAMEBUFFER_OPERATION: error="INVALID_FRAMEBUFFER_OPERATION"; break; | |
} | |
printf("%s, %s:%d \n", error, file, line); | |
err=glGetError(); | |
} | |
} | |
#pragma clang diagnostic pop | |
#define GL_CHECK() _check_gl_error(__FILE__,__LINE__) | |
unsigned char c; | |
static void *lock(void *data, void **p_pixels) | |
{ | |
struct ctx *ctx = (struct ctx *)data; | |
SDL_LockMutex(ctx->mutex); | |
// printf("lock\n"); | |
// *p_pixels = tex_mem; | |
// for (int x=0; x<100; x++) { | |
// for (int y=0; y<100; y++) { | |
// auto p = ((uint8_t*)tex_mem) + (y + 10)*VIDEOWIDTH*4 + (x + 10)*4; | |
// p[0] = c++; | |
// // p[1] = 255; | |
// // p[2] = 0; | |
// p[3] = 255; | |
// } | |
// } | |
return NULL; /* picture identifier, not needed here */ | |
} | |
static void unlock(void *data, void *id, void *const *p_pixels) | |
{ | |
struct ctx *ctx = (struct ctx *)data; | |
SDL_UnlockMutex(ctx->mutex); | |
assert(id == NULL); /* picture identifier, not needed here */ | |
} | |
static void display(void *data, void *id) | |
{ | |
/* VLC wants to display the video */ | |
(void) data; | |
assert(id == NULL); | |
} | |
void _event(const libvlc_event_t *event, void *data) { | |
// P_ERR; | |
switch (event->type) { | |
#define _e(event) case event: printf("event->type:%s ",#event); break | |
_e(libvlc_MediaSubItemAdded); | |
_e(libvlc_MediaDurationChanged); | |
_e(libvlc_MediaParsedChanged); | |
_e(libvlc_MediaFreed); | |
_e(libvlc_MediaStateChanged); | |
_e(libvlc_MediaSubItemTreeAdded); | |
_e(libvlc_MediaPlayerMediaChanged); | |
_e(libvlc_MediaPlayerNothingSpecial); | |
_e(libvlc_MediaPlayerOpening); | |
_e(libvlc_MediaPlayerBuffering); | |
_e(libvlc_MediaPlayerPlaying); | |
_e(libvlc_MediaPlayerPaused); | |
_e(libvlc_MediaPlayerStopped); | |
_e(libvlc_MediaPlayerForward); | |
_e(libvlc_MediaPlayerBackward); | |
_e(libvlc_MediaPlayerEndReached); | |
_e(libvlc_MediaPlayerEncounteredError); | |
_e(libvlc_MediaPlayerTimeChanged); | |
_e(libvlc_MediaPlayerPositionChanged); | |
_e(libvlc_MediaPlayerSeekableChanged); | |
_e(libvlc_MediaPlayerPausableChanged); | |
_e(libvlc_MediaPlayerTitleChanged); | |
_e(libvlc_MediaPlayerSnapshotTaken); | |
_e(libvlc_MediaPlayerLengthChanged); | |
_e(libvlc_MediaPlayerVout); | |
_e(libvlc_MediaPlayerScrambledChanged); | |
_e(libvlc_MediaPlayerCorked); | |
_e(libvlc_MediaPlayerUncorked); | |
_e(libvlc_MediaPlayerMuted); | |
_e(libvlc_MediaPlayerUnmuted); | |
_e(libvlc_MediaPlayerAudioVolume); | |
#undef _e | |
} | |
printf("got to %s\n", __func__); | |
// auto ctx = (Context*)data; | |
// u32 w, h; | |
// libvlc_video_get_size(ctx->mp, 0, &w, &h); | |
// if (w != ctx->width || h != ctx->height) { | |
// ctx->width = w; | |
// ctx->height = h; | |
// printf("got size3: %d, %d \n", ctx->width, ctx->height); | |
// } | |
// (void)ctx; | |
libvlc_media_t* m = (libvlc_media_t*)data; | |
libvlc_media_track_info_t * tracks = NULL; | |
libvlc_media_get_tracks_info(m, &tracks); | |
if( tracks ) | |
{ | |
int width = tracks->u.video.i_width; | |
int height = tracks->u.video.i_height; | |
printf( "%d x %d \n", width, height); | |
free(tracks); | |
} | |
else | |
{ | |
printf("tracks is NULL\n"); | |
} | |
} | |
#include <unistd.h> | |
u32 setup(void **opaque, char *chroma, u32 *width, u32 *height, u32 *pitches, u32 *lines) { | |
struct ctx *ctx = (struct ctx *)*opaque; | |
SDL_LockMutex(ctx->mutex); | |
printf("got to %s chroma:%s width:%u height:%u, pitches:%u,%u,%u,%u lines:%u,%u,%u,%u \n", | |
__func__, chroma, *width, *height, | |
*pitches, *(pitches +1), *(pitches +2), *(pitches +3), | |
*lines, *(lines +1), *(lines +2), *(lines +3) | |
); | |
VIDEOWIDTH = *width; | |
VIDEOHEIGHT = *height; | |
memcpy(chroma, "RV32", 4); | |
tex_mem = malloc(*width * *height * 4); | |
memset(tex_mem, 0xFF, VIDEOHEIGHT * VIDEOHEIGHT * 4); | |
SDL_UnlockMutex(ctx->mutex); | |
return 1; | |
} | |
void cleanup(void *opaque) { | |
printf("got to %s\n", __func__); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
libvlc_instance_t *libvlc; | |
libvlc_media_t *m; | |
libvlc_media_player_t *mp; | |
char const *vlc_argv[] = | |
{ | |
"--quiet", | |
"--ignore-config", | |
"--no-video-title", | |
"--no-xlib", /* tell VLC to not use Xlib */ | |
}; | |
int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); | |
SDL_Surface *screen; | |
SDL_Event event; | |
int done = 0, action = 0, pause = 0, n = 0; | |
struct ctx ctx; | |
if(argc < 2) | |
{ | |
printf("Usage: %s <filename>\n", argv[0]); | |
return EXIT_FAILURE; | |
} | |
/* | |
* Initialise libSDL | |
*/ | |
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD) == -1) | |
{ | |
printf("cannot initialize SDL\n"); | |
return EXIT_FAILURE; | |
} | |
ctx.mutex = SDL_CreateMutex(); | |
int options = SDL_ANYFORMAT | SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_OPENGL; | |
screen = SDL_SetVideoMode(WIDTH, HEIGHT, 0, options); | |
if(!screen) | |
{ | |
printf("cannot set video mode\n"); | |
return EXIT_FAILURE; | |
} | |
/* | |
* Initialise libVLC | |
*/ | |
libvlc = libvlc_new(vlc_argc, vlc_argv); | |
// m = libvlc_media_new_path(libvlc, argv[1]); | |
m = libvlc_media_new_location(libvlc, "http://www.streambox.fr/playlists/x36xhzz/x36xhzz.m3u8"); | |
auto media_event_manager = libvlc_media_event_manager(m); | |
#define _e(event) assert(!libvlc_event_attach(media_event_manager, event, _event, m)) | |
_e(libvlc_MediaSubItemAdded); | |
_e(libvlc_MediaDurationChanged); | |
_e(libvlc_MediaParsedChanged); | |
_e(libvlc_MediaFreed); | |
_e(libvlc_MediaStateChanged); | |
_e(libvlc_MediaSubItemTreeAdded); | |
#undef _e | |
libvlc_media_parse(m); | |
libvlc_media_track_info_t * tracks = NULL; | |
libvlc_media_get_tracks_info(m, &tracks); | |
if( tracks ) | |
{ | |
int width = tracks->u.video.i_width; | |
int height = tracks->u.video.i_height; | |
printf( "%d x %d \n", width, height); | |
free(tracks); | |
} | |
else | |
{ | |
printf("tracks is NULL\n"); | |
} | |
// libvlc_media_track_info_t * tracks = NULL; | |
// libvlc_media_get_tracks_info(m, &tracks); | |
// if( tracks ) | |
// { | |
// int width = tracks->u.video.i_width; | |
// int height = tracks->u.video.i_height; | |
// printf( "%d x %d \n", width, height); | |
// free(tracks); | |
// } | |
// else | |
// { | |
// printf("tracks is NULL\n");assert(false); | |
// } | |
mp = libvlc_media_player_new_from_media(m); | |
libvlc_media_release(m); | |
libvlc_video_set_callbacks(mp, lock, unlock, display, &ctx); | |
libvlc_video_set_format_callbacks(mp, setup, cleanup); | |
// // libvlc_video_get_size(ctx->mp, 0, &ctx->width, &ctx->height); | |
// unsigned int VIDEOWIDTH = 0; | |
// unsigned int VIDEOHEIGHT = 0; | |
// VIDEOWIDTH = 1280; VIDEOHEIGHT = 720; | |
// unsigned int VIDEOWIDTH_ = 0; | |
// unsigned int VIDEOHEIGHT_ = 0; | |
// // while(!VIDEOWIDTH_ || !VIDEOHEIGHT_) { | |
// // libvlc_video_get_size(mp, 0, &VIDEOWIDTH_, &VIDEOHEIGHT_); | |
// // } | |
// // printf("got size: %u, %u\n", VIDEOHEIGHT, VIDEOWIDTH); | |
// // printf("got size_: %u, %u\n", VIDEOHEIGHT_, VIDEOWIDTH_); | |
// printf("Sleeping\n"); sleep(10); | |
// printf("Done Sleeping\n"); | |
// libvlc_video_set_format(mp, "RV32", VIDEOWIDTH, VIDEOHEIGHT, VIDEOWIDTH*4); | |
libvlc_media_player_play(mp); | |
libvlc_media_player_set_pause(mp, 1); | |
libvlc_media_player_set_pause(mp, 0); | |
/* | |
* Main loop | |
*/ | |
glEnable(GL_TEXTURE_2D); | |
glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
GLuint image; | |
printf("SLEEPING\n"); | |
sleep(5); | |
printf("DONE SLEEPING\n"); | |
glGenTextures(1, &image); | |
glBindTexture(GL_TEXTURE_2D, image); | |
SDL_LockMutex(ctx.mutex); | |
//SDL_BlitSurface(ctx.surf, NULL, screen, NULL); | |
//gluBuild2DMipmaps(GL_TEXTURE_2D, 4, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (Uint8 *) raw); | |
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
{ | |
printf(" init VIDEOWIDTH:%d VIDEOHEIGHT:%d\n ", VIDEOWIDTH, VIDEOHEIGHT); | |
} | |
GL_CHECK(); | |
// for (int x=0; x<100; x++) { | |
// for (int y=0; y<100; y++) { | |
// auto p = ((uint8_t*)tex_mem) + y*VIDEOWIDTH*4 + x*4; | |
// p[0] = 128; | |
// p[1] = 255; | |
// p[2] = 0; | |
// p[3] = 255; | |
// } | |
// } | |
//glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, VIDEOWIDTH, VIDEOHEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE,(Uint8 *) tex_mem); | |
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, VIDEOWIDTH, VIDEOHEIGHT); | |
GL_CHECK(); | |
SDL_UnlockMutex(ctx.mutex); | |
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; | |
} | |
if(!pause) | |
n++; | |
glClear(GL_COLOR_BUFFER_BIT); | |
/* 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); | |
//gluBuild2DMipmaps(GL_TEXTURE_2D, 4, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (Uint8 *) raw); | |
// glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
// glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
// glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, VIDEOWIDTH, VIDEOHEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE,(Uint8 *) tex_mem); | |
GL_CHECK(); | |
if(tex_mem) { | |
// printf("VIDEOWIDTH:%d VIDEOHEIGHT:%d\n ", VIDEOWIDTH, VIDEOHEIGHT); | |
// for (int x=0; x<100; x++) { | |
// for (int y=0; y<100; y++) { | |
// auto p = ((uint8_t*)tex_mem) + y*VIDEOWIDTH*4 + x*4; | |
// p[0] = 128; | |
// p[1] = 255; | |
// p[2] = 0; | |
// p[3] = 255; | |
// } | |
// } | |
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VIDEOWIDTH, VIDEOHEIGHT, GL_BGRA, GL_UNSIGNED_BYTE, tex_mem); | |
} | |
GL_CHECK(); | |
SDL_UnlockMutex(ctx.mutex); | |
//SDL_Flip(screen); | |
// glDisable(GL_TEXTURE_2D); | |
// glBegin(GL_QUADS); | |
// glColor3f(1,1,1); | |
// glVertex2f(0, 0.9); | |
// glVertex2f(0.9, 0.9); | |
// glVertex2f(0.9, 0); | |
// glVertex2f(0, 0); | |
// glEnd(); | |
// glEnable(GL_TEXTURE_2D); | |
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); | |
glTexCoord2d(0, 0); | |
glVertex2f(0, 0); | |
glEnd(); | |
glFlush(); | |
SDL_GL_SwapBuffers(); | |
//SDL_Delay(5); | |
//SDL_BlitSurface(empty, NULL, screen, NULL); | |
//use SDL timers to determine playback | |
//printf("%i %i\n",libvlc_media_player_get_length(mp)-1000,libvlc_media_player_get_time(mp)); | |
if(libvlc_media_player_get_length(mp)-1000 == libvlc_media_player_get_time(mp)){ | |
done = 1; | |
} | |
} | |
glDeleteTextures(1, &image); | |
/* | |
* 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(ctx.mutex); | |
free(tex_mem); | |
//SDL_FreeSurface(empty); | |
SDL_Quit(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment