[player] Add suspend/resume on underrun + misc fixing up

This commit is contained in:
ejurgensen 2017-01-15 23:23:36 +01:00
parent 18918ce489
commit aa8edeead4
2 changed files with 44 additions and 23 deletions

View File

@ -323,6 +323,20 @@ speaker_deselect_output(struct output_device *device)
volume_master_find(); volume_master_find();
} }
static void
seek_save(void)
{
int seek;
if (!cur_streaming)
return;
if (cur_streaming->media_kind & (MEDIA_KIND_MOVIE | MEDIA_KIND_PODCAST | MEDIA_KIND_AUDIOBOOK | MEDIA_KIND_TVSHOW))
{
seek = (cur_streaming->output_start - cur_streaming->stream_start) / 44100 * 1000;
db_file_seek_update(cur_streaming->id, seek);
}
}
int int
player_get_current_pos(uint64_t *pos, struct timespec *ts, int commit) player_get_current_pos(uint64_t *pos, struct timespec *ts, int commit)
@ -429,6 +443,9 @@ pb_timer_stop(void)
static void static void
playback_abort(void); playback_abort(void);
static void
playback_suspend(void);
static void static void
player_metadata_send(struct player_metadata *pmd); player_metadata_send(struct player_metadata *pmd);
@ -1124,8 +1141,8 @@ playback_write(void)
} }
else if (pb_writes_pending > PLAYER_WRITES_PENDING_MAX) else if (pb_writes_pending > PLAYER_WRITES_PENDING_MAX)
{ {
DPRINTF(E_LOG, L_PLAYER, "Source is not providing sufficient data, temporarily pausing playback\n"); DPRINTF(E_LOG, L_PLAYER, "Source is not providing sufficient data, temporarily suspending playback\n");
playback_abort(); // TODO Actually pause input + implement a resume event playback_suspend();
return; return;
} }
else else
@ -1706,6 +1723,21 @@ playback_abort(void)
metadata_purge(); metadata_purge();
} }
/* Internal routine for waiting when input buffer underruns */
static void
playback_suspend(void)
{
outputs_playback_stop();
pb_timer_stop();
status_update(PLAY_PAUSED);
seek_save();
input_buffer_full_cb(player_playback_start);
}
/* Actual commands, executed in the player thread */ /* Actual commands, executed in the player thread */
static enum command_state static enum command_state
get_status(void *arg, int *retval) get_status(void *arg, int *retval)
@ -2011,7 +2043,6 @@ playback_start_item(void *arg, int *retval)
return COMMAND_END; return COMMAND_END;
} }
metadata_trigger(1); metadata_trigger(1);
/* Start sessions on selected devices */ /* Start sessions on selected devices */
@ -2080,14 +2111,14 @@ playback_start(void *arg, int *retval)
enum command_state cmd_state; enum command_state cmd_state;
if (player_state == PLAY_STOPPED) if (player_state == PLAY_STOPPED)
{ {
// Start playback of first item in queue // Start playback of first item in queue
queue_item = db_queue_fetch_bypos(0, shuffle); queue_item = db_queue_fetch_bypos(0, shuffle);
if (!queue_item) if (!queue_item)
{ {
*retval = -1; *retval = -1;
return COMMAND_END; return COMMAND_END;
} }
} }
cmd_state = playback_start_item(queue_item, retval); cmd_state = playback_start_item(queue_item, retval);
@ -2263,8 +2294,6 @@ playback_seek_bh(void *arg, int *retval)
static enum command_state static enum command_state
playback_pause_bh(void *arg, int *retval) playback_pause_bh(void *arg, int *retval)
{ {
int ret;
if (cur_streaming->data_kind == DATA_KIND_HTTP if (cur_streaming->data_kind == DATA_KIND_HTTP
|| cur_streaming->data_kind == DATA_KIND_PIPE) || cur_streaming->data_kind == DATA_KIND_PIPE)
{ {
@ -2276,11 +2305,7 @@ playback_pause_bh(void *arg, int *retval)
} }
status_update(PLAY_PAUSED); status_update(PLAY_PAUSED);
if (cur_streaming->media_kind & (MEDIA_KIND_MOVIE | MEDIA_KIND_PODCAST | MEDIA_KIND_AUDIOBOOK | MEDIA_KIND_TVSHOW)) seek_save();
{
ret = (cur_streaming->output_start - cur_streaming->stream_start) / 44100 * 1000;
db_file_save_seek(cur_streaming->id, ret);
}
*retval = 0; *retval = 0;
return COMMAND_END; return COMMAND_END;
@ -2787,18 +2812,15 @@ player_get_icy_artwork_url(uint32_t id)
/* /*
* Starts/resumes playback * Starts/resumes playback
* *
* Depending on the player state, this will either resume playing the current item (player is paused) * Depending on the player state, this will either resume playing the current
* or begin playing the queue from the beginning. * item (player is paused) or begin playing the queue from the beginning.
* *
* If shuffle is set, the queue is reshuffled prior to starting playback. * If shuffle is set, the queue is reshuffled prior to starting playback.
* *
* If a pointer is given as argument "itemid", its value will be set to the playing item dbmfi-id.
*
* @param *id if not NULL, will be set to the playing item dbmfi-id
* @return 0 if successful, -1 if an error occurred * @return 0 if successful, -1 if an error occurred
*/ */
int int
player_playback_start() player_playback_start(void)
{ {
int ret; int ret;
@ -2807,14 +2829,13 @@ player_playback_start()
} }
/* /*
* Starts playback with the media item at the given index of the play-queue. * Starts/resumes playback of the given queue_item
* *
* If shuffle is set, the queue is reshuffled prior to starting playback. * If shuffle is set, the queue is reshuffled prior to starting playback.
* *
* If a pointer is given as argument "itemid", its value will be set to the playing item id. * If a pointer is given as argument "itemid", its value will be set to the playing item id.
* *
* @param index the index of the item in the play-queue * @param queue_item to start playing
* @param *id if not NULL, will be set to the playing item id
* @return 0 if successful, -1 if an error occurred * @return 0 if successful, -1 if an error occurred
*/ */
int int

View File

@ -90,7 +90,7 @@ int
player_speaker_set(uint64_t *ids); player_speaker_set(uint64_t *ids);
int int
player_playback_start(); player_playback_start(void);
int int
player_playback_start_byitem(struct db_queue_item *queue_item); player_playback_start_byitem(struct db_queue_item *queue_item);