PR #25218 opened by nico-lab
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25218
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25218.patch

# Summary of changes

Add a `mode` option to `signalstats` so callers can calculate only the 
statistics they need, reducing unnecessary processing and buffer allocation. 
The default `mode=all` preserves existing behavior, and the `stat` and `out` 
options remain independent.

Also handle frame-cloning failures safely and remove an unused hue calculation. 
Update the documentation and add FATE coverage for metric selection with 8-bit 
and 10-bit inputs.

No new FATE test samples are required.

<!--
If this PR requires new FATE test samples, attach them to the PR and
list their target paths below (relative to the fate-suite root).

Attached filenames must match the sample's filename:

```fate-samples
# e.g. vorbis/new-sample.ogg
```
-->



>From 3cdbc95e0f8b24548c2debee8a96afa51fcf971e Mon Sep 17 00:00:00 2001
From: nico_lab <[email protected]>
Date: Mon, 19 Oct 2026 20:10:00 +0900
Subject: [PATCH 1/4] avfilter/vf_signalstats: cosmetics

Fix spacing around operators, realign the SET_META macro and
reword a comment.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 libavfilter/vf_signalstats.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/libavfilter/vf_signalstats.c b/libavfilter/vf_signalstats.c
index 5859b46478..431db1dc14 100644
--- a/libavfilter/vf_signalstats.c
+++ b/libavfilter/vf_signalstats.c
@@ -561,7 +561,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     int accy, accu, accv;
     int accsat, acchue = 0;
     int medhue, maxhue;
-    int64_t toty = 0, totu = 0, totv = 0, totsat=0;
+    int64_t toty = 0, totu = 0, totv = 0, totsat = 0;
     int64_t tothue = 0;
     int64_t dify = 0, difu = 0, difv = 0;
     uint16_t masky = 0, masku = 0, maskv = 0;
@@ -686,8 +686,8 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
         }
     }
 
