History

avfilter/avf_showcwt: reduce memory usage

Paul B Mahol committed 3 years ago

Commit b2ceed41 parent f25ad0f1 file · +52 −40Browse files

Showing the changes to libavfilter (1 of 1 file). Show all

Unified · Split

libavfilter/avf_showcwt.c+52−40
@@ -78,7 +78,7 @@ typedef struct ShowCWTContext { · 77 unmodified lines
78 int64_t old_pts;78 int64_t old_pts;
79 int64_t eof_pts;79 int64_t eof_pts;
80 float *frequency_band;80 float *frequency_band;
81 AVFrame *kernel;81 AVComplexFloat **kernel;
82 unsigned *index;82 unsigned *index;
83 int *kernel_start, *kernel_stop;83 int *kernel_start, *kernel_stop;
84 AVFrame *cache;84 AVFrame *cache;
@@ -87,7 +87,6 @@ typedef struct ShowCWTContext { · 2 unmodified lines
87 AVFrame *fft_out;87 AVFrame *fft_out;
88 AVFrame *dst_x;88 AVFrame *dst_x;
89 AVFrame *src_x;89 AVFrame *src_x;
90 AVFrame *kernel_x;
91 AVFrame *ifft_in;90 AVFrame *ifft_in;
92 AVFrame *ifft_out;91 AVFrame *ifft_out;
93 AVFrame *ch_out;92 AVFrame *ch_out;
@@ -169,14 +168,12 @@ static av_cold void uninit(AVFilterContext *ctx) · 75 unmodified lines
169 av_freep(&s->kernel_stop);168 av_freep(&s->kernel_stop);
170 av_freep(&s->index);169 av_freep(&s->index);
171 170
172 av_frame_free(&s->kernel);
173 av_frame_free(&s->cache);171 av_frame_free(&s->cache);
174 av_frame_free(&s->outpicref);172 av_frame_free(&s->outpicref);
175 av_frame_free(&s->fft_in);173 av_frame_free(&s->fft_in);
176 av_frame_free(&s->fft_out);174 av_frame_free(&s->fft_out);
177 av_frame_free(&s->dst_x);175 av_frame_free(&s->dst_x);
178 av_frame_free(&s->src_x);176 av_frame_free(&s->src_x);
179 av_frame_free(&s->kernel_x);
180 av_frame_free(&s->ifft_in);177 av_frame_free(&s->ifft_in);
181 av_frame_free(&s->ifft_out);178 av_frame_free(&s->ifft_out);
182 av_frame_free(&s->ch_out);179 av_frame_free(&s->ch_out);
@@ -194,6 +191,12 @@ static av_cold void uninit(AVFilterContext *ctx) · 11 unmodified lines
194 av_freep(&s->ifft);191 av_freep(&s->ifft);
195 }192 }
196 193
194 if (s->kernel) {
195 for (int n = 0; n < s->frequency_band_count; n++)
196 av_freep(&s->kernel[n]);
197 }
198 av_freep(&s->kernel);
199
197 av_freep(&s->fdsp);200 av_freep(&s->fdsp);
198}201}
199 202
@@ -588,18 +591,16 @@ static int run_channel_cwt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo · 388 unmodified lines
588 AVComplexFloat *chout = ((AVComplexFloat *)s->ch_out->extended_data[ch]) + y * ihop_size;591 AVComplexFloat *chout = ((AVComplexFloat *)s->ch_out->extended_data[ch]) + y * ihop_size;
589 AVComplexFloat *dstx = (AVComplexFloat *)s->dst_x->extended_data[jobnr];592 AVComplexFloat *dstx = (AVComplexFloat *)s->dst_x->extended_data[jobnr];
590 AVComplexFloat *srcx = (AVComplexFloat *)s->src_x->extended_data[jobnr];593 AVComplexFloat *srcx = (AVComplexFloat *)s->src_x->extended_data[jobnr];
591 AVComplexFloat *kernelx = (AVComplexFloat *)s->kernel_x->extended_data[jobnr];594 const AVComplexFloat *kernel = s->kernel[y];
592 const AVComplexFloat *kernel = (const AVComplexFloat *)s->kernel->extended_data[y];
593 const unsigned *index = (const unsigned *)s->index;595 const unsigned *index = (const unsigned *)s->index;
594 const int kernel_start = s->kernel_start[y];596 const int kernel_start = s->kernel_start[y];
595 const int kernel_stop = s->kernel_stop[y];597 const int kernel_stop = s->kernel_stop[y];
596 const int kernel_range = kernel_stop - kernel_start;598 const int kernel_range = kernel_stop - kernel_start;
597 599
598 memcpy(kernelx, kernel + kernel_start, sizeof(*kernel) * kernel_range);
599 memcpy(srcx, dst + kernel_start, sizeof(*dst) * kernel_range);600 memcpy(srcx, dst + kernel_start, sizeof(*dst) * kernel_range);
600 601
601 s->fdsp->vector_fmul((float *)dstx, (const float *)srcx,602 s->fdsp->vector_fmul((float *)dstx, (const float *)srcx,
602 (const float *)kernelx, FFALIGN(kernel_range * 2, 16));603 (const float *)kernel, FFALIGN(kernel_range * 2, 16));
603 604
604 memset(isrc, 0, sizeof(*isrc) * output_padding_size);605 memset(isrc, 0, sizeof(*isrc) * output_padding_size);
605 for (int i = 0; i < kernel_range; i++) {606 for (int i = 0; i < kernel_range; i++) {
@@ -629,41 +630,63 @@ static int compute_kernel(AVFilterContext *ctx) · 23 unmodified lines
629 int *kernel_stop = s->kernel_stop;630 int *kernel_stop = s->kernel_stop;
630 unsigned *index = s->index;631 unsigned *index = s->index;
631 int kernel_min = INT_MAX;632 int kernel_min = INT_MAX;
632 int kernel_max = 0;633 int kernel_max = 0, ret = 0;
634 float *tkernel;
635
636 tkernel = av_malloc_array(size, sizeof(*tkernel));
637 if (!tkernel)
638 return AVERROR(ENOMEM);
633 639
634 for (int y = 0; y < fsize; y++) {640 for (int y = 0; y < fsize; y++) {
635 AVComplexFloat *kernel = (AVComplexFloat *)s->kernel->extended_data[y];641 AVComplexFloat *kernel = s->kernel[y];
642 int start = 0, stop = 0;
636 float frequency = s->frequency_band[y*2] * correction;643 float frequency = s->frequency_band[y*2] * correction;
637 float deviation = 1.f / (s->frequency_band[y*2+1] *644 float deviation = 1.f / (s->frequency_band[y*2+1] *
638 output_sample_count * correction);645 output_sample_count * correction);
639 646
647 memset(tkernel, 0, size * sizeof(*tkernel));
640 for (int n = 0; n < size; n++) {648 for (int n = 0; n < size; n++) {
641 float ff, f = fabsf(n-frequency);649 float ff, f = fabsf(n-frequency);
642 650
643 ff = expf(-f*f*deviation) * scale_factor;651 ff = expf(-f*f*deviation) * scale_factor;
644 kernel[n].re = ff;652 tkernel[n] = ff;
645 kernel[n].im = ff;
646 }653 }
647 654
648 for (int n = 0; n < size; n++) {655 for (int n = 0; n < size; n++) {
649 if (kernel[n].re != 0.f) {656 if (tkernel[n] != 0.f) {
650 if (kernel[n].re > FLT_MIN)657 if (tkernel[n] > FLT_MIN)
651 av_log(ctx, AV_LOG_DEBUG, "out of range kernel\n");658 av_log(ctx, AV_LOG_DEBUG, "out of range kernel\n");
652 kernel_start[y] = n;659 start = n;
653 kernel_min = FFMIN(kernel_start[y], kernel_min);660 kernel_min = FFMIN(start, kernel_min);
654 break;661 break;
655 }662 }
656 }663 }
657 664
658 for (int n = 0; n < size; n++) {665 for (int n = 0; n < size; n++) {
659 if (kernel[size - n - 1].re != 0.f) {666 if (tkernel[size - n - 1] != 0.f) {
660 if (kernel[size - n - 1].re > FLT_MIN)667 if (tkernel[size - n - 1] > FLT_MIN)
661 av_log(ctx, AV_LOG_DEBUG, "out of range kernel\n");668 av_log(ctx, AV_LOG_DEBUG, "out of range kernel\n");
662 kernel_stop[y] = size - n - 1;669 stop = size - n - 1;
663 kernel_max = FFMAX(kernel_stop[y], kernel_max);670 kernel_max = FFMAX(stop, kernel_max);
664 break;671 break;
665 }672 }
666 }673 }
674
675 kernel_start[y] = start;
676 kernel_stop[y] = stop;
677
678 kernel = av_calloc(FFALIGN(stop - start + 1, 16), sizeof(*kernel));
679 if (!kernel) {
680 ret = AVERROR(ENOMEM);
681 break;
682 }
683
684 for (int n = start; n <= stop; n++) {
685 kernel[n - start].re = tkernel[n];
686 kernel[n - start].im = tkernel[n];
687 }
688
689 s->kernel[y] = kernel;
667 }690 }
668 691
669 for (int n = 0; n < size; n++)692 for (int n = 0; n < size; n++)
@@ -673,7 +696,9 @@ static int compute_kernel(AVFilterContext *ctx) · 3 unmodified lines
673 av_log(ctx, AV_LOG_DEBUG, "kernel_max: %d\n", kernel_max);696 av_log(ctx, AV_LOG_DEBUG, "kernel_max: %d\n", kernel_max);
674 av_log(ctx, AV_LOG_DEBUG, "kernel_range: %d\n", kernel_max - kernel_min);697 av_log(ctx, AV_LOG_DEBUG, "kernel_range: %d\n", kernel_max - kernel_min);
675 698
676 return kernel_max - kernel_min;699 av_freep(&tkernel);
700
701 return ret;
677}702}
678 703
679static int config_output(AVFilterLink *outlink)704static int config_output(AVFilterLink *outlink)
@@ -762,19 +787,18 @@ static int config_output(AVFilterLink *outlink) · 82 unmodified lines
762 s->fft_out = ff_get_audio_buffer(inlink, s->fft_out_size * 2);787 s->fft_out = ff_get_audio_buffer(inlink, s->fft_out_size * 2);
763 s->dst_x = av_frame_alloc();788 s->dst_x = av_frame_alloc();
764 s->src_x = av_frame_alloc();789 s->src_x = av_frame_alloc();
765 s->kernel_x = av_frame_alloc();790 s->kernel = av_calloc(s->frequency_band_count, sizeof(*s->kernel));
766 s->cache = ff_get_audio_buffer(inlink, s->fft_in_size * 2);791 s->cache = ff_get_audio_buffer(inlink, s->fft_in_size * 2);
767 s->ch_out = ff_get_audio_buffer(inlink, s->frequency_band_count * 2 * s->ihop_size);792 s->ch_out = ff_get_audio_buffer(inlink, s->frequency_band_count * 2 * s->ihop_size);
768 s->bh_out = ff_get_audio_buffer(inlink, s->frequency_band_count);793 s->bh_out = ff_get_audio_buffer(inlink, s->frequency_band_count);
769 s->ifft_in = av_frame_alloc();794 s->ifft_in = av_frame_alloc();
770 s->ifft_out = av_frame_alloc();795 s->ifft_out = av_frame_alloc();
771 s->kernel = av_frame_alloc();
772 s->index = av_calloc(s->input_padding_size, sizeof(*s->index));796 s->index = av_calloc(s->input_padding_size, sizeof(*s->index));
773 s->kernel_start = av_calloc(s->frequency_band_count, sizeof(*s->kernel_start));797 s->kernel_start = av_calloc(s->frequency_band_count, sizeof(*s->kernel_start));
774 s->kernel_stop = av_calloc(s->frequency_band_count, sizeof(*s->kernel_stop));798 s->kernel_stop = av_calloc(s->frequency_band_count, sizeof(*s->kernel_stop));
775 if (!s->outpicref || !s->fft_in || !s->fft_out || !s->src_x || !s->dst_x || !s->kernel_x ||799 if (!s->outpicref || !s->fft_in || !s->fft_out || !s->src_x || !s->dst_x ||
776 !s->ifft_in || !s->ifft_out || !s->kernel_start || !s->kernel_stop || !s->ch_out ||800 !s->ifft_in || !s->ifft_out || !s->kernel_start || !s->kernel_stop || !s->ch_out ||
777 !s->frequency_band || !s->kernel || !s->cache || !s->index || !s->bh_out)801 !s->frequency_band || !s->cache || !s->index || !s->bh_out || !s->kernel)
778 return AVERROR(ENOMEM);802 return AVERROR(ENOMEM);
779 803
780 s->ifft_in->format = inlink->format;804 s->ifft_in->format = inlink->format;
@@ -791,13 +815,6 @@ static int config_output(AVFilterLink *outlink) · 10 unmodified lines
791 if (ret < 0)815 if (ret < 0)
792 return ret;816 return ret;
793 817
794 s->kernel->format = inlink->format;
795 s->kernel->nb_samples = s->input_padding_size * 2;
796 s->kernel->ch_layout.nb_channels = s->frequency_band_count;
797 ret = av_frame_get_buffer(s->kernel, 0);
798 if (ret < 0)
799 return ret;
800
801 s->src_x->format = inlink->format;818 s->src_x->format = inlink->format;
802 s->src_x->nb_samples = s->fft_out_size * 2;819 s->src_x->nb_samples = s->fft_out_size * 2;
803 s->src_x->ch_layout.nb_channels = s->nb_threads;820 s->src_x->ch_layout.nb_channels = s->nb_threads;
@@ -812,13 +829,6 @@ static int config_output(AVFilterLink *outlink) · 8 unmodified lines
812 if (ret < 0)829 if (ret < 0)
813 return ret;830 return ret;
814 831
815 s->kernel_x->format = inlink->format;
816 s->kernel_x->nb_samples = s->fft_out_size * 2;
817 s->kernel_x->ch_layout.nb_channels = s->nb_threads;
818 ret = av_frame_get_buffer(s->kernel_x, 0);
819 if (ret < 0)
820 return ret;
821
822 s->outpicref->sample_aspect_ratio = (AVRational){1,1};832 s->outpicref->sample_aspect_ratio = (AVRational){1,1};
823 833
824 for (int y = 0; y < outlink->h; y++) {834 for (int y = 0; y < outlink->h; y++) {
@@ -899,7 +909,9 @@ static int config_output(AVFilterLink *outlink) · 74 unmodified lines
899 outlink->frame_rate = s->frame_rate;909 outlink->frame_rate = s->frame_rate;
900 outlink->time_base = av_inv_q(outlink->frame_rate);910 outlink->time_base = av_inv_q(outlink->frame_rate);
901 911
902 compute_kernel(ctx);912 ret = compute_kernel(ctx);
913 if (ret < 0)
914 return ret;
903 915
904 return 0;916 return 0;
905}917}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t