diff options
Diffstat (limited to 'src/fruits/sink')
| -rw-r--r-- | src/fruits/sink/meson.build | 10 | ||||
| -rw-r--r-- | src/fruits/sink/sink.c | 201 |
2 files changed, 211 insertions, 0 deletions
diff --git a/src/fruits/sink/meson.build b/src/fruits/sink/meson.build new file mode 100644 index 0000000..c409857 --- /dev/null +++ b/src/fruits/sink/meson.build @@ -0,0 +1,10 @@ +sink_src = ['sink.c'] +sink_deps = [common_deps, buffer, cache, av, screen, render, mixer, libsink] + +use_tui = false +if use_tui + sink_src += [] + sink_deps += [dependency('notcurses')] +endif + +executable('sink', sink_src, dependencies: sink_deps) diff --git a/src/fruits/sink/sink.c b/src/fruits/sink/sink.c new file mode 100644 index 0000000..d0455a4 --- /dev/null +++ b/src/fruits/sink/sink.c @@ -0,0 +1,201 @@ +#include <al/log.h> +#include <aki/event_loop.h> + +#include "../../codec/libav/common.h" + +#include "../../mixer/audio_miniaudio.h" + +#include "../../screen/screen.h" +#include "../../render/renderer_libplacebo.h" +//#include "../../render/renderer_tiger.h" + +#include "../../libsink/sink.h" +#include "../../tree/common.h" + +#include "../../shoki/src/search.h" + +struct cmv { + s32 quit; + struct camu_screen scr; + struct camu_renderer *renderer; + struct camu_mixer mixer; + struct aki_event_loop loop; + struct camu_sink sink; +}; + +static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque) +{ + struct cmv *c = (struct cmv *)userdata; + switch (op) { + case CAMU_SINK_ADD_BUFFER: + switch (type) { + case CAMU_SINK_AUDIO: { + struct camu_audio_buffer *buf = (struct camu_audio_buffer *)opaque; + camu_mixer_add_buffer(&c->mixer, buf); + al_log_debug("cmv", "Audio buffer added."); + break; + } + case CAMU_SINK_VIDEO: { + struct camu_video_buffer *buf = (struct camu_video_buffer *)opaque; + camu_screen_add_buffer(&c->scr, buf); + al_log_debug("cmv", "Video buffer added."); + break; + } + } + break; + case CAMU_SINK_REMOVE_BUFFER: + switch (type) { + case CAMU_SINK_AUDIO: { + struct camu_audio_buffer *buf = (struct camu_audio_buffer *)opaque; + camu_mixer_remove_buffer(&c->mixer, buf); + al_log_debug("cmv", "Audio buffer removed."); + break; + } + case CAMU_SINK_VIDEO: { + struct camu_video_buffer *buf = (struct camu_video_buffer *)opaque; + camu_screen_remove_buffer(&c->scr, buf); + al_log_debug("cmv", "Video buffer removed."); + break; + } + } + break; + case CAMU_SINK_SWAP_BUFFER: + switch (type) { + case CAMU_SINK_AUDIO: { + break; + } + } + break; + case CAMU_SINK_SET_BUFFERED: { + break; + } + case CAMU_SINK_START: + switch (type) { + case CAMU_SINK_AUDIO: { + camu_mixer_resume(&c->mixer); + al_log_debug("cmv", "Audio started."); + break; + } + case CAMU_SINK_VIDEO: { + camu_screen_set_state(&c->scr, CAMU_SCREEN_PLAYING); + camu_screen_wake(&c->scr); + al_log_debug("cmv", "Video started."); + break; + } + } + break; + case CAMU_SINK_STOP: + switch (type) { + case CAMU_SINK_AUDIO: { + camu_mixer_pause(&c->mixer); + al_log_debug("cmv", "Audio stopped."); + break; + } + case CAMU_SINK_VIDEO: { + camu_screen_set_state(&c->scr, CAMU_SCREEN_PAUSED); + al_log_debug("cmv", "Video stopped."); + break; + } + } + break; + case CAMU_SINK_EXIT: + camu_sink_close(&c->sink); + aki_event_loop_break(&c->loop); + break; + } + return CAMU_SINK_OK; +} + +static void screen_callback(void *userdata, u8 op, f64 float0) +{ + struct cmv *c = (struct cmv *)userdata; + switch (op) { + case CAMU_SCREEN_NEXT: + break; + case CAMU_SCREEN_PREVIOUS: + break; + case CAMU_SCREEN_TOGGLE_PAUSE: + camu_sink_toggle_pause(&c->sink); + break; + case CAMU_SCREEN_SEEK: + camu_sink_seek(&c->sink, float0); + break; + case CAMU_SCREEN_CLOSE: + c->quit = 1; + break; + } +} + +static aki_thread_result AKI_THREADCALL event_loop_thread(void *userdata) +{ + struct cmv *c = (struct cmv *)userdata; + aki_event_loop_run(&c->loop); + aki_event_loop_destroy(&c->loop); + return 0; +} + +static struct cmv c = { 0 }; + +static void sigint_handler(s32 signum) +{ + (void)signum; + c.quit = 1; +} + +s32 main(s32 argc, char *argv[]) +{ + if (!aki_common_init()) return EXIT_FAILURE; + + signal(SIGINT, sigint_handler); + + aki_event_loop_init(&c.loop); + + c.scr.callback = screen_callback; + c.scr.userdata = &c; + if (!camu_screen_init(&c.scr) || !camu_screen_create_window(&c.scr, "cmv")) { + goto err; + } + c.renderer = camu_renderer_lp_create(); + //c.renderer = camu_renderer_tiger_create(); + if (!camu_screen_create_renderer(&c.scr, c.renderer)) { + goto err; + } + c.renderer->render(c.renderer, &c.scr); + + camu_mixer_init(&c.mixer, (struct camu_audio *)&audio_plugin_miniaudio); + c.mixer.audio->configure_stream(c.mixer.audio, NULL); + + camu_sink_init(&c.sink, &c.loop, &c.mixer, c.renderer); + c.sink.callback = sink_callback; + c.sink.userdata = &c; + camu_sink_connect(&c.sink, al_str_c("127.0.0.1"), TREE_PORT); + + struct aki_thread thread0; + aki_thread_create(&thread0, event_loop_thread, &c); + + c.quit = 0; + + while (!c.quit) { + if (camu_screen_tick(&c.scr)) { + c.renderer->render(c.renderer, &c.scr); + } + } + + camu_screen_set_state(&c.scr, CAMU_SCREEN_CLOSED); + + camu_sink_stop(&c.sink); + + aki_thread_join(&thread0); + + camu_mixer_close(&c.mixer); + c.renderer->free(&c.renderer); + camu_screen_close(&c.scr); + + aki_common_close(); + + return EXIT_SUCCESS; +err: + aki_event_loop_destroy(&c.loop); + aki_common_close(); + return EXIT_FAILURE; +} |