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.
Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -102,8 +102,6 @@ static int config_input(AVFilterLink *inlink) · 101 unmodified lines | |||
| 102 | BlackDetectContext *s = ctx->priv; | 102 | BlackDetectContext *s = ctx->priv; |
| 103 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); | 103 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); |
| 104 | const int depth = desc->comp[0].depth; | 104 | const int depth = desc->comp[0].depth; |
| 105 | const int max = (1 << depth) - 1; | ||
| 106 | const int factor = (1 << (depth - 8)); | ||
| 107 | 105 | ||
| 108 | s->depth = depth; | 106 | s->depth = depth; |
| 109 | s->nb_threads = ff_filter_get_nb_threads(ctx); | 107 | s->nb_threads = ff_filter_get_nb_threads(ctx); |
| @@ -113,16 +111,10 @@ static int config_input(AVFilterLink *inlink) · 3 unmodified lines | |||
| 113 | if (!s->counter) | 111 | if (!s->counter) |
| 114 | return AVERROR(ENOMEM); | 112 | return AVERROR(ENOMEM); |
| 115 | 113 | ||
| 116 | s->pixel_black_th_i = ff_fmt_is_in(inlink->format, yuvj_formats) ? | ||
| 117 | // luminance_minimum_value + pixel_black_th * luminance_range_size | ||
| 118 | s->pixel_black_th * max : | ||
| 119 | 16 * factor + s->pixel_black_th * (235 - 16) * factor; | ||
| 120 | |||
| 121 | av_log(s, AV_LOG_VERBOSE, | 114 | av_log(s, AV_LOG_VERBOSE, |
| 122 | "black_min_duration:%s pixel_black_th:%f pixel_black_th_i:%d picture_black_ratio_th:%f\n", | 115 | "black_min_duration:%s pixel_black_th:%f picture_black_ratio_th:%f\n", |
| 123 | av_ts2timestr(s->black_min_duration, &s->time_base), | 116 | av_ts2timestr(s->black_min_duration, &s->time_base), |
| 124 | s->pixel_black_th, s->pixel_black_th_i, | 117 | s->pixel_black_th, s->picture_black_ratio_th); |
| 125 | s->picture_black_ratio_th); | ||
| 126 | return 0; | 118 | return 0; |
| 127 | } | 119 | } |
| 128 | 120 | ||
| @@ -182,6 +174,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) · 53 unmodified lines | |||
| 182 | AVFilterContext *ctx = inlink->dst; | 174 | AVFilterContext *ctx = inlink->dst; |
| 183 | BlackDetectContext *s = ctx->priv; | 175 | BlackDetectContext *s = ctx->priv; |
| 184 | double picture_black_ratio = 0; | 176 | double picture_black_ratio = 0; |
| 177 | const int max = (1 << s->depth) - 1; | ||
| 178 | const int factor = (1 << (s->depth - 8)); | ||
| 179 | const int full = picref->color_range == AVCOL_RANGE_JPEG || | ||
| 180 | ff_fmt_is_in(picref->format, yuvj_formats); | ||
| 181 | |||
| 182 | s->pixel_black_th_i = full ? s->pixel_black_th * max : | ||
| 183 | // luminance_minimum_value + pixel_black_th * luminance_range_size | ||
| 184 | 16 * factor + s->pixel_black_th * (235 - 16) * factor; | ||
| 185 | 185 | ||
| 186 | ff_filter_execute(ctx, black_counter, picref, NULL, | 186 | ff_filter_execute(ctx, black_counter, picref, NULL, |
| 187 | FFMIN(inlink->h, s->nb_threads)); | 187 | FFMIN(inlink->h, s->nb_threads)); |