summaryrefslogtreecommitdiff
path: root/libavfilter/vf_histogram.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2020-09-26 21:57:46 +0200
committerPaul B Mahol <onemda@gmail.com>2020-09-26 22:04:27 +0200
commit85195f6ae99931212ed89ebb59ce62d2b40d397b (patch)
tree4f7b5b47e231d9c54e13964f158e8289e673e55c /libavfilter/vf_histogram.c
parenta162e78cd5f6cf3d8fc30169fc7df482905df01b (diff)
avfilter/vf_histogram: add slide modes for thistogram
Diffstat (limited to 'libavfilter/vf_histogram.c')
-rw-r--r--libavfilter/vf_histogram.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/libavfilter/vf_histogram.c b/libavfilter/vf_histogram.c
index 4800c06f26..ed6892bc8b 100644
--- a/libavfilter/vf_histogram.c
+++ b/libavfilter/vf_histogram.c
@@ -34,6 +34,7 @@ typedef struct HistogramContext {
const AVClass *class; ///< AVClass context for log and options purpose
int thistogram;
int envelope;
+ int slide;
unsigned histogram[256*256];
int histogram_size;
int width;
@@ -354,8 +355,25 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
max_hval_log = log2(max_hval + 1);
if (s->thistogram) {
+ const int bpp = 1 + (s->histogram_size > 256);
int minh = s->histogram_size - 1, maxh = 0;
+ if (s->slide == 2) {
+ s->x_pos = out->width - 1;
+ for (j = 0; j < outlink->h; j++) {
+ memmove(out->data[p] + j * out->linesize[p] ,
+ out->data[p] + j * out->linesize[p] + bpp,
+ (outlink->w - 1) * bpp);
+ }
+ } else if (s->slide == 3) {
+ s->x_pos = 0;
+ for (j = 0; j < outlink->h; j++) {
+ memmove(out->data[p] + j * out->linesize[p] + bpp,
+ out->data[p] + j * out->linesize[p],
+ (outlink->w - 1) * bpp);
+ }
+ }
+
for (int i = 0; i < s->histogram_size; i++) {
int idx = s->histogram_size - i - 1;
int value = s->start[p];
@@ -443,8 +461,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
out->pts = in->pts;
av_frame_free(&in);
s->x_pos++;
- if (s->x_pos >= s->width)
+ if (s->x_pos >= s->width) {
s->x_pos = 0;
+ if (s->thistogram && (s->slide == 4 || s->slide == 0)) {
+ s->out = NULL;
+ goto end;
+ }
+ } else if (s->thistogram && s->slide == 4) {
+ return 0;
+ }
if (s->thistogram) {
AVFrame *clone = av_frame_clone(out);
@@ -453,6 +478,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
return AVERROR(ENOMEM);
return ff_filter_frame(outlink, clone);
}
+end:
return ff_filter_frame(outlink, out);
}
@@ -491,6 +517,13 @@ AVFilter ff_vf_histogram = {
#if CONFIG_THISTOGRAM_FILTER
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ HistogramContext *s = ctx->priv;
+
+ av_frame_free(&s->out);
+}
+
static const AVOption thistogram_options[] = {
{ "width", "set width", OFFSET(width), AV_OPT_TYPE_INT, {.i64=0}, 0, 8192, FLAGS},
{ "w", "set width", OFFSET(width), AV_OPT_TYPE_INT, {.i64=0}, 0, 8192, FLAGS},
@@ -501,6 +534,12 @@ static const AVOption thistogram_options[] = {
{ "e", "display envelope", OFFSET(envelope), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
{ "ecolor", "set envelope color", OFFSET(envelope_rgba), AV_OPT_TYPE_COLOR, {.str="gold"}, 0, 0, FLAGS },
{ "ec", "set envelope color", OFFSET(envelope_rgba), AV_OPT_TYPE_COLOR, {.str="gold"}, 0, 0, FLAGS },
+ { "slide", "set slide mode", OFFSET(slide), AV_OPT_TYPE_INT, {.i64=1}, 0, 4, FLAGS, "slide" },
+ {"frame", "draw new frames", OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "slide"},
+ {"replace", "replace old columns with new", OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "slide"},
+ {"scroll", "scroll from right to left", OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "slide"},
+ {"rscroll", "scroll from left to right", OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, FLAGS, "slide"},
+ {"picture", "display graph in single frame", OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, FLAGS, "slide"},
{ NULL }
};
@@ -513,6 +552,7 @@ AVFilter ff_vf_thistogram = {
.query_formats = query_formats,
.inputs = inputs,
.outputs = outputs,
+ .uninit = uninit,
.priv_class = &thistogram_class,
};