From: Jeffrey CHAPUIS <ashyni1987@gmail.com>
To: ffmpeg-devel@ffmpeg.org
Subject: Re: [FFmpeg-devel] [PATCH] avfilter/vf_cropdetect: add ability to change limit/reset at runtime
Date: Wed, 28 Dec 2022 16:37:30 +0100
Message-ID: <3d004628-9475-bf08-5cba-e935a358dfce@gmail.com> (raw)
In-Reply-To: <d2d915a2-b4a0-357d-b96e-b06530536413@gmail.com>
> 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-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2022-12-28 15:37 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-28 11:02 Jeffrey CHAPUIS
2022-12-28 11:21 ` Marton Balint
2022-12-28 11:51 ` James Almer
2022-12-28 15:37 ` Jeffrey CHAPUIS [this message]
-- strict thread matches above, loose matches on Subject: below --
2023-01-10 13:15 Jeffrey CHAPUIS
2023-01-10 15:45 ` Paul B Mahol
2023-01-11 11:42 ` Jeffrey Chapuis
2023-01-11 17:46 ` Jeffrey Chapuis
2023-01-12 15:53 ` Jeffrey Chapuis
2023-01-17 11:46 ` Jeffrey Chapuis
2023-01-17 11:52 ` Paul B Mahol
2023-01-17 12:27 ` Jeffrey Chapuis
2023-01-17 12:34 ` Paul B Mahol
2023-01-17 13:31 ` Jeffrey Chapuis
2023-01-17 13:45 ` Paul B Mahol
2023-01-17 14:24 ` Jeffrey Chapuis
2023-01-17 14:29 ` Paul B Mahol
2023-01-17 15:19 ` Jeffrey Chapuis
2023-01-17 16:23 ` Paul B Mahol
2023-01-17 18:00 ` Jeffrey Chapuis
2023-01-17 18:11 ` Paul B Mahol
2023-01-17 22:07 ` Jeffrey Chapuis
2023-01-19 12:11 ` Jeffrey Chapuis
2023-01-19 13:50 ` Jeffrey Chapuis
2022-12-27 12:33 Jeffrey CHAPUIS
2022-12-27 11:46 Jeffrey CHAPUIS
2022-12-27 12:34 ` James Almer
2022-12-27 12:57 ` Jeffrey CHAPUIS
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3d004628-9475-bf08-5cba-e935a358dfce@gmail.com \
--to=ashyni1987@gmail.com \
--cc=ffmpeg-devel@ffmpeg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git