Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH] fftools/ffmpeg: add force key frame by scdet metadata support (PR #21040)
@ 2025-11-28 14:20 Zhao Zhili via ffmpeg-devel
  0 siblings, 0 replies; only message in thread
From: Zhao Zhili via ffmpeg-devel @ 2025-11-28 14:20 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Zhao Zhili

PR #21040 opened by Zhao Zhili (quink)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21040
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21040.patch

For example:

./ffmpeg -hwaccel videotoolbox \
	-i input.mp4 -c:a copy \
	-vf scdet=threshold=10 \
	-c:v h264_videotoolbox \
	-force_key_frames scd_metadata \
	-g 1000 -t 30 output.mp4


>From c07193ae1b9bba6131c9292e6c92a5bdd95fff4e Mon Sep 17 00:00:00 2001
From: Zhao Zhili <zhilizhao@tencent.com>
Date: Fri, 28 Nov 2025 11:17:05 +0800
Subject: [PATCH] fftools/ffmpeg: add force key frame by scdet metadata support

For example:

./ffmpeg -hwaccel videotoolbox \
	-i input.mp4 -c:a copy \
	-vf scdet=threshold=10 \
	-c:v h264_videotoolbox \
	-force_key_frames scd_metadata \
	-g 1000 -t 30 output.mp4
---
 doc/ffmpeg.texi           | 9 +++++++++
 fftools/ffmpeg.h          | 2 ++
 fftools/ffmpeg_enc.c      | 3 +++
 fftools/ffmpeg_mux_init.c | 2 ++
 4 files changed, 16 insertions(+)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 3daf2f7ec2..2dae6632bc 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -1665,6 +1665,7 @@ Force video tag/fourcc. This is an alias for @code{-tag:v}.
 @item -force_key_frames[:@var{stream_specifier}] @var{time}[,@var{time}...] (@emph{output,per-stream})
 @item -force_key_frames[:@var{stream_specifier}] expr:@var{expr} (@emph{output,per-stream})
 @item -force_key_frames[:@var{stream_specifier}] source (@emph{output,per-stream})
+@item -force_key_frames[:@var{stream_specifier}] scd_metadata (@emph{output,per-stream})
 
 @var{force_key_frames} can take arguments of the following form:
 
@@ -1728,6 +1729,14 @@ the current frame being encoded is marked as a key frame in its source.
 In cases where this particular source frame has to be dropped,
 enforce the next available frame to become a key frame instead.
 
+@item scd_metadata
+If the argument is @code{scd_metadata}, ffmpeg will force a key frame if
+the current frame contains a metadata entry with the key @code{lavfi.scd.time}.
+The metadata can be added by filters like @code{scdet} and @code{scdet_vulkan}.
+Avoid inserting filters that duplicate frames after @code{scdet}, as this can
+cause duplicate metadata for multiple frames and repeated insertion of key
+frames.
+
 @end table
 
 Note that forcing too many keyframes is very harmful for the lookahead
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index cc2ea1a56e..7720dd9c59 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -602,6 +602,8 @@ enum {
 #if FFMPEG_OPT_FORCE_KF_SOURCE_NO_DROP
     KF_FORCE_SOURCE_NO_DROP = 2,
 #endif
+    // force keyframe if lavfi.scd.time metadata is set
+    KF_FORCE_SCD_METADATA = 3,
 };
 
 typedef struct KeyframeForceCtx {
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 8f07a10848..0f7d961472 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -768,6 +768,9 @@ static enum AVPictureType forced_kf_apply(void *logctx, KeyframeForceCtx *kf,
         }
     } else if (kf->type == KF_FORCE_SOURCE && (frame->flags & AV_FRAME_FLAG_KEY)) {
         goto force_keyframe;
+    } else if (kf->type == KF_FORCE_SCD_METADATA &&
+               av_dict_get(frame->metadata, "lavfi.scd.time", NULL, 0)) {
+        goto force_keyframe;
     }
 
     return AV_PICTURE_TYPE_NONE;
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index bcbbee9126..194a87875d 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -3279,6 +3279,8 @@ static int process_forced_keyframes(Muxer *mux, const OptionsContext *o)
                    "-force_key_frames is deprecated, use just 'source'\n");
             ost->kf.type = KF_FORCE_SOURCE;
 #endif
+        } else if (!strcmp(forced_keyframes, "scd_metadata")) {
+            ost->kf.type = KF_FORCE_SCD_METADATA;
         } else {
             int ret = parse_forced_key_frames(ost, &ost->kf, mux, forced_keyframes);
             if (ret < 0)
-- 
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-11-28 14:20 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-11-28 14:20 [FFmpeg-devel] [PATCH] fftools/ffmpeg: add force key frame by scdet metadata support (PR #21040) Zhao Zhili 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