From c00dc5c5c61ba185cc0e8698697cb9b365553a56 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 29 Jan 2016 22:44:35 +0100 Subject: 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. --- player/audio.c | 109 ++++++++++++++++++++++++++++++++------------------------- 1 file 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; } @@ -385,6 +346,60 @@ void reinit_audio_chain(struct MPContext *mpctx) return; +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); @@ -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 } -- cgit v1.2.3