mirror of https://github.com/mpv-player/mpv
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.
This commit is contained in:
parent
c5a48c6332
commit
c00dc5c5c6
109
player/audio.c
109
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 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;
|
struct ao_chain *ao_c = mpctx->ao_chain;
|
||||||
|
assert(ao_c);
|
||||||
if (!ao_c) {
|
struct af_stream *afs = ao_c->af;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mp_audio in_format = ao_c->input_format;
|
struct mp_audio in_format = ao_c->input_format;
|
||||||
|
|
||||||
|
@ -294,7 +254,8 @@ void reinit_audio_chain(struct MPContext *mpctx)
|
||||||
uninit_audio_out(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};
|
afs->output = (struct mp_audio){0};
|
||||||
if (mpctx->ao) {
|
if (mpctx->ao) {
|
||||||
|
@ -355,7 +316,7 @@ void reinit_audio_chain(struct MPContext *mpctx)
|
||||||
goto init_error;
|
goto init_error;
|
||||||
reset_audio_state(mpctx);
|
reset_audio_state(mpctx);
|
||||||
ao_c->input_format = (struct mp_audio){0};
|
ao_c->input_format = (struct mp_audio){0};
|
||||||
reinit_audio_chain(mpctx);
|
mpctx->sleeptime = 0; // reinit with new format next time
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,6 +346,60 @@ void reinit_audio_chain(struct MPContext *mpctx)
|
||||||
|
|
||||||
return;
|
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:
|
init_error:
|
||||||
uninit_audio_chain(mpctx);
|
uninit_audio_chain(mpctx);
|
||||||
uninit_audio_out(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);
|
int r = decode_new_frame(mpctx->ao_chain);
|
||||||
if (r == AD_WAIT)
|
if (r == AD_WAIT)
|
||||||
return; // continue later when new data is available
|
return; // continue later when new data is available
|
||||||
reinit_audio_chain(mpctx);
|
reinit_audio_filters_and_output(mpctx);
|
||||||
mpctx->sleeptime = 0;
|
mpctx->sleeptime = 0;
|
||||||
return; // try again next iteration
|
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)
|
if (mpctx->opts->gapless_audio < 1)
|
||||||
uninit_audio_out(mpctx);
|
uninit_audio_out(mpctx);
|
||||||
reinit_audio_chain(mpctx);
|
reinit_audio_filters_and_output(mpctx);
|
||||||
mpctx->sleeptime = 0;
|
mpctx->sleeptime = 0;
|
||||||
return; // retry on next iteration
|
return; // retry on next iteration
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue