diff --git a/libavfilter/vf_blackdetect.c b/libavfilter/vf_blackdetect.c index 6a51e2f290..99685491ff 100644 --- a/libavfilter/vf_blackdetect.c +++ b/libavfilter/vf_blackdetect.c @@ -36,6 +36,7 @@ typedef struct { int64_t black_min_duration; ///< minimum duration of detected black, expressed in timebase units int64_t black_start; ///< pts start time of the first black picture int64_t black_end; ///< pts end time of the last black picture + int64_t last_picref_pts; ///< pts of the last input picture int black_started; double picture_black_ratio_th; @@ -122,6 +123,35 @@ static int config_input(AVFilterLink *inlink) return 0; } +static void check_black_end(AVFilterContext *ctx) +{ + BlackDetectContext *blackdetect = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; + + if ((blackdetect->black_end - blackdetect->black_start) >= blackdetect->black_min_duration) { + av_log(blackdetect, AV_LOG_INFO, + "black_start:%s black_end:%s black_duration:%s\n", + av_ts2timestr(blackdetect->black_start, &inlink->time_base), + av_ts2timestr(blackdetect->black_end, &inlink->time_base), + av_ts2timestr(blackdetect->black_end - blackdetect->black_start, &inlink->time_base)); + } +} + +static int request_frame(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + BlackDetectContext *blackdetect = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; + int ret = avfilter_request_frame(inlink); + + if (ret == AVERROR_EOF && blackdetect->black_started) { + // FIXME: black_end should be set to last_picref_pts + last_picref_duration + blackdetect->black_end = blackdetect->last_picref_pts; + check_black_end(ctx); + } + return ret; +} + static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { AVFilterContext *ctx = inlink->dst; @@ -164,16 +194,10 @@ static void end_frame(AVFilterLink *inlink) /* black ends here */ blackdetect->black_started = 0; blackdetect->black_end = picref->pts; - - if ((blackdetect->black_end - blackdetect->black_start) >= blackdetect->black_min_duration) { - av_log(blackdetect, AV_LOG_INFO, - "black_start:%s black_end:%s black_duration:%s\n", - av_ts2timestr(blackdetect->black_start, &inlink->time_base), - av_ts2timestr(blackdetect->black_end, &inlink->time_base), - av_ts2timestr(blackdetect->black_end - blackdetect->black_start, &inlink->time_base)); - } + check_black_end(ctx); } + blackdetect->last_picref_pts = picref->pts; blackdetect->frame_count++; blackdetect->nb_black_pixels = 0; avfilter_unref_buffer(picref); @@ -200,7 +224,8 @@ AVFilter avfilter_vf_blackdetect = { .outputs = (const AVFilterPad[]) { { .name = "default", - .type = AVMEDIA_TYPE_VIDEO }, + .type = AVMEDIA_TYPE_VIDEO, + .request_frame = request_frame, }, { .name = NULL } }, };