commit 90f73476fb541f86d1e93625d5266f66b198d9a7
parent 6c5b8a2c45d54d2acacd224300f1c84d1c145d2c
Author: Louis Burda <quent.burda@gmail.com>
Date: Sun, 10 Mar 2024 00:01:23 +0100
Fix piped buffering, prevent holding lock in get_line
Diffstat:
M | mplay.mp3.c | | | 51 | +++++++++++++++++++++++++++++++++++++-------------- |
1 file changed, 37 insertions(+), 14 deletions(-)
diff --git a/mplay.mp3.c b/mplay.mp3.c
@@ -88,7 +88,9 @@ static bool headless = false;
static bool verbose = false;
static bool istty = false;
-__attribute__((noreturn)) static void
+static void
+__attribute__((noreturn))
+__attribute__((format(printf, 1, 2)))
die(const char *fmt, ...)
{
va_list ap;
@@ -129,7 +131,7 @@ get_line(char *buf, int size)
{
char *c;
- putc('>', stderr);
+ if (istty) putc('>', stderr);
if (istty) term_set_canonical();
fgets(buf, size, stdin);
if ((c = strchr(buf, '\n'))) *c = '\0';
@@ -376,10 +378,16 @@ user_time(void)
}
static void
-cmd_setvol(double vol)
+cmd_setvol(double vol, double delta)
{
pa_operation *op;
+ pa_threaded_mainloop_lock(pa_mloop);
+
+ if (delta != 0) {
+ vol = user_vol() + delta;
+ }
+
update_sink_input_info();
pa_cvolume_set(&pa_strm_sink.volume, 2,
(pa_volume_t) (vol * PA_VOLUME_NORM / 100.F));
@@ -393,14 +401,22 @@ cmd_setvol(double vol)
mplay_status(MPLAY_INFO_VOLUME, "%02.2f", (double) pa_cvolume_avg(&pa_strm_sink.volume)
* 100.f / (double) PA_VOLUME_NORM);
+
+ pa_threaded_mainloop_unlock(pa_mloop);
}
static void
-cmd_seek(double time_sec)
+cmd_seek(double time_sec, double delta)
{
size_t sample_pos;
pa_operation *op;
+ pa_threaded_mainloop_lock(pa_mloop);
+
+ if (delta != 0) {
+ time_sec = user_time() + delta;
+ }
+
if (time_sec < 0) time_sec = 0;
sample_pos = (size_t) (time_sec * mp3d.channels * mp3d.rate);
decoder_seek(sample_pos);
@@ -410,6 +426,8 @@ cmd_seek(double time_sec)
mp3d.seek = true;
mplay_status(MPLAY_INFO_SEEK, "%02.2f", user_time());
+
+ pa_threaded_mainloop_unlock(pa_mloop);
}
static void
@@ -417,21 +435,29 @@ cmd_playpause(void)
{
pa_operation *op;
+ pa_threaded_mainloop_lock(pa_mloop);
+
mp3d.pause ^= 1;
op = pa_stream_cork(pa_strm, mp3d.pause, NULL, NULL);
pa_operation_unref(op);
mplay_status(MPLAY_INFO_PAUSE, "%i", mp3d.pause);
+
+ pa_threaded_mainloop_unlock(pa_mloop);
}
static void
cmd_status(void)
{
+ pa_threaded_mainloop_lock(pa_mloop);
+
update_sink_input_info();
mplay_status(MPLAY_INFO_STATUS,
"volume=%02.2f,time=%02.2f,pause=%i",
user_vol(), user_time(), mp3d.pause);
+
+ pa_threaded_mainloop_unlock(pa_mloop);
}
static bool
@@ -443,8 +469,6 @@ key_input(void)
while ((key = mplay_getkey()) == MPLAY_KEY_EOF);
- pa_threaded_mainloop_lock(pa_mloop);
-
switch (mplay_action(key)) {
case MPLAY_ACTION_VOLUME:
get_line(linebuf, sizeof(linebuf));
@@ -453,13 +477,13 @@ key_input(void)
mplay_status(MPLAY_INFO_VOLUME, "fail:bad float");
break;
}
- cmd_setvol(fval);
+ cmd_setvol(fval, 0);
break;
case MPLAY_ACTION_VOLUME_UP:
- cmd_setvol(user_vol() + 5);
+ cmd_setvol(0, 5);
break;
case MPLAY_ACTION_VOLUME_DOWN:
- cmd_setvol(user_vol() - 5);
+ cmd_setvol(0, -5);
break;
case MPLAY_ACTION_SEEK:
get_line(linebuf, sizeof(linebuf));
@@ -468,13 +492,13 @@ key_input(void)
mplay_status(MPLAY_INFO_SEEK, "fail:bad float");
break;
}
- cmd_seek(fval);
+ cmd_seek(fval, 0);
break;
case MPLAY_ACTION_SEEK_BWD:
- cmd_seek(user_time() - 5);
+ cmd_seek(0, -5);
break;
case MPLAY_ACTION_SEEK_FWD:
- cmd_seek(user_time() + 5);
+ cmd_seek(0, 5);
break;
case MPLAY_ACTION_PAUSE:
cmd_playpause();
@@ -487,8 +511,6 @@ key_input(void)
break;
}
- pa_threaded_mainloop_unlock(pa_mloop);
-
return true;
}
@@ -498,6 +520,7 @@ input_worker(void *arg)
input_worker_alive = true;
setvbuf(stdin, NULL, _IONBF, 0);
+ setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
if (istty) {