]> git.sesse.net Git - ffmpeg/commitdiff
avfilter/vf_chromanr: add options for finer controls of filtering
authorPaul B Mahol <onemda@gmail.com>
Fri, 11 Dec 2020 12:35:41 +0000 (13:35 +0100)
committerPaul B Mahol <onemda@gmail.com>
Fri, 11 Dec 2020 12:39:50 +0000 (13:39 +0100)
doc/filters.texi
libavfilter/vf_chromanr.c

index d1c044cd9c1227ad0b2010cea1fe43101bb8120d..bd8bb85de379d99731b4549bec4247b681286d77 100644 (file)
@@ -7742,7 +7742,7 @@ The filter accepts the following options:
 @table @option
 @item thres
 Set threshold for averaging chrominance values.
-Sum of absolute difference of U and V pixel components or current
+Sum of absolute difference of Y, U and V pixel components of current
 pixel and neighbour pixels lower than this threshold will be used in
 averaging. Luma component is left unchanged and is copied to output.
 Default value is 30. Allowed range is from 1 to 200.
@@ -7764,6 +7764,24 @@ Mostly useful to speed-up filtering.
 Set vertical step when averaging. Default value is 1.
 Allowed range is from 1 to 50.
 Mostly useful to speed-up filtering.
+
+@item threy
+Set Y threshold for averaging chrominance values.
+Set finer control for max allowed difference between Y components
+of current pixel and neigbour pixels.
+Default value is 200. Allowed range is from 1 to 200.
+
+@item threu
+Set U threshold for averaging chrominance values.
+Set finer control for max allowed difference between U components
+of current pixel and neigbour pixels.
+Default value is 200. Allowed range is from 1 to 200.
+
+@item threv
+Set V threshold for averaging chrominance values.
+Set finer control for max allowed difference between V components
+of current pixel and neigbour pixels.
+Default value is 200. Allowed range is from 1 to 200.
 @end table
 
 @subsection Commands
index 78dbe37e683be168cded6da2c33f7e999c239392..3c027b8f42a65ec6734a15d5e6b3845ec1350525 100644 (file)
@@ -32,7 +32,13 @@ typedef struct ChromaNRContext {
     const AVClass *class;
 
     float threshold;
+    float threshold_y;
+    float threshold_u;
+    float threshold_v;
     int thres;
+    int thres_y;
+    int thres_u;
+    int thres_v;
     int sizew;
     int sizeh;
     int stepw;
@@ -91,6 +97,9 @@ static int filter_slice##name(AVFilterContext *ctx, void *arg, int jobnr, int nb
     const int sizew = s->sizew;                                                          \
     const int sizeh = s->sizeh;                                                          \
     const int thres = s->thres;                                                          \
+    const int thres_y = s->thres_y;                                                      \
+    const int thres_u = s->thres_u;                                                      \
+    const int thres_v = s->thres_v;                                                      \
     const int h = s->planeheight[1];                                                     \
     const int w = s->planewidth[1];                                                      \
     const int slice_start = (h * jobnr) / nb_jobs;                                       \
@@ -142,6 +151,8 @@ static int filter_slice##name(AVFilterContext *ctx, void *arg, int jobnr, int nb
                     const int V = in_vptr[xx];                                         \
                                                                                        \
                     if (FFABS(cu - U) + FFABS(cv - V) + FFABS(cy - Y) < thres &&       \
+                        FFABS(cu - U) < thres_u && FFABS(cv - V) < thres_v &&          \
+                        FFABS(cy - Y) < thres_y &&                                     \
                         xx != x && yy != y) {                                          \
                         su += U;                                                       \
                         sv += V;                                                       \
@@ -172,6 +183,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
     AVFrame *out;
 
     s->thres = s->threshold * (1 << (s->depth - 8));
+    s->thres_y = s->threshold_y * (1 << (s->depth - 8));
+    s->thres_u = s->threshold_u * (1 << (s->depth - 8));
+    s->thres_v = s->threshold_v * (1 << (s->depth - 8));
 
     out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
@@ -217,11 +231,14 @@ static int config_input(AVFilterLink *inlink)
 #define VF AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_RUNTIME_PARAM
 
 static const AVOption chromanr_options[] = {
-    { "thres", "set u/v threshold",   OFFSET(threshold), AV_OPT_TYPE_FLOAT, {.dbl=30}, 1, 200, VF },
+    { "thres", "set y+u+v threshold", OFFSET(threshold), AV_OPT_TYPE_FLOAT, {.dbl=30}, 1, 200, VF },
     { "sizew", "set horizontal size", OFFSET(sizew),     AV_OPT_TYPE_INT,   {.i64=5},  1, 100, VF },
     { "sizeh", "set vertical size",   OFFSET(sizeh),     AV_OPT_TYPE_INT,   {.i64=5},  1, 100, VF },
     { "stepw", "set horizontal step", OFFSET(stepw),     AV_OPT_TYPE_INT,   {.i64=1},  1,  50, VF },
     { "steph", "set vertical step",   OFFSET(steph),     AV_OPT_TYPE_INT,   {.i64=1},  1,  50, VF },
+    { "threy", "set y threshold",   OFFSET(threshold_y), AV_OPT_TYPE_FLOAT, {.dbl=200},1, 200, VF },
+    { "threu", "set u threshold",   OFFSET(threshold_u), AV_OPT_TYPE_FLOAT, {.dbl=200},1, 200, VF },
+    { "threv", "set v threshold",   OFFSET(threshold_v), AV_OPT_TYPE_FLOAT, {.dbl=200},1, 200, VF },
     { NULL }
 };