mirror of
https://github.com/owntone/owntone-server.git
synced 2025-03-30 17:23:44 -04:00
[player] Better fix for resuming playback af long pause (issue #766)
The fix in commit 3928ab6 broke resuming from an underrun, since it meant that pb_resume() would flush the input buffer. With this fix it is possible to call input_resume(), which will not flush the buffer if the source is already open. Also renamed some functions in player.c for consistency.
This commit is contained in:
parent
d7efd79e14
commit
3e9f8effa0
26
src/input.c
26
src/input.c
@ -113,7 +113,7 @@ struct input_arg
|
|||||||
{
|
{
|
||||||
uint32_t item_id;
|
uint32_t item_id;
|
||||||
int seek_ms;
|
int seek_ms;
|
||||||
struct input_metadata *metadata;
|
bool resume;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* --- Globals --- */
|
/* --- Globals --- */
|
||||||
@ -462,6 +462,16 @@ start(void *arg, int *retval)
|
|||||||
// If we are asked to start the item that is currently open we can just seek
|
// If we are asked to start the item that is currently open we can just seek
|
||||||
if (input_now_reading.open && cmdarg->item_id == input_now_reading.item_id)
|
if (input_now_reading.open && cmdarg->item_id == input_now_reading.item_id)
|
||||||
{
|
{
|
||||||
|
// When we resume we don't want to flush & seek, since that has either
|
||||||
|
// already been done, or it is not desired because we just filled the
|
||||||
|
// buffer after an underrun.
|
||||||
|
if (cmdarg->resume)
|
||||||
|
{
|
||||||
|
DPRINTF(E_DBG, L_PLAYER, "Resuming input read loop for item '%s' (item id %" PRIu32 ")\n", input_now_reading.path, input_now_reading.item_id);
|
||||||
|
*retval = cmdarg->seek_ms;
|
||||||
|
return COMMAND_END;
|
||||||
|
}
|
||||||
|
|
||||||
flush(&flags);
|
flush(&flags);
|
||||||
|
|
||||||
ret = seek(&input_now_reading, cmdarg->seek_ms);
|
ret = seek(&input_now_reading, cmdarg->seek_ms);
|
||||||
@ -763,6 +773,19 @@ input_seek(uint32_t item_id, int seek_ms)
|
|||||||
|
|
||||||
cmdarg.item_id = item_id;
|
cmdarg.item_id = item_id;
|
||||||
cmdarg.seek_ms = seek_ms;
|
cmdarg.seek_ms = seek_ms;
|
||||||
|
cmdarg.resume = false;
|
||||||
|
|
||||||
|
return commands_exec_sync(cmdbase, start, NULL, &cmdarg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
input_resume(uint32_t item_id, int seek_ms)
|
||||||
|
{
|
||||||
|
struct input_arg cmdarg;
|
||||||
|
|
||||||
|
cmdarg.item_id = item_id;
|
||||||
|
cmdarg.seek_ms = seek_ms;
|
||||||
|
cmdarg.resume = true;
|
||||||
|
|
||||||
return commands_exec_sync(cmdbase, start, NULL, &cmdarg);
|
return commands_exec_sync(cmdbase, start, NULL, &cmdarg);
|
||||||
}
|
}
|
||||||
@ -776,6 +799,7 @@ input_start(uint32_t item_id)
|
|||||||
|
|
||||||
cmdarg->item_id = item_id;
|
cmdarg->item_id = item_id;
|
||||||
cmdarg->seek_ms = 0;
|
cmdarg->seek_ms = 0;
|
||||||
|
cmdarg->resume = false;
|
||||||
|
|
||||||
commands_exec_async(cmdbase, start, cmdarg);
|
commands_exec_async(cmdbase, start, cmdarg);
|
||||||
}
|
}
|
||||||
|
11
src/input.h
11
src/input.h
@ -196,6 +196,17 @@ 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.
|
||||||
*
|
*
|
||||||
|
45
src/player.c
45
src/player.c
@ -612,19 +612,8 @@ source_stop(void)
|
|||||||
input_stop();
|
input_stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
source_start(struct player_source *ps)
|
|
||||||
{
|
|
||||||
if (!ps)
|
|
||||||
return;
|
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_PLAYER, "Opening next track: '%s' (id=%d)\n", ps->path, ps->item_id);
|
|
||||||
|
|
||||||
input_start(ps->item_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
source_restart(struct player_source *ps)
|
source_start(struct player_source *ps)
|
||||||
{
|
{
|
||||||
short flags;
|
short flags;
|
||||||
|
|
||||||
@ -638,6 +627,32 @@ source_restart(struct player_source *ps)
|
|||||||
return input_seek(ps->item_id, (int)ps->seek_ms);
|
return input_seek(ps->item_id, (int)ps->seek_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
source_next(struct player_source *ps)
|
||||||
|
{
|
||||||
|
if (!ps)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DPRINTF(E_DBG, L_PLAYER, "Opening next track: '%s' (id=%d)\n", ps->path, ps->item_id);
|
||||||
|
|
||||||
|
input_start(ps->item_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
source_restart(void)
|
||||||
|
{
|
||||||
|
if (!pb_session.playing_now)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_PLAYER, "Bug! source_restart called, but playing_now is null\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
input_resume(pb_session.playing_now->item_id, pb_session.playing_now->pos_ms);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------ Playback session upkeep ------------------------- */
|
/* ------------------------ Playback session upkeep ------------------------- */
|
||||||
|
|
||||||
@ -910,7 +925,7 @@ event_read_start_next()
|
|||||||
session_update_read_next(ps);
|
session_update_read_next(ps);
|
||||||
|
|
||||||
// Starts the input read loop
|
// Starts the input read loop
|
||||||
source_start(pb_session.source_list);
|
source_next(pb_session.source_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1604,7 +1619,7 @@ pb_session_start(struct db_queue_item *queue_item, uint32_t seek_ms)
|
|||||||
session_start(ps);
|
session_start(ps);
|
||||||
|
|
||||||
// Sets of opening of the new source
|
// Sets of opening of the new source
|
||||||
while ( (ret = source_restart(ps)) < 0)
|
while ( (ret = source_start(ps)) < 0)
|
||||||
{
|
{
|
||||||
// Couldn't start requested item, skip to next and remove failed item from queue
|
// Couldn't start requested item, skip to next and remove failed item from queue
|
||||||
item_id = ps->item_id;
|
item_id = ps->item_id;
|
||||||
@ -1665,7 +1680,7 @@ pb_resume(void)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = source_restart(pb_session.playing_now);
|
ret = source_restart();
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
pb_abort();
|
pb_abort();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user