summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-08-15 23:52:42 +0200
committerwm4 <wm4@nowhere>2014-08-15 23:52:42 +0200
commit07aba86b37887c0aef7ea90af250fcf19062369b (patch)
tree0ea00b6aca7e6d04340182ab310128f9f8409031 /player
parent72ee9bb56c2f145569ca38e2066950fd7e6e8a4e (diff)
downloadmpv-07aba86b37887c0aef7ea90af250fcf19062369b.tar.bz2
mpv-07aba86b37887c0aef7ea90af250fcf19062369b.tar.xz
audio: add a mode to insert silence on severe A/V desync
This is probably a stupid idea, but it can't be denied that this actually allows playing video without larger desync, even if video is too slow.
Diffstat (limited to 'player')
-rw-r--r--player/audio.c21
-rw-r--r--player/core.h2
2 files changed, 19 insertions, 4 deletions
diff --git a/player/audio.c b/player/audio.c
index abb81f987c..3a691fed09 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -384,6 +384,10 @@ void fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
return; // try again next iteration
}
+ struct mp_audio out_format = {0};
+ ao_get_format(mpctx->ao, &out_format);
+ double play_samplerate = out_format.rate / opts->playback_speed;
+
// If audio is infinitely fast, somehow try keeping approximate A/V sync.
if (mpctx->audio_status == STATUS_PLAYING && ao_untimed(mpctx->ao) &&
mpctx->video_status != STATUS_EOF && mpctx->delay > 0)
@@ -402,6 +406,19 @@ void fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
playsize = MPMAX(1, playsize + skip); // silence will be prepended
}
+ if (opts->insert_silence) {
+ float S = 0.5;
+ if (!mpctx->paused && mpctx->audio_status == STATUS_PLAYING &&
+ mpctx->last_av_difference - mpctx->insert_silence > S)
+ mpctx->insert_silence += S;
+
+ if (mpctx->insert_silence > 0) {
+ int samples = MPMIN(playsize, play_samplerate * mpctx->insert_silence);
+ mp_audio_buffer_prepend_silence(mpctx->ao_buffer, samples);
+ mpctx->insert_silence -= samples / play_samplerate;
+ }
+ }
+
int status = AD_OK;
if (playsize > mp_audio_buffer_samples(mpctx->ao_buffer)) {
status = audio_decode(d_audio, mpctx->ao_buffer, playsize);
@@ -470,10 +487,6 @@ void fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
bool partial_fill = false;
int playflags = 0;
- struct mp_audio out_format = {0};
- ao_get_format(mpctx->ao, &out_format);
- double play_samplerate = out_format.rate / opts->playback_speed;
-
if (endpts != MP_NOPTS_VALUE) {
double samples = (endpts - written_audio_pts(mpctx) - mpctx->audio_delay)
* play_samplerate;
diff --git a/player/core.h b/player/core.h
index 594f105668..2530e8acd2 100644
--- a/player/core.h
+++ b/player/core.h
@@ -260,6 +260,8 @@ typedef struct MPContext {
double delay;
// AV sync: time until next frame should be shown
double time_frame;
+ // Optional/additional AV sync compensation if video is too slow.
+ double insert_silence;
// Set to true some time after a new frame has been shown, and it turns out
// that this frame was the last one before video ends.
bool playing_last_frame;