[FFmpeg-cvslog] avfilter/avf_showcwt: fix truncation of low Hz kernels
Paul B Mahol
git at videolan.org
Sat Jul 29 18:10:18 EEST 2023
ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Sat Jul 29 17:11:28 2023 +0200| [37d3000e3ed790543505ebd80617fa6a60e213da] | committer: Paul B Mahol
avfilter/avf_showcwt: fix truncation of low Hz kernels
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=37d3000e3ed790543505ebd80617fa6a60e213da
---
libavfilter/avf_showcwt.c | 49 +++++++++++++++++++++++++++++++----------------
1 file changed, 33 insertions(+), 16 deletions(-)
diff --git a/libavfilter/avf_showcwt.c b/libavfilter/avf_showcwt.c
index 96b8841380..ba3ba1efc8 100644
--- a/libavfilter/avf_showcwt.c
+++ b/libavfilter/avf_showcwt.c
@@ -583,7 +583,8 @@ static int run_channel_cwt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo
AVComplexFloat *isrc = (AVComplexFloat *)s->ifft_in->extended_data[jobnr];
AVComplexFloat *idst = (AVComplexFloat *)s->ifft_out->extended_data[jobnr];
const int output_padding_size = s->output_padding_size;
- const float scale = 1.f / s->input_padding_size;
+ const int input_padding_size = s->input_padding_size;
+ const float scale = 1.f / input_padding_size;
const int ihop_size = s->ihop_size;
const int count = s->frequency_band_count;
const int start = (count * jobnr) / nb_jobs;
@@ -599,19 +600,36 @@ static int run_channel_cwt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo
const int kernel_start = s->kernel_start[y];
const int kernel_stop = s->kernel_stop[y];
const int kernel_range = kernel_stop - kernel_start + 1;
-
- memcpy(srcx, fft_out + kernel_start, sizeof(*fft_out) * kernel_range);
+ int offset;
+
+ if (kernel_start >= 0) {
+ offset = 0;
+ memcpy(srcx, fft_out + kernel_start, sizeof(*fft_out) * kernel_range);
+ } else {
+ offset = -kernel_start;
+ memcpy(srcx+offset, fft_out, sizeof(*fft_out) * (kernel_range-offset));
+ memcpy(srcx, fft_out+input_padding_size-offset, sizeof(*fft_out)*offset);
+ }
s->fdsp->vector_fmul_scalar((float *)srcx, (const float *)srcx, scale, FFALIGN(kernel_range * 2, 4));
s->fdsp->vector_fmul((float *)dstx, (const float *)srcx,
(const float *)kernel, FFALIGN(kernel_range * 2, 16));
memset(isrc, 0, sizeof(*isrc) * output_padding_size);
- for (int i = 0; i < kernel_range; i++) {
- const unsigned n = index[i + kernel_start];
+ if (offset == 0) {
+ for (int i = 0; i < kernel_range; i++) {
+ const unsigned n = index[i + kernel_start];
+
+ isrc[n].re += dstx[i].re;
+ isrc[n].im += dstx[i].im;
+ }
+ } else {
+ for (int i = 0; i < kernel_range; i++) {
+ const unsigned n = (i-kernel_start) & (output_padding_size-1);
- isrc[n].re += dstx[i].re;
- isrc[n].im += dstx[i].im;
+ isrc[n].re += dstx[i].re;
+ isrc[n].im += dstx[i].im;
+ }
}
s->itx_fn(s->ifft[jobnr], idst, isrc, sizeof(*isrc));
@@ -636,7 +654,6 @@ static int compute_kernel(AVFilterContext *ctx)
const int fsize = s->frequency_band_count;
int *kernel_start = s->kernel_start;
int *kernel_stop = s->kernel_stop;
- const int hsize = size >> 1;
unsigned *index = s->index;
int kernel_min = INT_MAX;
int kernel_max = 0, ret = 0;
@@ -649,17 +666,17 @@ static int compute_kernel(AVFilterContext *ctx)
for (int y = 0; y < fsize; y++) {
AVComplexFloat *kernel = s->kernel[y];
int start = 0, stop = 0;
- float frequency = s->frequency_band[y*2] * correction;
- float deviation = 1.f / (s->frequency_band[y*2+1] *
- output_sample_count * correction);
+ const float frequency = s->frequency_band[y*2] * correction;
+ const float deviation = 1.f / (s->frequency_band[y*2+1] *
+ output_sample_count * correction);
+ const int range = 8.f*M_PI*sqrtf(1.f/deviation);
memset(tkernel, 0, size * sizeof(*tkernel));
- for (int n = 0; n < size; n++) {
+ for (int n = -range; n < size-range; n++) {
float ff, f = n+0.5f-frequency;
- f = hsize - fabsf(f - hsize);
ff = expf(-f*f*deviation);
- tkernel[n] = ff;
+ tkernel[n+range] = ff;
}
for (int n = 0; n < size; n++) {
@@ -682,8 +699,8 @@ static int compute_kernel(AVFilterContext *ctx)
}
}
- kernel_start[y] = start;
- kernel_stop[y] = stop;
+ kernel_start[y] = start - range;
+ kernel_stop[y] = stop - range;
kernel = av_calloc(FFALIGN(stop - start + 1, 16), sizeof(*kernel));
if (!kernel) {
More information about the ffmpeg-cvslog
mailing list