// Drop audio buffer and reinit it (after format change) // Returns whether the format was valid at all. static bool reinit_audio_buffer(struct dec_audio *da) { if (!mp_audio_config_valid(&da->decoded)) { MP_ERR(da, "Audio decoder did not specify audio " "format, or requested an unsupported configuration!\n"); return false; } mp_audio_buffer_reinit(da->decode_buffer, &da->decoded); return true; }
// Drop audio buffer and reinit it (after format change) // Returns whether the format was valid at all. static bool reinit_audio_buffer(struct dec_audio *da) { if (!mp_audio_config_valid(&da->decoded)) { mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Audio decoder did not specify audio " "format, or requested an unsupported configuration!\n"); return false; } mp_audio_buffer_reinit(da->decode_buffer, &da->decoded); mp_audio_buffer_preallocate_min(da->decode_buffer, DECODE_BUFFER_SAMPLES); return true; }
static int control(struct af_instance *af, int cmd, void *arg) { struct priv *p = af->priv; switch (cmd) { case AF_CONTROL_REINIT: { struct mp_audio *in = arg; struct mp_audio orig_in = *in; struct mp_audio *out = af->data; if (af_to_avformat(in->format) == AV_SAMPLE_FMT_NONE) mp_audio_set_format(in, AF_FORMAT_FLOAT); // Removing this requires fixing AVFrame.data vs. AVFrame.extended_data if (in->channels.num > AV_NUM_DATA_POINTERS) return AF_ERROR; if (!mp_chmap_is_lavc(&in->channels)) mp_chmap_reorder_to_lavc(&in->channels); // will always work if (!recreate_graph(af, in)) return AF_ERROR; AVFilterLink *l_out = p->out->inputs[0]; out->rate = l_out->sample_rate; mp_audio_set_format(out, af_from_avformat(l_out->format)); struct mp_chmap out_cm; mp_chmap_from_lavc(&out_cm, l_out->channel_layout); mp_audio_set_channels(out, &out_cm); if (!mp_audio_config_valid(out) || out->channels.num > AV_NUM_DATA_POINTERS) return AF_ERROR; p->timebase_out = l_out->time_base; return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE; } case AF_CONTROL_GET_METADATA: if (p->metadata) { *(struct mp_tags *)arg = *p->metadata; return CONTROL_OK; } return CONTROL_NA; case AF_CONTROL_RESET: reset(af); return AF_OK; } return AF_UNKNOWN; }
/* Decode packets until we know the audio format. Then reinit the buffer. * Returns AD_OK on success, negative AD_* code otherwise. * Also returns AD_OK if already initialized (and does nothing). */ int initial_audio_decode(struct dec_audio *da) { while (!mp_audio_config_valid(&da->decoded)) { if (da->decoded.samples > 0) return AD_ERR; // invalid format, rather than uninitialized int ret = da->ad_driver->decode_packet(da); if (ret < 0) return ret; } if (mp_audio_buffer_samples(da->decode_buffer) > 0) // avoid accidental flush return AD_OK; return reinit_audio_buffer(da) ? AD_OK : AD_ERR; }
static int control(struct af_instance *af, int cmd, void *arg) { struct priv *p = af->priv; switch (cmd) { case AF_CONTROL_REINIT: { struct mp_audio *in = arg; struct mp_audio orig_in = *in; struct mp_audio *out = af->data; if (af_to_avformat(in->format) == AV_SAMPLE_FMT_NONE) mp_audio_set_format(in, AF_FORMAT_FLOAT); if (!mp_chmap_is_lavc(&in->channels)) mp_chmap_reorder_to_lavc(&in->channels); // will always work if (!recreate_graph(af, in)) return AF_ERROR; AVFilterLink *l_out = p->out->inputs[0]; out->rate = l_out->sample_rate; mp_audio_set_format(out, af_from_avformat(l_out->format)); struct mp_chmap out_cm; mp_chmap_from_lavc(&out_cm, l_out->channel_layout); if (!out_cm.num || out_cm.num != l_out->channels) mp_chmap_from_channels(&out_cm, l_out->channels); mp_audio_set_channels(out, &out_cm); if (!mp_audio_config_valid(out)) return AF_ERROR; p->timebase_out = l_out->time_base; // Blatantly incorrect; we don't know what the filters do. af->mul = out->rate / (double)in->rate; return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE; } } return AF_UNKNOWN; }