History

avfilter/avf_ahistogram: add new histogram mode option

Paul B Mahol committed 4 years ago

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

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

Unified · Split

libavfilter/avf_ahistogram.c+57−10
@@ -32,7 +32,7 @@ enum DisplayScale { LINEAR, SQRT, CBRT, LOG, RLOG, NB_SCALES }; · 31 unmodified lines
32enum AmplitudeScale { ALINEAR, ALOG, NB_ASCALES };32enum AmplitudeScale { ALINEAR, ALOG, NB_ASCALES };
33enum SlideMode { REPLACE, SCROLL, NB_SLIDES };33enum SlideMode { REPLACE, SCROLL, NB_SLIDES };
34enum DisplayMode { SINGLE, SEPARATE, NB_DMODES };34enum DisplayMode { SINGLE, SEPARATE, NB_DMODES };
35enum HistogramMode { ACCUMULATE, CURRENT, NB_HMODES };35enum HistogramMode { ABS, SIGN, NB_HMODES };
36 36
37typedef struct AudioHistogramContext {37typedef struct AudioHistogramContext {
38 const AVClass *class;38 const AVClass *class;
@@ -49,6 +49,7 @@ typedef struct AudioHistogramContext { · 10 unmodified lines
49 int ypos;49 int ypos;
50 int slide;50 int slide;
51 int dmode;51 int dmode;
52 int hmode;
52 int dchannels;53 int dchannels;
53 int count;54 int count;
54 int frame_count;55 int frame_count;
@@ -56,6 +57,8 @@ typedef struct AudioHistogramContext { · 1 unmodified line
56 AVFrame *in[101];57 AVFrame *in[101];
57 int first;58 int first;
58 int nb_samples;59 int nb_samples;
60
61 int (*get_bin)(float in, int w);
59} AudioHistogramContext;62} AudioHistogramContext;
60 63
61#define OFFSET(x) offsetof(AudioHistogramContext, x)64#define OFFSET(x) offsetof(AudioHistogramContext, x)
@@ -83,6 +86,9 @@ static const AVOption ahistogram_options[] = { · 21 unmodified lines
83 { "slide", "set sonogram sliding", OFFSET(slide), AV_OPT_TYPE_INT, {.i64=REPLACE}, 0, NB_SLIDES-1, FLAGS, "slide" },86 { "slide", "set sonogram sliding", OFFSET(slide), AV_OPT_TYPE_INT, {.i64=REPLACE}, 0, NB_SLIDES-1, FLAGS, "slide" },
84 { "replace", "replace old rows with new", 0, AV_OPT_TYPE_CONST, {.i64=REPLACE}, 0, 0, FLAGS, "slide" },87 { "replace", "replace old rows with new", 0, AV_OPT_TYPE_CONST, {.i64=REPLACE}, 0, 0, FLAGS, "slide" },
85 { "scroll", "scroll from top to bottom", 0, AV_OPT_TYPE_CONST, {.i64=SCROLL}, 0, 0, FLAGS, "slide" },88 { "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" },
86 { NULL }92 { NULL }
87};93};
88 94
@@ -133,6 +139,26 @@ static int config_input(AVFilterLink *inlink) · 44 unmodified lines
133 return 0;139 return 0;
134}140}
135 141
142static 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
147static 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
152static 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
157static 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
136static int config_output(AVFilterLink *outlink)162static int config_output(AVFilterLink *outlink)
137{163{
138 AudioHistogramContext *s = outlink->src->priv;164 AudioHistogramContext *s = outlink->src->priv;
@@ -145,6 +171,27 @@ static int config_output(AVFilterLink *outlink) · 6 unmodified lines
145 s->histogram_h = s->h * s->phisto;171 s->histogram_h = s->h * s->phisto;
146 s->ypos = s->h * s->phisto;172 s->ypos = s->h * s->phisto;
147 173
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
148 if (s->dmode == SEPARATE) {195 if (s->dmode == SEPARATE) {
149 s->combine_buffer = av_malloc_array(outlink->w * 3, sizeof(*s->combine_buffer));196 s->combine_buffer = av_malloc_array(outlink->w * 3, sizeof(*s->combine_buffer));
150 if (!s->combine_buffer)197 if (!s->combine_buffer)
@@ -207,7 +254,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 56 unmodified lines
207 uint64_t *achistogram = &s->achistogram[(s->dmode == SINGLE ? 0: c) * w];254 uint64_t *achistogram = &s->achistogram[(s->dmode == SINGLE ? 0: c) * w];
208 255
209 for (n = 0; n < in->nb_samples; n++) {256 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);
211 258
212 achistogram[bin]++;259 achistogram[bin]++;
213 }260 }
@@ -217,7 +264,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 3 unmodified lines
217 const float *src2 = (const float *)s->in[s->first]->extended_data[c];264 const float *src2 = (const float *)s->in[s->first]->extended_data[c];
218 265
219 for (n = 0; n < in->nb_samples; n++) {266 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);
221 268
222 shistogram[bin]++;269 shistogram[bin]++;
223 }270 }
@@ -230,7 +277,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 6 unmodified lines
230 uint64_t *achistogram = &s->achistogram[(s->dmode == SINGLE ? 0: c) * w];277 uint64_t *achistogram = &s->achistogram[(s->dmode == SINGLE ? 0: c) * w];
231 278
232 for (n = 0; n < in->nb_samples; n++) {279 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);
234 281
235 achistogram[bin]++;282 achistogram[bin]++;
236 }283 }
@@ -240,7 +287,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 3 unmodified lines
240 const float *src2 = (const float *)s->in[s->first]->extended_data[c];287 const float *src2 = (const float *)s->in[s->first]->extended_data[c];
241 288
242 for (n = 0; n < in->nb_samples; n++) {289 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);
244 291
245 shistogram[bin]++;292 shistogram[bin]++;
246 }293 }
@@ -265,7 +312,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 18 unmodified lines
265 float yf, uf, vf;312 float yf, uf, vf;
266 313
267 if (s->dmode == SEPARATE) {314 if (s->dmode == SEPARATE) {
268 yf = 256.0f / s->dchannels;315 yf = 255.0f / s->dchannels;
269 uf = yf * M_PI;316 uf = yf * M_PI;
270 vf = yf * M_PI;317 vf = yf * M_PI;
271 uf *= 0.5 * sin((2 * M_PI * c) / s->dchannels);318 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
312 if (s->h - H > 0) {359 if (s->h - H > 0) {
313 h = aa * 255;360 h = aa * 255;
314 361
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);
316 s->out->data[1][s->ypos * s->out->linesize[1] + n] = 127;363 s->out->data[1][s->ypos * s->out->linesize[1] + n] = 127;
317 s->out->data[2][s->ypos * s->out->linesize[2] + n] = 127;364 s->out->data[2][s->ypos * s->out->linesize[2] + n] = 127;
318 s->out->data[3][s->ypos * s->out->linesize[3] + n] = 255;365 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
326 if (s->out->data[0][y * s->out->linesize[0] + n] != old)373 if (s->out->data[0][y * s->out->linesize[0] + n] != old)
327 break;374 break;
328 old = s->out->data[0][y * s->out->linesize[0] + n];375 old = s->out->data[0][y * s->out->linesize[0] + n];
329 s->out->data[0][y * s->out->linesize[0] + n] = yf;376 s->out->data[0][y * s->out->linesize[0] + n] = av_clip(yf, 0, 255);
330 s->out->data[1][y * s->out->linesize[1] + n] = 128+uf;377 s->out->data[1][y * s->out->linesize[1] + n] = av_clip(128.f+uf, 0, 255);
331 s->out->data[2][y * s->out->linesize[2] + n] = 128+vf;378 s->out->data[2][y * s->out->linesize[2] + n] = av_clip(128.f+vf, 0, 255);
332 s->out->data[3][y * s->out->linesize[3] + n] = 255;379 s->out->data[3][y * s->out->linesize[3] + n] = 255;
333 }380 }
334 381

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