mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-26 22:23:17 -05:00
[player] Fix commit 3e9f8ef, input_resume() must be non-blocking (possibly issue #773)
This commit is contained in:
parent
2f3ec36c6a
commit
5307c6d94b
29
src/input.c
29
src/input.c
@ -50,6 +50,8 @@
|
||||
#define INPUT_OPEN_TIMEOUT 600
|
||||
|
||||
//#define DEBUG_INPUT 1
|
||||
// For testing http stream underruns
|
||||
//#define DEBUG_UNDERRUN 1
|
||||
|
||||
extern struct input_definition input_file;
|
||||
extern struct input_definition input_http;
|
||||
@ -142,6 +144,9 @@ static struct event *input_open_timeout_ev;
|
||||
#ifdef DEBUG_INPUT
|
||||
static size_t debug_elapsed;
|
||||
#endif
|
||||
#ifdef DEBUG_UNDERRUN
|
||||
int debug_underrun_trigger;
|
||||
#endif
|
||||
|
||||
|
||||
/* ------------------------------- MISC HELPERS ----------------------------- */
|
||||
@ -578,6 +583,16 @@ input_write(struct evbuffer *evbuf, struct media_quality *quality, short flags)
|
||||
if (evbuf)
|
||||
{
|
||||
len = evbuffer_get_length(evbuf);
|
||||
#ifdef DEBUG_UNDERRUN
|
||||
// Starves the player so it underruns after a few minutes
|
||||
debug_underrun_trigger++;
|
||||
if (debug_underrun_trigger % 10 == 0)
|
||||
{
|
||||
DPRINTF(E_DBG, L_PLAYER, "Underrun debug mode: Dropping audio buffer length %zu\n", len);
|
||||
evbuffer_drain(evbuf, len);
|
||||
len = 0;
|
||||
}
|
||||
#endif
|
||||
input_buffer.bytes_written += len;
|
||||
ret = evbuffer_add_buffer(input_buffer.evbuf, evbuf);
|
||||
if (ret < 0)
|
||||
@ -778,16 +793,18 @@ input_seek(uint32_t item_id, int seek_ms)
|
||||
return commands_exec_sync(cmdbase, start, NULL, &cmdarg);
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
input_resume(uint32_t item_id, int seek_ms)
|
||||
{
|
||||
struct input_arg cmdarg;
|
||||
struct input_arg *cmdarg;
|
||||
|
||||
cmdarg.item_id = item_id;
|
||||
cmdarg.seek_ms = seek_ms;
|
||||
cmdarg.resume = true;
|
||||
CHECK_NULL(L_PLAYER, cmdarg = malloc(sizeof(struct input_arg)));
|
||||
|
||||
return commands_exec_sync(cmdbase, start, NULL, &cmdarg);
|
||||
cmdarg->item_id = item_id;
|
||||
cmdarg->seek_ms = seek_ms;
|
||||
cmdarg->resume = true;
|
||||
|
||||
commands_exec_async(cmdbase, start, cmdarg);
|
||||
}
|
||||
|
||||
void
|
||||
|
21
src/input.h
21
src/input.h
@ -196,17 +196,6 @@ input_buffer_full_cb(input_cb cb);
|
||||
int
|
||||
input_seek(uint32_t item_id, int seek_ms);
|
||||
|
||||
/*
|
||||
* Same as input_seek(), except if the item is already being read we don't do
|
||||
* anything (no flush & seek)
|
||||
*
|
||||
* @in item_id Queue item id to start playing
|
||||
* @in seek_ms Position to start playing
|
||||
* @return Actual seek position if seekable, 0 otherwise, -1 on error
|
||||
*/
|
||||
int
|
||||
input_resume(uint32_t item_id, int seek_ms);
|
||||
|
||||
/*
|
||||
* Same as input_seek(), just non-blocking and does not offer seek.
|
||||
*
|
||||
@ -215,6 +204,16 @@ input_resume(uint32_t item_id, int seek_ms);
|
||||
void
|
||||
input_start(uint32_t item_id);
|
||||
|
||||
/*
|
||||
* Same as input_seek(), but non-blocking and if the item is already being read
|
||||
* we don't do anything (no flush & seek)
|
||||
*
|
||||
* @in item_id Queue item id to start playing
|
||||
* @in seek_ms Position to start playing
|
||||
*/
|
||||
void
|
||||
input_resume(uint32_t item_id, int seek_ms);
|
||||
|
||||
/*
|
||||
* Stops the input and clears everything. Flushes the input buffer.
|
||||
*/
|
||||
|
@ -649,6 +649,9 @@ source_restart(void)
|
||||
|
||||
DPRINTF(E_DBG, L_PLAYER, "Restarting track: '%s' (id=%d, pos=%d)\n", pb_session.playing_now->path, pb_session.playing_now->item_id, pb_session.playing_now->pos_ms);
|
||||
|
||||
// Must be non-blocking, because otherwise we get a deadlock via the input
|
||||
// thread making a sync call to player_playback_start() -> pb_resume() ->
|
||||
// source_restart() -> input_resume()
|
||||
input_resume(pb_session.playing_now->item_id, pb_session.playing_now->pos_ms);
|
||||
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user