summaryrefslogtreecommitdiffstats
path: root/mplayer.c
diff options
context:
space:
mode:
authorUoti Urpala <uau@mplayer2.org>2011-04-07 21:17:51 +0300
committerUoti Urpala <uau@mplayer2.org>2011-04-07 21:17:51 +0300
commit52f11f73b1b645290679a460329585ded512d8ca (patch)
tree257850240c7640b8c53d23710926bf9d0b4a2a2b /mplayer.c
parent968154ba77f8e8974d6dd36d1109a473b3ff5b6c (diff)
downloadmpv-52f11f73b1b645290679a460329585ded512d8ca.tar.bz2
mpv-52f11f73b1b645290679a460329585ded512d8ca.tar.xz
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.
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): =========================