* [FFmpeg-devel] [PATCH] WIP: avformat/mux: Allow to add list of supported codecs to muxers (PR #21206)
@ 2025-12-15 16:38 mkver via ffmpeg-devel
0 siblings, 0 replies; only message in thread
From: mkver via ffmpeg-devel @ 2025-12-15 16:38 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: mkver
PR #21206 opened by mkver
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21206
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21206.patch
Alternative to #21205.
>From 6d5108484f151b95b0e31edd58003999a6548cb9 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 15 Dec 2025 15:39:05 +0100
Subject: [PATCH 1/9] avformat/mux: Allow to add list of supported codecs to
muxers
This allows to check generically for supported codecs in
avformat_init_output() and avformat_query_codec().
Notice that using a union of codec_list and query_codec
is fine ABI-wise: Given that both members are pointers,
the offsets won't be affected (in practice); because
the information in which state the union is is given
by a flag contained in the FFOutputFormat, it works
to even use this for devices without a major ABI bump.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavformat/mux.c | 14 ++++++++++++++
libavformat/mux.h | 37 +++++++++++++++++++++++++++++--------
libavformat/mux_utils.c | 9 ++++++++-
3 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/libavformat/mux.c b/libavformat/mux.c
index db3b6c2bfe..d2f6914eac 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -294,6 +294,20 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
goto fail;
}
}
+ if (of->flags_internal & FF_OFMT_FLAG_CODEC_ID_LIST) {
+ const enum AVCodecID *codec_list = of->codec_list;
+ av_assert2(codec_list && *codec_list != AV_CODEC_ID_NONE);
+ while (1) {
+ if (par->codec_id == *codec_list)
+ break;
+ if (*++codec_list == AV_CODEC_ID_NONE) {
+ av_log(s, AV_LOG_ERROR, "%s muxer does not support codec %s\n",
+ of->p.name, avcodec_get_name(par->codec_id));
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ }
+ }
desc = avcodec_descriptor_get(par->codec_id);
if (desc && desc->props & AV_CODEC_PROP_REORDER)
diff --git a/libavformat/mux.h b/libavformat/mux.h
index 0b69109174..24cd4d92ac 100644
--- a/libavformat/mux.h
+++ b/libavformat/mux.h
@@ -57,6 +57,11 @@ struct AVDeviceInfoList;
* are disallowed.
*/
#define FF_OFMT_FLAG_ONLY_DEFAULT_CODECS (1 << 3)
+/**
+ * If this flag is set, it means that FFOutputFormat.codec_list
+ * is set; otherwise, the union is in query_codec state (which may be NULL).
+ */
+#define FF_OFMT_FLAG_CODEC_ID_LIST (1 << 4)
typedef struct FFOutputFormat {
/**
@@ -101,14 +106,27 @@ typedef struct FFOutputFormat {
*/
int (*interleave_packet)(AVFormatContext *s, AVPacket *pkt,
int flush, int has_packet);
- /**
- * Test if the given codec can be stored in this container.
- *
- * @return 1 if the codec is supported, 0 if it is not.
- * A negative number if unknown.
- * MKTAG('A', 'P', 'I', 'C') if the codec is only supported as AV_DISPOSITION_ATTACHED_PIC
- */
- int (*query_codec)(enum AVCodecID id, int std_compliance);
+ union {
+ /**
+ * Test if the given codec can be stored in this container.
+ * The union is in this state when the FF_OFMT_FLAG_CODEC_ID_LIST flag
+ * is not set.
+ *
+ * @return 1 if the codec is supported, 0 if it is not.
+ * A negative number if unknown.
+ * MKTAG('A', 'P', 'I', 'C') if the codec is only supported as AV_DISPOSITION_ATTACHED_PIC
+ */
+ int (*query_codec)(enum AVCodecID id, int std_compliance);
+ /**
+ * A list of supported codecs by this muxer.
+ * The union is in this state iff the FF_OFMT_FLAG_CODEC_ID_LIST flag
+ * is set; in this case, any codec not in this list can't be muxed by
+ * this muxer at all.
+ * The list is delimited by AV_CODEC_ID_NONE which must never be
+ * the only entry in this list.
+ */
+ const enum AVCodecID *codec_list;
+ };
void (*get_output_timestamp)(AVFormatContext *s, int stream,
int64_t *dts, int64_t *wall);
@@ -169,6 +187,9 @@ static inline const FFOutputFormat *ffofmt(const AVOutputFormat *fmt)
return (const FFOutputFormat*)fmt;
}
+#define OFMT_CODEC_LIST(...) \
+ .codec_list = (const enum AVCodecID []){ __VA_ARGS__, AV_CODEC_ID_NONE }
+
/**
* Add packet to an AVFormatContext's packet_buffer list, determining its
* interleaved position using compare() function argument.
diff --git a/libavformat/mux_utils.c b/libavformat/mux_utils.c
index 86d333dbe7..d41bbe4a14 100644
--- a/libavformat/mux_utils.c
+++ b/libavformat/mux_utils.c
@@ -34,7 +34,14 @@ int avformat_query_codec(const AVOutputFormat *ofmt, enum AVCodecID codec_id,
{
if (ofmt) {
unsigned int codec_tag;
- if (ffofmt(ofmt)->query_codec)
+ if (ffofmt(ofmt)->flags_internal & FF_OFMT_FLAG_CODEC_ID_LIST) {
+ const enum AVCodecID *codec_list = ffofmt(ofmt)->codec_list;
+ do {
+ if (codec_id == *codec_list)
+ return 1;
+ } while (*++codec_list != AV_CODEC_ID_NONE);
+ return 0;
+ } else if (ffofmt(ofmt)->query_codec)
return ffofmt(ofmt)->query_codec(codec_id, std_compliance);
else if (ofmt->codec_tag)
return !!av_codec_get_tag2(ofmt->codec_tag, codec_id, &codec_tag);
--
2.49.1
>From 72464569574ff88bd9014c40915b66307981c065 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 15 Dec 2025 16:20:55 +0100
Subject: [PATCH 2/9] avformat/a64: Check codec ids generically
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavformat/a64.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libavformat/a64.c b/libavformat/a64.c
index 6e722c7e9f..a4ca4d6817 100644
--- a/libavformat/a64.c
+++ b/libavformat/a64.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/avassert.h"
#include "libavutil/intreadwrite.h"
#include "libavcodec/codec_id.h"
#include "libavcodec/codec_par.h"
@@ -54,7 +55,7 @@ static int a64_write_header(AVFormatContext *s)
header[4] = 3;
break;
default:
- return AVERROR_INVALIDDATA;
+ av_unreachable("Already checked via codec_list");
}
avio_write(s->pb, header, 2);
return 0;
@@ -67,7 +68,8 @@ const FFOutputFormat ff_a64_muxer = {
.p.video_codec = AV_CODEC_ID_A64_MULTI,
.p.audio_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
- .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
+ .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH | FF_OFMT_FLAG_CODEC_ID_LIST,
+ OFMT_CODEC_LIST(AV_CODEC_ID_A64_MULTI, AV_CODEC_ID_A64_MULTI5),
.write_header = a64_write_header,
.write_packet = ff_raw_write_packet,
};
--
2.49.1
>From 581535fc4cb3f0dc5d624344f191c5934677a2bd Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 15 Dec 2025 16:22:48 +0100
Subject: [PATCH 3/9] avformat/amr: Check codec ids generically
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavformat/amr.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libavformat/amr.c b/libavformat/amr.c
index 9cc61baf55..ad4538aeaa 100644
--- a/libavformat/amr.c
+++ b/libavformat/amr.c
@@ -25,6 +25,7 @@ Write and read amr data according to RFC3267, http://www.ietf.org/rfc/rfc3267.tx
#include "config_components.h"
+#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/intreadwrite.h"
#include "avformat.h"
@@ -261,7 +262,7 @@ static int amr_write_header(AVFormatContext *s)
} else if (par->codec_id == AV_CODEC_ID_AMR_WB) {
avio_write(pb, AMRWB_header, sizeof(AMRWB_header)); /* magic number */
} else {
- return -1;
+ av_unreachable("Already checked via codec_list");
}
return 0;
}
@@ -275,7 +276,8 @@ const FFOutputFormat ff_amr_muxer = {
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.p.flags = AVFMT_NOTIMESTAMPS,
- .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
+ .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH | FF_OFMT_FLAG_CODEC_ID_LIST,
+ OFMT_CODEC_LIST(AV_CODEC_ID_AMR_NB, AV_CODEC_ID_AMR_WB),
.write_header = amr_write_header,
.write_packet = ff_raw_write_packet,
};
--
2.49.1
>From 1077e0445ef99197613485d30cd848cb2bc721e7 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 15 Dec 2025 16:31:33 +0100
Subject: [PATCH 4/9] avformat/icoenc: Check codec ids generically
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavformat/icoenc.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libavformat/icoenc.c b/libavformat/icoenc.c
index 9eba9e7926..f7292a5aeb 100644
--- a/libavformat/icoenc.c
+++ b/libavformat/icoenc.c
@@ -24,6 +24,7 @@
* Microsoft Windows ICO muxer
*/
+#include "libavutil/avassert.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mem.h"
@@ -66,8 +67,7 @@ static int ico_check_attributes(AVFormatContext *s, const AVCodecParameters *p)
return AVERROR(EINVAL);
}
} else {
- av_log(s, AV_LOG_ERROR, "Unsupported codec %s\n", avcodec_get_name(p->codec_id));
- return AVERROR(EINVAL);
+ av_unreachable("Already checked via codec_list");
}
if (p->width > 256 ||
@@ -207,4 +207,6 @@ const FFOutputFormat ff_ico_muxer = {
.write_trailer = ico_write_trailer,
.deinit = ico_deinit,
.p.flags = AVFMT_NOTIMESTAMPS,
+ .flags_internal = FF_OFMT_FLAG_CODEC_ID_LIST,
+ OFMT_CODEC_LIST(AV_CODEC_ID_BMP, AV_CODEC_ID_PNG),
};
--
2.49.1
>From 5f175d01eeae27d43f92d8bfd5c5b6902e628cd3 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 15 Dec 2025 16:35:16 +0100
Subject: [PATCH 5/9] avformat/latmenc: Check codec ids generically
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavformat/latmenc.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/libavformat/latmenc.c b/libavformat/latmenc.c
index 05004048aa..6da7864324 100644
--- a/libavformat/latmenc.c
+++ b/libavformat/latmenc.c
@@ -93,10 +93,6 @@ static int latm_write_header(AVFormatContext *s)
if (par->codec_id == AV_CODEC_ID_AAC_LATM)
return 0;
- if (par->codec_id != AV_CODEC_ID_AAC && par->codec_id != AV_CODEC_ID_MP4ALS) {
- av_log(s, AV_LOG_ERROR, "Only AAC, LATM and ALS are supported\n");
- return AVERROR(EINVAL);
- }
if (par->extradata_size > 0 &&
latm_decode_extradata(s, par->extradata, par->extradata_size) < 0)
@@ -269,7 +265,9 @@ const FFOutputFormat ff_latm_muxer = {
.p.audio_codec = AV_CODEC_ID_AAC,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
- .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
+ .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH |
+ FF_OFMT_FLAG_CODEC_ID_LIST,
+ OFMT_CODEC_LIST(AV_CODEC_ID_AAC_LATM, AV_CODEC_ID_AAC, AV_CODEC_ID_MP4ALS),
.write_header = latm_write_header,
.write_packet = latm_write_packet,
.p.priv_class = &latm_muxer_class,
--
2.49.1
>From 9e62af166607aa304c1a3ace70b692d5ed90d1c0 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 15 Dec 2025 16:36:59 +0100
Subject: [PATCH 6/9] avformat/lrcenc: Check codec ids generically
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavformat/lrcenc.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/libavformat/lrcenc.c b/libavformat/lrcenc.c
index bf295dfade..6190dfee6c 100644
--- a/libavformat/lrcenc.c
+++ b/libavformat/lrcenc.c
@@ -43,12 +43,6 @@ static int lrc_write_header(AVFormatContext *s)
{
const AVDictionaryEntry *metadata_item;
- if(s->streams[0]->codecpar->codec_id != AV_CODEC_ID_SUBRIP &&
- s->streams[0]->codecpar->codec_id != AV_CODEC_ID_TEXT) {
- av_log(s, AV_LOG_ERROR, "Unsupported subtitle codec: %s\n",
- avcodec_get_name(s->streams[0]->codecpar->codec_id));
- return AVERROR(EINVAL);
- }
avpriv_set_pts_info(s->streams[0], 64, 1, AV_TIME_BASE);
ff_standardize_creation_time(s);
@@ -157,9 +151,11 @@ const FFOutputFormat ff_lrc_muxer = {
.p.video_codec = AV_CODEC_ID_NONE,
.p.audio_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_SUBRIP,
- .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
+ .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH |
+ FF_OFMT_FLAG_CODEC_ID_LIST,
.priv_data_size = sizeof(LRCSubtitleContext),
.write_header = lrc_write_header,
.write_packet = lrc_write_packet,
.p.priv_class = &lrcenc_class,
+ OFMT_CODEC_LIST(AV_CODEC_ID_SUBRIP, AV_CODEC_ID_TEXT),
};
--
2.49.1
>From 20b5c4e5031b31a9695185d9086448ffdf70846e Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 15 Dec 2025 16:40:27 +0100
Subject: [PATCH 7/9] avformat/yuv4mpegenc: Check codec ids generically
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavformat/yuv4mpegenc.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/libavformat/yuv4mpegenc.c b/libavformat/yuv4mpegenc.c
index 371d3745c1..3c3a24aa34 100644
--- a/libavformat/yuv4mpegenc.c
+++ b/libavformat/yuv4mpegenc.c
@@ -221,12 +221,6 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
static int yuv4_init(AVFormatContext *s)
{
- if (s->streams[0]->codecpar->codec_id != AV_CODEC_ID_WRAPPED_AVFRAME &&
- s->streams[0]->codecpar->codec_id != AV_CODEC_ID_RAWVIDEO) {
- av_log(s, AV_LOG_ERROR, "ERROR: Codec not supported.\n");
- return AVERROR_INVALIDDATA;
- }
-
switch (s->streams[0]->codecpar->format) {
case AV_PIX_FMT_YUV411P:
av_log(s, AV_LOG_WARNING, "Warning: generating rarely used 4:1:1 YUV "
@@ -298,5 +292,7 @@ const FFOutputFormat ff_yuv4mpegpipe_muxer = {
.init = yuv4_init,
.write_header = yuv4_write_header,
.write_packet = yuv4_write_packet,
- .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
+ .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH |
+ FF_OFMT_FLAG_CODEC_ID_LIST,
+ OFMT_CODEC_LIST(AV_CODEC_ID_WRAPPED_AVFRAME, AV_CODEC_ID_RAWVIDEO),
};
--
2.49.1
>From 051ed8a6ecc3f9f28c2f44d13dbd3f0b59594a9b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 15 Dec 2025 17:02:37 +0100
Subject: [PATCH 8/9] avformat/segafilmenc: Check codec ids generically
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavformat/segafilmenc.c | 23 +++++++----------------
1 file changed, 7 insertions(+), 16 deletions(-)
diff --git a/libavformat/segafilmenc.c b/libavformat/segafilmenc.c
index 88a5b9f972..983a3b1a21 100644
--- a/libavformat/segafilmenc.c
+++ b/libavformat/segafilmenc.c
@@ -106,10 +106,9 @@ static int get_audio_codec_id(enum AVCodecID codec_id)
case AV_CODEC_ID_PCM_S8_PLANAR:
case AV_CODEC_ID_PCM_S16BE_PLANAR:
return 0;
+ default:
case AV_CODEC_ID_ADPCM_ADX:
return 2;
- default:
- return -1;
}
}
@@ -123,22 +122,10 @@ static int film_init(AVFormatContext *format_context)
for (int i = 0; i < format_context->nb_streams; i++) {
AVStream *st = format_context->streams[i];
- if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
- if (get_audio_codec_id(st->codecpar->codec_id) < 0) {
- av_log(format_context, AV_LOG_ERROR,
- "Incompatible audio stream format.\n");
- return AVERROR(EINVAL);
- }
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
film->audio_index = i;
- }
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
- if (st->codecpar->codec_id != AV_CODEC_ID_CINEPAK &&
- st->codecpar->codec_id != AV_CODEC_ID_RAWVIDEO) {
- av_log(format_context, AV_LOG_ERROR,
- "Incompatible video stream format.\n");
- return AVERROR(EINVAL);
- }
if (st->codecpar->format != AV_PIX_FMT_RGB24) {
av_log(format_context, AV_LOG_ERROR,
"Pixel format must be rgb24.\n");
@@ -280,7 +267,11 @@ const FFOutputFormat ff_segafilm_muxer = {
.p.audio_codec = AV_CODEC_ID_PCM_S16BE_PLANAR,
.p.video_codec = AV_CODEC_ID_CINEPAK,
.p.subtitle_codec = AV_CODEC_ID_NONE,
- .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
+ .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH |
+ FF_OFMT_FLAG_CODEC_ID_LIST,
+ OFMT_CODEC_LIST(AV_CODEC_ID_CINEPAK, AV_CODEC_ID_RAWVIDEO,
+ AV_CODEC_ID_PCM_S8_PLANAR, AV_CODEC_ID_PCM_S16BE_PLANAR,
+ AV_CODEC_ID_ADPCM_ADX),
.init = film_init,
.write_trailer = film_write_header,
.write_packet = film_write_packet,
--
2.49.1
>From 6c72e1ffca07dc697118013e9ab19d947e2373bf Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 15 Dec 2025 17:04:42 +0100
Subject: [PATCH 9/9] avformat/supenc: Only allow AV_CODEC_ID_HDMV_PGS_SUBTITLE
Do this by setting the FF_OFMT_FLAG_ONLY_DEFAULT_CODECS flag.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavformat/supenc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libavformat/supenc.c b/libavformat/supenc.c
index c664723bc4..04a21a9e65 100644
--- a/libavformat/supenc.c
+++ b/libavformat/supenc.c
@@ -88,7 +88,8 @@ const FFOutputFormat ff_sup_muxer = {
.p.audio_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_HDMV_PGS_SUBTITLE,
.p.flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
- .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
+ .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH |
+ FF_OFMT_FLAG_ONLY_DEFAULT_CODECS,
.init = sup_init,
.write_packet = sup_write_packet,
};
--
2.49.1
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2025-12-15 16:57 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-15 16:38 [FFmpeg-devel] [PATCH] WIP: avformat/mux: Allow to add list of supported codecs to muxers (PR #21206) mkver via ffmpeg-devel
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