| @@ -44,6 +44,7 @@ enum VectorScopeMode { · 43 unmodified lines |
| 44 | enum VectorScopeDraw { | 44 | enum 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 | |
| 116 | AVFILTER_DEFINE_CLASS(avectorscope); | 118 | AVFILTER_DEFINE_CLASS(avectorscope); |
| 117 | | 119 | |
| 118 | static void draw_dot(AudioVectorScopeContext *s, unsigned x, unsigned y) | 120 | static 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 | |
| 138 | static void draw_line(AudioVectorScopeContext *s, int x0, int y0, int x1, int y1) | 140 | static 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 | |
| | 166 | static 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 | |
| 164 | static int fade(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) | 200 | static 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; |