diff options
| author | 2024-01-01 11:23:22 -0500 | |
|---|---|---|
| committer | 2024-01-01 11:23:22 -0500 | |
| commit | 130a0edc0405e53b45f8b2f8da0b94356480a644 (patch) | |
| tree | 76cda2f7e0098bdcb6c54dc152bf3e95467fd44e /src/fruits/cmv | |
| parent | 099126fdca625c5f6c219c5a1a7ecbc0e145988f (diff) | |
| download | camu-130a0edc0405e53b45f8b2f8da0b94356480a644.tar.gz camu-130a0edc0405e53b45f8b2f8da0b94356480a644.tar.bz2 camu-130a0edc0405e53b45f8b2f8da0b94356480a644.zip | |
wip
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/fruits/cmv')
| -rw-r--r-- | src/fruits/cmv/cmv2.c | 88 | ||||
| -rw-r--r-- | src/fruits/cmv/meson.build | 30 | ||||
| -rw-r--r-- | src/fruits/cmv/tui.c | 99 | ||||
| -rw-r--r-- | src/fruits/cmv/tui.h | 14 |
4 files changed, 138 insertions, 93 deletions
diff --git a/src/fruits/cmv/cmv2.c b/src/fruits/cmv/cmv2.c index 74a4113..89e3427 100644 --- a/src/fruits/cmv/cmv2.c +++ b/src/fruits/cmv/cmv2.c @@ -1,7 +1,8 @@ -#define CMV_USE_TUI 1 -#define CMV_USE_SOCKET 1 +#define CMV_USE_TUI 0 +#define CMV_USE_SOCKET 0 #include <al/log.h> +#include <aki/event_loop.h> #if CMV_USE_SOCKET #include <aki/line_processor.h> #endif @@ -14,7 +15,8 @@ #include "../../render/renderer_libplacebo.h" //#include "../../render/renderer_tiger.h" -#include "../../libsink/sink.h" +#include "../../libsink/sink2.h" +#include "../../tree/common.h" #include "../../shoki/src/search.h" @@ -162,14 +164,7 @@ static void screen_callback(void *userdata, u8 op, f64 float0) } } -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 bool cap_callback(void *userdata, u8 op, str *name, str *unique_id, void *opaque) { struct cmv *c = (struct cmv *)userdata; @@ -190,6 +185,7 @@ static bool cap_callback(void *userdata, u8 op, str *name, str *unique_id, void } return true; } +*/ #if CMV_USE_SOCKET static u8 line_callback(void *userdata, str *line) @@ -214,7 +210,7 @@ static void timer_callback(void *userdata, struct aki_timer *timer) struct cmv *c = (struct cmv *)userdata; struct camu_sink_entry *entry = camu_sink_get_current(&c->sink); if (entry) { - tui_draw(&c->tui, &entry->runner, &entry->clock); + tui_draw(&c->tui, &((struct camu_sink_local *)entry)->runner, &entry->clock); } else { tui_draw(&c->tui, NULL, NULL); } @@ -233,22 +229,39 @@ static s32 log_callback(void *userdata, char *s) static void lav_log_callback(void *userdata, s32 level, const char *fmt, va_list args) { (void)userdata; - if (level < AV_LOG_VERBOSE) al_logv(warn, "lav_internal", (char *)fmt, args); + if (level < AV_LOG_VERBOSE) al_logv("warn", "lav_internal", (char *)fmt, args); } #endif #endif +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[]) { - aki_common_init(); + if (!aki_common_init()) return EXIT_FAILURE; - struct cmv c = { }; + signal(SIGINT, sigint_handler); + + aki_event_loop_init(&c.loop); #if CMV_USE_TUI - if (!tui_init(&c.tui)) { - aki_common_close(); - return EXIT_FAILURE; - } + if (!tui_init(&c.tui, &c.loop)) { + goto err; + }; al_set_print(log_callback, &c); #ifdef HAVE_FFMPEG camu_lav_set_log_callback(lav_log_callback); @@ -257,37 +270,35 @@ s32 main(s32 argc, char *argv[]) c.scr.callback = screen_callback; c.scr.userdata = &c; - if (!camu_screen_init(&c.scr)) { - aki_common_close(); - return EXIT_FAILURE; - } - - if (!camu_screen_create_window(&c.scr, "cmv")) { - aki_common_close(); - return EXIT_FAILURE; + 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(); - camu_screen_create_renderer(&c.scr, c.renderer); + if (!camu_screen_create_renderer(&c.scr, c.renderer)) { + goto err; + } + c.renderer->render(c.renderer, &c.scr); #if CAP_USE_PYTHON - bool py_init = sho_python_init(); + bool py_init = argc == 1 ? sho_python_init() : false; #endif camu_mixer_init(&c.mixer, (struct camu_audio *)&audio_plugin_miniaudio); c.mixer.audio->configure_stream(c.mixer.audio, NULL); - aki_event_loop_init(&c.loop); - + camu_sink_init(&c.sink, &c.loop, &c.mixer, c.renderer); c.sink.callback = sink_callback; c.sink.userdata = &c; - camu_sink_init(&c.sink, &c.loop, &c.mixer, c.renderer); + camu_sink_connect(&c.sink, al_str_c("127.0.0.1"), TREE_PORT); + /* cap_init(&c.cap, cap_callback, &c); cap_make_list(&c.cap, default_list); for (s32 i = 1; i < argc; i++) { cap_list_add(&c.cap, default_list, al_str_c(argv[i])); } + */ #if CMV_USE_SOCKET c.socket.type = AKI_SOCKET_UNIX; @@ -304,7 +315,7 @@ s32 main(s32 argc, char *argv[]) #if CMV_USE_TUI aki_timer_init(&c.timer, &c.loop, timer_callback, &c); - aki_timer_set_repeat(&c.timer, 0.10); + aki_timer_set_repeat(&c.timer, 0.05); aki_timer_again(&c.timer); #endif @@ -326,10 +337,10 @@ s32 main(s32 argc, char *argv[]) aki_thread_join(&thread0); camu_mixer_close(&c.mixer); - camu_screen_close(&c.scr); c.renderer->free(&c.renderer); + camu_screen_close(&c.scr); - cap_close(&c.cap); + //cap_close(&c.cap); #if CAP_USE_PYTHON if (py_init) sho_python_close(); @@ -342,4 +353,11 @@ s32 main(s32 argc, char *argv[]) aki_common_close(); return EXIT_SUCCESS; +err: +#if CMV_USE_TUI + tui_close(&c.tui); +#endif + aki_event_loop_destroy(&c.loop); + aki_common_close(); + return EXIT_FAILURE; } diff --git a/src/fruits/cmv/meson.build b/src/fruits/cmv/meson.build index b604104..1c9ed2d 100644 --- a/src/fruits/cmv/meson.build +++ b/src/fruits/cmv/meson.build @@ -1,26 +1,10 @@ -cmv2_src = ['cmv2.c', 'tui.c'] -#cmv2_src = ['cmv2.c'] +cmv_src = ['cmv2.c'] cmv_deps = [common_deps, buffer, cache, av, screen, render, mixer, bimu, libsink, cap] -miniaudio_args = [ - '-DMA_NO_JACK', - '-DMA_NO_ALSA', - '-DMA_NO_DECODING', - '-DMA_NO_ENCODING', - '-DMA_NO_GENERATION', - '-DMA_NO_RESOURCE_MANAGER', - '-DMA_NO_NODE_GRAPH', - '-DMA_NO_ENGINE', - '-DMA_NO_RUNTIME_LINKING' -] +use_tui = true +if use_tui + cmv_src += ['tui.c'] + cmv_deps += [dependency('notcurses')] +endif -sekihi_args = [ - '-DSEKIHI_WINDOW_WAYLAND', -# '-DSEKIHI_WINDOW_GLFW', - '-DSEKIHI_API_OPENGL', -# '-DSEKIHI_API_VULKAN', - '-DSEKIHI_POLL_INLINE', - '-DSEKIHI_PAUSE' -] - -executable('cmv2', cmv2_src, dependencies: cmv_deps, c_args: [miniaudio_args, sekihi_args]) +executable('cmv', cmv_src, dependencies: cmv_deps) diff --git a/src/fruits/cmv/tui.c b/src/fruits/cmv/tui.c index 21aeac8..8315a13 100644 --- a/src/fruits/cmv/tui.c +++ b/src/fruits/cmv/tui.c @@ -1,6 +1,7 @@ #include <aki/file.h> #include <al/log.h> #include <sys/ioctl.h> +#include <notcurses/direct.h> #include "tui.h" @@ -23,16 +24,39 @@ static void handle_winch(s32 sig) aki_mutex_unlock(&tui->mutex); } -bool tui_init(struct cmv_tui *tui) +static void input_poll_callback(void *userdata, s32 revents) +{ + struct cmv_tui *tui = (struct cmv_tui *)userdata; + (void)revents; + struct ncinput input; + u32 ret; + while (1) { + ret = ncdirect_get_nblock(tui->dir, &input); + if (ret == (u32)-1 || ret == 0) break; + if (input.evtype == NCTYPE_PRESS || input.evtype == NCTYPE_UNKNOWN) { + } + } +} + +bool tui_init(struct cmv_tui *tui, struct aki_event_loop *loop) { tui->update_size = true; tui->width = 0; tui->height = 0; - //tui->prev_lines = 0; + tui->prev_lines = 0; - tui->fd = fileno(stdin); + tui->fd = fileno(stdout); tui->out = fdopen(tui->fd, "w"); if (!tui->out) return false; + tui->buffer = al_malloc(256); + + //if (!(tui->dir = ncdirect_init(NULL, tui->out, 0))) { + // fclose(tui->out); + // return false; + //} + + //aki_poll_init(&tui->poll, ncdirect_inputready_fd(tui->dir), AKI_POLL_READ, input_poll_callback, tui); + //aki_poll_start(&tui->poll, loop); tui_global = tui; aki_mutex_init(&tui->mutex); @@ -46,81 +70,96 @@ bool tui_init(struct cmv_tui *tui) tui->term.c_lflag &= ~ECHO; tcsetattr(tui->fd, 0, &tui->term); - al_array_init(tui->log_buffer); - tui->last_pts = 0.0; + al_queue_init(&tui->log_buffer, 256); return true; } void tui_push_log_msg(struct cmv_tui *tui, char *msg) { - aki_mutex_lock(&tui->mutex); - al_array_push(tui->log_buffer, msg); - aki_mutex_unlock(&tui->mutex); + al_queue_push(&tui->log_buffer, msg); } -static char buffer[128]; - -static void draw_now_playing(struct cmv_tui *tui, struct camu_clock *clock, struct bmu_local *runner) +static void draw_now_playing(struct cmv_tui *tui, struct bmu_local *runner, struct camu_clock *clock) { + char *buffer = tui->buffer; f64 pts = camu_clock_get_pts(clock); - if (pts == -1) pts = tui->last_pts; - else tui->last_pts = pts; - s32 parts = 0; f64 duration = bmu_local_get_duration(runner); + s32 text = 0; + s64 minute = (s64)(pts / 60L); + s64 hour = minute / 60L; + minute -= hour * 60L; + text += al_sprintf(buffer + text, "["); + if (hour > 0) text += al_sprintf(buffer + text, "%.2ld:", hour); + text += al_sprintf(buffer + text, "%.2ld:%.2ld/", minute, (s64)pts % 60L); + minute = (s64)(duration / 60L); + hour = minute / 60L; + minute -= hour * 60L; + if (hour > 0) text += al_sprintf(buffer + text, "%.2ld:", hour); + text += al_sprintf(buffer + text, "%.2ld:%.2ld", minute, (s64)duration % 60L); + text += al_sprintf(buffer + text, "]"); + s32 parts = 0; if (pts > 0.0 && duration != 0.0) { if (pts > duration) pts = duration; f64 percent = pts / duration; - parts = tui->width * percent; + parts = ((tui->width - text) * percent); } else if (duration == 0.0) { - parts = tui->width; + parts = (tui->width - text); } - al_memset(buffer, '-', parts); - buffer[parts] = '\0'; + al_memset(buffer + text, '-', parts); + buffer[text + parts] = '\0'; fprintf(tui->out, "%s", buffer); } void tui_draw(struct cmv_tui *tui, struct bmu_local *runner, struct camu_clock *clock) { aki_mutex_lock(&tui->mutex); - if (tui->update_size) { update_term_size(tui); tui->update_size = false; } + aki_mutex_unlock(&tui->mutex); + // Erase line. fprintf(tui->out, "\r\033[K"); - //for (u32 i = 1; i < tui->prev_lines; i++) { - // fprintf(tui->out, "\033[A\r\033[K"); - //} + for (u32 i = 0; i < tui->prev_lines; i++) { + // Up one, erase line. + fprintf(tui->out, "\033[A\r\033[K"); + } char *msg; - for (u32 i = 0; i < tui->log_buffer.size; i++) { - al_array_pop_at(tui->log_buffer, 0, msg); + while (al_queue_pop(&tui->log_buffer, (void **)&msg)) { fprintf(tui->out, "%s\n", msg); al_free(msg); } - //tui->prev_lines = 0; + // Simply printing each log message with a newline will leave + // a one character high space in the bottom of the terminal window. + // We use that to display a very basic status line (like mpv). + // Trying to use more than that one line space without a more complete + // terminal interface gets scuffed very fast. + + tui->prev_lines = 0; if (runner) { - draw_now_playing(tui, clock, runner); + draw_now_playing(tui, runner, clock); } - - aki_mutex_unlock(&tui->mutex); } void tui_close(struct cmv_tui *tui) { + if (!tui->out) return; + al_free(tui->buffer); char *msg; - al_array_foreach(tui->log_buffer, i, msg) { + while (al_queue_pop(&tui->log_buffer, (void **)&msg)) { al_free(msg); } - al_array_free(tui->log_buffer); + al_queue_free(&tui->log_buffer); aki_mutex_destroy(&tui->mutex); fprintf(tui->out, "\n"); fflush(tui->out); tui->term.c_lflag |= ECHO; tcsetattr(tui->fd, 0, &tui->term); + //ncdirect_stop(tui->dir); fclose(tui->out); } diff --git a/src/fruits/cmv/tui.h b/src/fruits/cmv/tui.h index fb4215e..6898539 100644 --- a/src/fruits/cmv/tui.h +++ b/src/fruits/cmv/tui.h @@ -1,24 +1,28 @@ #pragma once +#include <al/queue.h> +#include <aki/event_loop.h> #include <termios.h> #include "../../bimu/local.h" -#include "../../buffer/clock.h" +#include "../../buffer/video.h" struct cmv_tui { s32 fd; FILE *out; + char *buffer; + struct ncdirect *dir; + struct aki_poll poll; struct aki_mutex mutex; struct termios term; bool update_size; u32 width; u32 height; - //u32 prev_lines; - array(char *) log_buffer; - f64 last_pts; + u32 prev_lines; + queue log_buffer; }; -bool tui_init(struct cmv_tui *tui); +bool tui_init(struct cmv_tui *tui, struct aki_event_loop *loop); void tui_push_log_msg(struct cmv_tui *tui, char *msg); void tui_draw(struct cmv_tui *tui, struct bmu_local *runner, struct camu_clock *clock); void tui_close(struct cmv_tui *tui); |