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".