mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-27 14:43:21 -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 INPUT_OPEN_TIMEOUT 600
|
||||||
|
|
||||||
//#define DEBUG_INPUT 1
|
//#define DEBUG_INPUT 1
|
||||||
|
// For testing http stream underruns
|
||||||
|
//#define DEBUG_UNDERRUN 1
|
||||||
|
|
||||||
extern struct input_definition input_file;
|
extern struct input_definition input_file;
|
||||||
extern struct input_definition input_http;
|
extern struct input_definition input_http;
|
||||||
@ -142,6 +144,9 @@ static struct event *input_open_timeout_ev;
|
|||||||
#ifdef DEBUG_INPUT
|
#ifdef DEBUG_INPUT
|
||||||
static size_t debug_elapsed;
|
static size_t debug_elapsed;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef DEBUG_UNDERRUN
|
||||||
|
int debug_underrun_trigger;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------- MISC HELPERS ----------------------------- */
|
/* ------------------------------- MISC HELPERS ----------------------------- */
|
||||||
@ -578,6 +583,16 @@ input_write(struct evbuffer *evbuf, struct media_quality *quality, short flags)
|
|||||||
if (evbuf)
|
if (evbuf)
|
||||||
{
|
{
|
||||||
len = evbuffer_get_length(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;
|
input_buffer.bytes_written += len;
|
||||||
ret = evbuffer_add_buffer(input_buffer.evbuf, evbuf);
|
ret = evbuffer_add_buffer(input_buffer.evbuf, evbuf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -778,16 +793,18 @@ input_seek(uint32_t item_id, int seek_ms)
|
|||||||
return commands_exec_sync(cmdbase, start, NULL, &cmdarg);
|
return commands_exec_sync(cmdbase, start, NULL, &cmdarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
input_resume(uint32_t item_id, int seek_ms)
|
input_resume(uint32_t item_id, int seek_ms)
|
||||||
{
|
{
|
||||||
struct input_arg cmdarg;
|
struct input_arg *cmdarg;
|
||||||
|
|
||||||
cmdarg.item_id = item_id;
|
CHECK_NULL(L_PLAYER, cmdarg = malloc(sizeof(struct input_arg)));
|
||||||
cmdarg.seek_ms = seek_ms;
|
|
||||||
cmdarg.resume = true;
|
|
||||||
|
|
||||||
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
|
void
|
||||||
|
21
src/input.h
21
src/input.h
@ -196,17 +196,6 @@ input_buffer_full_cb(input_cb cb);
|
|||||||
int
|
int
|
||||||
input_seek(uint32_t item_id, int seek_ms);
|
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.
|
* 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
|
void
|
||||||
input_start(uint32_t item_id);
|
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.
|
* 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);
|
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);
|
input_resume(pb_session.playing_now->item_id, pb_session.playing_now->pos_ms);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user