mirror of
https://mirror.skon.top/https://github.com/FFmpeg/FFmpeg
synced 2026-04-30 22:00:51 +08:00
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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user