summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-01-29 22:44:35 +0100
committerwm4 <wm4@nowhere>2016-01-29 22:44:35 +0100
commitc00dc5c5c61ba185cc0e8698697cb9b365553a56 (patch)
tree2799f284326e6feecd8cd3798f38891ed6700e8c
parentc5a48c63321de00bb8cb6b91a8d6ed22caa3b36f (diff)
downloadmpv-c00dc5c5c61ba185cc0e8698697cb9b365553a56.tar.bz2
mpv-c00dc5c5c61ba185cc0e8698697cb9b365553a56.tar.xz
audio: refactor: separate audio init and filter/output init
Before this commit, reinit_audio_chain() did 2 things: create all the management data structures and initialize the decoder, and handling lazy filter/output init (as well as dealing with format changes). For the second purpose, it could be called multiple times (even though it wasn't really idempotent). This was pretty weird, so make them separate functions. The new function is actually idempotent too. It also turns out the reinit functions don't have to call themselves recursively for the spdif PCM fallback.
-rw-r--r--player/audio.c109
1 files changed, 62 insertions, 47 deletions
diff --git a/player/audio.c b/player/audio.c
index e9320d5117..7e1137590e 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -231,52 +231,12 @@ void uninit_audio_chain(struct MPContext *mpctx)
}
}
-void reinit_audio_chain(struct MPContext *mpctx)
+static void reinit_audio_filters_and_output(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
- struct track *track = mpctx->current_track[0][STREAM_AUDIO];
- struct sh_stream *sh = track ? track->stream : NULL;
- if (!sh) {
- uninit_audio_out(mpctx);
- goto no_audio;
- }
-
- mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
-
struct ao_chain *ao_c = mpctx->ao_chain;
-
- if (!ao_c) {
- assert(!ao_c);
- ao_c = talloc_zero(NULL, struct ao_chain);
- mpctx->ao_chain = ao_c;
- ao_c->log = mpctx->log;
- ao_c->af = af_new(mpctx->global);
- ao_c->af->replaygain_data = sh->codec->replaygain_data;
- ao_c->spdif_passthrough = true;
- ao_c->pts = MP_NOPTS_VALUE;
- ao_c->ao = mpctx->ao;
-
- struct dec_audio *d_audio = talloc_zero(NULL, struct dec_audio);
- d_audio->log = mp_log_new(d_audio, mpctx->log, "!ad");
- d_audio->global = mpctx->global;
- d_audio->opts = opts;
- d_audio->header = sh;
-
- track->d_audio = d_audio;
- ao_c->audio_src = d_audio;
-
- d_audio->try_spdif = ao_c->spdif_passthrough;
- ao_c->ao_buffer = mp_audio_buffer_create(NULL);
- if (!audio_init_best_codec(d_audio))
- goto init_error;
- reset_audio_state(mpctx);
-
- if (mpctx->ao) {
- struct mp_audio fmt;
- ao_get_format(mpctx->ao, &fmt);
- mp_audio_buffer_reinit(ao_c->ao_buffer, &fmt);
- }
- }
+ assert(ao_c);
+ struct af_stream *afs = ao_c->af;
struct mp_audio in_format = ao_c->input_format;
@@ -294,7 +254,8 @@ void reinit_audio_chain(struct MPContext *mpctx)
uninit_audio_out(mpctx);
}
- struct af_stream *afs = ao_c->af;
+ if (mpctx->ao && mp_audio_config_equals(&in_format, &afs->input))
+ return;
afs->output = (struct mp_audio){0};
if (mpctx->ao) {
@@ -355,7 +316,7 @@ void reinit_audio_chain(struct MPContext *mpctx)
goto init_error;
reset_audio_state(mpctx);
ao_c->input_format = (struct mp_audio){0};
- reinit_audio_chain(mpctx);
+ mpctx->sleeptime = 0; // reinit with new format next time
return;
}
@@ -388,6 +349,60 @@ void reinit_audio_chain(struct MPContext *mpctx)
init_error:
uninit_audio_chain(mpctx);
uninit_audio_out(mpctx);
+ struct track *track = mpctx->current_track[0][STREAM_AUDIO];
+ if (track)
+ error_on_track(mpctx, track);
+}
+
+void reinit_audio_chain(struct MPContext *mpctx)
+{
+ assert(!mpctx->ao_chain);
+
+ struct track *track = mpctx->current_track[0][STREAM_AUDIO];
+ struct sh_stream *sh = track ? track->stream : NULL;
+ if (!sh) {
+ uninit_audio_out(mpctx);
+ goto no_audio;
+ }
+
+ mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
+
+ struct ao_chain *ao_c = ao_c = talloc_zero(NULL, struct ao_chain);
+ mpctx->ao_chain = ao_c;
+ ao_c->log = mpctx->log;
+ ao_c->af = af_new(mpctx->global);
+ ao_c->af->replaygain_data = sh->codec->replaygain_data;
+ ao_c->spdif_passthrough = true;
+ ao_c->pts = MP_NOPTS_VALUE;
+ ao_c->ao = mpctx->ao;
+
+ struct dec_audio *d_audio = talloc_zero(NULL, struct dec_audio);
+ d_audio->log = mp_log_new(d_audio, mpctx->log, "!ad");
+ d_audio->global = mpctx->global;
+ d_audio->opts = mpctx->opts;
+ d_audio->header = sh;
+
+ track->d_audio = d_audio;
+ ao_c->audio_src = d_audio;
+
+ d_audio->try_spdif = ao_c->spdif_passthrough;
+ ao_c->ao_buffer = mp_audio_buffer_create(NULL);
+ if (!audio_init_best_codec(d_audio))
+ goto init_error;
+ reset_audio_state(mpctx);
+
+ if (mpctx->ao) {
+ struct mp_audio fmt;
+ ao_get_format(mpctx->ao, &fmt);
+ mp_audio_buffer_reinit(ao_c->ao_buffer, &fmt);
+ }
+
+ mpctx->sleeptime = 0;
+ return;
+
+init_error:
+ uninit_audio_chain(mpctx);
+ uninit_audio_out(mpctx);
no_audio:
if (track)
error_on_track(mpctx, track);
@@ -668,7 +683,7 @@ void fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
int r = decode_new_frame(mpctx->ao_chain);
if (r == AD_WAIT)
return; // continue later when new data is available
- reinit_audio_chain(mpctx);
+ reinit_audio_filters_and_output(mpctx);
mpctx->sleeptime = 0;
return; // try again next iteration
}
@@ -733,7 +748,7 @@ void fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
*/
if (mpctx->opts->gapless_audio < 1)
uninit_audio_out(mpctx);
- reinit_audio_chain(mpctx);
+ reinit_audio_filters_and_output(mpctx);
mpctx->sleeptime = 0;
return; // retry on next iteration
}