[FFmpeg-devel] [PATCH] swresample: Add swr_get_out_samples()

Pavel Koshevoy pkoshevoy at gmail.com
Wed Jun 3 06:04:03 CEST 2015


On 6/2/15 16:22, Michael Niedermayer wrote:
> Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
> ---
>   libswresample/resample.c            |   17 +++++++++++++++++
>   libswresample/swresample.c          |   30 ++++++++++++++++++++++++++++++
>   libswresample/swresample.h          |   14 ++++++++++++++
>   libswresample/swresample_internal.h |    2 ++
>   libswresample/version.h             |    2 +-
>   5 files changed, 64 insertions(+), 1 deletion(-)
>
> diff --git a/libswresample/resample.c b/libswresample/resample.c
> index d4c7d06..c61bcb0 100644
> --- a/libswresample/resample.c
> +++ b/libswresample/resample.c
> @@ -345,6 +345,22 @@ static int64_t get_delay(struct SwrContext *s, int64_t base){
>       return av_rescale(num, base, s->in_sample_rate*(int64_t)c->src_incr << c->phase_shift);
>   }
>   
> +static int64_t get_out_samples(struct SwrContext *s, int in_samples) {
> +    ResampleContext *c = s->resample;
> +    int64_t num = s->in_buffer_count + 2LL + in_samples;
> +    num *= 1 << c->phase_shift;
> +    num -= c->index;
> +    num = av_rescale_rnd(num, s->out_sample_rate, ((int64_t)s->in_sample_rate) << c->phase_shift, AV_ROUND_UP);
> +
> +    if (c->compensation_distance) {
> +        if (num > INT_MAX)
> +            return AVERROR(EINVAL);
> +
> +        num = FFMAX(num, (num * c->ideal_dst_incr - 1) / c->dst_incr + 1);
> +    }
> +    return num + 2;
> +}
> +
>   static int resample_flush(struct SwrContext *s) {
>       AudioData *a= &s->in_buffer;
>       int i, j, ret;
> @@ -414,4 +430,5 @@ struct Resampler const swri_resampler={
>     set_compensation,
>     get_delay,
>     invert_initial_buffer,
> +  get_out_samples,
>   };
> diff --git a/libswresample/swresample.c b/libswresample/swresample.c
> index 3d3ab83..a5f5930 100644
> --- a/libswresample/swresample.c
> +++ b/libswresample/swresample.c
> @@ -672,11 +672,15 @@ int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_C
>                                                       const uint8_t *in_arg [SWR_CH_MAX], int  in_count){
>       AudioData * in= &s->in;
>       AudioData *out= &s->out;
> +    int av_unused max_output;
>   
>       if (!swr_is_initialized(s)) {
>           av_log(s, AV_LOG_ERROR, "Context has not been initialized\n");
>           return AVERROR(EINVAL);
>       }
> +#if ASSERT_LEVEL >1
> +    max_output = swr_get_out_samples(s, in_count);
> +#endif
>   
>       while(s->drop_output > 0){
>           int ret;
> @@ -719,6 +723,9 @@ int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_C
>           int ret = swr_convert_internal(s, out, out_count, in, in_count);
>           if(ret>0 && !s->drop_output)
>               s->outpts += ret * (int64_t)s->in_sample_rate;
> +
> +        av_assert2(max_output < 0 || ret < 0 || ret <= max_output);
> +
>           return ret;
>       }else{
>           AudioData tmp= *in;
> @@ -770,6 +777,7 @@ int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_C
>           }
>           if(ret2>0 && !s->drop_output)
>               s->outpts += ret2 * (int64_t)s->in_sample_rate;
> +        av_assert2(max_output < 0 || ret2 < 0 || ret2 <= max_output);
>           return ret2;
>       }
>   }
> @@ -821,6 +829,28 @@ int64_t swr_get_delay(struct SwrContext *s, int64_t base){
>       }
>   }
>   
> +int swr_get_out_samples(struct SwrContext *s, int in_samples)
> +{
> +    int64_t out_samples;
> +
> +    if (in_samples < 0)
> +        return AVERROR(EINVAL);
> +
> +    if (s->resampler && s->resample) {
> +        if (!s->resampler->get_out_samples)
> +            return AVERROR(ENOSYS);
> +        out_samples = s->resampler->get_out_samples(s, in_samples);
> +    } else {
> +        out_samples = swr_get_delay(s, s->out_sample_rate) + 2 + in_samples;
> +        av_assert0(s->out_sample_rate == s->in_sample_rate);
> +    }
> +
> +    if (out_samples > INT_MAX)
> +        return AVERROR(EINVAL);
> +
> +    return out_samples;
> +}
> +
>   int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance){
>       int ret;
>   
> diff --git a/libswresample/swresample.h b/libswresample/swresample.h
> index 37656a6..3b7b916 100644
> --- a/libswresample/swresample.h
> +++ b/libswresample/swresample.h
> @@ -436,6 +436,20 @@ int swr_inject_silence(struct SwrContext *s, int count);
>   int64_t swr_get_delay(struct SwrContext *s, int64_t base);
>   
>   /**
> + * Finds an upper bound on the number of samples that the next swr_convert will output.
> + *
> + * @param in_samples    number of input samples.
> + * @note any call to swr_inject_silence(), swr_convert(), swr_next_pts()
> + *       or swr_set_compensation() invalidates this limit
> + * @note it is recommanded to pass the correct avaialable buffer size

You probably meant "... recommended to pass the correct available ..."

> + *       to all functions like swr_convert() even if swr_get_out_samples()
> + *       indicates that less would be used.
> + * @returns an upper bound on the number of samples that the next swr_convert
> + *          will output or a negative value to indicate an error
> + */
> +int swr_get_out_samples(struct SwrContext *s, int in_samples);
> +
> +/**
>    * @}
>    *
>    * @name Configuration accessors
> diff --git a/libswresample/swresample_internal.h b/libswresample/swresample_internal.h
> index 7296a3f..0ddc670 100644
> --- a/libswresample/swresample_internal.h
> +++ b/libswresample/swresample_internal.h
> @@ -76,6 +76,7 @@ typedef int     (* resample_flush_func)(struct SwrContext *c);
>   typedef int     (* set_compensation_func)(struct ResampleContext *c, int sample_delta, int compensation_distance);
>   typedef int64_t (* get_delay_func)(struct SwrContext *s, int64_t base);
>   typedef int     (* invert_initial_buffer_func)(struct ResampleContext *c, AudioData *dst, const AudioData *src, int src_size, int *dst_idx, int *dst_count);
> +typedef int64_t (* get_out_samples_func)(struct SwrContext *s, int in_samples);
>   
>   struct Resampler {
>     resample_init_func            init;
> @@ -85,6 +86,7 @@ struct Resampler {
>     set_compensation_func         set_compensation;
>     get_delay_func                get_delay;
>     invert_initial_buffer_func    invert_initial_buffer;
> +  get_out_samples_func          get_out_samples;
>   };
>   
>   extern struct Resampler const swri_resampler;
> diff --git a/libswresample/version.h b/libswresample/version.h
> index 61c76fa..94ac9c5 100644
> --- a/libswresample/version.h
> +++ b/libswresample/version.h
> @@ -29,7 +29,7 @@
>   #include "libavutil/avutil.h"
>   
>   #define LIBSWRESAMPLE_VERSION_MAJOR   1
> -#define LIBSWRESAMPLE_VERSION_MINOR   1
> +#define LIBSWRESAMPLE_VERSION_MINOR   2
>   #define LIBSWRESAMPLE_VERSION_MICRO 100
>   
>   #define LIBSWRESAMPLE_VERSION_INT  AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \



More information about the ffmpeg-devel mailing list