/* Try to get at least minsamples decoded+filtered samples in outbuf * (total length including possible existing data). * Return 0 on success, -1 on error/EOF (not distinguidaed). * In the former case outbuf has at least minsamples buffered on return. * In case of EOF/error it might or might not be. */ int audio_decode(struct dec_audio *d_audio, struct mp_audio_buffer *outbuf, int minsamples) { // Indicates that a filter seems to be buffering large amounts of data int huge_filter_buffer = 0; // Decoded audio must be cut at boundaries of this many samples // (Note: the reason for this is unknown, possibly a refactoring artifact) int unitsize = 16; /* Filter output size will be about filter_multiplier times input size. * If some filter buffers audio in big blocks this might only hold * as average over time. */ double filter_multiplier = af_calc_filter_multiplier(d_audio->afilter); int prev_buffered = -1; int res = 0; MP_STATS(d_audio, "start audio"); while (res >= 0 && minsamples >= 0) { int buffered = mp_audio_buffer_samples(outbuf); if (minsamples < buffered || buffered == prev_buffered) break; prev_buffered = buffered; int decsamples = (minsamples - buffered) / filter_multiplier; // + some extra for possible filter buffering decsamples += unitsize << 5; if (huge_filter_buffer) { /* Some filter must be doing significant buffering if the estimated * input length didn't produce enough output from filters. * Feed the filters 250 samples at a time until we have enough * output. Very small amounts could make filtering inefficient while * large amounts can make mpv demux the file unnecessarily far ahead * to get audio data and buffer video frames in memory while doing * so. However the performance impact of either is probably not too * significant as long as the value is not completely insane. */ decsamples = 250; } /* if this iteration does not fill buffer, we must have lots * of buffering in filters */ huge_filter_buffer = 1; res = filter_n_bytes(d_audio, outbuf, decsamples); } MP_STATS(d_audio, "end audio"); return res; }
static int filter_n_bytes(sh_audio_t *sh, struct bstr *outbuf, int len) { assert(len-1 + sh->audio_out_minsize <= sh->a_buffer_size); int error = 0; // Decode more bytes if needed int old_samplerate = sh->samplerate; int old_channels = sh->channels; int old_sample_format = sh->sample_format; while (sh->a_buffer_len < len) { unsigned char *buf = sh->a_buffer + sh->a_buffer_len; int minlen = len - sh->a_buffer_len; int maxlen = sh->a_buffer_size - sh->a_buffer_len; int ret = sh->ad_driver->decode_audio(sh, buf, minlen, maxlen); int format_change = sh->samplerate != old_samplerate || sh->channels != old_channels || sh->sample_format != old_sample_format; if (ret <= 0 || format_change) { error = format_change ? -2 : -1; // samples from format-changing call get discarded too len = sh->a_buffer_len; break; } sh->a_buffer_len += ret; } // Filter af_data_t filter_input = { .audio = sh->a_buffer, .len = len, .rate = sh->samplerate, .nch = sh->channels, .format = sh->sample_format }; af_fix_parameters(&filter_input); af_data_t *filter_output = af_play(sh->afilter, &filter_input); if (!filter_output) return -1; set_min_out_buffer_size(outbuf, outbuf->len + filter_output->len); memcpy(outbuf->start + outbuf->len, filter_output->audio, filter_output->len); outbuf->len += filter_output->len; // remove processed data from decoder buffer: sh->a_buffer_len -= len; memmove(sh->a_buffer, sh->a_buffer + len, sh->a_buffer_len); return error; } /* Try to get at least minlen decoded+filtered bytes in outbuf * (total length including possible existing data). * Return 0 on success, -1 on error/EOF (not distinguished). * In the former case outbuf->len is always >= minlen on return. * In case of EOF/error it might or might not be. * Outbuf.start must be talloc-allocated, and will be reallocated * if needed to fit all filter output. */ int decode_audio(sh_audio_t *sh_audio, struct bstr *outbuf, int minlen) { // Indicates that a filter seems to be buffering large amounts of data int huge_filter_buffer = 0; // Decoded audio must be cut at boundaries of this many bytes int unitsize = sh_audio->channels * sh_audio->samplesize * 16; /* Filter output size will be about filter_multiplier times input size. * If some filter buffers audio in big blocks this might only hold * as average over time. */ double filter_multiplier = af_calc_filter_multiplier(sh_audio->afilter); /* If the decoder set audio_out_minsize then it can do the equivalent of * "while (output_len < target_len) output_len += audio_out_minsize;", * so we must guarantee there is at least audio_out_minsize-1 bytes * more space in the output buffer than the minimum length we try to * decode. */ int max_decode_len = sh_audio->a_buffer_size - sh_audio->audio_out_minsize; max_decode_len -= max_decode_len % unitsize; while (outbuf->len < minlen) { int declen = (minlen - outbuf->len) / filter_multiplier + (unitsize << 5); // some extra for possible filter buffering if (huge_filter_buffer) /* Some filter must be doing significant buffering if the estimated * input length didn't produce enough output from filters. * Feed the filters 2k bytes at a time until we have enough output. * Very small amounts could make filtering inefficient while large * amounts can make MPlayer demux the file unnecessarily far ahead * to get audio data and buffer video frames in memory while doing * so. However the performance impact of either is probably not too * significant as long as the value is not completely insane. */ declen = 2000; declen -= declen % unitsize; if (declen > max_decode_len) declen = max_decode_len; else /* if this iteration does not fill buffer, we must have lots * of buffering in filters */ huge_filter_buffer = 1; int res = filter_n_bytes(sh_audio, outbuf, declen); if (res < 0) return res; } return 0; }