* [FFmpeg-devel] [PATCH] avfilter/setpts: add command support
@ 2023-05-01 21:01 Oleg Afanasyev
2023-05-07 22:46 ` Stefano Sabatini
0 siblings, 1 reply; 4+ messages in thread
From: Oleg Afanasyev @ 2023-05-01 21:01 UTC (permalink / raw)
To: ffmpeg-devel
[-- Attachment #1: Type: text/plain, Size: 389 bytes --]
I'm using setpts to generate timelapses with slowdowns in the middle.
Using setpts filter requires complicated expr to handle intervals. This
patch allows commands to change expr and also adds a constant that
provides time of last command applications to allow specifying gradual
changes using difference between time and cmd time.
----------------------
with best regards
Oleg Afanasyev
[-- Attachment #2: 0001-avfilter-setpts-add-command-support.patch --]
[-- Type: text/x-patch, Size: 6035 bytes --]
From a714a0957a57c1d392feca0ba675ba5ac7c875ee Mon Sep 17 00:00:00 2001
From: Oleg <oafanasiev@gmail.com>
Date: Sat, 29 Apr 2023 19:56:46 +0100
Subject: [PATCH] avfilter/setpts: add command support
Add support for changing expr on the fly.
Signed-off-by: Oleg <oafanasiev@gmail.com>
---
doc/filters.texi | 7 +++++
libavfilter/setpts.c | 68 +++++++++++++++++++++++++++++++++-----------
2 files changed, 58 insertions(+), 17 deletions(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index 50e1682144..fbdb1f8ecf 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -29384,6 +29384,9 @@ The wallclock (RTC) time at the start of the movie in microseconds.
@item TB
The timebase of the input timestamps.
+@item T_CHANGE
+Time of the first frame after command was applied or time of the first frame if no commands.
+
@end table
@subsection Examples
@@ -29439,6 +29442,10 @@ asetpts=N/SR/TB
@end itemize
+@subsection Commands
+
+Both filters support all above options as @ref{commands}.
+
@section setrange
Force color range for the output video frame.
diff --git a/libavfilter/setpts.c b/libavfilter/setpts.c
index 5bcc0c2dcf..7b09ce7707 100644
--- a/libavfilter/setpts.c
+++ b/libavfilter/setpts.c
@@ -63,6 +63,7 @@ static const char *const var_names[] = {
"S", // Number of samples in the current frame
"SR", // Audio sample rate
"FR", ///< defined only for constant frame-rate video
+ "T_CHANGE", ///< time of first frame after latest command was applied
NULL
};
@@ -90,7 +91,8 @@ enum var_name {
VAR_S,
VAR_SR,
VAR_FR,
- VAR_VARS_NB
+ VAR_T_CHANGE,
+ VAR_VARS_NB,
};
typedef struct SetPTSContext {
@@ -120,6 +122,7 @@ static av_cold int init(AVFilterContext *ctx)
setpts->var_values[VAR_PREV_OUTT] = NAN;
setpts->var_values[VAR_STARTPTS] = NAN;
setpts->var_values[VAR_STARTT] = NAN;
+ setpts->var_values[VAR_T_CHANGE] = NAN;
return 0;
}
@@ -163,6 +166,9 @@ static double eval_pts(SetPTSContext *setpts, AVFilterLink *inlink, AVFrame *fra
setpts->var_values[VAR_STARTPTS] = TS2D(pts);
setpts->var_values[VAR_STARTT ] = TS2T(pts, inlink->time_base);
}
+ if (isnan(setpts->var_values[VAR_T_CHANGE])) {
+ setpts->var_values[VAR_T_CHANGE] = TS2T(pts, inlink->time_base);
+ }
setpts->var_values[VAR_PTS ] = TS2D(pts);
setpts->var_values[VAR_T ] = TS2T(pts, inlink->time_base);
#if FF_API_FRAME_PKT
@@ -269,14 +275,40 @@ static av_cold void uninit(AVFilterContext *ctx)
setpts->expr = NULL;
}
+static int process_command(AVFilterContext *ctx, const char *cmd, const char *arg,
+ char *res, int res_len, int flags)
+{
+ SetPTSContext *setpts = ctx->priv;
+ int ret;
+
+ ret = ff_filter_process_command(ctx, cmd, arg, res, res_len, flags);
+
+ if (ret < 0)
+ return ret;
+
+ if (!strcmp(cmd, "expr")) {
+ av_expr_free(setpts->expr);
+ ret = av_expr_parse(&setpts->expr, arg, var_names, NULL, NULL, NULL, NULL, 0, ctx);
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", arg);
+ }
+ setpts->var_values[VAR_T_CHANGE] = NAN;
+ } else {
+ ret = AVERROR(EINVAL);
+ }
+
+ return ret;
+}
+
#define OFFSET(x) offsetof(SetPTSContext, x)
#define V AV_OPT_FLAG_VIDEO_PARAM
#define A AV_OPT_FLAG_AUDIO_PARAM
+#define R AV_OPT_FLAG_RUNTIME_PARAM
#define F AV_OPT_FLAG_FILTERING_PARAM
#if CONFIG_SETPTS_FILTER
static const AVOption setpts_options[] = {
- { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = V|F },
+ { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = V|F|R },
{ NULL }
};
AVFILTER_DEFINE_CLASS(setpts);
@@ -297,12 +329,13 @@ static const AVFilterPad avfilter_vf_setpts_outputs[] = {
};
const AVFilter ff_vf_setpts = {
- .name = "setpts",
- .description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."),
- .init = init,
- .activate = activate,
- .uninit = uninit,
- .flags = AVFILTER_FLAG_METADATA_ONLY,
+ .name = "setpts",
+ .description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."),
+ .init = init,
+ .activate = activate,
+ .uninit = uninit,
+ .process_command = process_command,
+ .flags = AVFILTER_FLAG_METADATA_ONLY,
.priv_size = sizeof(SetPTSContext),
.priv_class = &setpts_class,
@@ -315,7 +348,7 @@ const AVFilter ff_vf_setpts = {
#if CONFIG_ASETPTS_FILTER
static const AVOption asetpts_options[] = {
- { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = A|F },
+ { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = A|F|R },
{ NULL }
};
AVFILTER_DEFINE_CLASS(asetpts);
@@ -336,14 +369,15 @@ static const AVFilterPad asetpts_outputs[] = {
};
const AVFilter ff_af_asetpts = {
- .name = "asetpts",
- .description = NULL_IF_CONFIG_SMALL("Set PTS for the output audio frame."),
- .init = init,
- .activate = activate,
- .uninit = uninit,
- .priv_size = sizeof(SetPTSContext),
- .priv_class = &asetpts_class,
- .flags = AVFILTER_FLAG_METADATA_ONLY,
+ .name = "asetpts",
+ .description = NULL_IF_CONFIG_SMALL("Set PTS for the output audio frame."),
+ .init = init,
+ .activate = activate,
+ .uninit = uninit,
+ .process_command = process_command,
+ .priv_size = sizeof(SetPTSContext),
+ .priv_class = &asetpts_class,
+ .flags = AVFILTER_FLAG_METADATA_ONLY,
FILTER_INPUTS(asetpts_inputs),
FILTER_OUTPUTS(asetpts_outputs),
};
--
2.40.0
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
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".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH] avfilter/setpts: add command support
2023-05-01 21:01 [FFmpeg-devel] [PATCH] avfilter/setpts: add command support Oleg Afanasyev
@ 2023-05-07 22:46 ` Stefano Sabatini
2023-05-09 23:12 ` Oleg Afanasyev
0 siblings, 1 reply; 4+ messages in thread
From: Stefano Sabatini @ 2023-05-07 22:46 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On date Monday 2023-05-01 22:01:05 +0100, Oleg Afanasyev wrote:
> I'm using setpts to generate timelapses with slowdowns in the middle.
> Using setpts filter requires complicated expr to handle intervals. This
> patch allows commands to change expr and also adds a constant that
> provides time of last command applications to allow specifying gradual
> changes using difference between time and cmd time.
>
> ----------------------
> with best regards
> Oleg Afanasyev
> From a714a0957a57c1d392feca0ba675ba5ac7c875ee Mon Sep 17 00:00:00 2001
> From: Oleg <oafanasiev@gmail.com>
> Date: Sat, 29 Apr 2023 19:56:46 +0100
> Subject: [PATCH] avfilter/setpts: add command support
>
> Add support for changing expr on the fly.
>
> Signed-off-by: Oleg <oafanasiev@gmail.com>
> ---
> doc/filters.texi | 7 +++++
> libavfilter/setpts.c | 68 +++++++++++++++++++++++++++++++++-----------
> 2 files changed, 58 insertions(+), 17 deletions(-)
>
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 50e1682144..fbdb1f8ecf 100644
> diff --git a/libavfilter/setpts.c b/libavfilter/setpts.c
> index 5bcc0c2dcf..7b09ce7707 100644
> --- a/libavfilter/setpts.c
> +++ b/libavfilter/setpts.c
[...]
> +static int process_command(AVFilterContext *ctx, const char *cmd, const char *arg,
> + char *res, int res_len, int flags)
> +{
> + SetPTSContext *setpts = ctx->priv;
> + int ret;
> +
> + ret = ff_filter_process_command(ctx, cmd, arg, res, res_len, flags);
> +
> + if (ret < 0)
> + return ret;
> +
> + if (!strcmp(cmd, "expr")) {
> + av_expr_free(setpts->expr);
> + ret = av_expr_parse(&setpts->expr, arg, var_names, NULL, NULL, NULL, NULL, 0, ctx);
> + if (ret < 0) {
> + av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", arg);
> + }
what happens in case setpts->expr is freed and this fails?
probably it should keep a reference to expr and remove it only in case
the new expression was successfully parsed
[...]
Looks good to me otherwise.
_______________________________________________
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".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH] avfilter/setpts: add command support
2023-05-07 22:46 ` Stefano Sabatini
@ 2023-05-09 23:12 ` Oleg Afanasyev
2023-05-14 9:14 ` Stefano Sabatini
0 siblings, 1 reply; 4+ messages in thread
From: Oleg Afanasyev @ 2023-05-09 23:12 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1: Type: text/plain, Size: 2630 bytes --]
On Sun, 7 May 2023 at 23:47, Stefano Sabatini <stefasab@gmail.com> wrote:
>
> On date Monday 2023-05-01 22:01:05 +0100, Oleg Afanasyev wrote:
> > I'm using setpts to generate timelapses with slowdowns in the middle.
> > Using setpts filter requires complicated expr to handle intervals. This
> > patch allows commands to change expr and also adds a constant that
> > provides time of last command applications to allow specifying gradual
> > changes using difference between time and cmd time.
> >
> > ----------------------
> > with best regards
> > Oleg Afanasyev
>
> > From a714a0957a57c1d392feca0ba675ba5ac7c875ee Mon Sep 17 00:00:00 2001
> > From: Oleg <oafanasiev@gmail.com>
> > Date: Sat, 29 Apr 2023 19:56:46 +0100
> > Subject: [PATCH] avfilter/setpts: add command support
> >
> > Add support for changing expr on the fly.
> >
> > Signed-off-by: Oleg <oafanasiev@gmail.com>
> > ---
> > doc/filters.texi | 7 +++++
> > libavfilter/setpts.c | 68 +++++++++++++++++++++++++++++++++-----------
> > 2 files changed, 58 insertions(+), 17 deletions(-)
> >
> > diff --git a/doc/filters.texi b/doc/filters.texi
> > index 50e1682144..fbdb1f8ecf 100644
> > diff --git a/libavfilter/setpts.c b/libavfilter/setpts.c
> > index 5bcc0c2dcf..7b09ce7707 100644
> > --- a/libavfilter/setpts.c
> > +++ b/libavfilter/setpts.c
> [...]
> > +static int process_command(AVFilterContext *ctx, const char *cmd, const char *arg,
> > + char *res, int res_len, int flags)
> > +{
> > + SetPTSContext *setpts = ctx->priv;
> > + int ret;
> > +
> > + ret = ff_filter_process_command(ctx, cmd, arg, res, res_len, flags);
> > +
> > + if (ret < 0)
> > + return ret;
> > +
>
> > + if (!strcmp(cmd, "expr")) {
> > + av_expr_free(setpts->expr);
> > + ret = av_expr_parse(&setpts->expr, arg, var_names, NULL, NULL, NULL, NULL, 0, ctx);
> > + if (ret < 0) {
> > + av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", arg);
> > + }
>
> what happens in case setpts->expr is freed and this fails?
>
> probably it should keep a reference to expr and remove it only in case
> the new expression was successfully parsed
Fixed! Didn't realize that encoding continues even if command fails,
so it was crashing with the previous expression still in place.
>
> [...]
>
> Looks good to me otherwise.
>
> _______________________________________________
> 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".
[-- Attachment #2: 0001-avfilter-setpts-add-command-support.patch --]
[-- Type: text/x-patch, Size: 6278 bytes --]
From a50bf9e58a0f90d63aba3c84de40f31dc22ebfce Mon Sep 17 00:00:00 2001
From: Oleg <oafanasiev@gmail.com>
Date: Sat, 29 Apr 2023 19:56:46 +0100
Subject: [PATCH] avfilter/setpts: add command support
Add support for changing expr on the fly.
Signed-off-by: Oleg <oafanasiev@gmail.com>
---
doc/filters.texi | 7 +++++
libavfilter/setpts.c | 73 +++++++++++++++++++++++++++++++++-----------
2 files changed, 63 insertions(+), 17 deletions(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index 50e1682144..fbdb1f8ecf 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -29384,6 +29384,9 @@ The wallclock (RTC) time at the start of the movie in microseconds.
@item TB
The timebase of the input timestamps.
+@item T_CHANGE
+Time of the first frame after command was applied or time of the first frame if no commands.
+
@end table
@subsection Examples
@@ -29439,6 +29442,10 @@ asetpts=N/SR/TB
@end itemize
+@subsection Commands
+
+Both filters support all above options as @ref{commands}.
+
@section setrange
Force color range for the output video frame.
diff --git a/libavfilter/setpts.c b/libavfilter/setpts.c
index 5bcc0c2dcf..c805a60ee4 100644
--- a/libavfilter/setpts.c
+++ b/libavfilter/setpts.c
@@ -63,6 +63,7 @@ static const char *const var_names[] = {
"S", // Number of samples in the current frame
"SR", // Audio sample rate
"FR", ///< defined only for constant frame-rate video
+ "T_CHANGE", ///< time of first frame after latest command was applied
NULL
};
@@ -90,7 +91,8 @@ enum var_name {
VAR_S,
VAR_SR,
VAR_FR,
- VAR_VARS_NB
+ VAR_T_CHANGE,
+ VAR_VARS_NB,
};
typedef struct SetPTSContext {
@@ -120,6 +122,7 @@ static av_cold int init(AVFilterContext *ctx)
setpts->var_values[VAR_PREV_OUTT] = NAN;
setpts->var_values[VAR_STARTPTS] = NAN;
setpts->var_values[VAR_STARTT] = NAN;
+ setpts->var_values[VAR_T_CHANGE] = NAN;
return 0;
}
@@ -163,6 +166,9 @@ static double eval_pts(SetPTSContext *setpts, AVFilterLink *inlink, AVFrame *fra
setpts->var_values[VAR_STARTPTS] = TS2D(pts);
setpts->var_values[VAR_STARTT ] = TS2T(pts, inlink->time_base);
}
+ if (isnan(setpts->var_values[VAR_T_CHANGE])) {
+ setpts->var_values[VAR_T_CHANGE] = TS2T(pts, inlink->time_base);
+ }
setpts->var_values[VAR_PTS ] = TS2D(pts);
setpts->var_values[VAR_T ] = TS2T(pts, inlink->time_base);
#if FF_API_FRAME_PKT
@@ -269,14 +275,45 @@ static av_cold void uninit(AVFilterContext *ctx)
setpts->expr = NULL;
}
+static int process_command(AVFilterContext *ctx, const char *cmd, const char *arg,
+ char *res, int res_len, int flags)
+{
+ SetPTSContext *setpts = ctx->priv;
+ AVExpr *new_expr;
+ int ret;
+
+ ret = ff_filter_process_command(ctx, cmd, arg, res, res_len, flags);
+
+ if (ret < 0)
+ return ret;
+
+ if (!strcmp(cmd, "expr")) {
+ ret = av_expr_parse(&new_expr, arg, var_names, NULL, NULL, NULL, NULL, 0, ctx);
+ // Only free and replace previous expression if new one succeeds,
+ // otherwise defensively keep everything intact even if reporting an error.
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", arg);
+ } else {
+ av_expr_free(setpts->expr);
+ setpts->expr = new_expr;
+ setpts->var_values[VAR_T_CHANGE] = NAN;
+ }
+ } else {
+ ret = AVERROR(EINVAL);
+ }
+
+ return ret;
+}
+
#define OFFSET(x) offsetof(SetPTSContext, x)
#define V AV_OPT_FLAG_VIDEO_PARAM
#define A AV_OPT_FLAG_AUDIO_PARAM
+#define R AV_OPT_FLAG_RUNTIME_PARAM
#define F AV_OPT_FLAG_FILTERING_PARAM
#if CONFIG_SETPTS_FILTER
static const AVOption setpts_options[] = {
- { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = V|F },
+ { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = V|F|R },
{ NULL }
};
AVFILTER_DEFINE_CLASS(setpts);
@@ -297,12 +334,13 @@ static const AVFilterPad avfilter_vf_setpts_outputs[] = {
};
const AVFilter ff_vf_setpts = {
- .name = "setpts",
- .description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."),
- .init = init,
- .activate = activate,
- .uninit = uninit,
- .flags = AVFILTER_FLAG_METADATA_ONLY,
+ .name = "setpts",
+ .description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."),
+ .init = init,
+ .activate = activate,
+ .uninit = uninit,
+ .process_command = process_command,
+ .flags = AVFILTER_FLAG_METADATA_ONLY,
.priv_size = sizeof(SetPTSContext),
.priv_class = &setpts_class,
@@ -315,7 +353,7 @@ const AVFilter ff_vf_setpts = {
#if CONFIG_ASETPTS_FILTER
static const AVOption asetpts_options[] = {
- { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = A|F },
+ { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = A|F|R },
{ NULL }
};
AVFILTER_DEFINE_CLASS(asetpts);
@@ -336,14 +374,15 @@ static const AVFilterPad asetpts_outputs[] = {
};
const AVFilter ff_af_asetpts = {
- .name = "asetpts",
- .description = NULL_IF_CONFIG_SMALL("Set PTS for the output audio frame."),
- .init = init,
- .activate = activate,
- .uninit = uninit,
- .priv_size = sizeof(SetPTSContext),
- .priv_class = &asetpts_class,
- .flags = AVFILTER_FLAG_METADATA_ONLY,
+ .name = "asetpts",
+ .description = NULL_IF_CONFIG_SMALL("Set PTS for the output audio frame."),
+ .init = init,
+ .activate = activate,
+ .uninit = uninit,
+ .process_command = process_command,
+ .priv_size = sizeof(SetPTSContext),
+ .priv_class = &asetpts_class,
+ .flags = AVFILTER_FLAG_METADATA_ONLY,
FILTER_INPUTS(asetpts_inputs),
FILTER_OUTPUTS(asetpts_outputs),
};
--
2.40.0
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
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".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH] avfilter/setpts: add command support
2023-05-09 23:12 ` Oleg Afanasyev
@ 2023-05-14 9:14 ` Stefano Sabatini
0 siblings, 0 replies; 4+ messages in thread
From: Stefano Sabatini @ 2023-05-14 9:14 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On date Wednesday 2023-05-10 00:12:52 +0100, Oleg Afanasyev wrote:
> On Sun, 7 May 2023 at 23:47, Stefano Sabatini <stefasab@gmail.com> wrote:
[...]
> >
> > what happens in case setpts->expr is freed and this fails?
> >
> > probably it should keep a reference to expr and remove it only in case
> > the new expression was successfully parsed
>
> Fixed! Didn't realize that encoding continues even if command fails,
> so it was crashing with the previous expression still in place.
>
> >
> > [...]
> >
> > Looks good to me otherwise.
Applied, thanks.
_______________________________________________
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".
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-05-14 9:14 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-01 21:01 [FFmpeg-devel] [PATCH] avfilter/setpts: add command support Oleg Afanasyev
2023-05-07 22:46 ` Stefano Sabatini
2023-05-09 23:12 ` Oleg Afanasyev
2023-05-14 9:14 ` Stefano Sabatini
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