player: unrangle one aspect of audio EOF handling

For some reason, the buffered_audio variable was used to "cache" the
ao_get_delay() result. But I can't really see any reason why this should
be done, and it just seems to complicate everything.

One reason might be that the value should be checked only if the AO
buffers have been recently filled (as otherwise the delay could go low
and trigger an accidental EOF condition), but this didn't work anyway,
since buffered_audio is set from ao_get_delay() anyway at a later point
if it was unset. And in both cases, the value is used _after_ filling
the audio buffers anyway.

Simplify it. Also, move the audio EOF condition to a separate function.
(Note that ao_eof_reached() probably could/should whether the last
ao_play() call had AOPLAY_FINAL_CHUNK set to avoid accidental EOF on
underflows, but for now let's keep the code equivalent.)
This commit is contained in:
wm4 2014-04-17 23:48:09 +02:00
parent 0ab3482f73
commit 5059039c95
4 changed files with 15 additions and 14 deletions

View File

@ -327,6 +327,11 @@ void ao_drain(struct ao *ao)
}
}
bool ao_eof_reached(struct ao *ao)
{
return ao_get_delay(ao) < AO_EOF_DELAY;
}
bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
struct mp_chmap *map)
{

View File

@ -49,11 +49,6 @@ typedef struct ao_control_vol {
float right;
} ao_control_vol_t;
// If ao_get_delay() reaches this value after ao_play() was called with the
// AOPLAY_FINAL_CHUNK flag set, the playback core expects that the audio has
// all been played.
#define AO_EOF_DELAY 0.05
struct ao;
struct mpv_global;
struct input_ctx;
@ -77,5 +72,6 @@ void ao_reset(struct ao *ao);
void ao_pause(struct ao *ao);
void ao_resume(struct ao *ao);
void ao_drain(struct ao *ao);
bool ao_eof_reached(struct ao *ao);
#endif /* MPLAYER_AUDIO_OUT_H */

View File

@ -27,6 +27,11 @@
// Minimum buffer size in seconds.
#define MIN_BUFFER 0.2
// If ao_get_delay() reaches this value after ao_play() was called with the
// AOPLAY_FINAL_CHUNK flag set, the playback core expects that the audio has
// all been played.
#define AO_EOF_DELAY 0.05
/* global data used by ao.c and ao drivers */
struct ao {
int samplerate;

View File

@ -961,7 +961,6 @@ void run_playloop(struct MPContext *mpctx)
handle_cursor_autohide(mpctx);
}
double buffered_audio = -1;
while (mpctx->d_video) { // never loops, for "break;" only
struct vo *vo = mpctx->video_out;
update_fps(mpctx);
@ -1032,7 +1031,7 @@ void run_playloop(struct MPContext *mpctx)
mpctx->time_frame -= get_relative_time(mpctx);
double audio_pts = playing_audio_pts(mpctx);
if (full_audio_buffers && !mpctx->restart_playback) {
buffered_audio = ao_get_delay(mpctx->ao);
double buffered_audio = ao_get_delay(mpctx->ao);
MP_TRACE(mpctx, "audio delay=%f\n", buffered_audio);
if (opts->autosync) {
@ -1184,17 +1183,13 @@ void run_playloop(struct MPContext *mpctx)
}
if (!video_left)
mpctx->restart_playback = false;
if (mpctx->d_audio && buffered_audio == -1)
buffered_audio = mpctx->paused ? 0 : ao_get_delay(mpctx->ao);
update_osd_msg(mpctx);
if (!video_left && (!mpctx->paused || was_restart)) {
double a_pos = 0;
if (mpctx->d_audio) {
a_pos = (written_audio_pts(mpctx) -
mpctx->opts->playback_speed * buffered_audio);
}
if (mpctx->d_audio)
a_pos = playing_audio_pts(mpctx);
mpctx->playback_pts = a_pos;
if (was_restart)
mp_notify(mpctx, MPV_EVENT_PLAYBACK_RESTART, NULL);
@ -1219,7 +1214,7 @@ void run_playloop(struct MPContext *mpctx)
* buffered.
*/
if ((mpctx->d_audio || mpctx->d_video) && !audio_left && !video_left
&& (opts->gapless_audio || buffered_audio < AO_EOF_DELAY)
&& (opts->gapless_audio || (mpctx->d_audio && ao_eof_reached(mpctx->ao)))
&& (!mpctx->paused || was_restart)) {
if (end_is_chapter) {
mp_seek(mpctx, (struct seek_params){