summaryrefslogtreecommitdiffstats
path: root/mplayer.c
diff options
context:
space:
mode:
Diffstat (limited to 'mplayer.c')
-rw-r--r--mplayer.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/mplayer.c b/mplayer.c
index 2afbbbb821..ec42de4548 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -2378,9 +2378,12 @@ static int fill_audio_out_buffers(struct MPContext *mpctx)
double tt;
int playsize;
int playflags=0;
- int audio_eof=0;
+ bool audio_eof = false;
+ bool partial_fill = false;
bool format_change = false;
sh_audio_t * const sh_audio = mpctx->sh_audio;
+ bool modifiable_audio_format = !(ao_data.format & AF_FORMAT_SPECIAL_MASK);
+ int unitsize = ao_data.channels * af_fmt2bits(ao_data.format) / 8;
current_module="play_audio";
@@ -2406,7 +2409,7 @@ static int fill_audio_out_buffers(struct MPContext *mpctx)
current_module="decode_audio";
t = GetTimer();
- if (!opts->initial_audio_sync || (ao_data.format & AF_FORMAT_SPECIAL_MASK))
+ if (!opts->initial_audio_sync || !modifiable_audio_format)
mpctx->syncing_audio = false;
int res;
@@ -2418,23 +2421,33 @@ static int fill_audio_out_buffers(struct MPContext *mpctx)
if (res == -2)
format_change = true;
else if (res == ASYNC_PLAY_DONE)
- return 1;
- else if (mpctx->d_audio->eof) {
- audio_eof = 1;
- int unitsize = ao_data.channels * af_fmt2bits(ao_data.format) / 8;
- if (sh_audio->a_out_buffer_len < unitsize)
- return 0;
- }
+ return 0;
+ else if (mpctx->d_audio->eof)
+ audio_eof = true;
}
t = GetTimer() - t;
tt = t*0.000001f; audio_time_usage+=tt;
+ if (mpctx->timeline && modifiable_audio_format) {
+ double endpts = mpctx->timeline[mpctx->timeline_part + 1].start;
+ double bytes = (endpts - written_audio_pts(mpctx) + audio_delay)
+ * ao_data.bps / opts->playback_speed;
+ if (playsize > bytes) {
+ playsize = FFMAX(bytes, 0);
+ playflags |= AOPLAY_FINAL_CHUNK;
+ audio_eof = true;
+ partial_fill = true;
+ }
+ }
+
if (playsize > sh_audio->a_out_buffer_len) {
+ partial_fill = true;
playsize = sh_audio->a_out_buffer_len;
if (audio_eof)
playflags |= AOPLAY_FINAL_CHUNK;
}
+ playsize -= playsize % unitsize;
if (!playsize)
- return 1;
+ return partial_fill && audio_eof ? -2 : -partial_fill;
// play audio:
current_module="play_audio";
@@ -2464,13 +2477,14 @@ static int fill_audio_out_buffers(struct MPContext *mpctx)
if (format_change) {
uninit_player(mpctx, INITIALIZED_AO);
reinit_audio_chain(mpctx);
+ return -1;
}
- return 1;
+ return -partial_fill;
}
static int sleep_until_near_frame(struct MPContext *mpctx, float *time_frame,
- float *aq_sleep_time)
+ bool sync_to_audio, float *aq_sleep_time)
{
struct MPOpts *opts = &mpctx->opts;
double audio_limit = 2;
@@ -2481,7 +2495,7 @@ static int sleep_until_near_frame(struct MPContext *mpctx, float *time_frame,
*time_frame -= get_relative_time(mpctx); // reset timer
- if (mpctx->sh_audio && !mpctx->d_audio->eof) {
+ if (sync_to_audio) {
float delay = mpctx->audio_out->get_delay();
mp_dbg(MSGT_AVSYNC, MSGL_DBG2, "delay=%f\n", delay);
@@ -3310,6 +3324,7 @@ static void run_playloop(struct MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
float aq_sleep_time = 0;
+ bool full_audio_buffers = false;
if (opts->chapterrange[1] > 0) {
int cur_chapter = get_current_chapter(mpctx);
@@ -3326,11 +3341,14 @@ static void run_playloop(struct MPContext *mpctx)
/*========================== PLAY AUDIO ============================*/
if (mpctx->sh_audio && !mpctx->paused
- && (!mpctx->restart_playback || !mpctx->sh_video))
- if (!fill_audio_out_buffers(mpctx))
+ && (!mpctx->restart_playback || !mpctx->sh_video)) {
+ int status = fill_audio_out_buffers(mpctx);
+ full_audio_buffers = status >= 0;
+ if (status == -2)
// at eof, all audio at least written to ao
if (!mpctx->sh_video)
mpctx->stop_play = AT_END_OF_FILE;
+ }
if (!mpctx->sh_video) {
@@ -3413,6 +3431,7 @@ static void run_playloop(struct MPContext *mpctx)
bool frame_time_remaining = sleep_until_near_frame(mpctx,
&mpctx->time_frame,
+ full_audio_buffers,
&aq_sleep_time);
//====================== FLIP PAGE (VIDEO BLT): =========================