You need a custom function that will keep old values around and realloc the buffers for bboxes using the new reset_count value passed as a runtime command, but one that will not call config_input() like you did the first time as that one does a lot more than what you need.

It should also call init() to reset frame_nb, a value you of course also need to preserve for the fallback scenario, and allocate the new buffers but only replace them in the filter context if all four allocations succeeded, as doing av_realloc() could potentially not let you fallback to continue the process with the old values if required.

Here is my last attempt to do it myself, i don't want to waste everyone's time, i barely understand what i code, without proper knowledge in c/c++ and ffmpeg project.

diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c
index 7e985fb27..f4d2f1379 100644
--- a/libavfilter/vf_cropdetect.c
+++ b/libavfilter/vf_cropdetect.c
@@ -422,26 +422,65 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
         SET_META("lavfi.cropdetect.h",  h);
         SET_META("lavfi.cropdetect.x",  x);
         SET_META("lavfi.cropdetect.y",  y);
+        SET_META("lavfi.cropdetect.pts", frame->pts);
+        SET_META("lavfi.cropdetect.limit", limit);
+        SET_META("lavfi.cropdetect.reset", s->reset_count);

         av_log(ctx, AV_LOG_INFO,
-               "x1:%d x2:%d y1:%d y2:%d w:%d h:%d x:%d y:%d pts:%"PRId64" t:%f crop=%d:%d:%d:%d\n", +               "x1:%d x2:%d y1:%d y2:%d w:%d h:%d x:%d y:%d pts:%"PRId64" t:%f limit:%d crop=%d:%d:%d:%d\n",
                s->x1, s->x2, s->y1, s->y2, w, h, x, y, frame->pts,
                frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base),
-               w, h, x, y);
+               limit, w, h, x, y);
     }

     return ff_filter_frame(inlink->dst->outputs[0], frame);
 }

+static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
+                           char *res, int res_len, int flags)
+{
+    CropDetectContext *s = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+    int old_limit = s->limit;
+    int old_reset_count = s->reset_count;
+    int old_frame_nb = s->frame_nb;
+    int ret;
+
+    if ((ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags)) < 0)
+        return ret;
+
+    init;
+
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+    const int bufsize = inlink->w * inlink->h;
+    av_image_fill_max_pixsteps(s->max_pixsteps, NULL, desc);
+    if (s->limit < 1.0)
+        s->limit *= (1 << desc->comp[0].depth) - 1;
+
+    s->window_size = FFMAX(s->reset_count, 15);
+    if ((ret = (av_realloc(s->filterbuf, bufsize * s->max_pixsteps[0])
+        || av_realloc(s->bboxes[0], s->window_size * sizeof(*s->bboxes[0]))
+        || av_realloc(s->bboxes[1], s->window_size * sizeof(*s->bboxes[1]))
+        || av_realloc(s->bboxes[2], s->window_size * sizeof(*s->bboxes[2]))
+        || av_realloc(s->bboxes[3], s->window_size * sizeof(*s->bboxes[3])))) < 0) {
+        s->limit = old_limit;
+        s->reset_count = old_reset_count;
+        s->frame_nb = old_frame_nb;
+    }
+
+    return ret;
+}
+
 #define OFFSET(x) offsetof(CropDetectContext, x)
 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+#define TFLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_RUNTIME_PARAM

 static const AVOption cropdetect_options[] = {
-    { "limit", "Threshold below which the pixel is considered black", OFFSET(limit),       AV_OPT_TYPE_FLOAT, { .dbl = 24.0/255 }, 0, 65535, FLAGS }, +    { "limit", "Threshold below which the pixel is considered black", OFFSET(limit),       AV_OPT_TYPE_FLOAT, { .dbl = 24.0/255 }, 0, 65535, TFLAGS },      { "round", "Value by which the width/height should be divisible", OFFSET(round),       AV_OPT_TYPE_INT, { .i64 = 16 }, 0, INT_MAX, FLAGS }, -    { "reset", "Recalculate the crop area after this many frames",    OFFSET(reset_count), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, +    { "reset", "Recalculate the crop area after this many frames",    OFFSET(reset_count), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, TFLAGS },      { "skip",  "Number of initial frames to skip",                    OFFSET(skip),        AV_OPT_TYPE_INT, { .i64 = 2 },  0, INT_MAX, FLAGS }, -    { "reset_count", "Recalculate the crop area after this many frames",OFFSET(reset_count),AV_OPT_TYPE_INT,{ .i64 = 0 },  0, INT_MAX, FLAGS }, +    { "reset_count", "Recalculate the crop area after this many frames",OFFSET(reset_count),AV_OPT_TYPE_INT,{ .i64 = 0 },  0, INT_MAX, TFLAGS },      { "max_outliers", "Threshold count of outliers",                  OFFSET(max_outliers),AV_OPT_TYPE_INT, { .i64 = 0 },  0, INT_MAX, FLAGS },      { "mode", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_BLACK}, 0, MODE_NB-1, FLAGS, "mode" },          { "black",    "detect black pixels surrounding the video",     0, AV_OPT_TYPE_CONST, {.i64=MODE_BLACK},    INT_MIN, INT_MAX, FLAGS, "mode" },
@@ -481,4 +520,5 @@ const AVFilter ff_vf_cropdetect = {
     FILTER_OUTPUTS(avfilter_vf_cropdetect_outputs),
     FILTER_PIXFMTS_ARRAY(pix_fmts),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_METADATA_ONLY,
+    .process_command = process_command,
 };


Why are you adding frame pts as metadata? Or the detection parameters? Those are not detected, so have no business being there in metadata or log.

Regards,
Marton
It make sense for my lua script, https://github.com/Ashyni/mpv-scripts.
For pts, it's because mpv doesn't provide the frame/pts/pts_time data alongside others tag field in the metadata, may be an issue should be open for mpv to change that. As for the parameters, It's added as a reference to be sure when i look at the metadata that the result come from the new limit and not the previous one, same for reset. It's the only way i can be sure of the result without waiting an arbitrary time between every change to limit/reset.

In the end, the goal is to analyzed data ahead with something like :

ffmpeg -i <input> -filter_complex 'split[a1][b1];[b1]setpts=PTS-2/TB,cropdetect@cd1=reset=1[b2];[b2][a1]overlay,setpts=PTS-2/TB,cropdetect@cd2=reset=1' -f null -

with mpv : mp.set_property_native("lavfi-complex", "[vid1]split[a_1][b_1];[b_1]setpts=PTS-2/TB,cropdetect@cd1=reset=1[b_2];[b_2][a_1]overlay,setpts=PTS-2/TB,cropdetect@cd2=reset=1[vo]")

but that another topic, and mpv have some issue anyway with vf-command and graph/lavfi-complex.

Reminder, that was an attempt for https://trac.ffmpeg.org/ticket/9851, if someone wants to take over.
Thanks for your time everyone.

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to