[FFmpeg-devel] [PATCH] libavfilter: add atempo filter (revised patch v4)

Pavel Koshevoy pkoshevoy at gmail.com
Tue Jun 12 05:16:41 CEST 2012


On 06/11/2012 05:15 PM, Stefano Sabatini wrote:
> On date Sunday 2012-06-10 16:49:17 -0600, Pavel Koshevoy encoded:
>> Add atempo audio filter for adjusting audio tempo without affecting
>> pitch. This filter implements WSOLA algorithm with fast cross
>> correlation calculation in frequency domain.
>>
>> Signed-off-by: Pavel Koshevoy<pavel at homestead.aragog.com>
>> ---
>>   Changelog                |    1 +
>>   MAINTAINERS              |    1 +
>>   configure                |    1 +
>>   doc/filters.texi         |   18 +
>>   libavfilter/Makefile     |    2 +
>>   libavfilter/af_atempo.c  | 1158 ++++++++++++++++++++++++++++++++++++++++++++++
>>   libavfilter/allfilters.c |    1 +
>>   7 files changed, 1182 insertions(+), 0 deletions(-)
>>   create mode 100644 libavfilter/af_atempo.c
>>
>> diff --git a/Changelog b/Changelog
>> index 41b0bdc..a639c71 100644
>> --- a/Changelog
>> +++ b/Changelog
>> @@ -5,6 +5,7 @@ version next:
>>   - INI and flat output in ffprobe
>>   - Scene detection in libavfilter
>>   - Indeo Audio decoder
>> +- atempo filter
>>
> [...]
>> +/**
>> + * A fragment of audio waveform
>> + */
>> +typedef struct {
>> +    // index of the first sample of this fragment in the overall waveform;
>> +    // 0: input sample position
>> +    // 1: output sample position
>> +    int64_t position[2];
>> +
>> +    // original packed multi-channel samples:
>> +    uint8_t *data;
>> +
>> +    // number of samples in this fragment:
>> +    int nsamples;
>> +
>> +    // FFT transform of the down-mixed mono fragment, used for
>> +    // fast waveform alignment via correlation in frequency domain:
>> +    FFTComplex *xdat;
>> +
>> +} AudioFragment;
> Nit++: weird space before end of block to my eyes

Removed blank line.


>> +
>> +/**
>> + * Filter state machine states
>> + */
>> +typedef enum {
>> +    YAE_LOAD_FRAGMENT,
>> +    YAE_ADJUST_POSITION,
>> +    YAE_RELOAD_FRAGMENT,
>> +    YAE_OUTPUT_OVERLAP_ADD,
>> +    YAE_FLUSH_OUTPUT,
>> +
>> +} FilterState;
> Ditto.

Removed blank line.

[...]

>
>> +    // initialize audio fragment buffers:
>> +    atempo->frag[0].data = av_realloc(atempo->frag[0].data,
>> +                                      atempo->window * atempo->stride);
>> +    if (!atempo->frag[0].data) {
>> +        return AVERROR(ENOMEM);
>> +    }
>> +
>> +    atempo->frag[1].data = av_realloc(atempo->frag[1].data,
>> +                                      atempo->window * atempo->stride);
>> +    if (!atempo->frag[1].data) {
>> +        return AVERROR(ENOMEM);
>> +    }
>> +
>> +    atempo->frag[0].xdat = av_realloc(atempo->frag[0].xdat,
>> +                                      atempo->window * 2 *
>> +                                      sizeof(FFTComplex));
>> +    if (!atempo->frag[0].xdat) {
>> +        return AVERROR(ENOMEM);
>> +    }
>> +
>> +    atempo->frag[1].xdat = av_realloc(atempo->frag[1].xdat,
>> +                                      atempo->window * 2 *
>> +                                      sizeof(FFTComplex));
>> +    if (!atempo->frag[1].xdat) {
>> +        return AVERROR(ENOMEM);
>> +    }
> Suggestion:
> #define REALLOC_FIELD_OR_FAIL(field, size)      \
>     atempo->field = av_realloc(field, size);     \
>     if (!atempo->field)                          \
>          return AVERROR(ENOMEM)

Done

[...]

>> + * @return 0 if the overlap region was completely stored in the dst buffer.
>> + * @return AVERROR(EAGAIN) if more destination buffer space is required.
> nit++: double return

Fixed this and another one.

[...]


>> +            atempo->dst_buffer->audio->sample_rate = outlink->sample_rate;
>> +            atempo->dst_buffer->audio->nb_samples  = n_out;
>> +
>> +            // adjust the PTS:
>> +            atempo->dst_buffer->pts =
>> +                av_rescale_q(atempo->nsamples_out,
>> +                             (AVRational){ 1, outlink->sample_rate },
>> +                             outlink->time_base);
>> +
>> +            ff_filter_samples(outlink, atempo->dst_buffer);
>> +            atempo->dst_buffer = NULL;
>> +            atempo->dst        = NULL;
>> +            atempo->dst_end    = NULL;
>> +
>> +            atempo->nsamples_out += n_out;
>> +            atempo->request_fulfilled = 1;
> Maybe this can be factorized with the below code (push_samples?)

Done.

Thank you, I'll send another patch revision shortly.

     Pavel.



More information about the ffmpeg-devel mailing list