diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-10-03 15:37:20 +0200 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-10-03 15:37:20 +0200 |
commit | c61253adbd5bed1d7393a3153f9c865517280431 (patch) | |
tree | f13e3d561129b2e9824895fbee82d9f65322b257 /src | |
parent | bca127f7f24f6a4b70e8797639619913e945b62b (diff) | |
download | osc-graphics-c61253adbd5bed1d7393a3153f9c865517280431.tar.gz |
added video recorder based on SDL_ffmpeg
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/main.cpp | 10 | ||||
-rw-r--r-- | src/recorder.cpp | 125 | ||||
-rw-r--r-- | src/recorder.h | 38 |
4 files changed, 172 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 5c1a23c..3b1ba79 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,6 +11,7 @@ LDADD = -lsupc++ bin_PROGRAMS = osc-graphics osc_graphics_SOURCES = main.cpp osc_graphics.h \ osc_server.cpp osc_server.h \ + recorder.cpp recorder.h \ layer.cpp layer.h \ layer_box.cpp layer_box.h \ layer_text.cpp layer_text.h \ diff --git a/src/main.cpp b/src/main.cpp index f9c3eb8..8fd714f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,6 +17,7 @@ #include "osc_graphics.h" #include "osc_server.h" +#include "recorder.h" #include "layer.h" #include "layer_box.h" @@ -50,8 +51,9 @@ static void cleanup(void); SDL_Surface *screen; -OSCServer osc_server; -LayerList layers; +OSCServer osc_server; +static Recorder recorder; +LayerList layers; int config_dump_osc = 0; @@ -267,6 +269,8 @@ main(int argc, char **argv) osc_server.open(port); + recorder.register_methods(); + REGISTER_LAYER(LayerImage); REGISTER_LAYER(LayerVideo); REGISTER_LAYER(LayerBox); @@ -282,6 +286,8 @@ main(int argc, char **argv) layers.render(screen); + recorder.record(screen); + SDL_Flip(screen); SDL_framerateDelay(&fpsm); } diff --git a/src/recorder.cpp b/src/recorder.cpp new file mode 100644 index 0000000..13e2b13 --- /dev/null +++ b/src/recorder.cpp @@ -0,0 +1,125 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <stdio.h> + +#include <SDL.h> +#include <SDL/SDL_ffmpeg.h> + +#include "osc_graphics.h" +#include "osc_server.h" + +#include "recorder.h" + +/* + * Macros + */ +#define SDL_FFMPEGFREE_SAFE(FILE) do { \ + if (FILE) { \ + SDL_ffmpegFree(FILE); \ + FILE = NULL; \ + } \ +} while (0) + +#define SDL_FFMPEG_ERROR(FMT, ...) do { \ + fprintf(stderr, "%s(%d): " FMT ": %s\n", \ + __FILE__, __LINE__, ##__VA_ARGS__, \ + SDL_ffmpegGetError()); \ +} while (0) + +extern "C" { + +static int start_handler(const char *path, const char *types, + lo_arg **argv, int argc, + void *data, void *user_data); +static int stop_handler(const char *path, const char *types, + lo_arg **argv, int argc, + void *data, void *user_data); + +} + +void +Recorder::register_methods() +{ + osc_server.add_method("s", start_handler, this, "/recorder/start"); + osc_server.add_method("", stop_handler, this, "/recorder/stop"); +} + +static int +start_handler(const char *path, const char *types, + lo_arg **argv, int argc, void *data, void *user_data) +{ + Recorder *obj = (Recorder *)user_data; + + obj->start(&argv[0]->s); + + return 0; +} + +void +Recorder::start(const char *filename) +{ + SDL_ffmpegCodec codec = { + -1, /* video codec based on file name */ + screen->w, screen->h, + 1, 20 /* FIXME */, /* framerate */ + 6000000, -1, -1, + -1, 0, -1, -1, -1, -1 /* no audio */ + }; + + lock(); + + SDL_FFMPEGFREE_SAFE(file); + + file = SDL_ffmpegCreate(filename); + if (!file) { + SDL_FFMPEG_ERROR("SDL_ffmpegCreate"); + exit(EXIT_FAILURE); + } + + SDL_ffmpegAddVideoStream(file, codec); + SDL_ffmpegSelectVideoStream(file, 0); + + unlock(); +} + +static int +stop_handler(const char *path, const char *types, + lo_arg **argv, int argc, void *data, void *user_data) +{ + Recorder *obj = (Recorder *)user_data; + + obj->stop(); + + return 0; +} + +void +Recorder::stop() +{ + lock(); + SDL_FFMPEGFREE_SAFE(file); + unlock(); +} + +void +Recorder::record(SDL_Surface *surf) +{ + lock(); + + if (file) + SDL_ffmpegAddVideoFrame(file, surf); + + unlock(); +} + +Recorder::~Recorder() +{ + osc_server.del_method("s", "/recorder/start"); + osc_server.del_method("", "/recorder/stop"); + + SDL_FFMPEGFREE_SAFE(file); + SDL_DestroyMutex(mutex); +} diff --git a/src/recorder.h b/src/recorder.h new file mode 100644 index 0000000..b2ee5e6 --- /dev/null +++ b/src/recorder.h @@ -0,0 +1,38 @@ +#ifndef __RECORDER_H +#define __RECORDER_H + +#include <SDL.h> +#include <SDL_thread.h> +#include <SDL/SDL_ffmpeg.h> + +#include "osc_graphics.h" + +class Recorder { + SDL_ffmpegFile *file; + + SDL_mutex *mutex; + + inline void + lock() + { + SDL_LockMutex(mutex); + } + inline void + unlock() + { + SDL_UnlockMutex(mutex); + } + +public: + Recorder() : file(NULL), mutex(SDL_CreateMutex()) {} + ~Recorder(); + + void register_methods(); + + void start(const char *filename); + void stop(); + + void record(SDL_Surface *surf); +}; + +#endif |