* [FFmpeg-devel] [PATCH] libavcodec/qsvenc: Add skip_frame support to qsvenc
@ 2022-11-02 8:11 wenbin.chen-at-intel.com
2022-11-07 3:07 ` Xiang, Haihao
0 siblings, 1 reply; 2+ messages in thread
From: wenbin.chen-at-intel.com @ 2022-11-02 8:11 UTC (permalink / raw)
To: ffmpeg-devel
From: Wenbin Chen <wenbin.chen@intel.com>
Add skip_frame support to qsvenc. Use per-frame metadata
"qsv_skip_frame" to control it. skip_frame option defines the behavior
of qsv_skip_frame.
no_skip: Frame skipping is disabled.
insert_dummy: Encoder inserts into bitstream frame where all macroblocks
are encoded as skipped.
insert_nothing: Similar to insert_dummy, but encoder inserts nothing.
The skipped frames are still used in brc. For example, gop still include
skipped frames, and the frames after skipped frames will be larger in
size.
brc_only: skip_frame metadata indicates the number of missed frames
before the current frame.
Signed-off-by: Wenbin Chen <wenbin.chen@intel.com>
---
doc/encoders.texi | 36 ++++++++++++++++++++++++++++++++++++
libavcodec/qsvenc.c | 36 ++++++++++++++++++++++++++++++++++++
libavcodec/qsvenc.h | 13 +++++++++++++
libavcodec/qsvenc_h264.c | 1 +
libavcodec/qsvenc_hevc.c | 1 +
5 files changed, 87 insertions(+)
diff --git a/doc/encoders.texi b/doc/encoders.texi
index 53dd02fd28..59f39d18f6 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3564,6 +3564,24 @@ bitrate, @var{target_bitrate}, within the accuracy range @var{avbr_accuracy},
after a @var{avbr_Convergence} period. This method does not follow HRD and the
instant bitrate is not capped or padded.
+@item @var{skip_frame}
+Use per-frame metadata "qsv_skip_frame" to skip frame when encoding. This option
+defines the usage of this metadata.
+@table @samp
+@item no_skip
+Frame skipping is disabled.
+@item insert_dummy
+Encoder inserts into bitstream frame where all macroblocks are encoded as
+skipped.
+@item insert_nothing
+Similar to insert_dummy, but encoder inserts nothing into bitstream. The skipped
+frames are still used in brc. For example, gop still include skipped frames, and
+the frames after skipped frames will be larger in size.
+@item brc_only
+skip_frame metadata indicates the number of missed frames before the current
+frame.
+@end table
+
@end table
@subsection HEVC Options
@@ -3742,6 +3760,24 @@ bitrate, @var{target_bitrate}, within the accuracy range @var{avbr_accuracy},
after a @var{avbr_Convergence} period. This method does not follow HRD and the
instant bitrate is not capped or padded.
+@item @var{skip_frame}
+Use per-frame metadata "qsv_skip_frame" to skip frame when encoding. This option
+defines the usage of this metadata.
+@table @samp
+@item no_skip
+Frame skipping is disabled.
+@item insert_dummy
+Encoder inserts into bitstream frame where all macroblocks are encoded as
+skipped.
+@item insert_nothing
+Similar to insert_dummy, but encoder inserts nothing into bitstream. The skipped
+frames are still used in brc. For example, gop still include skipped frames, and
+the frames after skipped frames will be larger in size.
+@item brc_only
+skip_frame metadata indicates the number of missed frames before the current
+frame.
+@end table
+
@end table
@subsection MPEG2 Options
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 0db774ea63..4bfa65c575 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -329,6 +329,22 @@ static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q,
"MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8"; MaxQPP: %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",
co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2->MinQPB, co2->MaxQPB);
av_log(avctx, AV_LOG_VERBOSE, "DisableDeblockingIdc: %"PRIu32" \n", co2->DisableDeblockingIdc);
+
+ switch (co2->SkipFrame) {
+ case MFX_SKIPFRAME_NO_SKIP:
+ av_log(avctx, AV_LOG_VERBOSE, "SkipFrame: no_skip\n");
+ break;
+ case MFX_SKIPFRAME_INSERT_DUMMY:
+ av_log(avctx, AV_LOG_VERBOSE, "SkipFrame: insert_dummy\n");
+ break;
+ case MFX_SKIPFRAME_INSERT_NOTHING:
+ av_log(avctx, AV_LOG_VERBOSE, "SkipFrame: insert_nothing\n");
+ break;
+ case MFX_SKIPFRAME_BRC_ONLY:
+ av_log(avctx, AV_LOG_VERBOSE, "SkipFrame: brc_only\n");
+ break;
+ default: break;
+ }
}
if (co3) {
@@ -991,6 +1007,8 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
q->old_max_qp_b = q->max_qp_b;
if (q->mbbrc >= 0)
q->extco2.MBBRC = q->mbbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
+ if (q->skip_frame >= 0)
+ q->extco2.SkipFrame = q->skip_frame;
q->extco2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2;
q->extco2.Header.BufferSz = sizeof(q->extco2);
@@ -1911,6 +1929,19 @@ static int set_roi_encode_ctrl(AVCodecContext *avctx, const AVFrame *frame,
return 0;
}
+static void set_skip_frame_encode_ctrl(AVCodecContext *avctx, const AVFrame *frame,
+ mfxEncodeCtrl *enc_ctrl)
+{
+ AVDictionaryEntry* skip_frame_dict = NULL;
+ if (!frame->metadata)
+ return;
+ skip_frame_dict = av_dict_get(frame->metadata, "qsv_skip_frame", NULL, 0);
+ if (!skip_frame_dict)
+ return;
+ enc_ctrl->SkipFrame = strtol(skip_frame_dict->value, NULL, 10);
+ return;
+}
+
static int update_qp(AVCodecContext *avctx, QSVEncContext *q)
{
int updated = 0, new_qp = 0;
@@ -2282,6 +2313,11 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
if (ret < 0)
goto free;
}
+ if ((avctx->codec_id == AV_CODEC_ID_H264 ||
+ avctx->codec_id == AV_CODEC_ID_H265) &&
+ q->skip_frame != MFX_SKIPFRAME_NO_SKIP &&
+ enc_ctrl && QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 13))
+ set_skip_frame_encode_ctrl(avctx, frame, enc_ctrl);
pkt.sync = av_mallocz(sizeof(*pkt.sync));
if (!pkt.sync)
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index eb79db9871..d46575ef78 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -127,6 +127,18 @@
{ "avbr_accuracy", "Accuracy of the AVBR ratecontrol (unit of tenth of percent)", OFFSET(qsv.avbr_accuracy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, VE }, \
{ "avbr_convergence", "Convergence of the AVBR ratecontrol (unit of 100 frames)", OFFSET(qsv.avbr_convergence), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, VE },
+#define QSV_OPTION_SKIP_FRAME \
+{ "skip_frame", "Allow frame skipping", OFFSET(qsv.skip_frame), AV_OPT_TYPE_INT, { .i64 = MFX_SKIPFRAME_NO_SKIP }, \
+ MFX_SKIPFRAME_NO_SKIP, MFX_SKIPFRAME_BRC_ONLY, VE, "skip_frame" }, \
+{ "no_skip", "Frame skipping is disabled", \
+ 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_NO_SKIP }, .flags = VE, "skip_frame" }, \
+{ "insert_dummy", "Encoder inserts into bitstream frame where all macroblocks are encoded as skipped", \
+ 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_INSERT_DUMMY }, .flags = VE, "skip_frame" }, \
+{ "insert_nothing", "Encoder inserts nothing into bitstream", \
+ 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_INSERT_NOTHING }, .flags = VE, "skip_frame" }, \
+{ "brc_only", "skip_frame metadata indicates the number of missed frames before the current frame", \
+ 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_BRC_ONLY }, .flags = VE, "skip_frame" },
+
extern const AVCodecHWConfigInternal *const ff_qsv_enc_hw_configs[];
typedef int SetEncodeCtrlCB (AVCodecContext *avctx,
@@ -285,6 +297,7 @@ typedef struct QSVEncContext {
int old_rc_max_rate;
// This is used for SEI Timing reset
int old_pic_timing_sei;
+ int skip_frame;
} QSVEncContext;
int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index 11aaabbd1b..0ff7356346 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -116,6 +116,7 @@ static const AVOption options[] = {
QSV_OPTION_MAX_MIN_QP
QSV_OPTION_SCENARIO
QSV_OPTION_AVBR
+ QSV_OPTION_SKIP_FRAME
{ "cavlc", "Enable CAVLC", OFFSET(qsv.cavlc), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
#if QSV_HAVE_VCM
diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index 28d2cfcae1..95cf417f67 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -317,6 +317,7 @@ static const AVOption options[] = {
QSV_OPTION_ADAPTIVE_B
QSV_OPTION_SCENARIO
QSV_OPTION_AVBR
+ QSV_OPTION_SKIP_FRAME
{ "idr_interval", "Distance (in I-frames) between IDR frames", OFFSET(qsv.idr_interval), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, INT_MAX, VE, "idr_interval" },
{ "begin_only", "Output an IDR-frame only at the beginning of the stream", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, 0, 0, VE, "idr_interval" },
--
2.34.1
_______________________________________________
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] 2+ messages in thread
* Re: [FFmpeg-devel] [PATCH] libavcodec/qsvenc: Add skip_frame support to qsvenc
2022-11-02 8:11 [FFmpeg-devel] [PATCH] libavcodec/qsvenc: Add skip_frame support to qsvenc wenbin.chen-at-intel.com
@ 2022-11-07 3:07 ` Xiang, Haihao
0 siblings, 0 replies; 2+ messages in thread
From: Xiang, Haihao @ 2022-11-07 3:07 UTC (permalink / raw)
To: ffmpeg-devel
On Wed, 2022-11-02 at 16:11 +0800, wenbin.chen-at-intel.com@ffmpeg.org wrote:
> From: Wenbin Chen <wenbin.chen@intel.com>
>
> Add skip_frame support to qsvenc. Use per-frame metadata
> "qsv_skip_frame" to control it. skip_frame option defines the behavior
> of qsv_skip_frame.
> no_skip: Frame skipping is disabled.
> insert_dummy: Encoder inserts into bitstream frame where all macroblocks
> are encoded as skipped.
> insert_nothing: Similar to insert_dummy, but encoder inserts nothing.
> The skipped frames are still used in brc. For example, gop still include
> skipped frames, and the frames after skipped frames will be larger in
> size.
> brc_only: skip_frame metadata indicates the number of missed frames
> before the current frame.
>
> Signed-off-by: Wenbin Chen <wenbin.chen@intel.com>
> ---
> doc/encoders.texi | 36 ++++++++++++++++++++++++++++++++++++
> libavcodec/qsvenc.c | 36 ++++++++++++++++++++++++++++++++++++
> libavcodec/qsvenc.h | 13 +++++++++++++
> libavcodec/qsvenc_h264.c | 1 +
> libavcodec/qsvenc_hevc.c | 1 +
> 5 files changed, 87 insertions(+)
>
> diff --git a/doc/encoders.texi b/doc/encoders.texi
> index 53dd02fd28..59f39d18f6 100644
> --- a/doc/encoders.texi
> +++ b/doc/encoders.texi
> @@ -3564,6 +3564,24 @@ bitrate, @var{target_bitrate}, within the accuracy
> range @var{avbr_accuracy},
> after a @var{avbr_Convergence} period. This method does not follow HRD and
> the
> instant bitrate is not capped or padded.
>
> +@item @var{skip_frame}
> +Use per-frame metadata "qsv_skip_frame" to skip frame when encoding. This
> option
> +defines the usage of this metadata.
> +@table @samp
> +@item no_skip
> +Frame skipping is disabled.
> +@item insert_dummy
> +Encoder inserts into bitstream frame where all macroblocks are encoded as
> +skipped.
> +@item insert_nothing
> +Similar to insert_dummy, but encoder inserts nothing into bitstream. The
> skipped
> +frames are still used in brc. For example, gop still include skipped frames,
> and
> +the frames after skipped frames will be larger in size.
> +@item brc_only
> +skip_frame metadata indicates the number of missed frames before the current
> +frame.
> +@end table
> +
> @end table
>
> @subsection HEVC Options
> @@ -3742,6 +3760,24 @@ bitrate, @var{target_bitrate}, within the accuracy
> range @var{avbr_accuracy},
> after a @var{avbr_Convergence} period. This method does not follow HRD and
> the
> instant bitrate is not capped or padded.
>
> +@item @var{skip_frame}
> +Use per-frame metadata "qsv_skip_frame" to skip frame when encoding. This
> option
> +defines the usage of this metadata.
> +@table @samp
> +@item no_skip
> +Frame skipping is disabled.
> +@item insert_dummy
> +Encoder inserts into bitstream frame where all macroblocks are encoded as
> +skipped.
> +@item insert_nothing
> +Similar to insert_dummy, but encoder inserts nothing into bitstream. The
> skipped
> +frames are still used in brc. For example, gop still include skipped frames,
> and
> +the frames after skipped frames will be larger in size.
> +@item brc_only
> +skip_frame metadata indicates the number of missed frames before the current
> +frame.
> +@end table
> +
> @end table
>
> @subsection MPEG2 Options
> diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
> index 0db774ea63..4bfa65c575 100644
> --- a/libavcodec/qsvenc.c
> +++ b/libavcodec/qsvenc.c
> @@ -329,6 +329,22 @@ static void dump_video_param(AVCodecContext *avctx,
> QSVEncContext *q,
> "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8"; MaxQPP:
> %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",
> co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2-
> >MinQPB, co2->MaxQPB);
> av_log(avctx, AV_LOG_VERBOSE, "DisableDeblockingIdc: %"PRIu32" \n",
> co2->DisableDeblockingIdc);
> +
> + switch (co2->SkipFrame) {
> + case MFX_SKIPFRAME_NO_SKIP:
> + av_log(avctx, AV_LOG_VERBOSE, "SkipFrame: no_skip\n");
> + break;
> + case MFX_SKIPFRAME_INSERT_DUMMY:
> + av_log(avctx, AV_LOG_VERBOSE, "SkipFrame: insert_dummy\n");
> + break;
> + case MFX_SKIPFRAME_INSERT_NOTHING:
> + av_log(avctx, AV_LOG_VERBOSE, "SkipFrame: insert_nothing\n");
> + break;
> + case MFX_SKIPFRAME_BRC_ONLY:
> + av_log(avctx, AV_LOG_VERBOSE, "SkipFrame: brc_only\n");
> + break;
> + default: break;
> + }
> }
>
> if (co3) {
> @@ -991,6 +1007,8 @@ static int init_video_param(AVCodecContext *avctx,
> QSVEncContext *q)
> q->old_max_qp_b = q->max_qp_b;
> if (q->mbbrc >= 0)
> q->extco2.MBBRC = q->mbbrc ? MFX_CODINGOPTION_ON :
> MFX_CODINGOPTION_OFF;
> + if (q->skip_frame >= 0)
> + q->extco2.SkipFrame = q->skip_frame;
>
> q->extco2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2;
> q->extco2.Header.BufferSz = sizeof(q->extco2);
> @@ -1911,6 +1929,19 @@ static int set_roi_encode_ctrl(AVCodecContext *avctx,
> const AVFrame *frame,
> return 0;
> }
>
> +static void set_skip_frame_encode_ctrl(AVCodecContext *avctx, const AVFrame
> *frame,
> + mfxEncodeCtrl *enc_ctrl)
> +{
> + AVDictionaryEntry* skip_frame_dict = NULL;
> + if (!frame->metadata)
> + return;
> + skip_frame_dict = av_dict_get(frame->metadata, "qsv_skip_frame", NULL,
> 0);
> + if (!skip_frame_dict)
> + return;
> + enc_ctrl->SkipFrame = strtol(skip_frame_dict->value, NULL, 10);
> + return;
> +}
> +
> static int update_qp(AVCodecContext *avctx, QSVEncContext *q)
> {
> int updated = 0, new_qp = 0;
> @@ -2282,6 +2313,11 @@ static int encode_frame(AVCodecContext *avctx,
> QSVEncContext *q,
> if (ret < 0)
> goto free;
> }
> + if ((avctx->codec_id == AV_CODEC_ID_H264 ||
> + avctx->codec_id == AV_CODEC_ID_H265) &&
> + q->skip_frame != MFX_SKIPFRAME_NO_SKIP &&
> + enc_ctrl && QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 13))
> + set_skip_frame_encode_ctrl(avctx, frame, enc_ctrl);
>
> pkt.sync = av_mallocz(sizeof(*pkt.sync));
> if (!pkt.sync)
> diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
> index eb79db9871..d46575ef78 100644
> --- a/libavcodec/qsvenc.h
> +++ b/libavcodec/qsvenc.h
> @@ -127,6 +127,18 @@
> { "avbr_accuracy", "Accuracy of the AVBR ratecontrol (unit of tenth of
> percent)", OFFSET(qsv.avbr_accuracy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0,
> UINT16_MAX, VE }, \
> { "avbr_convergence", "Convergence of the AVBR ratecontrol (unit of 100
> frames)", OFFSET(qsv.avbr_convergence), AV_OPT_TYPE_INT, { .i64 = 0 }, 0,
> UINT16_MAX, VE },
>
> +#define QSV_OPTION_SKIP_FRAME \
> +{ "skip_frame", "Allow frame skipping",
> OFFSET(qsv.skip_frame), AV_OPT_TYPE_INT, { .i64 = MFX_SKIPFRAME_NO_SKIP }, \
> + MFX_SKIPFRAME_NO_SKIP, MFX_SKIPFRAME_BRC_ONLY, VE, "skip_frame" }, \
> +{ "no_skip", "Frame skipping is disabled", \
> + 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_NO_SKIP }, .flags
> = VE, "skip_frame" }, \
> +{ "insert_dummy", "Encoder inserts into bitstream frame where all
> macroblocks are encoded as skipped", \
> + 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_INSERT_DUMMY }, .flags
> = VE, "skip_frame" }, \
> +{ "insert_nothing", "Encoder inserts nothing into
> bitstream", \
> + 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_INSERT_NOTHING }, .flags
> = VE, "skip_frame" }, \
> +{ "brc_only", "skip_frame metadata indicates the number of missed
> frames before the current frame", \
> + 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_BRC_ONLY }, .flags
> = VE, "skip_frame" },
> +
> extern const AVCodecHWConfigInternal *const ff_qsv_enc_hw_configs[];
>
> typedef int SetEncodeCtrlCB (AVCodecContext *avctx,
> @@ -285,6 +297,7 @@ typedef struct QSVEncContext {
> int old_rc_max_rate;
> // This is used for SEI Timing reset
> int old_pic_timing_sei;
> + int skip_frame;
> } QSVEncContext;
>
> int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
> diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
> index 11aaabbd1b..0ff7356346 100644
> --- a/libavcodec/qsvenc_h264.c
> +++ b/libavcodec/qsvenc_h264.c
> @@ -116,6 +116,7 @@ static const AVOption options[] = {
> QSV_OPTION_MAX_MIN_QP
> QSV_OPTION_SCENARIO
> QSV_OPTION_AVBR
> + QSV_OPTION_SKIP_FRAME
>
> { "cavlc", "Enable
> CAVLC", OFFSET(qsv.cavlc), AV_OPT_TYPE_BOOL
> , { .i64 = 0 }, 0, 1, VE },
> #if QSV_HAVE_VCM
> diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
> index 28d2cfcae1..95cf417f67 100644
> --- a/libavcodec/qsvenc_hevc.c
> +++ b/libavcodec/qsvenc_hevc.c
> @@ -317,6 +317,7 @@ static const AVOption options[] = {
> QSV_OPTION_ADAPTIVE_B
> QSV_OPTION_SCENARIO
> QSV_OPTION_AVBR
> + QSV_OPTION_SKIP_FRAME
>
> { "idr_interval", "Distance (in I-frames) between IDR frames",
> OFFSET(qsv.idr_interval), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, INT_MAX, VE,
> "idr_interval" },
> { "begin_only", "Output an IDR-frame only at the beginning of the
> stream", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, 0, 0, VE, "idr_interval" },
Applied, thx
-Haihao
_______________________________________________
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] 2+ messages in thread
end of thread, other threads:[~2022-11-07 3:07 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-02 8:11 [FFmpeg-devel] [PATCH] libavcodec/qsvenc: Add skip_frame support to qsvenc wenbin.chen-at-intel.com
2022-11-07 3:07 ` Xiang, Haihao
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