diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index b27b9fe2c4..dad21c6ae6 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -1011,6 +1011,7 @@ Deprecated see -bsf @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}] source_no_drop (@emph{output,per-stream}) @var{force_key_frames} can take arguments of the following form: @@ -1072,6 +1073,12 @@ starting from second 13: If the argument is @code{source}, ffmpeg will force a key frame if the current frame being encoded is marked as a key frame in its source. +@item source_no_drop +If the argument is @code{source_no_drop}, ffmpeg will force a key frame if +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. + @end table Note that forcing too many keyframes is very harmful for the lookahead diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index e97d879cb3..1ac2e48600 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -1287,6 +1287,7 @@ static void do_video_out(OutputFile *of, } } ost->last_dropped = nb_frames == nb0_frames && next_picture; + ost->dropped_keyframe = ost->last_dropped && next_picture && next_picture->key_frame; /* duplicates frame if needed */ for (i = 0; i < nb_frames; i++) { @@ -1347,6 +1348,11 @@ static void do_video_out(OutputFile *of, && in_picture->key_frame==1 && !i) { forced_keyframe = 1; + } else if ( ost->forced_keyframes + && !strncmp(ost->forced_keyframes, "source_no_drop", 6) + && !i) { + forced_keyframe = (in_picture->key_frame == 1) || ost->dropped_keyframe; + ost->dropped_keyframe = 0; } if (forced_keyframe) { diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index e9d30fbd67..3cfb4c4488 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -504,6 +504,7 @@ typedef struct OutputStream { char *forced_keyframes; AVExpr *forced_keyframes_pexpr; double forced_keyframes_expr_const_values[FKF_NB]; + int dropped_keyframe; /* audio only */ int *audio_channels_map; /* list of the channels id to pick from the source stream */