summaryrefslogtreecommitdiff
path: root/src/fruits/cmv
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2024-01-01 11:23:22 -0500
committerAndrew Opalach <andrew@akon.city> 2024-01-01 11:23:22 -0500
commit130a0edc0405e53b45f8b2f8da0b94356480a644 (patch)
tree76cda2f7e0098bdcb6c54dc152bf3e95467fd44e /src/fruits/cmv
parent099126fdca625c5f6c219c5a1a7ecbc0e145988f (diff)
downloadcamu-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.c88
-rw-r--r--src/fruits/cmv/meson.build30
-rw-r--r--src/fruits/cmv/tui.c99
-rw-r--r--src/fruits/cmv/tui.h14
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);