Exemplo n.º 1
0
/* 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;
}
Exemplo n.º 2
0
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;
}