mirror of https://github.com/mpv-player/mpv
core: audio: cut audio writes at end of timeline part
Cut audio data written to AO at the point where current timeline part ends (before, AO buffers were always completely filled, but playback of the "extra" audio was then cut short by resetting the AO when switching timeline parts). This doesn't make much difference for current playback behavior, but will be used by timeline support for audio-only files and is necessary for future encoding support where "playback" of written audio cannot be aborted later.
This commit is contained in:
parent
968154ba77
commit
52f11f73b1
49
mplayer.c
49
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): =========================
|
||||
|
|
Loading…
Reference in New Issue