summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2017-04-06 19:32:35 -0400
committerMichael Sevakis <jethead71@rockbox.org>2017-04-06 19:32:35 -0400
commit5e4532c87cf747600ec1d7ae22531e89ecdce6a4 (patch)
treed65ce6f0c4fb0fd6b214ccf5f12414739f0160cd
parent1597c4fe343f4fee0821f590b592341a00362d85 (diff)
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
-rw-r--r--apps/pcmbuf.c31
-rw-r--r--apps/pcmbuf.h1
-rw-r--r--apps/playback.c7
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;
}