1
mirror of https://github.com/mpv-player/mpv synced 2024-11-18 21:16:10 +01:00

af: factor channel filter insertion

Do this just like it has been done for the format filter.
This commit is contained in:
wm4 2013-03-23 16:03:17 +01:00
parent c866583e1e
commit 8a53b3f523

View File

@ -361,6 +361,43 @@ static int af_fix_format_conversion(struct af_stream *s,
return AF_OK; return AF_OK;
} }
// same as af_fix_format_conversion - only wrt. channels
static int af_fix_channels(struct af_stream *s, struct af_instance **p_af,
struct mp_audio in)
{
int rv;
struct af_instance *af = p_af ? *p_af : NULL;
struct mp_audio actual;
if (af) {
actual = af->prev ? *af->prev->data : s->input;
} else {
actual = *s->last->data;
}
if (actual.nch == in.nch)
return AF_FALSE;
struct af_instance *new;
if (af) {
new = af_prepend(s, af, "channels");
new->auto_inserted = true;
} else {
if (strcmp(s->last->info->name, "channels") == 0) {
new = s->last;
} else {
new = af_append(s, s->last, "channels");
new->auto_inserted = true;
}
}
if (new == NULL)
return AF_ERROR;
if (AF_OK != (rv = new->control(new, AF_CONTROL_CHANNELS, &in.nch)))
return rv;
if (AF_OK != (rv = new->control(new, AF_CONTROL_REINIT, &actual)))
return rv == AF_FALSE ? AF_ERROR : rv;
if (p_af)
*p_af = new;
return AF_OK;
}
// Warning: // Warning:
// A failed af_reinit() leaves the audio chain behind in a useless, broken // A failed af_reinit() leaves the audio chain behind in a useless, broken
// state (for example, format filters that were tentatively inserted stay // state (for example, format filters that were tentatively inserted stay
@ -391,23 +428,10 @@ int af_reinit(struct af_stream *s)
// Do auto insertion only if force is not specified // Do auto insertion only if force is not specified
if ((AF_INIT_TYPE_MASK & s->cfg.force) != AF_INIT_FORCE) { if ((AF_INIT_TYPE_MASK & s->cfg.force) != AF_INIT_FORCE) {
int progress = 0; int progress = 0;
// Insert channels filter if ((rv = af_fix_channels(s, &af, in)) < 0)
if ((af->prev ? af->prev->data->nch : s->input.nch) != in.nch) { return rv;
struct af_instance *new = NULL; if (rv == AF_OK)
// Create channels filter
if (NULL == (new = af_prepend(s, af, "channels")))
return AF_ERROR;
new->auto_inserted = true;
// Set number of output channels
if (AF_OK !=
(rv = new->control(new, AF_CONTROL_CHANNELS, &in.nch)))
return rv;
// Initialize channels filter
in = new->prev ? (*new->prev->data) : s->input;
if (AF_OK != (rv = new->control(new, AF_CONTROL_REINIT, &in)))
return rv;
progress = 1; progress = 1;
}
if ((rv = af_fix_format_conversion(s, &af, in)) < 0) if ((rv = af_fix_format_conversion(s, &af, in)) < 0)
return rv; return rv;
if (rv == AF_OK) if (rv == AF_OK)
@ -474,21 +498,12 @@ void af_uninit(struct af_stream *s)
*/ */
static int fixup_output_format(struct af_stream *s) static int fixup_output_format(struct af_stream *s)
{ {
// Check number of output channels fix if not OK if (s->output.nch != 0) {
// If needed always inserted last -> easy to screw up other filters
if (s->output.nch && s->last->data->nch != s->output.nch) {
struct af_instance *af = NULL; struct af_instance *af = NULL;
if (af_is_conversion_filter(s->last)) if (af_fix_channels(s, &af, s->output) == AF_OK) {
af = af_prepend(s, s->last, "channels"); if (AF_OK != af_reinit(s))
else return AF_ERROR;
af = af_append(s, s->last, "channels"); }
af->auto_inserted = true;
// Init the new filter
if (!af ||
(AF_OK != af->control(af, AF_CONTROL_CHANNELS, &(s->output.nch))))
return AF_ERROR;
if (AF_OK != af_reinit(s))
return AF_ERROR;
} }
if (s->output.format != AF_FORMAT_UNKNOWN) { if (s->output.format != AF_FORMAT_UNKNOWN) {