mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-25 08:42:39 +00:00
avfilter/avf_avectorscope: add line drawing support
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
c13216ac08
commit
206f65b06d
@ -13372,6 +13372,20 @@ Allowed range is @code{[0, 255]}.
|
||||
|
||||
@item zoom
|
||||
Set the zoom factor. Default value is @code{1}. Allowed range is @code{[1, 10]}.
|
||||
|
||||
@item draw
|
||||
Set the vectorscope drawing mode.
|
||||
|
||||
Available values are:
|
||||
@table @samp
|
||||
@item dot
|
||||
Draw dot for each sample.
|
||||
|
||||
@item line
|
||||
Draw line between previous and current sample.
|
||||
@end table
|
||||
|
||||
Default value is @samp{dot}.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
@ -40,15 +40,23 @@ enum VectorScopeMode {
|
||||
MODE_NB,
|
||||
};
|
||||
|
||||
enum VectorScopeDraw {
|
||||
DOT,
|
||||
LINE,
|
||||
DRAW_NB,
|
||||
};
|
||||
|
||||
typedef struct AudioVectorScopeContext {
|
||||
const AVClass *class;
|
||||
AVFrame *outpicref;
|
||||
int w, h;
|
||||
int hw, hh;
|
||||
int mode;
|
||||
int draw;
|
||||
int contrast[4];
|
||||
int fade[4];
|
||||
double zoom;
|
||||
unsigned prev_x, prev_y;
|
||||
AVRational frame_rate;
|
||||
} AudioVectorScopeContext;
|
||||
|
||||
@ -74,6 +82,9 @@ static const AVOption avectorscope_options[] = {
|
||||
{ "bf", "set blue fade", OFFSET(fade[2]), AV_OPT_TYPE_INT, {.i64=5}, 0, 255, FLAGS },
|
||||
{ "af", "set alpha fade", OFFSET(fade[3]), AV_OPT_TYPE_INT, {.i64=5}, 0, 255, FLAGS },
|
||||
{ "zoom", "set zoom factor", OFFSET(zoom), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 1, 10, FLAGS },
|
||||
{ "draw", "set draw mode", OFFSET(draw), AV_OPT_TYPE_INT, {.i64=DOT}, 0, DRAW_NB-1, FLAGS, "draw" },
|
||||
{ "dot", "", 0, AV_OPT_TYPE_CONST, {.i64=DOT} , 0, 0, FLAGS, "draw" },
|
||||
{ "line", "", 0, AV_OPT_TYPE_CONST, {.i64=LINE}, 0, 0, FLAGS, "draw" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -99,6 +110,32 @@ static void draw_dot(AudioVectorScopeContext *s, unsigned x, unsigned y)
|
||||
dst[3] = FFMIN(dst[3] + s->contrast[3], 255);
|
||||
}
|
||||
|
||||
static void draw_line(AudioVectorScopeContext *s, int x0, int y0, int x1, int y1)
|
||||
{
|
||||
int dx = FFABS(x1-x0), sx = x0 < x1 ? 1 : -1;
|
||||
int dy = FFABS(y1-y0), sy = y0 < y1 ? 1 : -1;
|
||||
int err = (dx>dy ? dx : -dy) / 2, e2;
|
||||
|
||||
for (;;) {
|
||||
draw_dot(s, x0, y0);
|
||||
|
||||
if (x0 == x1 && y0 == y1)
|
||||
break;
|
||||
|
||||
e2 = err;
|
||||
|
||||
if (e2 >-dx) {
|
||||
err -= dy;
|
||||
x0 += sx;
|
||||
}
|
||||
|
||||
if (e2 < dy) {
|
||||
err += dx;
|
||||
y0 += sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void fade(AudioVectorScopeContext *s)
|
||||
{
|
||||
const int linesize = s->outpicref->linesize[0];
|
||||
@ -168,8 +205,8 @@ static int config_output(AVFilterLink *outlink)
|
||||
outlink->sample_aspect_ratio = (AVRational){1,1};
|
||||
outlink->frame_rate = s->frame_rate;
|
||||
|
||||
s->hw = s->w / 2;
|
||||
s->hh = s->h / 2;
|
||||
s->prev_x = s->hw = s->w / 2;
|
||||
s->prev_y = s->hh = s->h / 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -182,6 +219,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
|
||||
const int hw = s->hw;
|
||||
const int hh = s->hh;
|
||||
unsigned x, y;
|
||||
unsigned prev_x = s->prev_x, prev_y = s->prev_y;
|
||||
const double zoom = s->zoom;
|
||||
int i;
|
||||
|
||||
@ -223,7 +261,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
|
||||
y = s->h - s->h * fabsf(cx + cy) * .7;
|
||||
}
|
||||
|
||||
draw_dot(s, x, y);
|
||||
if (s->draw == DOT) {
|
||||
draw_dot(s, x, y);
|
||||
} else {
|
||||
draw_line(s, x, y, prev_x, prev_y);
|
||||
}
|
||||
prev_x = x;
|
||||
prev_y = y;
|
||||
}
|
||||
break;
|
||||
case AV_SAMPLE_FMT_FLT:
|
||||
@ -247,11 +291,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
|
||||
y = s->h - s->h * fabsf(cx + cy) * .7;
|
||||
}
|
||||
|
||||
draw_dot(s, x, y);
|
||||
if (s->draw == DOT) {
|
||||
draw_dot(s, x, y);
|
||||
} else {
|
||||
draw_line(s, x, y, prev_x, prev_y);
|
||||
}
|
||||
prev_x = x;
|
||||
prev_y = y;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
s->prev_x = x, s->prev_y = y;
|
||||
av_frame_free(&insamples);
|
||||
|
||||
return ff_filter_frame(outlink, av_frame_clone(s->outpicref));
|
||||
|
Loading…
Reference in New Issue
Block a user