Commit 8e2f61ef authored by Niklas Haas's avatar Niklas Haas

avfilter/vf_blackdetect: support full-range YUV

This filter currently makes the distinction between limited and full
range by testing for the deprecated YUVJ pixel formats at link setup
time. This is deprecated and should be improved to perform the detection
based on the per-frame metadata.

Rewrite it to calculate the black pixel threshold at the time of
filtering a frame, when metadata about the frame's color range is known.
Doing it this way has the small side benefit of being able to handle
streams with variable metadata, and is not a meaningful performance
cost.
Signed-off-by: 's avatarNiklas Haas <git@haasn.dev>
parent 3b66757d
......@@ -102,8 +102,6 @@ static int config_input(AVFilterLink *inlink)
BlackDetectContext *s = ctx->priv;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
const int depth = desc->comp[0].depth;
const int max = (1 << depth) - 1;
const int factor = (1 << (depth - 8));
s->depth = depth;
s->nb_threads = ff_filter_get_nb_threads(ctx);
......@@ -113,16 +111,10 @@ static int config_input(AVFilterLink *inlink)
if (!s->counter)
return AVERROR(ENOMEM);
s->pixel_black_th_i = ff_fmt_is_in(inlink->format, yuvj_formats) ?
// luminance_minimum_value + pixel_black_th * luminance_range_size
s->pixel_black_th * max :
16 * factor + s->pixel_black_th * (235 - 16) * factor;
av_log(s, AV_LOG_VERBOSE,
"black_min_duration:%s pixel_black_th:%f pixel_black_th_i:%d picture_black_ratio_th:%f\n",
"black_min_duration:%s pixel_black_th:%f picture_black_ratio_th:%f\n",
av_ts2timestr(s->black_min_duration, &s->time_base),
s->pixel_black_th, s->pixel_black_th_i,
s->picture_black_ratio_th);
s->pixel_black_th, s->picture_black_ratio_th);
return 0;
}
......@@ -182,6 +174,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
AVFilterContext *ctx = inlink->dst;
BlackDetectContext *s = ctx->priv;
double picture_black_ratio = 0;
const int max = (1 << s->depth) - 1;
const int factor = (1 << (s->depth - 8));
const int full = picref->color_range == AVCOL_RANGE_JPEG ||
ff_fmt_is_in(picref->format, yuvj_formats);
s->pixel_black_th_i = full ? s->pixel_black_th * max :
// luminance_minimum_value + pixel_black_th * luminance_range_size
16 * factor + s->pixel_black_th * (235 - 16) * factor;
ff_filter_execute(ctx, black_counter, picref, NULL,
FFMIN(inlink->h, s->nb_threads));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment