From 5e4532c87cf747600ec1d7ae22531e89ecdce6a4 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Thu, 6 Apr 2017 19:32:35 -0400 Subject: Fix a problem with audio not starting on a list of short files Forced audio start was left out when a third codec attempts to start a second track transition. Only one pending transition is allowed at a time. There wouldn't be enough PCM in the buffer to trigger audio playback and audio would just return without giving the pcm buffer a kick. Fixes FS#13100 - Player failed on short tracks Change-Id: I338b0b12022c591930451fd5ed26a2a73008835f --- apps/pcmbuf.c | 31 ++++++++++++++++++++++--------- apps/pcmbuf.h | 1 + apps/playback.c | 7 +++++++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c index 6e2c51c80a..773e97cce0 100644 --- a/apps/pcmbuf.c +++ b/apps/pcmbuf.c @@ -204,6 +204,13 @@ extern void audio_pcmbuf_sync_position(void); /**************************************/ +/* start PCM if callback says it's alright */ +static void start_audio_playback(void) +{ + if (audio_pcmbuf_may_play()) + pcmbuf_play_start(); +} + /* Return number of commited bytes in buffer (committed chunks count as a full chunk even if only partially filled) */ static size_t pcmbuf_unplayed_bytes(void) @@ -492,8 +499,8 @@ void * pcmbuf_request_buffer(int *count) trigger_cpu_boost(); /* If pre-buffered to the watermark, start playback */ - if (!pcmbuf_data_critical() && audio_pcmbuf_may_play()) - pcmbuf_play_start(); + if (!pcmbuf_data_critical()) + start_audio_playback(); } void *buf; @@ -672,15 +679,22 @@ void pcmbuf_monitor_track_change(bool monitor) void pcmbuf_start_track_change(enum pcm_track_change_type type) { + /* Commit all outstanding data before starting next track - tracks don't + comingle inside a single buffer chunk */ + commit_if_needed(COMMIT_ALL_DATA); + + if (type == TRACK_CHANGE_AUTO_PILEUP) + { + /* Fill might not have been above watermark */ + start_audio_playback(); + return; + } + #ifdef HAVE_CROSSFADE bool crossfade = false; #endif bool auto_skip = type != TRACK_CHANGE_MANUAL; - /* Commit all outstanding data before starting next track - tracks don't - comingle inside a single buffer chunk */ - commit_if_needed(COMMIT_ALL_DATA); - /* Update position key so that: 1) Positions are keyed to the track to which they belong for sync purposes @@ -695,9 +709,8 @@ void pcmbuf_start_track_change(enum pcm_track_change_type type) { crossfade_cancel(); - /* If end of all data, force playback */ - if (audio_pcmbuf_may_play()) - pcmbuf_play_start(); + /* Fill might not have been above watermark */ + start_audio_playback(); } #ifdef HAVE_CROSSFADE /* Determine whether this track change needs to crossfaded and how */ diff --git a/apps/pcmbuf.h b/apps/pcmbuf.h index e16f86174c..33422bbee5 100644 --- a/apps/pcmbuf.h +++ b/apps/pcmbuf.h @@ -43,6 +43,7 @@ enum pcm_track_change_type TRACK_CHANGE_NONE = 0, /* No track change pending */ TRACK_CHANGE_MANUAL, /* Manual change (from user) */ TRACK_CHANGE_AUTO, /* Automatic change (from codec) */ + TRACK_CHANGE_AUTO_PILEUP, /* Auto change during pending change */ TRACK_CHANGE_END_OF_DATA, /* Expect no more data (from codec) */ }; void pcmbuf_monitor_track_change(bool monitor); diff --git a/apps/playback.c b/apps/playback.c index 8a25375fec..54410ad2cc 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -2376,9 +2376,16 @@ static void audio_on_codec_complete(int status) Skipping: There was already a skip in progress, remember it and allow no further progress until the PCM from the previous song has finished + + This function will be reentered upon completing the existing + transition in order to do the one that was just tried (below) */ codec_skip_pending = true; codec_skip_status = status; + + /* PCM buffer must know; audio could still be filling and hasn't + yet reached the play watermark */ + pcmbuf_start_track_change(TRACK_CHANGE_AUTO_PILEUP); return; } -- cgit