History

avfilter/avf_showfreqs: add rate option

Fix possible buffer overflow.

Paul B Mahol committed 4 years ago

Commit d8e8aa91 parent fe06e702 files · +35 −26Browse files

Unified · Split

2 files
  1. doc/filters.texi +3 −0
  2. libavfilter/avf_showfreqs.c +32 −26
doc/filters.texi+3−0
@@ -28476,6 +28476,9 @@ Specify size of video. For the syntax of this option, check the · 28475 unmodified lines
28476@ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.28476@ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
28477Default is @code{1024x512}.28477Default is @code{1024x512}.
28478 28478
28479@item rate, r
28480Set video rate. Default is @code{25}.
28481
28479@item mode28482@item mode
28480Set display mode.28483Set display mode.
28481This set how each frequency bin will be represented.28484This set how each frequency bin will be represented.
libavfilter/avf_showfreqs.c+32−26
@@ -70,6 +70,9 @@ typedef struct ShowFreqsContext { · 69 unmodified lines
70 int win_size;70 int win_size;
71 float scale;71 float scale;
72 char *colors;72 char *colors;
73 int64_t pts;
74 int64_t old_pts;
75 AVRational frame_rate;
73} ShowFreqsContext;76} ShowFreqsContext;
74 77
75#define OFFSET(x) offsetof(ShowFreqsContext, x)78#define OFFSET(x) offsetof(ShowFreqsContext, x)
@@ -78,6 +81,8 @@ typedef struct ShowFreqsContext { · 2 unmodified lines
78static const AVOption showfreqs_options[] = {81static const AVOption showfreqs_options[] = {
79 { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "1024x512"}, 0, 0, FLAGS },82 { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "1024x512"}, 0, 0, FLAGS },
80 { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "1024x512"}, 0, 0, FLAGS },83 { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "1024x512"}, 0, 0, FLAGS },
84 { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },
85 { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },
81 { "mode", "set display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=BAR}, 0, NB_MODES-1, FLAGS, "mode" },86 { "mode", "set display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=BAR}, 0, NB_MODES-1, FLAGS, "mode" },
82 { "line", "show lines", 0, AV_OPT_TYPE_CONST, {.i64=LINE}, 0, 0, FLAGS, "mode" },87 { "line", "show lines", 0, AV_OPT_TYPE_CONST, {.i64=LINE}, 0, 0, FLAGS, "mode" },
83 { "bar", "show bars", 0, AV_OPT_TYPE_CONST, {.i64=BAR}, 0, 0, FLAGS, "mode" },88 { "bar", "show bars", 0, AV_OPT_TYPE_CONST, {.i64=BAR}, 0, 0, FLAGS, "mode" },
@@ -149,6 +154,7 @@ static int config_output(AVFilterLink *outlink) · 65 unmodified lines
149 float overlap, scale;154 float overlap, scale;
150 int i, ret;155 int i, ret;
151 156
157 s->old_pts = AV_NOPTS_VALUE;
152 s->nb_freq = s->fft_size / 2;158 s->nb_freq = s->fft_size / 2;
153 s->win_size = s->fft_size;159 s->win_size = s->fft_size;
154 av_tx_uninit(&s->fft);160 av_tx_uninit(&s->fft);
@@ -215,7 +221,7 @@ static int config_output(AVFilterLink *outlink) · 60 unmodified lines
215 if (!s->window)221 if (!s->window)
216 return AVERROR(ENOMEM);222 return AVERROR(ENOMEM);
217 223
218 outlink->frame_rate = av_make_q(inlink->sample_rate, s->hop_size);224 outlink->frame_rate = s->frame_rate;
219 outlink->time_base = av_inv_q(outlink->frame_rate);225 outlink->time_base = av_inv_q(outlink->frame_rate);
220 outlink->sample_aspect_ratio = (AVRational){1,1};226 outlink->sample_aspect_ratio = (AVRational){1,1};
221 outlink->w = s->w;227 outlink->w = s->w;
@@ -328,13 +334,13 @@ static inline void plot_freq(ShowFreqsContext *s, int ch, · 106 unmodified lines
328 334
329 switch (s->avg) {335 switch (s->avg) {
330 case 0:336 case 0:
331 y = s->avg_data[ch][f] = !outlink->frame_count_in ? y : FFMIN(avg, y);337 y = s->avg_data[ch][f] = !outlink->frame_count_in ? y : FFMIN(0, y);
332 break;338 break;
333 case 1:339 case 1:
334 break;340 break;
335 default:341 default:
336 s->avg_data[ch][f] = avg + y * (y - avg) / (FFMIN(outlink->frame_count_in + 1, s->avg) * y);342 s->avg_data[ch][f] = avg + y * (y - avg) / (FFMIN(outlink->frame_count_in + 1, s->avg) * (float)y);
337 y = s->avg_data[ch][f];343 y = av_clip(s->avg_data[ch][f], 0, outlink->h - 1);
338 break;344 break;
339 }345 }
340 346
@@ -379,13 +385,6 @@ static int plot_freqs(AVFilterLink *inlink, int64_t pts) · 38 unmodified lines
379 AVFrame *out;385 AVFrame *out;
380 int ch, n;386 int ch, n;
381 387
382 out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
383 if (!out)
384 return AVERROR(ENOMEM);
385
386 for (n = 0; n < outlink->h; n++)
387 memset(out->data[0] + out->linesize[0] * n, 0, outlink->w * 4);
388
389 /* fill FFT input with the number of samples available */388 /* fill FFT input with the number of samples available */
390 for (ch = 0; ch < s->nb_channels; ch++) {389 for (ch = 0; ch < s->nb_channels; ch++) {
391 const float *p = (float *)in->extended_data[ch];390 const float *p = (float *)in->extended_data[ch];
@@ -407,16 +406,26 @@ static int plot_freqs(AVFilterLink *inlink, int64_t pts) · 15 unmodified lines
407 s->tx_fn(s->fft, s->fft_data[ch], s->fft_input[ch], sizeof(float));406 s->tx_fn(s->fft, s->fft_data[ch], s->fft_input[ch], sizeof(float));
408 }407 }
409 408
409 s->pts = av_rescale_q(pts, inlink->time_base, outlink->time_base);
410 if (s->old_pts >= s->pts)
411 return 0;
412 s->old_pts = s->pts;
413
410#define RE(x, ch) s->fft_data[ch][x].re414#define RE(x, ch) s->fft_data[ch][x].re
411#define IM(x, ch) s->fft_data[ch][x].im415#define IM(x, ch) s->fft_data[ch][x].im
412#define M(a, b) (sqrt((a) * (a) + (b) * (b)))416#define M(a, b) (sqrt((a) * (a) + (b) * (b)))
413#define P(a, b) (atan2((b), (a)))417#define P(a, b) (atan2((b), (a)))
414 418
415 colors = av_strdup(s->colors);419 colors = av_strdup(s->colors);
416 if (!colors) {420 if (!colors)
417 av_frame_free(&out);
418 return AVERROR(ENOMEM);421 return AVERROR(ENOMEM);
419 }422
423 out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
424 if (!out)
425 return AVERROR(ENOMEM);
426
427 for (n = 0; n < outlink->h; n++)
428 memset(out->data[0] + out->linesize[0] * n, 0, outlink->w * 4);
420 429
421 for (ch = 0; ch < s->nb_channels; ch++) {430 for (ch = 0; ch < s->nb_channels; ch++) {
422 uint8_t fg[4] = { 0xff, 0xff, 0xff, 0xff };431 uint8_t fg[4] = { 0xff, 0xff, 0xff, 0xff };
@@ -432,29 +441,21 @@ static int plot_freqs(AVFilterLink *inlink, int64_t pts) · 9 unmodified lines
432 441
433 switch (s->data_mode) {442 switch (s->data_mode) {
434 case MAGNITUDE:443 case MAGNITUDE:
435 a = av_clipd(M(RE(0, ch), 0) / s->scale, 0, 1);444 for (f = 0; f < s->nb_freq; f++) {
436 plot_freq(s, ch, a, 0, fg, &prev_y, out, outlink);
437
438 for (f = 1; f < s->nb_freq; f++) {
439 a = av_clipd(M(RE(f, ch), IM(f, ch)) / s->scale, 0, 1);445 a = av_clipd(M(RE(f, ch), IM(f, ch)) / s->scale, 0, 1);
440 446
441 plot_freq(s, ch, a, f, fg, &prev_y, out, outlink);447 plot_freq(s, ch, a, f, fg, &prev_y, out, outlink);
442 }448 }
443 break;449 break;
444 case PHASE:450 case PHASE:
445 a = av_clipd((M_PI + P(RE(0, ch), 0)) / (2. * M_PI), 0, 1);451 for (f = 0; f < s->nb_freq; f++) {
446 plot_freq(s, ch, a, 0, fg, &prev_y, out, outlink);
447
448 for (f = 1; f < s->nb_freq; f++) {
449 a = av_clipd((M_PI + P(RE(f, ch), IM(f, ch))) / (2. * M_PI), 0, 1);452 a = av_clipd((M_PI + P(RE(f, ch), IM(f, ch))) / (2. * M_PI), 0, 1);
450 453
451 plot_freq(s, ch, a, f, fg, &prev_y, out, outlink);454 plot_freq(s, ch, a, f, fg, &prev_y, out, outlink);
452 }455 }
453 break;456 break;
454 case DELAY:457 case DELAY:
455 plot_freq(s, ch, 0, 0, fg, &prev_y, out, outlink);458 for (f = 0; f < s->nb_freq; f++) {
456
457 for (f = 1; f < s->nb_freq; f++) {
458 a = av_clipd((M_PI - P(IM(f, ch) * RE(f-1, ch) - IM(f-1, ch) * RE(f, ch),459 a = av_clipd((M_PI - P(IM(f, ch) * RE(f-1, ch) - IM(f-1, ch) * RE(f, ch),
459 RE(f, ch) * RE(f-1, ch) + IM(f, ch) * IM(f-1, ch))) / (2. * M_PI), 0, 1);460 RE(f, ch) * RE(f-1, ch) + IM(f, ch) * IM(f-1, ch))) / (2. * M_PI), 0, 1);
460 461
@@ -465,7 +466,7 @@ static int plot_freqs(AVFilterLink *inlink, int64_t pts) · 4 unmodified lines
465 }466 }
466 467
467 av_free(colors);468 av_free(colors);
468 out->pts = av_rescale_q(pts, inlink->time_base, outlink->time_base);469 out->pts = s->pts;
469 out->sample_aspect_ratio = (AVRational){1,1};470 out->sample_aspect_ratio = (AVRational){1,1};
470 return ff_filter_frame(outlink, out);471 return ff_filter_frame(outlink, out);
471}472}
@@ -509,6 +510,11 @@ static int activate(AVFilterContext *ctx) · 37 unmodified lines
509 if (ret < 0)510 if (ret < 0)
510 return ret;511 return ret;
511 512
513 if (ff_inlink_queued_samples(inlink) >= s->hop_size) {
514 ff_filter_set_ready(ctx, 10);
515 return 0;
516 }
517
512 FF_FILTER_FORWARD_STATUS(inlink, outlink);518 FF_FILTER_FORWARD_STATUS(inlink, outlink);
513 FF_FILTER_FORWARD_WANTED(outlink, inlink);519 FF_FILTER_FORWARD_WANTED(outlink, inlink);
514 520

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