Permalink
Browse files

start of video support

  • Loading branch information...
1 parent acc07da commit 5184711add8f6029957447e3d5ea2f630d150331 @eclecticc eclecticc committed Sep 11, 2011
Showing with 156 additions and 11 deletions.
  1. +3 −3 sosg/Makefile
  2. +30 −5 sosg/sosg.c
  3. +5 −3 sosg/sosg_image.c
  4. +104 −0 sosg/sosg_video.c
  5. +14 −0 sosg/sosg_video.h
View
@@ -1,7 +1,7 @@
-OBJS = sosg_image.o
+OBJS = sosg_image.o sosg_video.o
CC = gcc
CFLAGS = -O3 -Wall `sdl-config --cflags` -DGL_GLEXT_PROTOTYPES
-LDFLAGS = -L/usr/X11R6/lib -lGL -lGLU `sdl-config --libs` -lSDL_image
+LDFLAGS = -L/usr/X11R6/lib -lGL -lGLU `sdl-config --libs` -lSDL_image -lvlc
.PHONY: all
all: sosg
@@ -11,4 +11,4 @@ sosg: sosg.o $(OBJS)
.PHONY: clean
clean:
- rm -f sosg_image.o sosg.o sosg
+ rm -f $(OBJS) sosg.o sosg
View
@@ -16,6 +16,7 @@
#include "SDL_image.h"
#include "sosg_image.h"
+#include "sosg_video.h"
#include <stdio.h>
#include <stdlib.h>
@@ -24,6 +25,11 @@
#define PI 3.141592653589793
#define ROTATION_INTERVAL PI/(120.0*(1000.0/TICK_INTERVAL))
+enum sosg_mode {
+ SOSG_IMAGES,
+ SOSG_VIDEO
+};
+
typedef struct sosg_struct {
int w;
int h;
@@ -34,7 +40,9 @@ typedef struct sosg_struct {
float rotation;
float drotation;
Uint32 time;
+ int mode;
sosg_image_p images;
+ sosg_video_p video;
SDL_Surface *screen;
GLuint texture;
GLuint program;
@@ -50,7 +58,7 @@ static void load_texture(sosg_p data, SDL_Surface *surface)
// Edit the texture object's image data using the information SDL_Surface gives us
glTexImage2D(GL_TEXTURE_2D, 0, 4, surface->w, surface->h, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
+ GL_BGRA, GL_UNSIGNED_BYTE, surface->pixels);
}
static char *load_file(char *filename)
@@ -216,7 +224,13 @@ static void update_media(sosg_p data)
{
SDL_Surface *surface;
- if ((surface = sosg_image_update(data->images))) {
+ if (data->mode == SOSG_IMAGES) {
+ surface = sosg_image_update(data->images);
+ } else {
+ surface = sosg_video_update(data->video);
+ }
+
+ if (surface) {
// Check that the image's dimensions are a power of 2
if ((surface->w & (surface->w - 1)) != 0 ||
(surface->h & (surface->h - 1)) != 0) {
@@ -261,6 +275,7 @@ static void update_display(sosg_p data)
int main(int argc, char *argv[])
{
char *filename = "2048.jpg";
+// char *filename = "china_quakes_2048.mp4";
sosg_p data = calloc(1, sizeof(sosg_t));
if (!data) {
@@ -275,13 +290,19 @@ int main(int argc, char *argv[])
data->center[0] = 431.0;
data->center[1] = 210.0;
data->rotation = PI;
+ data->mode = SOSG_IMAGES;
if (setup(data)) {
return 1;
}
- data->images = sosg_image_init(filename);
- sosg_image_get_resolution(data->images, data->texres);
+ if (data->mode == SOSG_IMAGES) {
+ data->images = sosg_image_init(filename);
+ sosg_image_get_resolution(data->images, data->texres);
+ } else {
+ data->video = sosg_video_init(filename);
+ sosg_video_get_resolution(data->video, data->texres);
+ }
if (load_shaders(data)) {
SDL_Quit();
@@ -295,7 +316,11 @@ int main(int argc, char *argv[])
data->rotation += data->drotation;
}
- sosg_image_destroy(data->images);
+ if (data->mode == SOSG_IMAGES) {
+ sosg_image_destroy(data->images);
+ } else {
+ sosg_video_destroy(data->video);
+ }
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures(1, &data->texture);
SDL_Quit();
View
@@ -1,4 +1,5 @@
#include "sosg_image.h"
+#include <stdio.h>
typedef struct sosg_image_struct {
char *path;
@@ -43,12 +44,13 @@ SDL_Surface *sosg_image_update(sosg_image_p images)
if (!images->buffer) {
SDL_Surface *surface = IMG_Load(images->path);
if (surface) {
- SDL_PixelFormat format = {NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24,
- 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000, 0, 255};
- images->buffer = SDL_ConvertSurface(surface, &format, SDL_SWSURFACE);
+ images->buffer = SDL_CreateRGBSurface(SDL_SWSURFACE, surface->w, surface->h, 32,
+ 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+ SDL_BlitSurface(surface, NULL, images->buffer, NULL);
SDL_FreeSurface(surface);
}
} else if (images->num_images > 1) {
+ // TODO: actually load additional images
SDL_Surface *surface = IMG_Load(images->path);
if (surface) {
SDL_BlitSurface(surface, NULL, images->buffer, NULL);
View
@@ -0,0 +1,104 @@
+#include "sosg_video.h"
+#include <stdio.h>
+#include <vlc/vlc.h>
+
+#define VIDEOWIDTH 1024
+#define VIDEOHEIGHT 512
+
+typedef struct sosg_video_struct {
+ char *path;
+ SDL_Surface *buffer;
+ SDL_Surface *surface;
+ SDL_mutex *mutex;
+ libvlc_instance_t *libvlc;
+ libvlc_media_t *m;
+ libvlc_media_player_t *mp;
+} sosg_video_t;
+
+static void *lock(void *data, void **p_pixels)
+{
+ sosg_video_p video = data;
+
+ SDL_LockMutex(video->mutex);
+ SDL_LockSurface(video->buffer);
+ *p_pixels = video->buffer->pixels;
+ return NULL; /* picture identifier, not needed here */
+}
+
+static void unlock(void *data, void *id, void *const *p_pixels)
+{
+ sosg_video_p video = data;
+
+ SDL_UnlockSurface(video->buffer);
+ SDL_UnlockMutex(video->mutex);
+}
+
+static void display(void *data, void *id)
+{
+
+}
+
+sosg_video_p sosg_video_init(const char *path)
+{
+ sosg_video_p video = calloc(1, sizeof(sosg_video_t));
+ if (video) {
+ if (path) video->path = strdup(path);
+ video->mutex = SDL_CreateMutex();
+
+ video->buffer = SDL_CreateRGBSurface(SDL_SWSURFACE, VIDEOWIDTH, VIDEOHEIGHT, 32,
+ 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+ video->surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIDEOWIDTH, VIDEOHEIGHT, 32,
+ 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+
+ char const *vlc_argv[] =
+ {
+ "--input-repeat=-1",
+ "--no-video-title-show",
+ "--no-audio", /* skip any audio track */
+ "--no-xlib", /* tell VLC to not use Xlib */
+ };
+ int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);
+ video->libvlc = libvlc_new(vlc_argc, vlc_argv);
+ video->m = libvlc_media_new_path(video->libvlc, video->path);
+ video->mp = libvlc_media_player_new_from_media(video->m);
+
+ libvlc_video_set_callbacks(video->mp, lock, unlock, display, video);
+ libvlc_video_set_format(video->mp, "RV32", VIDEOWIDTH, VIDEOHEIGHT, VIDEOWIDTH*2);
+ libvlc_media_player_play(video->mp);
+ }
+
+ return video;
+}
+
+void sosg_video_destroy(sosg_video_p video)
+{
+ if (video) {
+ if (video->m) libvlc_media_release(video->m);
+ if (video->mp) {
+ libvlc_media_player_stop(video->mp);
+ libvlc_media_player_release(video->mp);
+ }
+ if (video->libvlc) libvlc_release(video->libvlc);
+ if (video->path) free(video->path);
+ if (video->buffer) SDL_FreeSurface(video->buffer);
+ if (video->mutex) SDL_DestroyMutex(video->mutex);
+ free(video);
+ }
+}
+
+void sosg_video_get_resolution(sosg_video_p video, int *resolution)
+{
+ if (resolution) {
+ resolution[0] = VIDEOWIDTH;
+ resolution[1] = VIDEOHEIGHT;
+ }
+}
+
+SDL_Surface *sosg_video_update(sosg_video_p video)
+{
+ SDL_LockMutex(video->mutex);
+ SDL_BlitSurface(video->buffer, NULL, video->surface, NULL);
+ SDL_UnlockMutex(video->mutex);
+
+ return video->surface;
+}
View
@@ -0,0 +1,14 @@
+#ifndef _SOSG_VIDEO_H_
+#define _SOSG_VIDEO_H_
+
+#include "SDL.h"
+#include "SDL_image.h"
+
+typedef struct sosg_video_struct *sosg_video_p;
+
+sosg_video_p sosg_video_init(const char *path);
+void sosg_video_destroy(sosg_video_p video);
+void sosg_video_get_resolution(sosg_video_p video, int *resolution);
+SDL_Surface *sosg_video_update(sosg_video_p video);
+
+#endif /* _SOSG_VIDEO_H_ */

0 comments on commit 5184711

Please sign in to comment.