[FFmpeg-devel] [PATCH 13/19] avfilter/af_aiir: Avoid temporary buffer when drawing image
Paul B Mahol
onemda at gmail.com
Tue Aug 25 20:48:42 EEST 2020
On 8/25/20, Andreas Rheinhardt <andreas.rheinhardt at gmail.com> wrote:
> When creating the output video, a temporary buffer is used whose elments
> are only used three times: Once to store a value in it, once more to add
> the value of the preceding element of the temporary buffer to the current
> element and once more to add the current i. element to the i. element of
> another bufffer; the two latter operations were performed in one loop,
> whereas the first was performed in a loop of its own.
>
> Yet these loops can be combined and the temporary buffer avoided. All
> one needs to do is store the running total of the elements that
> currently are in the temporary buffer and keep the preceding value of
> the destination buffer (it is needed to calculate the next element of
> the current temporary buffer, i.e. it is needed to know by how much to
> increment the running total).
>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
> ---
> One could combine various allocations here and in many other places.
> But for now I'll leave this to a future patchset.
>
> libavfilter/af_aiir.c | 21 +++++++++------------
> 1 file changed, 9 insertions(+), 12 deletions(-)
>
> diff --git a/libavfilter/af_aiir.c b/libavfilter/af_aiir.c
> index 3df25b4d9b..75bb79eb06 100644
> --- a/libavfilter/af_aiir.c
> +++ b/libavfilter/af_aiir.c
> @@ -866,8 +866,9 @@ static void get_response(int channel, int format, double
> w,
> static void draw_response(AVFilterContext *ctx, AVFrame *out, int
> sample_rate)
> {
> AudioIIRContext *s = ctx->priv;
> - double *mag, *phase, *temp, *delay, min = DBL_MAX, max = -DBL_MAX;
> + double *mag, *phase, *delay, min = DBL_MAX, max = -DBL_MAX;
> double min_delay = DBL_MAX, max_delay = -DBL_MAX, min_phase, max_phase;
> + double tmp, oldphase;
> int prev_ymag = -1, prev_yphase = -1, prev_ydelay = -1;
> char text[32];
> int ch, i;
> @@ -875,10 +876,9 @@ static void draw_response(AVFilterContext *ctx, AVFrame
> *out, int sample_rate)
> memset(out->data[0], 0, s->h * out->linesize[0]);
>
> phase = av_malloc_array(s->w, sizeof(*phase));
> - temp = av_malloc_array(s->w, sizeof(*temp));
> mag = av_malloc_array(s->w, sizeof(*mag));
> delay = av_malloc_array(s->w, sizeof(*delay));
> - if (!mag || !phase || !delay || !temp)
> + if (!mag || !phase || !delay)
> goto end;
>
> ch = av_clip(s->ir_channel, 0, s->channels - 1);
> @@ -898,17 +898,15 @@ static void draw_response(AVFilterContext *ctx,
> AVFrame *out, int sample_rate)
> max = fmax(max, mag[i]);
> }
>
> - temp[0] = 0.;
> - for (i = 0; i < s->w - 1; i++) {
> - double d = phase[i] - phase[i + 1];
> - temp[i + 1] = ceil(fabs(d) / (2. * M_PI)) * 2. * M_PI * ((d > M_PI)
> - (d < -M_PI));
> - }
> -
> + tmp = 0.;
> + oldphase = phase[0];
> min_phase = phase[0];
> max_phase = phase[0];
> for (i = 1; i < s->w; i++) {
> - temp[i] += temp[i - 1];
> - phase[i] += temp[i];
> + double d = oldphase - phase[i];
> + oldphase = phase[i];
> + tmp += ceil(fabs(d) / (2. * M_PI)) * 2. * M_PI * ((d > M_PI) - (d <
> -M_PI));
> + phase[i] += tmp;
> min_phase = fmin(min_phase, phase[i]);
> max_phase = fmax(max_phase, phase[i]);
> }
> @@ -975,7 +973,6 @@ static void draw_response(AVFilterContext *ctx, AVFrame
> *out, int sample_rate)
>
> end:
> av_free(delay);
> - av_free(temp);
> av_free(phase);
> av_free(mag);
> }
> --
> 2.20.1
>
Should be fine if output drawn does not change drastically.
More information about the ffmpeg-devel
mailing list