History

avfilter/avf_ahistogram: add new histogram mode option

Paul B Mahol committed 4 years ago

Commit fb5e8711 parent 044c09c2 files · +69 −10Browse files

Unified · Split

2 files
  1. doc/filters.texi +12 −0
  2. libavfilter/avf_ahistogram.c +57 −10
doc/filters.texi+12−0
@@ -25969,6 +25969,18 @@ replace old rows with new ones. · 25968 unmodified lines
2596925969 scroll from top to bottom.
2597025970 @end table
2597125971 Default is @code{replace}.
25972+
25973+@item hmode
25974+Set histogram mode.
25975+
25976+It accepts the following values:
25977+@table @samp
25978+@item abs
25979+Use absolute values of samples.
25980+@item sign
25981+Use untouched values of samples.
25982+@end table
25983+Default is @code{abs}.
2597225984 @end table
2597325985
2597425986 @section aphasemeter
libavfilter/avf_ahistogram.c+57−10
@@ -32,7 +32,7 @@ enum DisplayScale { LINEAR, SQRT, CBRT, LOG, RLOG, NB_SCALES }; · 31 unmodified lines
3232 enum AmplitudeScale { ALINEAR, ALOG, NB_ASCALES };
3333 enum SlideMode { REPLACE, SCROLL, NB_SLIDES };
3434 enum DisplayMode { SINGLE, SEPARATE, NB_DMODES };
35−enum HistogramMode { ACCUMULATE, CURRENT, NB_HMODES };
35+enum HistogramMode { ABS, SIGN, NB_HMODES };
3636
3737 typedef struct AudioHistogramContext {
3838 const AVClass *class;
@@ -49,6 +49,7 @@ typedef struct AudioHistogramContext { · 10 unmodified lines
4949 int ypos;
5050 int slide;
5151 int dmode;
52+ int hmode;
5253 int dchannels;
5354 int count;
5455 int frame_count;
@@ -56,6 +57,8 @@ typedef struct AudioHistogramContext { · 1 unmodified line
5657 AVFrame *in[101];
5758 int first;
5859 int nb_samples;
60+
61+ int (*get_bin)(float in, int w);
5962 } AudioHistogramContext;
6063
6164 #define OFFSET(x) offsetof(AudioHistogramContext, x)
@@ -83,6 +86,9 @@ static const AVOption ahistogram_options[] = { · 21 unmodified lines
8386 { "slide", "set sonogram sliding", OFFSET(slide), AV_OPT_TYPE_INT, {.i64=REPLACE}, 0, NB_SLIDES-1, FLAGS, "slide" },
8487 { "replace", "replace old rows with new", 0, AV_OPT_TYPE_CONST, {.i64=REPLACE}, 0, 0, FLAGS, "slide" },
8588 { "scroll", "scroll from top to bottom", 0, AV_OPT_TYPE_CONST, {.i64=SCROLL}, 0, 0, FLAGS, "slide" },
89+ { "hmode", "set histograms mode", OFFSET(hmode), AV_OPT_TYPE_INT, {.i64=ABS}, 0, NB_HMODES-1, FLAGS, "hmode" },
90+ { "abs", "use absolute samples", 0, AV_OPT_TYPE_CONST, {.i64=ABS}, 0, 0, FLAGS, "hmode" },
91+ { "sign", "use unchanged samples", 0, AV_OPT_TYPE_CONST, {.i64=SIGN},0, 0, FLAGS, "hmode" },
8692 { NULL }
8793 };
8894
@@ -133,6 +139,26 @@ static int config_input(AVFilterLink *inlink) · 44 unmodified lines
133139 return 0;
134140 }
135141
142+static int get_lin_bin_abs(float in, int w)
143+{
144+ return lrintf(av_clipf(fabsf(in), 0.f, 1.f) * (w - 1));
145+}
146+
147+static int get_lin_bin_sign(float in, int w)
148+{
149+ return lrintf((1.f + av_clipf(in, -1.f, 1.f)) * 0.5f * (w - 1));
150+}
151+
152+static int get_log_bin_abs(float in, int w)
153+{
154+ return lrintf(av_clipf(1.f + log10f(fabsf(in)) / 6.f, 0.f, 1.f) * (w - 1));
155+}
156+
157+static int get_log_bin_sign(float in, int w)
158+{
159+ return (w / 2) + FFSIGN(in) * lrintf(av_clipf(1.f + log10f(fabsf(in)) / 6.f, 0.f, 1.f) * (w / 2));
160+}
161+
136162 static int config_output(AVFilterLink *outlink)
137163 {
138164 AudioHistogramContext *s = outlink->src->priv;
@@ -145,6 +171,27 @@ static int config_output(AVFilterLink *outlink) · 6 unmodified lines
145171 s->histogram_h = s->h * s->phisto;
146172 s->ypos = s->h * s->phisto;
147173
174+ switch (s->ascale) {
175+ case ALINEAR:
176+ switch (s->hmode) {
177+ case ABS: s->get_bin = get_lin_bin_abs; break;
178+ case SIGN: s->get_bin = get_lin_bin_sign; break;
179+ default:
180+ return AVERROR_BUG;
181+ }
182+ break;
183+ case ALOG:
184+ switch (s->hmode) {
185+ case ABS: s->get_bin = get_log_bin_abs; break;
186+ case SIGN: s->get_bin = get_log_bin_sign; break;
187+ default:
188+ return AVERROR_BUG;
189+ }
190+ break;
191+ default:
192+ return AVERROR_BUG;
193+ }
194+
148195 if (s->dmode == SEPARATE) {
149196 s->combine_buffer = av_malloc_array(outlink->w * 3, sizeof(*s->combine_buffer));
150197 if (!s->combine_buffer)
@@ -207,7 +254,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 56 unmodified lines
207254 uint64_t *achistogram = &s->achistogram[(s->dmode == SINGLE ? 0: c) * w];
208255
209256 for (n = 0; n < in->nb_samples; n++) {
210− bin = lrint(av_clipf(fabsf(src[n]), 0, 1) * (w - 1));
257+ bin = s->get_bin(src[n], w);
211258
212259 achistogram[bin]++;
213260 }
@@ -217,7 +264,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 3 unmodified lines
217264 const float *src2 = (const float *)s->in[s->first]->extended_data[c];
218265
219266 for (n = 0; n < in->nb_samples; n++) {
220− bin = lrint(av_clipf(fabsf(src2[n]), 0, 1) * (w - 1));
267+ bin = s->get_bin(src2[n], w);
221268
222269 shistogram[bin]++;
223270 }
@@ -230,7 +277,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 6 unmodified lines
230277 uint64_t *achistogram = &s->achistogram[(s->dmode == SINGLE ? 0: c) * w];
231278
232279 for (n = 0; n < in->nb_samples; n++) {
233− bin = lrint(av_clipf(1 + log10(fabsf(src[n])) / 6, 0, 1) * (w - 1));
280+ bin = s->get_bin(src[n], w);
234281
235282 achistogram[bin]++;
236283 }
@@ -240,7 +287,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 3 unmodified lines
240287 const float *src2 = (const float *)s->in[s->first]->extended_data[c];
241288
242289 for (n = 0; n < in->nb_samples; n++) {
243− bin = lrint(av_clipf(1 + log10(fabsf(src2[n])) / 6, 0, 1) * (w - 1));
290+ bin = s->get_bin(src2[n], w);
244291
245292 shistogram[bin]++;
246293 }
@@ -265,7 +312,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 18 unmodified lines
265312 float yf, uf, vf;
266313
267314 if (s->dmode == SEPARATE) {
268− yf = 256.0f / s->dchannels;
315+ yf = 255.0f / s->dchannels;
269316 uf = yf * M_PI;
270317 vf = yf * M_PI;
271318 uf *= 0.5 * sin((2 * M_PI * c) / s->dchannels);
@@ -312,7 +359,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 40 unmodified lines
312359 if (s->h - H > 0) {
313360 h = aa * 255;
314361
315− s->out->data[0][s->ypos * s->out->linesize[0] + n] = h;
362+ s->out->data[0][s->ypos * s->out->linesize[0] + n] = av_clip(h, 0, 255);
316363 s->out->data[1][s->ypos * s->out->linesize[1] + n] = 127;
317364 s->out->data[2][s->ypos * s->out->linesize[2] + n] = 127;
318365 s->out->data[3][s->ypos * s->out->linesize[3] + n] = 255;
@@ -326,9 +373,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 7 unmodified lines
326373 if (s->out->data[0][y * s->out->linesize[0] + n] != old)
327374 break;
328375 old = s->out->data[0][y * s->out->linesize[0] + n];
329− s->out->data[0][y * s->out->linesize[0] + n] = yf;
330− s->out->data[1][y * s->out->linesize[1] + n] = 128+uf;
331− s->out->data[2][y * s->out->linesize[2] + n] = 128+vf;
376+ s->out->data[0][y * s->out->linesize[0] + n] = av_clip(yf, 0, 255);
377+ s->out->data[1][y * s->out->linesize[1] + n] = av_clip(128.f+uf, 0, 255);
378+ s->out->data[2][y * s->out->linesize[2] + n] = av_clip(128.f+vf, 0, 255);
332379 s->out->data[3][y * s->out->linesize[3] + n] = 255;
333380 }
334381

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