History

avfilter/avf_avectorscope: add anti-aliased line drawing mode

Paul B Mahol committed 3 years ago

Commit 5d3f0221 parent dae36792 files · +53 −11Browse files

Unified · Split

2 files
  1. doc/filters.texi +3 −0
  2. libavfilter/avf_avectorscope.c +50 −11
doc/filters.texi+3−0
@@ -27933,6 +27933,9 @@ Draw dot for each sample. · 27932 unmodified lines
27933 27933
27934@item line27934@item line
27935Draw line between previous and current sample.27935Draw line between previous and current sample.
27936
27937@item aaline
27938Draw anti-aliased line between previous and current sample.
27936@end table27939@end table
27937 27940
27938Default value is @samp{dot}.27941Default value is @samp{dot}.
libavfilter/avf_avectorscope.c+50−11
@@ -44,6 +44,7 @@ enum VectorScopeMode { · 43 unmodified lines
44enum VectorScopeDraw {44enum VectorScopeDraw {
45 DOT,45 DOT,
46 LINE,46 LINE,
47 AALINE,
47 DRAW_NB,48 DRAW_NB,
48};49};
49 50
@@ -97,8 +98,9 @@ static const AVOption avectorscope_options[] = { · 47 unmodified lines
97 { "af", "set alpha fade", OFFSET(fade[3]), AV_OPT_TYPE_INT, {.i64=5}, 0, 255, TFLAGS },98 { "af", "set alpha fade", OFFSET(fade[3]), AV_OPT_TYPE_INT, {.i64=5}, 0, 255, TFLAGS },
98 { "zoom", "set zoom factor", OFFSET(zoom), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 10, TFLAGS },99 { "zoom", "set zoom factor", OFFSET(zoom), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 10, TFLAGS },
99 { "draw", "set draw mode", OFFSET(draw), AV_OPT_TYPE_INT, {.i64=DOT}, 0, DRAW_NB-1, TFLAGS, "draw" },100 { "draw", "set draw mode", OFFSET(draw), AV_OPT_TYPE_INT, {.i64=DOT}, 0, DRAW_NB-1, TFLAGS, "draw" },
100 { "dot", "", 0, AV_OPT_TYPE_CONST, {.i64=DOT} , 0, 0, TFLAGS, "draw" },101 { "dot", "draw dots", 0, AV_OPT_TYPE_CONST, {.i64=DOT} , 0, 0, TFLAGS, "draw" },
101 { "line", "", 0, AV_OPT_TYPE_CONST, {.i64=LINE}, 0, 0, TFLAGS, "draw" },102 { "line", "draw lines", 0, AV_OPT_TYPE_CONST, {.i64=LINE}, 0, 0, TFLAGS, "draw" },
103 { "aaline","draw anti-aliased lines", 0, AV_OPT_TYPE_CONST, {.i64=AALINE},0,0, TFLAGS, "draw" },
102 { "scale", "set amplitude scale mode", OFFSET(scale), AV_OPT_TYPE_INT, {.i64=LIN}, 0, SCALE_NB-1, TFLAGS, "scale" },104 { "scale", "set amplitude scale mode", OFFSET(scale), AV_OPT_TYPE_INT, {.i64=LIN}, 0, SCALE_NB-1, TFLAGS, "scale" },
103 { "lin", "linear", 0, AV_OPT_TYPE_CONST, {.i64=LIN}, 0, 0, TFLAGS, "scale" },105 { "lin", "linear", 0, AV_OPT_TYPE_CONST, {.i64=LIN}, 0, 0, TFLAGS, "scale" },
104 { "sqrt", "square root", 0, AV_OPT_TYPE_CONST, {.i64=SQRT}, 0, 0, TFLAGS, "scale" },106 { "sqrt", "square root", 0, AV_OPT_TYPE_CONST, {.i64=SQRT}, 0, 0, TFLAGS, "scale" },
@@ -115,7 +117,7 @@ static const AVOption avectorscope_options[] = { · 10 unmodified lines
115 117
116AVFILTER_DEFINE_CLASS(avectorscope);118AVFILTER_DEFINE_CLASS(avectorscope);
117 119
118static void draw_dot(AudioVectorScopeContext *s, unsigned x, unsigned y)120static void draw_dot(AudioVectorScopeContext *s, unsigned x, unsigned y, int value)
119{121{
120 const ptrdiff_t linesize = s->outpicref->linesize[0];122 const ptrdiff_t linesize = s->outpicref->linesize[0];
121 uint8_t *dst;123 uint8_t *dst;
@@ -129,10 +131,10 @@ static void draw_dot(AudioVectorScopeContext *s, unsigned x, unsigned y) · 7 unmodified lines
129 }131 }
130 132
131 dst = s->outpicref->data[0] + y * linesize + x * 4;133 dst = s->outpicref->data[0] + y * linesize + x * 4;
132 dst[0] = FFMIN(dst[0] + s->contrast[0], 255);134 dst[0] = FFMIN(dst[0] + s->contrast[0], value);
133 dst[1] = FFMIN(dst[1] + s->contrast[1], 255);135 dst[1] = FFMIN(dst[1] + s->contrast[1], value);
134 dst[2] = FFMIN(dst[2] + s->contrast[2], 255);136 dst[2] = FFMIN(dst[2] + s->contrast[2], value);
135 dst[3] = FFMIN(dst[3] + s->contrast[3], 255);137 dst[3] = FFMIN(dst[3] + s->contrast[3], value);
136}138}
137 139
138static void draw_line(AudioVectorScopeContext *s, int x0, int y0, int x1, int y1)140static void draw_line(AudioVectorScopeContext *s, int x0, int y0, int x1, int y1)
@@ -142,7 +144,7 @@ static void draw_line(AudioVectorScopeContext *s, int x0, int y0, int x1, int y1 · 3 unmodified lines
142 int err = (dx>dy ? dx : -dy) / 2, e2;144 int err = (dx>dy ? dx : -dy) / 2, e2;
143 145
144 for (;;) {146 for (;;) {
145 draw_dot(s, x0, y0);147 draw_dot(s, x0, y0, 255);
146 148
147 if (x0 == x1 && y0 == y1)149 if (x0 == x1 && y0 == y1)
148 break;150 break;
@@ -161,6 +163,40 @@ static void draw_line(AudioVectorScopeContext *s, int x0, int y0, int x1, int y1 · 12 unmodified lines
161 }163 }
162}164}
163 165
166static void draw_aaline(AudioVectorScopeContext *s, int x0, int y0, int x1, int y1)
167{
168 int sx = x0 < x1 ? 1 : -1, sy = y0 < y1 ? 1 : -1, x2;
169 int dx = FFABS(x1-x0), dy = FFABS(y1-y0), err = dx * dx + dy * dy;
170 int e2 = err == 0 ? 1 : 0xffffff / (dx + dy);
171
172 dx *= e2;
173 dy *= e2;
174 err = dx - dy;
175
176 for (;;) {
177 draw_dot(s, x0, y0, 255-(FFABS(err - dx + dy) >> 16));
178 e2 = err;
179 x2 = x0;
180 if (2 * e2 >= -dx) {
181 if (x0 == x1)
182 break;
183 if (e2 + dy < 0xff0000)
184 draw_dot(s, x0, y0 + sy, 255-((e2 + dy) >> 16));
185 err -= dy;
186 x0 += sx;
187 }
188
189 if (2 * e2 <= dy) {
190 if (y0 == y1)
191 break;
192 if (dx - e2 < 0xff0000)
193 draw_dot(s, x2 + sx, y0, 255-((dx - e2) >> 16));
194 err += dx;
195 y0 += sy;
196 }
197 }
198}
199
164static int fade(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)200static int fade(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
165{201{
166 AudioVectorScopeContext *s = ctx->priv;202 AudioVectorScopeContext *s = ctx->priv;
@@ -312,7 +348,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 145 unmodified lines
312 break;348 break;
313 }349 }
314 350
315 zoom = 1. / max;351 if (max > 0.f)
352 zoom = 1. / max;
316 }353 }
317 354
318 for (int i = 0; i < insamples->nb_samples; i++) {355 for (int i = 0; i < insamples->nb_samples; i++) {
@@ -373,9 +410,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 54 unmodified lines
373 }410 }
374 411
375 if (s->draw == DOT) {412 if (s->draw == DOT) {
376 draw_dot(s, x, y);413 draw_dot(s, x, y, 255);
377 } else {414 } else if (s->draw == LINE) {
378 draw_line(s, x, y, prev_x, prev_y);415 draw_line(s, x, y, prev_x, prev_y);
416 } else {
417 draw_aaline(s, x, y, prev_x, prev_y);
379 }418 }
380 prev_x = x;419 prev_x = x;
381 prev_y = y;420 prev_y = y;

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