-    for (fil = 0; fil < FILT_NUMB; fil ++) {
-        if (s->filters & 1<<fil) {
+    for (fil = 0; fil < FILT_NUMB; fil++) {
+        if (s->filters & 1 << fil) {
             ThreadData td = {
                 .in = in,
                 .out = out != in && s->outfilter == fil ? out : NULL,
@@ -700,9 +700,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
         }
     }
 
-    // find low / high based on histogram percentile
-    // these only need to be calculated once.
-
+    // Find low / high based on histogram percentile.
     lowp   = lrint(s->fs  * 10 / 100.);
     highp  = lrint(s->fs  * 90 / 100.);
     clowp  = lrint(s->cfs * 10 / 100.);
@@ -757,9 +755,9 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     av_frame_free(&s->frame_prev);
     s->frame_prev = av_frame_clone(in);
 
-#define SET_META(key, fmt, val) do {                                \
-    snprintf(metabuf, sizeof(metabuf), fmt, val);                   \
-    av_dict_set(&out->metadata, "lavfi.signalstats." key, metabuf, 0);   \
+#define SET_META(key, fmt, val) do {                                    \
+    snprintf(metabuf, sizeof(metabuf), fmt, val);                       \
+    av_dict_set(&out->metadata, "lavfi.signalstats." key, metabuf, 0);  \
 } while (0)
 
     av_dict_set_int(&out->metadata, "lavfi.signalstats.YMIN", miny, 0);
@@ -797,8 +795,8 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     av_dict_set_int(&out->metadata, "lavfi.signalstats.UBITDEPTH", 
compute_bit_depth(masku), 0);
     av_dict_set_int(&out->metadata, "lavfi.signalstats.VBITDEPTH", 
compute_bit_depth(maskv), 0);
 
-    for (fil = 0; fil < FILT_NUMB; fil ++) {
-        if (s->filters & 1<<fil) {
+    for (fil = 0; fil < FILT_NUMB; fil++) {
+        if (s->filters & 1 << fil) {
             char metaname[128];
             snprintf(metabuf,  sizeof(metabuf),  "%g", 1.0 * filtot[fil] / 
s->fs);
             snprintf(metaname, sizeof(metaname), "lavfi.signalstats.%s", 
filters_def[fil].name);
-- 
2.54.0


>From c1d6af4d474ada9196a4060a535ddf5219b36a0f Mon Sep 17 00:00:00 2001
From: nico_lab <[email protected]>
Date: Mon, 19 Oct 2026 20:10:01 +0900
Subject: [PATCH 2/4] avfilter/vf_signalstats: remove unused maxhue

maxhue is computed for every frame but never exported or used.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 libavfilter/vf_signalstats.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/libavfilter/vf_signalstats.c b/libavfilter/vf_signalstats.c
index 431db1dc14..7405b7b2bb 100644
--- a/libavfilter/vf_signalstats.c
+++ b/libavfilter/vf_signalstats.c
@@ -560,7 +560,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     int lowp, highp, clowp, chighp;
     int accy, accu, accv;
     int accsat, acchue = 0;
-    int medhue, maxhue;
+    int medhue;
     int64_t toty = 0, totu = 0, totv = 0, totsat = 0;
     int64_t tothue = 0;
     int64_t dify = 0, difu = 0, difv = 0;
@@ -739,7 +739,6 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
         if (highsat == -1 && accsat >= chighp) highsat = fil;
     }
 
-    maxhue = histhue[0];
     medhue = -1;
     for (fil = 0; fil < 360; fil++) {
         tothue += (uint64_t)histhue[fil] * fil;
@@ -747,9 +746,6 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
 
         if (medhue == -1 && acchue > s->cfs / 2)
             medhue = fil;
-        if (histhue[fil] > maxhue) {
-            maxhue = histhue[fil];
-        }
     }
 
     av_frame_free(&s->frame_prev);
-- 
2.54.0


>From 79efee22d194f0e0456a7a56ba98b3eef183491e Mon Sep 17 00:00:00 2001
From: nico_lab <[email protected]>
Date: Mon, 19 Oct 2026 20:10:02 +0900
Subject: [PATCH 3/4] avfilter/vf_signalstats: check av_frame_clone() results

If cloning the first input frame failed, frame_prev stayed NULL and
was dereferenced while computing the frame differences. Return
ENOMEM instead, and keep the previous reference frame if replacing
it fails.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 libavfilter/vf_signalstats.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/libavfilter/vf_signalstats.c b/libavfilter/vf_signalstats.c
index 7405b7b2bb..a7bbfd94f6 100644
--- a/libavfilter/vf_signalstats.c
+++ b/libavfilter/vf_signalstats.c
@@ -567,7 +567,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     uint16_t masky = 0, masku = 0, maskv = 0;
 
     int filtot[FILT_NUMB] = {0};
-    AVFrame *prev;
+    AVFrame *prev, *new_prev;
     int ret;
     AVFrame *sat = s->frame_sat;
     AVFrame *hue = s->frame_hue;
@@ -580,6 +580,10 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
 
     if (!s->frame_prev)
         s->frame_prev = av_frame_clone(in);
+    if (!s->frame_prev) {
+        av_frame_free(&in);
+        return AVERROR(ENOMEM);
+    }
 
     prev = s->frame_prev;
 
@@ -748,8 +752,15 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
             medhue = fil;
     }
 
+    new_prev = av_frame_clone(in);
+    if (!new_prev) {
+        if (out != in)
+            av_frame_free(&out);
+        av_frame_free(&in);
+        return AVERROR(ENOMEM);
+    }
     av_frame_free(&s->frame_prev);
-    s->frame_prev = av_frame_clone(in);
+    s->frame_prev = new_prev;
 
 #define SET_META(key, fmt, val) do {                                    \
     snprintf(metabuf, sizeof(metabuf), fmt, val);                       \
-- 
2.54.0


>From d67dde306a09eca331ee2fe0f54b63f79eebdd18 Mon Sep 17 00:00:00 2001
From: nico_lab <[email protected]>
Date: Mon, 19 Oct 2026 20:10:03 +0900
Subject: [PATCH 4/4] avfilter/vf_signalstats: add mode option to select
 statistics

Add a mode option that allows callers to select which signal statistics
are calculated. Keep all statistics enabled by default to preserve the
existing behavior.

Skip unused luma/chroma histogram, frame-difference, bit-depth,
saturation, and hue calculations, and avoid allocating the associated
buffers when they are not requested. Keep combined calculations in a
single plane pass when multiple modes are enabled.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 doc/filters.texi                              |  78 +++
 libavfilter/vf_signalstats.c                  | 508 +++++++++++-------
 tests/fate/filter-video.mak                   |  24 +
 ...lter-metadata-signalstats-mode-all-hue-sat |   5 +
 .../filter-metadata-signalstats-mode-default  |   5 +
 .../filter-metadata-signalstats-mode-depth    |   5 +
 .../fate/filter-metadata-signalstats-mode-dif |   5 +
 .../fate/filter-metadata-signalstats-mode-hue |   5 +
 ...filter-metadata-signalstats-mode-minus-hue |   5 +
 .../filter-metadata-signalstats-mode-none     |   5 +
 ...filter-metadata-signalstats-mode-none-brng |   5 +
 .../fate/filter-metadata-signalstats-mode-sat |   5 +
 .../fate/filter-metadata-signalstats-mode-uv  |   5 +
 .../filter-metadata-signalstats-mode-uvdepth  |   5 +
 .../filter-metadata-signalstats-mode-uvdif    |   5 +
 .../fate/filter-metadata-signalstats-mode-y   |   5 +
 .../filter-metadata-signalstats-mode-y-ydif   |   5 +
 .../filter-metadata-signalstats-mode-ydepth   |   5 +
 .../filter-metadata-signalstats-mode-ydif     |   5 +
 19 files changed, 509 insertions(+), 181 deletions(-)
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-all-hue-sat
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-default
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-depth
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-dif
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-hue
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-minus-hue
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-none
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-none-brng
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-sat
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-uv
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-uvdepth
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-uvdif
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-y
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-y-ydif
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-ydepth
 create mode 100644 tests/ref/fate/filter-metadata-signalstats-mode-ydif

diff --git a/doc/filters.texi b/doc/filters.texi
index 3d82a4778f..0a9fa78b92 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -23031,6 +23031,65 @@ Identify pixels that fall outside of legal broadcast 
range.
 @item color, c
 Set the highlight color for the @option{out} option. The default color is
 yellow.
+
+@item mode
+Specify the statistics to calculate. Multiple values can be combined with
+@samp{+}, and values can be removed with @samp{-}, for example
+@samp{all-hue-sat}. A leading @samp{+} or @samp{-} is applied to the default
+value, so @samp{+y} still selects all statistics; use @samp{y} to select only
+the Y-plane statistics.
+
+The default is @samp{all}, which preserves the behavior of calculating and
+exporting all of the statistics listed above. Statistics not selected by this
+option are not calculated and their metadata keys are not exported. The 
analysis selected with the @option{stat} and @option{out}
+options is not affected by this option.
+
+The following values are available:
+
+@table @samp
+@item y
+Calculate Y-plane statistics: @samp{YMIN}, @samp{YLOW}, @samp{YAVG},
+@samp{YHIGH}, and @samp{YMAX}.
+
+@item uv
+Calculate U- and V-plane statistics: @samp{UMIN}, @samp{ULOW}, @samp{UAVG},
+@samp{UHIGH}, @samp{UMAX}, @samp{VMIN}, @samp{VLOW}, @samp{VAVG},
+@samp{VHIGH}, and @samp{VMAX}.
+
+@item sat
+Calculate saturation statistics: @samp{SATMIN}, @samp{SATLOW}, @samp{SATAVG},
+@samp{SATHIGH}, and @samp{SATMAX}.
+
+@item hue
+Calculate hue statistics: @samp{HUEMED} and @samp{HUEAVG}.
+
+@item ydif
+Calculate @samp{YDIF}.
+
+@item uvdif
+Calculate @samp{UDIF} and @samp{VDIF}.
+
+@item ydepth
+Calculate @samp{YBITDEPTH}.
+
+@item uvdepth
+Calculate @samp{UBITDEPTH} and @samp{VBITDEPTH}.
+
+@item dif
+Calculate all frame-difference statistics. This is equivalent to
+@samp{ydif+uvdif}.
+
+@item depth
+Calculate all bit-depth statistics. This is equivalent to
+@samp{ydepth+uvdepth}.
+
+@item all
+Calculate all statistics. This is the default.
+
+@item none
+Calculate none of the statistics selectable with this option. Only the
+analysis selected with the @option{stat} and @option{out} options is performed.
+@end table
 @end table
 
 @subsection Examples
@@ -23048,6 +23107,25 @@ Output specific data about the minimum and maximum 
values of the Y plane per fra
 ffprobe -f lavfi movie=example.mov,signalstats -show_entries 
frame_tags=lavfi.signalstats.YMAX,lavfi.signalstats.YMIN
 @end example
 
+@item
+Calculate only the Y-plane frame difference, avoiding the other signal 
statistics:
+@example
+ffprobe -f lavfi movie=example.mov,signalstats=mode=ydif -show_entries 
frame_tags=lavfi.signalstats.YDIF
+@end example
+
+@item
+Calculate Y-plane statistics and Y-plane frame difference only:
+@example
+ffprobe -f lavfi movie=example.mov,signalstats=mode=y+ydif -show_frames
+@end example
+
+@item
+Analyze only pixels outside of broadcast range, without calculating any of the
+statistics selected by @option{mode}:
+@example
+ffprobe -f lavfi movie=example.mov,signalstats=mode=none:stat=brng 
-show_entries frame_tags=lavfi.signalstats.BRNG
+@end example
+
 @item
 Playback video while highlighting pixels that are outside of broadcast range 
in red.
 @example
diff --git a/libavfilter/vf_signalstats.c b/libavfilter/vf_signalstats.c
index a7bbfd94f6..955bc83c86 100644
--- a/libavfilter/vf_signalstats.c
+++ b/libavfilter/vf_signalstats.c
@@ -34,6 +34,21 @@ enum FilterMode {
     FILT_NUMB
 };
 
+enum StatMode {
+    MODE_Y       = 1 << 0,
+    MODE_UV      = 1 << 1,
+    MODE_SAT     = 1 << 2,
+    MODE_HUE     = 1 << 3,
+    MODE_YDIF    = 1 << 4,
+    MODE_UVDIF   = 1 << 5,
+    MODE_YDEPTH  = 1 << 6,
+    MODE_UVDEPTH = 1 << 7,
+    MODE_DIF     = MODE_YDIF | MODE_UVDIF,
+    MODE_DEPTH   = MODE_YDEPTH | MODE_UVDEPTH,
+    MODE_ALL     = MODE_Y | MODE_UV | MODE_SAT | MODE_HUE |
+                   MODE_YDIF | MODE_UVDIF | MODE_YDEPTH | MODE_UVDEPTH,
+};
+
 typedef struct SignalstatsContext {
     const AVClass *class;
     int chromah;    // height of chroma plane
@@ -45,6 +60,7 @@ typedef struct SignalstatsContext {
     int cfs;        // pixel count per frame of chroma planes
     int outfilter;  // FilterMode
     int filters;
+    int mode;
     AVFrame *frame_prev;
     uint8_t rgba_color[4];
     int yuv_color[3];
@@ -82,6 +98,19 @@ static const AVOption signalstats_options[] = {
         {"brng", "highlight pixels that are outside of broadcast range",       
 0, AV_OPT_TYPE_CONST, {.i64=FILTER_BRNG}, 0, 0, FLAGS, .unit = "out"},
     {"c",     "set highlight color", OFFSET(rgba_color), AV_OPT_TYPE_COLOR, 
{.str="yellow"}, .flags=FLAGS},
     {"color", "set highlight color", OFFSET(rgba_color), AV_OPT_TYPE_COLOR, 
{.str="yellow"}, .flags=FLAGS},
+    {"mode", "set statistics to calculate", OFFSET(mode), AV_OPT_TYPE_FLAGS, 
{.i64=MODE_ALL}, 0, MODE_ALL, FLAGS, .unit = "mode"},
+        {"y",       "calculate Y statistics",                  0, 
AV_OPT_TYPE_CONST, {.i64=MODE_Y},       0, 0, FLAGS, .unit = "mode"},
+        {"uv",      "calculate U/V statistics",                0, 
AV_OPT_TYPE_CONST, {.i64=MODE_UV},      0, 0, FLAGS, .unit = "mode"},
+        {"sat",     "calculate saturation statistics",         0, 
AV_OPT_TYPE_CONST, {.i64=MODE_SAT},     0, 0, FLAGS, .unit = "mode"},
+        {"hue",     "calculate hue statistics",                0, 
AV_OPT_TYPE_CONST, {.i64=MODE_HUE},     0, 0, FLAGS, .unit = "mode"},
+        {"ydif",    "calculate Y frame difference",            0, 
AV_OPT_TYPE_CONST, {.i64=MODE_YDIF},    0, 0, FLAGS, .unit = "mode"},
+        {"uvdif",   "calculate U/V frame differences",         0, 
AV_OPT_TYPE_CONST, {.i64=MODE_UVDIF},   0, 0, FLAGS, .unit = "mode"},
+        {"ydepth",  "calculate Y bit depth",                   0, 
AV_OPT_TYPE_CONST, {.i64=MODE_YDEPTH},  0, 0, FLAGS, .unit = "mode"},
+        {"uvdepth", "calculate U/V bit depth",                 0, 
AV_OPT_TYPE_CONST, {.i64=MODE_UVDEPTH}, 0, 0, FLAGS, .unit = "mode"},
+        {"dif",     "calculate Y/U/V frame differences",       0, 
AV_OPT_TYPE_CONST, {.i64=MODE_DIF},     0, 0, FLAGS, .unit = "mode"},
+        {"depth",   "calculate Y/U/V bit depth",               0, 
AV_OPT_TYPE_CONST, {.i64=MODE_DEPTH},   0, 0, FLAGS, .unit = "mode"},
+        {"all",     "calculate all statistics",                0, 
AV_OPT_TYPE_CONST, {.i64=MODE_ALL},     0, 0, FLAGS, .unit = "mode"},
+        {"none",    "calculate no statistics",                 0, 
AV_OPT_TYPE_CONST, {.i64=0},            0, 0, FLAGS, .unit = "mode"},
     {NULL}
 };
 
@@ -161,12 +190,18 @@ static int config_output(AVFilterLink *outlink)
     s->vsub = desc->log2_chroma_h;
     s->depth = desc->comp[0].depth;
     s->maxsize = 1 << s->depth;
-    s->histy = av_malloc_array(s->maxsize, sizeof(*s->histy));
-    s->histu = av_malloc_array(s->maxsize, sizeof(*s->histu));
-    s->histv = av_malloc_array(s->maxsize, sizeof(*s->histv));
-    s->histsat = av_malloc_array(s->maxsize, sizeof(*s->histsat));
+    if (s->mode & MODE_Y)
+        s->histy = av_malloc_array(s->maxsize, sizeof(*s->histy));
+    if (s->mode & MODE_UV) {
+        s->histu = av_malloc_array(s->maxsize, sizeof(*s->histu));
+        s->histv = av_malloc_array(s->maxsize, sizeof(*s->histv));
+    }
+    if (s->mode & MODE_SAT)
+        s->histsat = av_malloc_array(s->maxsize, sizeof(*s->histsat));
 
-    if (!s->histy || !s->histu || !s->histv || !s->histsat)
+    if (((s->mode & MODE_Y)   && !s->histy) ||
+        ((s->mode & MODE_UV)  && (!s->histu || !s->histv)) ||
+        ((s->mode & MODE_SAT) && !s->histsat))
         return AVERROR(ENOMEM);
 
     outlink->w = inlink->w;
@@ -183,9 +218,12 @@ static int config_output(AVFilterLink *outlink)
     if (!s->jobs_rets)
         return AVERROR(ENOMEM);
 
-    s->frame_sat = alloc_frame(s->depth > 8 ? AV_PIX_FMT_GRAY16 : 
AV_PIX_FMT_GRAY8,  inlink->w, inlink->h);
-    s->frame_hue = alloc_frame(AV_PIX_FMT_GRAY16, inlink->w, inlink->h);
-    if (!s->frame_sat || !s->frame_hue)
+    if (s->mode & MODE_SAT)
+        s->frame_sat = alloc_frame(s->depth > 8 ? AV_PIX_FMT_GRAY16 : 
AV_PIX_FMT_GRAY8, inlink->w, inlink->h);
+    if (s->mode & MODE_HUE)
+        s->frame_hue = alloc_frame(AV_PIX_FMT_GRAY16, inlink->w, inlink->h);
+    if (((s->mode & MODE_SAT) && !s->frame_sat) ||
+        ((s->mode & MODE_HUE) && !s->frame_hue))
         return AVERROR(ENOMEM);
 
     return 0;
@@ -463,6 +501,8 @@ static int compute_sat_hue_metrics8(AVFilterContext *ctx, 
void *arg, int jobnr,
     const AVFrame *src = td->src;
     AVFrame *dst_sat = td->dst_sat;
     AVFrame *dst_hue = td->dst_hue;
+    const int need_sat = !!dst_sat;
+    const int need_hue = !!dst_hue;
 
     const int slice_start = ff_slice_pos(s->chromah, jobnr, nb_jobs);
     const int slice_end   = ff_slice_pos(s->chromah, jobnr + 1, nb_jobs);
@@ -472,22 +512,27 @@ static int compute_sat_hue_metrics8(AVFilterContext *ctx, 
void *arg, int jobnr,
     const uint8_t *p_u = src->data[1] + slice_start * lsz_u;
     const uint8_t *p_v = src->data[2] + slice_start * lsz_v;
 
-    const int lsz_sat = dst_sat->linesize[0];
-    const int lsz_hue = dst_hue->linesize[0];
-    uint8_t *p_sat = dst_sat->data[0] + slice_start * lsz_sat;
-    uint8_t *p_hue = dst_hue->data[0] + slice_start * lsz_hue;
+    const int lsz_sat = need_sat ? dst_sat->linesize[0] : 0;
+    const int lsz_hue = need_hue ? dst_hue->linesize[0] : 0;
+    uint8_t *p_sat = need_sat ? dst_sat->data[0] + slice_start * lsz_sat : 
NULL;
+    uint8_t *p_hue = need_hue ? dst_hue->data[0] + slice_start * lsz_hue : 
NULL;
 
     for (j = slice_start; j < slice_end; j++) {
         for (i = 0; i < s->chromaw; i++) {
             const int yuvu = p_u[i];
             const int yuvv = p_v[i];
-            p_sat[i] = hypotf(yuvu - 128, yuvv - 128); // int or round?
-            ((int16_t*)p_hue)[i] = fmodf(floorf((180.f / M_PI) * 
atan2f(yuvu-128, yuvv-128) + 180.f), 360.f);
+
+            if (need_sat)
+                p_sat[i] = hypotf(yuvu - 128, yuvv - 128); // int or round?
+            if (need_hue)
+                ((int16_t*)p_hue)[i] = fmodf(floorf((180.f / M_PI) * 
atan2f(yuvu-128, yuvv-128) + 180.f), 360.f);
         }
-        p_u   += lsz_u;
-        p_v   += lsz_v;
-        p_sat += lsz_sat;
-        p_hue += lsz_hue;
+        p_u += lsz_u;
+        p_v += lsz_v;
+        if (need_sat)
+            p_sat += lsz_sat;
+        if (need_hue)
+            p_hue += lsz_hue;
     }
 
     return 0;
@@ -501,6 +546,8 @@ static int compute_sat_hue_metrics16(AVFilterContext *ctx, 
void *arg, int jobnr,
     const AVFrame *src = td->src;
     AVFrame *dst_sat = td->dst_sat;
     AVFrame *dst_hue = td->dst_hue;
+    const int need_sat = !!dst_sat;
+    const int need_hue = !!dst_hue;
     const int mid = 1 << (s->depth - 1);
 
     const int slice_start = ff_slice_pos(s->chromah, jobnr, nb_jobs);
@@ -511,22 +558,27 @@ static int compute_sat_hue_metrics16(AVFilterContext 
*ctx, void *arg, int jobnr,
     const uint16_t *p_u = (uint16_t*)src->data[1] + slice_start * lsz_u;
     const uint16_t *p_v = (uint16_t*)src->data[2] + slice_start * lsz_v;
 
-    const int lsz_sat = dst_sat->linesize[0] / 2;
-    const int lsz_hue = dst_hue->linesize[0] / 2;
-    uint16_t *p_sat = (uint16_t*)dst_sat->data[0] + slice_start * lsz_sat;
-    uint16_t *p_hue = (uint16_t*)dst_hue->data[0] + slice_start * lsz_hue;
+    const int lsz_sat = need_sat ? dst_sat->linesize[0] / 2 : 0;
+    const int lsz_hue = need_hue ? dst_hue->linesize[0] / 2 : 0;
+    uint16_t *p_sat = need_sat ? (uint16_t*)dst_sat->data[0] + slice_start * 
lsz_sat : NULL;
+    uint16_t *p_hue = need_hue ? (uint16_t*)dst_hue->data[0] + slice_start * 
lsz_hue : NULL;
 
     for (j = slice_start; j < slice_end; j++) {
         for (i = 0; i < s->chromaw; i++) {
             const int yuvu = p_u[i];
             const int yuvv = p_v[i];
-            p_sat[i] = hypotf(yuvu - mid, yuvv - mid); // int or round?
-            ((int16_t*)p_hue)[i] = fmodf(floorf((180.f / M_PI) * 
atan2f(yuvu-mid, yuvv-mid) + 180.f), 360.f);
+
+            if (need_sat)
+                p_sat[i] = hypotf(yuvu - mid, yuvv - mid); // int or round?
+            if (need_hue)
+                ((int16_t*)p_hue)[i] = fmodf(floorf((180.f / M_PI) * 
atan2f(yuvu-mid, yuvv-mid) + 180.f), 360.f);
         }
-        p_u   += lsz_u;
-        p_v   += lsz_v;
-        p_sat += lsz_sat;
-        p_hue += lsz_hue;
+        p_u += lsz_u;
+        p_v += lsz_v;
+        if (need_sat)
+            p_sat += lsz_sat;
+        if (need_hue)
+            p_hue += lsz_hue;
     }
 
     return 0;
@@ -550,7 +602,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     unsigned int *histy = s->histy,
                  *histu = s->histu,
                  *histv = s->histv,
-                 histhue[360] = {0},
+                 histhue[360],
                  *histsat = s->histsat;
     int miny  = -1, minu  = -1, minv  = -1;
     int maxy  = -1, maxu  = -1, maxv  = -1;
@@ -558,34 +610,43 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     int highy = -1, highu = -1, highv = -1;
     int minsat = -1, maxsat = -1, lowsat = -1, highsat = -1;
     int lowp, highp, clowp, chighp;
-    int accy, accu, accv;
-    int accsat, acchue = 0;
-    int medhue;
+    int accy = 0, accu = 0, accv = 0, accsat = 0, acchue = 0;
+    int medhue = -1;
     int64_t toty = 0, totu = 0, totv = 0, totsat = 0;
     int64_t tothue = 0;
     int64_t dify = 0, difu = 0, difv = 0;
     uint16_t masky = 0, masku = 0, maskv = 0;
 
     int filtot[FILT_NUMB] = {0};
-    AVFrame *prev, *new_prev;
+    AVFrame *prev = NULL, *new_prev;
     int ret;
     AVFrame *sat = s->frame_sat;
     AVFrame *hue = s->frame_hue;
     const int hbd = s->depth > 8;
+    const int need_y = s->mode & (MODE_Y | MODE_YDIF | MODE_YDEPTH);
+    const int need_uv_values = s->mode & (MODE_UV | MODE_UVDIF | MODE_UVDEPTH);
+    const int need_uv = need_uv_values || (s->mode & (MODE_SAT | MODE_HUE));
+    const int need_dif = s->mode & MODE_DIF;
+    const int need_sat = s->mode & MODE_SAT;
+    const int need_hue = s->mode & MODE_HUE;
     ThreadDataHueSatMetrics td_huesat = {
         .src     = in,
         .dst_sat = sat,
         .dst_hue = hue,
     };
 
-    if (!s->frame_prev)
-        s->frame_prev = av_frame_clone(in);
-    if (!s->frame_prev) {
-        av_frame_free(&in);
-        return AVERROR(ENOMEM);
-    }
+    if (need_hue)
+        memset(histhue, 0, sizeof(histhue));
 
-    prev = s->frame_prev;
+    if (need_dif) {
+        if (!s->frame_prev)
+            s->frame_prev = av_frame_clone(in);
+        if (!s->frame_prev) {
+            av_frame_free(&in);
+            return AVERROR(ENOMEM);
+        }
+        prev = s->frame_prev;
+    }
 
     if (s->outfilter != FILTER_NONE) {
         out = av_frame_clone(in);
@@ -601,92 +662,141 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
         }
     }
 
-    ff_filter_execute(ctx, hbd ? compute_sat_hue_metrics16
-                               : compute_sat_hue_metrics8, &td_huesat,
-                      NULL, FFMIN(s->chromah, ff_filter_get_nb_threads(ctx)));
+    if (need_sat || need_hue)
+        ff_filter_execute(ctx, hbd ? compute_sat_hue_metrics16
+                                   : compute_sat_hue_metrics8, &td_huesat,
+                          NULL, FFMIN(s->chromah, 
ff_filter_get_nb_threads(ctx)));
 
-    memset(s->histy, 0, s->maxsize * sizeof(*s->histy));
-    memset(s->histu, 0, s->maxsize * sizeof(*s->histu));
-    memset(s->histv, 0, s->maxsize * sizeof(*s->histv));
-    memset(s->histsat, 0, s->maxsize * sizeof(*s->histsat));
+    if (s->mode & MODE_Y)
+        memset(s->histy, 0, s->maxsize * sizeof(*s->histy));
+    if (s->mode & MODE_UV) {
+        memset(s->histu, 0, s->maxsize * sizeof(*s->histu));
+        memset(s->histv, 0, s->maxsize * sizeof(*s->histv));
+    }
+    if (need_sat)
+        memset(s->histsat, 0, s->maxsize * sizeof(*s->histsat));
 
     if (hbd) {
-        const uint16_t *p_sat = (uint16_t *)sat->data[0];
-        const uint16_t *p_hue = (uint16_t *)hue->data[0];
-        const int lsz_sat = sat->linesize[0] / 2;
-        const int lsz_hue = hue->linesize[0] / 2;
-        // Calculate luma histogram and difference with previous frame or 
field.
-        for (int j = 0; j < link->h; j++) {
-            for (int i = 0; i < link->w; i++) {
-                const int yuv = AV_RN16(in->data[0] + w + i * 2);
+        const uint16_t *p_sat = need_sat ? (uint16_t *)sat->data[0] : NULL;
+        const uint16_t *p_hue = need_hue ? (uint16_t *)hue->data[0] : NULL;
+        const int lsz_sat = need_sat ? sat->linesize[0] / 2 : 0;
+        const int lsz_hue = need_hue ? hue->linesize[0] / 2 : 0;
 
-                masky |= yuv;
-                histy[yuv]++;
-                dify += abs(yuv - (int)AV_RN16(prev->data[0] + pw + i * 2));
+        if (need_y) {
+            // Calculate requested luma statistics in a single plane pass.
+            for (int j = 0; j < link->h; j++) {
+                for (int i = 0; i < link->w; i++) {
+                    const int yuv = AV_RN16(in->data[0] + w + i * 2);
+
+                    if (s->mode & MODE_YDEPTH)
+                        masky |= yuv;
+                    if (s->mode & MODE_Y)
+                        histy[yuv]++;
+                    if (s->mode & MODE_YDIF)
+                        dify += abs(yuv - (int)AV_RN16(prev->data[0] + pw + i 
* 2));
+                }
+                w += in->linesize[0];
+                if (s->mode & MODE_YDIF)
+                    pw += prev->linesize[0];
             }
-            w  += in->linesize[0];
-            pw += prev->linesize[0];
         }
 
-        // Calculate chroma histogram and difference with previous frame or 
field.
-        for (int j = 0; j < s->chromah; j++) {
-            for (int i = 0; i < s->chromaw; i++) {
-                const int yuvu = AV_RN16(in->data[1] + cw + i * 2);
-                const int yuvv = AV_RN16(in->data[2] + cw + i * 2);
+        if (need_uv) {
+            // Calculate requested chroma statistics in a single plane pass.
+            for (int j = 0; j < s->chromah; j++) {
+                for (int i = 0; i < s->chromaw; i++) {
+                    int yuvu = 0, yuvv = 0;
 
-                masku |= yuvu;
-                maskv |= yuvv;
-                histu[yuvu]++;
-                difu += abs(yuvu - (int)AV_RN16(prev->data[1] + cpw + i * 2));
-                histv[yuvv]++;
-                difv += abs(yuvv - (int)AV_RN16(prev->data[2] + cpw + i * 2));
-
-                histsat[p_sat[i]]++;
-                histhue[((int16_t*)p_hue)[i]]++;
+                    if (need_uv_values) {
+                        yuvu = AV_RN16(in->data[1] + cw + i * 2);
+                        yuvv = AV_RN16(in->data[2] + cw + i * 2);
+                    }
+                    if (s->mode & MODE_UVDEPTH) {
+                        masku |= yuvu;
+                        maskv |= yuvv;
+                    }
+                    if (s->mode & MODE_UV) {
+                        histu[yuvu]++;
+                        histv[yuvv]++;
+                    }
+                    if (s->mode & MODE_UVDIF) {
+                        difu += abs(yuvu - (int)AV_RN16(prev->data[1] + cpw + 
i * 2));
+                        difv += abs(yuvv - (int)AV_RN16(prev->data[2] + cpw + 
i * 2));
+                    }
+                    if (need_sat)
+                        histsat[p_sat[i]]++;
+                    if (need_hue)
+                        histhue[((int16_t*)p_hue)[i]]++;
+                }
+                cw += in->linesize[1];
+                if (s->mode & MODE_UVDIF)
+                    cpw += prev->linesize[1];
+                if (need_sat)
+                    p_sat += lsz_sat;
+                if (need_hue)
+                    p_hue += lsz_hue;
             }
-            cw  += in->linesize[1];
-            cpw += prev->linesize[1];
-            p_sat += lsz_sat;
-            p_hue += lsz_hue;
         }
     } else {
-        const uint8_t *p_sat = sat->data[0];
-        const uint8_t *p_hue = hue->data[0];
-        const int lsz_sat = sat->linesize[0];
-        const int lsz_hue = hue->linesize[0];
-        // Calculate luma histogram and difference with previous frame or 
field.
-        for (int j = 0; j < link->h; j++) {
-            for (int i = 0; i < link->w; i++) {
-                const int yuv = in->data[0][w + i];
+        const uint8_t *p_sat = need_sat ? sat->data[0] : NULL;
+        const uint8_t *p_hue = need_hue ? hue->data[0] : NULL;
+        const int lsz_sat = need_sat ? sat->linesize[0] : 0;
+        const int lsz_hue = need_hue ? hue->linesize[0] : 0;
 
-                masky |= yuv;
-                histy[yuv]++;
-                dify += abs(yuv - prev->data[0][pw + i]);
+        if (need_y) {
+            // Calculate requested luma statistics in a single plane pass.
+            for (int j = 0; j < link->h; j++) {
+                for (int i = 0; i < link->w; i++) {
+                    const int yuv = in->data[0][w + i];
+
+                    if (s->mode & MODE_YDEPTH)
+                        masky |= yuv;
+                    if (s->mode & MODE_Y)
+                        histy[yuv]++;
+                    if (s->mode & MODE_YDIF)
+                        dify += abs(yuv - prev->data[0][pw + i]);
+                }
+                w += in->linesize[0];
+                if (s->mode & MODE_YDIF)
+                    pw += prev->linesize[0];
             }
-            w  += in->linesize[0];
-            pw += prev->linesize[0];
         }
 
-        // Calculate chroma histogram and difference with previous frame or 
field.
-        for (int j = 0; j < s->chromah; j++) {
-            for (int i = 0; i < s->chromaw; i++) {
-                const int yuvu = in->data[1][cw+i];
-                const int yuvv = in->data[2][cw+i];
+        if (need_uv) {
+            // Calculate requested chroma statistics in a single plane pass.
+            for (int j = 0; j < s->chromah; j++) {
+                for (int i = 0; i < s->chromaw; i++) {
+                    int yuvu = 0, yuvv = 0;
 
-                masku |= yuvu;
-                maskv |= yuvv;
-                histu[yuvu]++;
-                difu += abs(yuvu - prev->data[1][cpw+i]);
-                histv[yuvv]++;
-                difv += abs(yuvv - prev->data[2][cpw+i]);
-
-                histsat[p_sat[i]]++;
-                histhue[((int16_t*)p_hue)[i]]++;
+                    if (need_uv_values) {
+                        yuvu = in->data[1][cw + i];
+                        yuvv = in->data[2][cw + i];
+                    }
+                    if (s->mode & MODE_UVDEPTH) {
+                        masku |= yuvu;
+                        maskv |= yuvv;
+                    }
+                    if (s->mode & MODE_UV) {
+                        histu[yuvu]++;
+                        histv[yuvv]++;
+                    }
+                    if (s->mode & MODE_UVDIF) {
+                        difu += abs(yuvu - prev->data[1][cpw + i]);
+                        difv += abs(yuvv - prev->data[2][cpw + i]);
+                    }
+                    if (need_sat)
+                        histsat[p_sat[i]]++;
+                    if (need_hue)
+                        histhue[((int16_t*)p_hue)[i]]++;
+                }
+                cw += in->linesize[1];
+                if (s->mode & MODE_UVDIF)
+                    cpw += prev->linesize[1];
+                if (need_sat)
+                    p_sat += lsz_sat;
+                if (need_hue)
+                    p_hue += lsz_hue;
             }
-            cw  += in->linesize[1];
-            cpw += prev->linesize[1];
-            p_sat += lsz_sat;
-            p_hue += lsz_hue;
         }
     }
 
@@ -710,97 +820,133 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     clowp  = lrint(s->cfs * 10 / 100.);
     chighp = lrint(s->cfs * 90 / 100.);
 
-    accy = accu = accv = accsat = 0;
-    for (fil = 0; fil < s->maxsize; fil++) {
-        if (miny   < 0 && histy[fil])   miny = fil;
-        if (minu   < 0 && histu[fil])   minu = fil;
-        if (minv   < 0 && histv[fil])   minv = fil;
-        if (minsat < 0 && histsat[fil]) minsat = fil;
+    if (s->mode & (MODE_Y | MODE_UV | MODE_SAT)) {
+        for (fil = 0; fil < s->maxsize; fil++) {
+            if (s->mode & MODE_Y) {
+                if (miny < 0 && histy[fil])
+                    miny = fil;
+                if (histy[fil])
+                    maxy = fil;
+                toty += (uint64_t)histy[fil] * fil;
+                accy += histy[fil];
+                if (lowy == -1 && accy >= lowp)
+                    lowy = fil;
+                if (highy == -1 && accy >= highp)
+                    highy = fil;
+            }
 
-        if (histy[fil])   maxy   = fil;
-        if (histu[fil])   maxu   = fil;
-        if (histv[fil])   maxv   = fil;
-        if (histsat[fil]) maxsat = fil;
+            if (s->mode & MODE_UV) {
+                if (minu < 0 && histu[fil])
+                    minu = fil;
+                if (minv < 0 && histv[fil])
+                    minv = fil;
+                if (histu[fil])
+                    maxu = fil;
+                if (histv[fil])
+                    maxv = fil;
+                totu += (uint64_t)histu[fil] * fil;
+                totv += (uint64_t)histv[fil] * fil;
+                accu += histu[fil];
+                accv += histv[fil];
+                if (lowu == -1 && accu >= clowp)
+                    lowu = fil;
+                if (lowv == -1 && accv >= clowp)
+                    lowv = fil;
+                if (highu == -1 && accu >= chighp)
+                    highu = fil;
+                if (highv == -1 && accv >= chighp)
+                    highv = fil;
+            }
 
-        toty   += (uint64_t)histy[fil]   * fil;
-        totu   += (uint64_t)histu[fil]   * fil;
-        totv   += (uint64_t)histv[fil]   * fil;
-        totsat += (uint64_t)histsat[fil] * fil;
-
-        accy   += histy[fil];
-        accu   += histu[fil];
-        accv   += histv[fil];
-        accsat += histsat[fil];
-
-        if (lowy   == -1 && accy   >=  lowp) lowy   = fil;
-        if (lowu   == -1 && accu   >= clowp) lowu   = fil;
-        if (lowv   == -1 && accv   >= clowp) lowv   = fil;
-        if (lowsat == -1 && accsat >= clowp) lowsat = fil;
-
-        if (highy   == -1 && accy   >=  highp) highy   = fil;
-        if (highu   == -1 && accu   >= chighp) highu   = fil;
-        if (highv   == -1 && accv   >= chighp) highv   = fil;
-        if (highsat == -1 && accsat >= chighp) highsat = fil;
+            if (need_sat) {
+                if (minsat < 0 && histsat[fil])
+                    minsat = fil;
+                if (histsat[fil])
+                    maxsat = fil;
+                totsat += (uint64_t)histsat[fil] * fil;
+                accsat += histsat[fil];
+                if (lowsat == -1 && accsat >= clowp)
+                    lowsat = fil;
+                if (highsat == -1 && accsat >= chighp)
+                    highsat = fil;
+            }
+        }
     }
 
-    medhue = -1;
-    for (fil = 0; fil < 360; fil++) {
-        tothue += (uint64_t)histhue[fil] * fil;
-        acchue += histhue[fil];
-
-        if (medhue == -1 && acchue > s->cfs / 2)
-            medhue = fil;
+    if (need_hue) {
+        for (fil = 0; fil < 360; fil++) {
+            tothue += (uint64_t)histhue[fil] * fil;
+            acchue += histhue[fil];
+            if (medhue == -1 && acchue > s->cfs / 2)
+                medhue = fil;
+        }
     }
 
-    new_prev = av_frame_clone(in);
-    if (!new_prev) {
-        if (out != in)
-            av_frame_free(&out);
-        av_frame_free(&in);
-        return AVERROR(ENOMEM);
+    if (need_dif) {
+        new_prev = av_frame_clone(in);
+        if (!new_prev) {
+            if (out != in)
+                av_frame_free(&out);
+            av_frame_free(&in);
+            return AVERROR(ENOMEM);
+        }
+        av_frame_free(&s->frame_prev);
+        s->frame_prev = new_prev;
     }
-    av_frame_free(&s->frame_prev);
-    s->frame_prev = new_prev;
 
 #define SET_META(key, fmt, val) do {                                    \
     snprintf(metabuf, sizeof(metabuf), fmt, val);                       \
     av_dict_set(&out->metadata, "lavfi.signalstats." key, metabuf, 0);  \
 } while (0)
 
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.YMIN", miny, 0);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.YLOW", lowy, 0);
-    SET_META("YAVG",    "%g", 1.0 * toty / s->fs);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.YHIGH", highy, 0);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.YMAX", maxy, 0);
+    if (s->mode & MODE_Y) {
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.YMIN", miny, 0);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.YLOW", lowy, 0);
+        SET_META("YAVG", "%g", 1.0 * toty / s->fs);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.YHIGH", highy, 0);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.YMAX", maxy, 0);
+    }
 
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.UMIN", minu, 0);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.ULOW", lowu, 0);
-    SET_META("UAVG",    "%g", 1.0 * totu / s->cfs);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.UHIGH", highu, 0);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.UMAX", maxu, 0);
+    if (s->mode & MODE_UV) {
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.UMIN", minu, 0);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.ULOW", lowu, 0);
+        SET_META("UAVG", "%g", 1.0 * totu / s->cfs);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.UHIGH", highu, 0);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.UMAX", maxu, 0);
 
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.VMIN", minv, 0);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.VLOW", lowv, 0);
-    SET_META("VAVG",    "%g", 1.0 * totv / s->cfs);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.VHIGH", highv, 0);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.VMAX", maxv, 0);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.VMIN", minv, 0);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.VLOW", lowv, 0);
+        SET_META("VAVG", "%g", 1.0 * totv / s->cfs);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.VHIGH", highv, 0);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.VMAX", maxv, 0);
+    }
 
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.SATMIN", minsat, 0);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.SATLOW", lowsat, 0);
-    SET_META("SATAVG",  "%g", 1.0 * totsat / s->cfs);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.SATHIGH", highsat, 0);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.SATMAX", maxsat, 0);
+    if (need_sat) {
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.SATMIN", minsat, 0);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.SATLOW", lowsat, 0);
+        SET_META("SATAVG", "%g", 1.0 * totsat / s->cfs);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.SATHIGH", highsat, 
0);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.SATMAX", maxsat, 0);
+    }
 
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.HUEMED", medhue, 0);
-    SET_META("HUEAVG",  "%g", 1.0 * tothue / s->cfs);
+    if (need_hue) {
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.HUEMED", medhue, 0);
+        SET_META("HUEAVG", "%g", 1.0 * tothue / s->cfs);
+    }
 
-    SET_META("YDIF",    "%g", 1.0 * dify / s->fs);
-    SET_META("UDIF",    "%g", 1.0 * difu / s->cfs);
-    SET_META("VDIF",    "%g", 1.0 * difv / s->cfs);
+    if (s->mode & MODE_YDIF)
+        SET_META("YDIF", "%g", 1.0 * dify / s->fs);
+    if (s->mode & MODE_UVDIF) {
+        SET_META("UDIF", "%g", 1.0 * difu / s->cfs);
+        SET_META("VDIF", "%g", 1.0 * difv / s->cfs);
+    }
 
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.YBITDEPTH", 
compute_bit_depth(masky), 0);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.UBITDEPTH", 
compute_bit_depth(masku), 0);
-    av_dict_set_int(&out->metadata, "lavfi.signalstats.VBITDEPTH", 
compute_bit_depth(maskv), 0);
+    if (s->mode & MODE_YDEPTH)
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.YBITDEPTH", 
compute_bit_depth(masky), 0);
+    if (s->mode & MODE_UVDEPTH) {
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.UBITDEPTH", 
compute_bit_depth(masku), 0);
+        av_dict_set_int(&out->metadata, "lavfi.signalstats.VBITDEPTH", 
compute_bit_depth(maskv), 0);
+    }
 
     for (fil = 0; fil < FILT_NUMB; fil++) {
         if (s->filters & 1 << fil) {
diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak
index 4a065ec032..cac6152bf0 100644
--- a/tests/fate/filter-video.mak
+++ b/tests/fate/filter-video.mak
@@ -913,6 +913,30 @@ FATE_METADATA_FILTER-$(call ALLYES, $(SIGNALSTATS_DEPS)) 
+= fate-filter-metadata
 fate-filter-metadata-signalstats-yuv420p: CMD = run $(FILTER_METADATA_COMMAND) 
"sws_flags=+accurate_rnd+bitexact;color=white:duration=1:r=1,signalstats"
 fate-filter-metadata-signalstats-yuv420p10: CMD = run 
$(FILTER_METADATA_COMMAND) 
"sws_flags=+accurate_rnd+bitexact;color=white:duration=1:r=1,format=yuv420p10le,signalstats"
 
+SIGNALSTATS_MODE_DEPS = FFPROBE LAVFI_INDEV WRAPPED_AVFRAME_DECODER 
TESTSRC2_FILTER FORMAT_FILTER SCALE_FILTER SIGNALSTATS_FILTER
+SIGNALSTATS_MODE_SRC = 
sws_flags=+accurate_rnd+bitexact;testsrc2=s=160x120:r=5:d=1
+FATE_FILTER_FFPROBE-$(call ALLYES, $(SIGNALSTATS_MODE_DEPS)) += $(addprefix 
fate-filter-metadata-signalstats-mode-, y uv sat hue ydif uvdif ydepth uvdepth 
y-ydif \
+    default all plus-ydif minus-hue all-hue-sat dif depth none none-brng)
+fate-filter-metadata-signalstats-mode-default: CMD = run 
$(FILTER_METADATA_COMMAND) "$(SIGNALSTATS_MODE_SRC),format=yuv420p,signalstats"
+fate-filter-metadata-signalstats-mode-all: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p,signalstats=mode=all"
+fate-filter-metadata-signalstats-mode-plus-ydif: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p,signalstats=mode=+ydif"
+$(addprefix fate-filter-metadata-signalstats-mode-, all plus-ydif): REF = 
$(SRC_PATH)/tests/ref/fate/filter-metadata-signalstats-mode-default
+fate-filter-metadata-signalstats-mode-minus-hue: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p10le,signalstats=mode=-hue"
+fate-filter-metadata-signalstats-mode-all-hue-sat: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p,signalstats=mode=all-hue-sat"
+fate-filter-metadata-signalstats-mode-dif: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p10le,signalstats=mode=dif"
+fate-filter-metadata-signalstats-mode-depth: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p10le,signalstats=mode=depth"
+fate-filter-metadata-signalstats-mode-none: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p,signalstats=mode=none"
+fate-filter-metadata-signalstats-mode-none-brng: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuvj420p,signalstats=mode=none:stat=brng"
+fate-filter-metadata-signalstats-mode-y: CMD = run $(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p,signalstats=mode=y"
+fate-filter-metadata-signalstats-mode-uv: CMD = run $(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p10le,signalstats=mode=uv"
+fate-filter-metadata-signalstats-mode-sat: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p,signalstats=mode=sat"
+fate-filter-metadata-signalstats-mode-hue: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p10le,signalstats=mode=hue"
+fate-filter-metadata-signalstats-mode-ydif: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p,signalstats=mode=ydif"
+fate-filter-metadata-signalstats-mode-uvdif: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p10le,signalstats=mode=uvdif"
+fate-filter-metadata-signalstats-mode-ydepth: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p,signalstats=mode=ydepth"
+fate-filter-metadata-signalstats-mode-uvdepth: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p10le,signalstats=mode=uvdepth"
+fate-filter-metadata-signalstats-mode-y-ydif: CMD = run 
$(FILTER_METADATA_COMMAND) 
"$(SIGNALSTATS_MODE_SRC),format=yuv420p,signalstats=mode=y+ydif"
+
 SILENCEDETECT_DEPS = LAVFI_INDEV AMOVIE_FILTER TTA_DEMUXER TTA_DECODER 
SILENCEDETECT_FILTER
 FATE_METADATA_FILTER-$(call ALLYES, $(SILENCEDETECT_DEPS)) += 
fate-filter-metadata-silencedetect
 fate-filter-metadata-silencedetect: SRC = 
$(TARGET_SAMPLES)/lossless-audio/inside.tta
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-all-hue-sat 
b/tests/ref/fate/filter-metadata-signalstats-mode-all-hue-sat
new file mode 100644
index 0000000000..fe09c10203
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-all-hue-sat
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.UBITDEPTH=8|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=111.34|tag:lavfi.signalstats.YHIGH=210|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.UMIN=16|tag:lavfi.signalstats.ULOW=16|tag:lavfi.signalstats.UAVG=131.22|tag:lavfi.signalstats.UHIGH=240|tag:lavfi.signalstats.UMAX=240|tag:lavfi.signalstats.VMIN=16|tag:lavfi.signalstats.VLOW=16|tag:lavfi.signalstats.VAVG=129.903|tag:lavfi.signalstats.VHIGH=240|tag:lavfi.signalstats.VMAX=240|tag:lavfi.signalstats.YDIF=0|tag:lavfi.signalstats.UDIF=0|tag:lavfi.signalstats.VDIF=0|tag:lavfi.signalstats.YBITDEPTH=8|tag:lavfi.signalstats.VBITDEPTH=8
+pts=1|tag:lavfi.signalstats.UBITDEPTH=8|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=110.923|tag:lavfi.signalstats.YHIGH=170|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.UMIN=16|tag:lavfi.signalstats.ULOW=53|tag:lavfi.signalstats.UAVG=132.665|tag:lavfi.signalstats.UHIGH=240|tag:lavfi.signalstats.UMAX=240|tag:lavfi.signalstats.VMIN=16|tag:lavfi.signalstats.VLOW=16|tag:lavfi.signalstats.VAVG=129.743|tag:lavfi.signalstats.VHIGH=240|tag:lavfi.signalstats.VMAX=240|tag:lavfi.signalstats.YDIF=7.73203|tag:lavfi.signalstats.UDIF=7.13667|tag:lavfi.signalstats.VDIF=14.9523|tag:lavfi.signalstats.YBITDEPTH=8|tag:lavfi.signalstats.VBITDEPTH=8
+pts=2|tag:lavfi.signalstats.UBITDEPTH=8|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=111.217|tag:lavfi.signalstats.YHIGH=170|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.UMIN=16|tag:lavfi.signalstats.ULOW=48|tag:lavfi.signalstats.UAVG=133.742|tag:lavfi.signalstats.UHIGH=240|tag:lavfi.signalstats.UMAX=240|tag:lavfi.signalstats.VMIN=16|tag:lavfi.signalstats.VLOW=16|tag:lavfi.signalstats.VAVG=128.208|tag:lavfi.signalstats.VHIGH=240|tag:lavfi.signalstats.VMAX=240|tag:lavfi.signalstats.YDIF=10.2877|tag:lavfi.signalstats.UDIF=9.36729|tag:lavfi.signalstats.VDIF=17.3152|tag:lavfi.signalstats.YBITDEPTH=8|tag:lavfi.signalstats.VBITDEPTH=8
+pts=3|tag:lavfi.signalstats.UBITDEPTH=8|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=112.215|tag:lavfi.signalstats.YHIGH=172|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.UMIN=16|tag:lavfi.signalstats.ULOW=35|tag:lavfi.signalstats.UAVG=133.012|tag:lavfi.signalstats.UHIGH=240|tag:lavfi.signalstats.UMAX=240|tag:lavfi.signalstats.VMIN=16|tag:lavfi.signalstats.VLOW=16|tag:lavfi.signalstats.VAVG=127.644|tag:lavfi.signalstats.VHIGH=236|tag:lavfi.signalstats.VMAX=240|tag:lavfi.signalstats.YDIF=8.89365|tag:lavfi.signalstats.UDIF=8.73979|tag:lavfi.signalstats.VDIF=15.5563|tag:lavfi.signalstats.YBITDEPTH=8|tag:lavfi.signalstats.VBITDEPTH=8
+pts=4|tag:lavfi.signalstats.UBITDEPTH=8|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=112.498|tag:lavfi.signalstats.YHIGH=195|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.UMIN=16|tag:lavfi.signalstats.ULOW=24|tag:lavfi.signalstats.UAVG=131.556|tag:lavfi.signalstats.UHIGH=240|tag:lavfi.signalstats.UMAX=240|tag:lavfi.signalstats.VMIN=16|tag:lavfi.signalstats.VLOW=16|tag:lavfi.signalstats.VAVG=129.5|tag:lavfi.signalstats.VHIGH=240|tag:lavfi.signalstats.VMAX=240|tag:lavfi.signalstats.YDIF=11.4572|tag:lavfi.signalstats.UDIF=11.9827|tag:lavfi.signalstats.VDIF=18.6021|tag:lavfi.signalstats.YBITDEPTH=8|tag:lavfi.signalstats.VBITDEPTH=8
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-default 
b/tests/ref/fate/filter-metadata-signalstats-mode-default
new file mode 100644
index 0000000000..49e2aa0fa8
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-default
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.UBITDEPTH=8|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=111.34|tag:lavfi.signalstats.YHIGH=210|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.UMIN=16|tag:lavfi.signalstats.ULOW=16|tag:lavfi.signalstats.UAVG=131.22|tag:lavfi.signalstats.UHIGH=240|tag:lavfi.signalstats.UMAX=240|tag:lavfi.signalstats.VMIN=16|tag:lavfi.signalstats.VLOW=16|tag:lavfi.signalstats.VAVG=129.903|tag:lavfi.signalstats.VHIGH=240|tag:lavfi.signalstats.VMAX=240|tag:lavfi.signalstats.SATMIN=0|tag:lavfi.signalstats.SATLOW=28|tag:lavfi.signalstats.SATAVG=98.6198|tag:lavfi.signalstats.SATHIGH=119|tag:lavfi.signalstats.SATMAX=119|tag:lavfi.signalstats.HUEMED=180|tag:lavfi.signalstats.HUEAVG=190.909|tag:lavfi.signalstats.YDIF=0|tag:lavfi.signalstats.UDIF=0|tag:lavfi.signalstats.VDIF=0|tag:lavfi.signalstats.YBITDEPTH=8|tag:lavfi.signalstats.VBITDEPTH=8
+pts=1|tag:lavfi.signalstats.UBITDEPTH=8|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=110.923|tag:lavfi.signalstats.YHIGH=170|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.UMIN=16|tag:lavfi.signalstats.ULOW=53|tag:lavfi.signalstats.UAVG=132.665|tag:lavfi.signalstats.UHIGH=240|tag:lavfi.signalstats.UMAX=240|tag:lavfi.signalstats.VMIN=16|tag:lavfi.signalstats.VLOW=16|tag:lavfi.signalstats.VAVG=129.743|tag:lavfi.signalstats.VHIGH=240|tag:lavfi.signalstats.VMAX=240|tag:lavfi.signalstats.SATMIN=0|tag:lavfi.signalstats.SATLOW=28|tag:lavfi.signalstats.SATAVG=95.984|tag:lavfi.signalstats.SATHIGH=119|tag:lavfi.signalstats.SATMAX=119|tag:lavfi.signalstats.HUEMED=180|tag:lavfi.signalstats.HUEAVG=192.611|tag:lavfi.signalstats.YDIF=7.73203|tag:lavfi.signalstats.UDIF=7.13667|tag:lavfi.signalstats.VDIF=14.9523|tag:lavfi.signalstats.YBITDEPTH=8|tag:lavfi.signalstats.VBITDEPTH=8
+pts=2|tag:lavfi.signalstats.UBITDEPTH=8|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=111.217|tag:lavfi.signalstats.YHIGH=170|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.UMIN=16|tag:lavfi.signalstats.ULOW=48|tag:lavfi.signalstats.UAVG=133.742|tag:lavfi.signalstats.UHIGH=240|tag:lavfi.signalstats.UMAX=240|tag:lavfi.signalstats.VMIN=16|tag:lavfi.signalstats.VLOW=16|tag:lavfi.signalstats.VAVG=128.208|tag:lavfi.signalstats.VHIGH=240|tag:lavfi.signalstats.VMAX=240|tag:lavfi.signalstats.SATMIN=0|tag:lavfi.signalstats.SATLOW=28|tag:lavfi.signalstats.SATAVG=93.3056|tag:lavfi.signalstats.SATHIGH=119|tag:lavfi.signalstats.SATMAX=119|tag:lavfi.signalstats.HUEMED=180|tag:lavfi.signalstats.HUEAVG=193.915|tag:lavfi.signalstats.YDIF=10.2877|tag:lavfi.signalstats.UDIF=9.36729|tag:lavfi.signalstats.VDIF=17.3152|tag:lavfi.signalstats.YBITDEPTH=8|tag:lavfi.signalstats.VBITDEPTH=8
+pts=3|tag:lavfi.signalstats.UBITDEPTH=8|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=112.215|tag:lavfi.signalstats.YHIGH=172|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.UMIN=16|tag:lavfi.signalstats.ULOW=35|tag:lavfi.signalstats.UAVG=133.012|tag:lavfi.signalstats.UHIGH=240|tag:lavfi.signalstats.UMAX=240|tag:lavfi.signalstats.VMIN=16|tag:lavfi.signalstats.VLOW=16|tag:lavfi.signalstats.VAVG=127.644|tag:lavfi.signalstats.VHIGH=236|tag:lavfi.signalstats.VMAX=240|tag:lavfi.signalstats.SATMIN=0|tag:lavfi.signalstats.SATLOW=28|tag:lavfi.signalstats.SATAVG=93.0731|tag:lavfi.signalstats.SATHIGH=119|tag:lavfi.signalstats.SATMAX=119|tag:lavfi.signalstats.HUEMED=180|tag:lavfi.signalstats.HUEAVG=193.66|tag:lavfi.signalstats.YDIF=8.89365|tag:lavfi.signalstats.UDIF=8.73979|tag:lavfi.signalstats.VDIF=15.5563|tag:lavfi.signalstats.YBITDEPTH=8|tag:lavfi.signalstats.VBITDEPTH=8
+pts=4|tag:lavfi.signalstats.UBITDEPTH=8|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=112.498|tag:lavfi.signalstats.YHIGH=195|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.UMIN=16|tag:lavfi.signalstats.ULOW=24|tag:lavfi.signalstats.UAVG=131.556|tag:lavfi.signalstats.UHIGH=240|tag:lavfi.signalstats.UMAX=240|tag:lavfi.signalstats.VMIN=16|tag:lavfi.signalstats.VLOW=16|tag:lavfi.signalstats.VAVG=129.5|tag:lavfi.signalstats.VHIGH=240|tag:lavfi.signalstats.VMAX=240|tag:lavfi.signalstats.SATMIN=0|tag:lavfi.signalstats.SATLOW=29|tag:lavfi.signalstats.SATAVG=95.0733|tag:lavfi.signalstats.SATHIGH=119|tag:lavfi.signalstats.SATMAX=119|tag:lavfi.signalstats.HUEMED=180|tag:lavfi.signalstats.HUEAVG=192.252|tag:lavfi.signalstats.YDIF=11.4572|tag:lavfi.signalstats.UDIF=11.9827|tag:lavfi.signalstats.VDIF=18.6021|tag:lavfi.signalstats.YBITDEPTH=8|tag:lavfi.signalstats.VBITDEPTH=8
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-depth 
b/tests/ref/fate/filter-metadata-signalstats-mode-depth
new file mode 100644
index 0000000000..54c7004f65
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-depth
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.YBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
+pts=1|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.YBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
+pts=2|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.YBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
+pts=3|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.YBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
+pts=4|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.YBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-dif 
b/tests/ref/fate/filter-metadata-signalstats-mode-dif
new file mode 100644
index 0000000000..720f0466ad
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-dif
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.UDIF=0|tag:lavfi.signalstats.YDIF=0|tag:lavfi.signalstats.VDIF=0
+pts=1|tag:lavfi.signalstats.UDIF=28.5346|tag:lavfi.signalstats.YDIF=31.0404|tag:lavfi.signalstats.VDIF=59.9269
+pts=2|tag:lavfi.signalstats.UDIF=37.5127|tag:lavfi.signalstats.YDIF=41.3124|tag:lavfi.signalstats.VDIF=69.4265
+pts=3|tag:lavfi.signalstats.UDIF=35.056|tag:lavfi.signalstats.YDIF=35.666|tag:lavfi.signalstats.VDIF=62.3544
+pts=4|tag:lavfi.signalstats.UDIF=48.0933|tag:lavfi.signalstats.YDIF=45.8823|tag:lavfi.signalstats.VDIF=74.616
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-hue 
b/tests/ref/fate/filter-metadata-signalstats-mode-hue
new file mode 100644
index 0000000000..51d5c3d9fa
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-hue
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.HUEMED=182|tag:lavfi.signalstats.HUEAVG=191.261
+pts=1|tag:lavfi.signalstats.HUEMED=212|tag:lavfi.signalstats.HUEAVG=193.835
+pts=2|tag:lavfi.signalstats.HUEMED=218|tag:lavfi.signalstats.HUEAVG=195.963
+pts=3|tag:lavfi.signalstats.HUEMED=218|tag:lavfi.signalstats.HUEAVG=195.694
+pts=4|tag:lavfi.signalstats.HUEMED=208|tag:lavfi.signalstats.HUEAVG=193.387
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-minus-hue 
b/tests/ref/fate/filter-metadata-signalstats-mode-minus-hue
new file mode 100644
index 0000000000..f1d9ce1eb7
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-minus-hue
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.YMIN=88|tag:lavfi.signalstats.YLOW=164|tag:lavfi.signalstats.YAVG=446.59|tag:lavfi.signalstats.YHIGH=843|tag:lavfi.signalstats.YMAX=843|tag:lavfi.signalstats.UMIN=64|tag:lavfi.signalstats.ULOW=64|tag:lavfi.signalstats.UAVG=526.307|tag:lavfi.signalstats.UHIGH=963|tag:lavfi.signalstats.UMAX=963|tag:lavfi.signalstats.VMIN=64|tag:lavfi.signalstats.VLOW=64|tag:lavfi.signalstats.VAVG=520.986|tag:lavfi.signalstats.VHIGH=963|tag:lavfi.signalstats.VMAX=963|tag:lavfi.signalstats.SATMIN=2|tag:lavfi.signalstats.SATLOW=113|tag:lavfi.signalstats.SATAVG=396.661|tag:lavfi.signalstats.SATHIGH=481|tag:lavfi.signalstats.SATMAX=481|tag:lavfi.signalstats.YDIF=0|tag:lavfi.signalstats.UDIF=0|tag:lavfi.signalstats.VDIF=0|tag:lavfi.signalstats.YBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
+pts=1|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.YMIN=88|tag:lavfi.signalstats.YLOW=164|tag:lavfi.signalstats.YAVG=444.898|tag:lavfi.signalstats.YHIGH=680|tag:lavfi.signalstats.YMAX=843|tag:lavfi.signalstats.UMIN=64|tag:lavfi.signalstats.ULOW=212|tag:lavfi.signalstats.UAVG=532.118|tag:lavfi.signalstats.UHIGH=963|tag:lavfi.signalstats.UMAX=963|tag:lavfi.signalstats.VMIN=64|tag:lavfi.signalstats.VLOW=64|tag:lavfi.signalstats.VAVG=520.354|tag:lavfi.signalstats.VHIGH=963|tag:lavfi.signalstats.VMAX=963|tag:lavfi.signalstats.SATMIN=2|tag:lavfi.signalstats.SATLOW=111|tag:lavfi.signalstats.SATAVG=386.128|tag:lavfi.signalstats.SATHIGH=481|tag:lavfi.signalstats.SATMAX=481|tag:lavfi.signalstats.YDIF=31.0404|tag:lavfi.signalstats.UDIF=28.5346|tag:lavfi.signalstats.VDIF=59.9269|tag:lavfi.signalstats.YBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
+pts=2|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.YMIN=88|tag:lavfi.signalstats.YLOW=164|tag:lavfi.signalstats.YAVG=446|tag:lavfi.signalstats.YHIGH=680|tag:lavfi.signalstats.YMAX=843|tag:lavfi.signalstats.UMIN=64|tag:lavfi.signalstats.ULOW=193|tag:lavfi.signalstats.UAVG=536.403|tag:lavfi.signalstats.UHIGH=963|tag:lavfi.signalstats.UMAX=963|tag:lavfi.signalstats.VMIN=64|tag:lavfi.signalstats.VLOW=64|tag:lavfi.signalstats.VAVG=514.177|tag:lavfi.signalstats.VHIGH=963|tag:lavfi.signalstats.VMAX=963|tag:lavfi.signalstats.SATMIN=2|tag:lavfi.signalstats.SATLOW=111|tag:lavfi.signalstats.SATAVG=375.36|tag:lavfi.signalstats.SATHIGH=481|tag:lavfi.signalstats.SATMAX=481|tag:lavfi.signalstats.YDIF=41.3124|tag:lavfi.signalstats.UDIF=37.5127|tag:lavfi.signalstats.VDIF=69.4265|tag:lavfi.signalstats.YBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
+pts=3|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.YMIN=88|tag:lavfi.signalstats.YLOW=164|tag:lavfi.signalstats.YAVG=449.966|tag:lavfi.signalstats.YHIGH=691|tag:lavfi.signalstats.YMAX=843|tag:lavfi.signalstats.UMIN=64|tag:lavfi.signalstats.ULOW=140|tag:lavfi.signalstats.UAVG=533.432|tag:lavfi.signalstats.UHIGH=963|tag:lavfi.signalstats.UMAX=963|tag:lavfi.signalstats.VMIN=64|tag:lavfi.signalstats.VLOW=64|tag:lavfi.signalstats.VAVG=511.871|tag:lavfi.signalstats.VHIGH=947|tag:lavfi.signalstats.VMAX=963|tag:lavfi.signalstats.SATMIN=2|tag:lavfi.signalstats.SATLOW=113|tag:lavfi.signalstats.SATAVG=374.43|tag:lavfi.signalstats.SATHIGH=481|tag:lavfi.signalstats.SATMAX=481|tag:lavfi.signalstats.YDIF=35.666|tag:lavfi.signalstats.UDIF=35.056|tag:lavfi.signalstats.VDIF=62.3544|tag:lavfi.signalstats.YBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
+pts=4|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.YMIN=88|tag:lavfi.signalstats.YLOW=164|tag:lavfi.signalstats.YAVG=451.134|tag:lavfi.signalstats.YHIGH=784|tag:lavfi.signalstats.YMAX=843|tag:lavfi.signalstats.UMIN=64|tag:lavfi.signalstats.ULOW=98|tag:lavfi.signalstats.UAVG=527.586|tag:lavfi.signalstats.UHIGH=963|tag:lavfi.signalstats.UMAX=963|tag:lavfi.signalstats.VMIN=64|tag:lavfi.signalstats.VLOW=64|tag:lavfi.signalstats.VAVG=519.321|tag:lavfi.signalstats.VHIGH=963|tag:lavfi.signalstats.VMAX=963|tag:lavfi.signalstats.SATMIN=2|tag:lavfi.signalstats.SATLOW=116|tag:lavfi.signalstats.SATAVG=382.484|tag:lavfi.signalstats.SATHIGH=481|tag:lavfi.signalstats.SATMAX=481|tag:lavfi.signalstats.YDIF=45.8823|tag:lavfi.signalstats.UDIF=48.0933|tag:lavfi.signalstats.VDIF=74.616|tag:lavfi.signalstats.YBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-none 
b/tests/ref/fate/filter-metadata-signalstats-mode-none
new file mode 100644
index 0000000000..4f5a7e5b34
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-none
@@ -0,0 +1,5 @@
+pts=0
+pts=1
+pts=2
+pts=3
+pts=4
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-none-brng 
b/tests/ref/fate/filter-metadata-signalstats-mode-none-brng
new file mode 100644
index 0000000000..b8a9408d76
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-none-brng
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.BRNG=0.537865
+pts=1|tag:lavfi.signalstats.BRNG=0.540625
+pts=2|tag:lavfi.signalstats.BRNG=0.518698
+pts=3|tag:lavfi.signalstats.BRNG=0.509531
+pts=4|tag:lavfi.signalstats.BRNG=0.526354
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-sat 
b/tests/ref/fate/filter-metadata-signalstats-mode-sat
new file mode 100644
index 0000000000..9d2f77ae39
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-sat
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.SATHIGH=119|tag:lavfi.signalstats.SATMIN=0|tag:lavfi.signalstats.SATLOW=28|tag:lavfi.signalstats.SATAVG=98.6198|tag:lavfi.signalstats.SATMAX=119
+pts=1|tag:lavfi.signalstats.SATHIGH=119|tag:lavfi.signalstats.SATMIN=0|tag:lavfi.signalstats.SATLOW=28|tag:lavfi.signalstats.SATAVG=95.984|tag:lavfi.signalstats.SATMAX=119
+pts=2|tag:lavfi.signalstats.SATHIGH=119|tag:lavfi.signalstats.SATMIN=0|tag:lavfi.signalstats.SATLOW=28|tag:lavfi.signalstats.SATAVG=93.3056|tag:lavfi.signalstats.SATMAX=119
+pts=3|tag:lavfi.signalstats.SATHIGH=119|tag:lavfi.signalstats.SATMIN=0|tag:lavfi.signalstats.SATLOW=28|tag:lavfi.signalstats.SATAVG=93.0731|tag:lavfi.signalstats.SATMAX=119
+pts=4|tag:lavfi.signalstats.SATHIGH=119|tag:lavfi.signalstats.SATMIN=0|tag:lavfi.signalstats.SATLOW=29|tag:lavfi.signalstats.SATAVG=95.0733|tag:lavfi.signalstats.SATMAX=119
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-uv 
b/tests/ref/fate/filter-metadata-signalstats-mode-uv
new file mode 100644
index 0000000000..75c65391ca
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-uv
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.VHIGH=963|tag:lavfi.signalstats.UMIN=64|tag:lavfi.signalstats.ULOW=64|tag:lavfi.signalstats.UAVG=526.307|tag:lavfi.signalstats.UHIGH=963|tag:lavfi.signalstats.UMAX=963|tag:lavfi.signalstats.VMIN=64|tag:lavfi.signalstats.VLOW=64|tag:lavfi.signalstats.VAVG=520.986|tag:lavfi.signalstats.VMAX=963
+pts=1|tag:lavfi.signalstats.VHIGH=963|tag:lavfi.signalstats.UMIN=64|tag:lavfi.signalstats.ULOW=212|tag:lavfi.signalstats.UAVG=532.118|tag:lavfi.signalstats.UHIGH=963|tag:lavfi.signalstats.UMAX=963|tag:lavfi.signalstats.VMIN=64|tag:lavfi.signalstats.VLOW=64|tag:lavfi.signalstats.VAVG=520.354|tag:lavfi.signalstats.VMAX=963
+pts=2|tag:lavfi.signalstats.VHIGH=963|tag:lavfi.signalstats.UMIN=64|tag:lavfi.signalstats.ULOW=193|tag:lavfi.signalstats.UAVG=536.403|tag:lavfi.signalstats.UHIGH=963|tag:lavfi.signalstats.UMAX=963|tag:lavfi.signalstats.VMIN=64|tag:lavfi.signalstats.VLOW=64|tag:lavfi.signalstats.VAVG=514.177|tag:lavfi.signalstats.VMAX=963
+pts=3|tag:lavfi.signalstats.VHIGH=947|tag:lavfi.signalstats.UMIN=64|tag:lavfi.signalstats.ULOW=140|tag:lavfi.signalstats.UAVG=533.432|tag:lavfi.signalstats.UHIGH=963|tag:lavfi.signalstats.UMAX=963|tag:lavfi.signalstats.VMIN=64|tag:lavfi.signalstats.VLOW=64|tag:lavfi.signalstats.VAVG=511.871|tag:lavfi.signalstats.VMAX=963
+pts=4|tag:lavfi.signalstats.VHIGH=963|tag:lavfi.signalstats.UMIN=64|tag:lavfi.signalstats.ULOW=98|tag:lavfi.signalstats.UAVG=527.586|tag:lavfi.signalstats.UHIGH=963|tag:lavfi.signalstats.UMAX=963|tag:lavfi.signalstats.VMIN=64|tag:lavfi.signalstats.VLOW=64|tag:lavfi.signalstats.VAVG=519.321|tag:lavfi.signalstats.VMAX=963
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-uvdepth 
b/tests/ref/fate/filter-metadata-signalstats-mode-uvdepth
new file mode 100644
index 0000000000..c46ec6bc59
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-uvdepth
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
+pts=1|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
+pts=2|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
+pts=3|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
+pts=4|tag:lavfi.signalstats.UBITDEPTH=10|tag:lavfi.signalstats.VBITDEPTH=10
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-uvdif 
b/tests/ref/fate/filter-metadata-signalstats-mode-uvdif
new file mode 100644
index 0000000000..1cd6379437
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-uvdif
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.UDIF=0|tag:lavfi.signalstats.VDIF=0
+pts=1|tag:lavfi.signalstats.UDIF=28.5346|tag:lavfi.signalstats.VDIF=59.9269
+pts=2|tag:lavfi.signalstats.UDIF=37.5127|tag:lavfi.signalstats.VDIF=69.4265
+pts=3|tag:lavfi.signalstats.UDIF=35.056|tag:lavfi.signalstats.VDIF=62.3544
+pts=4|tag:lavfi.signalstats.UDIF=48.0933|tag:lavfi.signalstats.VDIF=74.616
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-y 
b/tests/ref/fate/filter-metadata-signalstats-mode-y
new file mode 100644
index 0000000000..2019a8e90f
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-y
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.YHIGH=210|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=111.34|tag:lavfi.signalstats.YMAX=210
+pts=1|tag:lavfi.signalstats.YHIGH=170|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=110.923|tag:lavfi.signalstats.YMAX=210
+pts=2|tag:lavfi.signalstats.YHIGH=170|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=111.217|tag:lavfi.signalstats.YMAX=210
+pts=3|tag:lavfi.signalstats.YHIGH=172|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=112.215|tag:lavfi.signalstats.YMAX=210
+pts=4|tag:lavfi.signalstats.YHIGH=195|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=112.498|tag:lavfi.signalstats.YMAX=210
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-y-ydif 
b/tests/ref/fate/filter-metadata-signalstats-mode-y-ydif
new file mode 100644
index 0000000000..259257b4ea
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-y-ydif
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=111.34|tag:lavfi.signalstats.YHIGH=210|tag:lavfi.signalstats.YDIF=0
+pts=1|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=110.923|tag:lavfi.signalstats.YHIGH=170|tag:lavfi.signalstats.YDIF=7.73203
+pts=2|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=111.217|tag:lavfi.signalstats.YHIGH=170|tag:lavfi.signalstats.YDIF=10.2877
+pts=3|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=112.215|tag:lavfi.signalstats.YHIGH=172|tag:lavfi.signalstats.YDIF=8.89365
+pts=4|tag:lavfi.signalstats.YMAX=210|tag:lavfi.signalstats.YMIN=22|tag:lavfi.signalstats.YLOW=41|tag:lavfi.signalstats.YAVG=112.498|tag:lavfi.signalstats.YHIGH=195|tag:lavfi.signalstats.YDIF=11.4572
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-ydepth 
b/tests/ref/fate/filter-metadata-signalstats-mode-ydepth
new file mode 100644
index 0000000000..31ee43d167
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-ydepth
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.YBITDEPTH=8
+pts=1|tag:lavfi.signalstats.YBITDEPTH=8
+pts=2|tag:lavfi.signalstats.YBITDEPTH=8
+pts=3|tag:lavfi.signalstats.YBITDEPTH=8
+pts=4|tag:lavfi.signalstats.YBITDEPTH=8
diff --git a/tests/ref/fate/filter-metadata-signalstats-mode-ydif 
b/tests/ref/fate/filter-metadata-signalstats-mode-ydif
new file mode 100644
index 0000000000..943fca9a80
--- /dev/null
+++ b/tests/ref/fate/filter-metadata-signalstats-mode-ydif
@@ -0,0 +1,5 @@
+pts=0|tag:lavfi.signalstats.YDIF=0
+pts=1|tag:lavfi.signalstats.YDIF=7.73203
+pts=2|tag:lavfi.signalstats.YDIF=10.2877
+pts=3|tag:lavfi.signalstats.YDIF=8.89365
+pts=4|tag:lavfi.signalstats.YDIF=11.4572
-- 
2.54.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to