* [FFmpeg-devel] [PATCH 01/12] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process()
@ 2023-10-03 15:35 Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 02/12] fftools/ffmpeg_enc: move remaining vsync-related code " Anton Khirnov
` (10 more replies)
0 siblings, 11 replies; 12+ messages in thread
From: Anton Khirnov @ 2023-10-03 15:35 UTC (permalink / raw)
To: ffmpeg-devel
That is a more appropriate place for this.
---
fftools/ffmpeg_enc.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index ec9cebbd96..8ae36294ce 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -965,12 +965,12 @@ early_exit:
* should this (and possibly previous) frame be repeated in order to conform to
* desired target framerate (if any).
*/
-static void video_sync_process(OutputFile *of, OutputStream *ost,
- AVFrame *frame, double duration,
+static void video_sync_process(OutputFile *of, OutputStream *ost, AVFrame *frame,
int64_t *nb_frames, int64_t *nb_frames_prev)
{
Encoder *e = ost->enc;
- double delta0, delta, sync_ipts;
+ AVCodecContext *enc = ost->enc_ctx;
+ double delta0, delta, sync_ipts, duration;
if (!frame) {
*nb_frames_prev = *nb_frames = mid_pred(e->frames_prev_hist[0],
@@ -979,6 +979,8 @@ static void video_sync_process(OutputFile *of, OutputStream *ost,
goto finish;
}
+ duration = frame->duration * av_q2d(frame->time_base) / av_q2d(enc->time_base);
+
sync_ipts = adjust_frame_pts_to_encoder_tb(of, ost, frame);
/* delta0 is the "drift" between the input frame and
* where it would fall in the output. */
@@ -1107,12 +1109,8 @@ static int do_video_out(OutputFile *of, OutputStream *ost, AVFrame *frame)
Encoder *e = ost->enc;
AVCodecContext *enc = ost->enc_ctx;
int64_t nb_frames, nb_frames_prev, i;
- double duration = 0;
- if (frame)
- duration = frame->duration * av_q2d(frame->time_base) / av_q2d(enc->time_base);
-
- video_sync_process(of, ost, frame, duration,
+ video_sync_process(of, ost, frame,
&nb_frames, &nb_frames_prev);
if (nb_frames_prev == 0 && ost->last_dropped) {
--
2.40.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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 02/12] fftools/ffmpeg_enc: move remaining vsync-related code to video_sync_process()
2023-10-03 15:35 [FFmpeg-devel] [PATCH 01/12] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process() Anton Khirnov
@ 2023-10-03 15:35 ` Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 03/12] fftools/ffmpeg_enc: simplify adjust_frame_pts_to_encoder_tb() signature Anton Khirnov
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Anton Khirnov @ 2023-10-03 15:35 UTC (permalink / raw)
To: ffmpeg-devel
---
fftools/ffmpeg_enc.c | 46 +++++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 8ae36294ce..0c51d9f0c6 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -1048,6 +1048,30 @@ finish:
e->frames_prev_hist,
sizeof(e->frames_prev_hist[0]) * (FF_ARRAY_ELEMS(e->frames_prev_hist) - 1));
e->frames_prev_hist[0] = *nb_frames_prev;
+
+ if (*nb_frames_prev == 0 && ost->last_dropped) {
+ ost->nb_frames_drop++;
+ av_log(ost, AV_LOG_VERBOSE,
+ "*** dropping frame %"PRId64" at ts %"PRId64"\n",
+ e->vsync_frame_number, e->last_frame->pts);
+ }
+ if (*nb_frames > (*nb_frames_prev && ost->last_dropped) + (*nb_frames > *nb_frames_prev)) {
+ if (*nb_frames > dts_error_threshold * 30) {
+ av_log(ost, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", *nb_frames - 1);
+ ost->nb_frames_drop++;
+ *nb_frames = 0;
+ return;
+ }
+ ost->nb_frames_dup += *nb_frames - (*nb_frames_prev && ost->last_dropped) - (*nb_frames > *nb_frames_prev);
+ av_log(ost, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", *nb_frames - 1);
+ if (ost->nb_frames_dup > e->dup_warning) {
+ av_log(ost, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", e->dup_warning);
+ e->dup_warning *= 10;
+ }
+ }
+
+ ost->last_dropped = *nb_frames == *nb_frames_prev && frame;
+ ost->kf.dropped_keyframe = ost->last_dropped && frame && (frame->flags & AV_FRAME_FLAG_KEY);
}
static enum AVPictureType forced_kf_apply(void *logctx, KeyframeForceCtx *kf,
@@ -1113,28 +1137,6 @@ static int do_video_out(OutputFile *of, OutputStream *ost, AVFrame *frame)
video_sync_process(of, ost, frame,
&nb_frames, &nb_frames_prev);
- if (nb_frames_prev == 0 && ost->last_dropped) {
- ost->nb_frames_drop++;
- av_log(ost, AV_LOG_VERBOSE,
- "*** dropping frame %"PRId64" at ts %"PRId64"\n",
- e->vsync_frame_number, e->last_frame->pts);
- }
- if (nb_frames > (nb_frames_prev && ost->last_dropped) + (nb_frames > nb_frames_prev)) {
- if (nb_frames > dts_error_threshold * 30) {
- av_log(ost, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", nb_frames - 1);
- ost->nb_frames_drop++;
- return 0;
- }
- ost->nb_frames_dup += nb_frames - (nb_frames_prev && ost->last_dropped) - (nb_frames > nb_frames_prev);
- av_log(ost, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", nb_frames - 1);
- if (ost->nb_frames_dup > e->dup_warning) {
- av_log(ost, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", e->dup_warning);
- e->dup_warning *= 10;
- }
- }
- ost->last_dropped = nb_frames == nb_frames_prev && frame;
- ost->kf.dropped_keyframe = ost->last_dropped && frame && (frame->flags & AV_FRAME_FLAG_KEY);
-
/* duplicates frame if needed */
for (i = 0; i < nb_frames; i++) {
AVFrame *in_picture;
--
2.40.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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 03/12] fftools/ffmpeg_enc: simplify adjust_frame_pts_to_encoder_tb() signature
2023-10-03 15:35 [FFmpeg-devel] [PATCH 01/12] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process() Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 02/12] fftools/ffmpeg_enc: move remaining vsync-related code " Anton Khirnov
@ 2023-10-03 15:35 ` Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 04/12] ffools/ffmpeg_filter: stop trying to handle an unreachable state Anton Khirnov
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Anton Khirnov @ 2023-10-03 15:35 UTC (permalink / raw)
To: ffmpeg-devel
It does not need an OutputFile and an OutputStream, only the target
timebase and the timestamp offset.
---
fftools/ffmpeg_enc.c | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 0c51d9f0c6..b928bf208c 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -917,16 +917,12 @@ static int do_audio_out(OutputFile *of, OutputStream *ost,
return (ret < 0 && ret != AVERROR_EOF) ? ret : 0;
}
-static double adjust_frame_pts_to_encoder_tb(OutputFile *of, OutputStream *ost,
- AVFrame *frame)
+static double adjust_frame_pts_to_encoder_tb(AVFrame *frame, AVRational tb_dst,
+ int64_t start_time)
{
double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision
- const int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ?
- 0 : of->start_time;
- AVCodecContext *const enc = ost->enc_ctx;
-
- AVRational tb = enc->time_base;
+ AVRational tb = tb_dst;
AVRational filter_tb = frame->time_base;
const int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16);
@@ -943,19 +939,17 @@ static double adjust_frame_pts_to_encoder_tb(OutputFile *of, OutputStream *ost,
if (float_pts != llrint(float_pts))
float_pts += FFSIGN(float_pts) * 1.0 / (1<<17);
- frame->pts = av_rescale_q(frame->pts, filter_tb, enc->time_base) -
- av_rescale_q(start_time, AV_TIME_BASE_Q, enc->time_base);
- frame->time_base = enc->time_base;
+ frame->pts = av_rescale_q(frame->pts, filter_tb, tb_dst) -
+ av_rescale_q(start_time, AV_TIME_BASE_Q, tb_dst);
+ frame->time_base = tb_dst;
early_exit:
if (debug_ts) {
av_log(NULL, AV_LOG_INFO, "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n",
frame ? av_ts2str(frame->pts) : "NULL",
- (enc && frame) ? av_ts2timestr(frame->pts, &enc->time_base) : "NULL",
- float_pts,
- enc ? enc->time_base.num : -1,
- enc ? enc->time_base.den : -1);
+ av_ts2timestr(frame->pts, &tb_dst),
+ float_pts, tb_dst.num, tb_dst.den);
}
return float_pts;
@@ -981,7 +975,8 @@ static void video_sync_process(OutputFile *of, OutputStream *ost, AVFrame *frame
duration = frame->duration * av_q2d(frame->time_base) / av_q2d(enc->time_base);
- sync_ipts = adjust_frame_pts_to_encoder_tb(of, ost, frame);
+ sync_ipts = adjust_frame_pts_to_encoder_tb(frame, enc->time_base,
+ of->start_time == AV_NOPTS_VALUE ? 0 : of->start_time);
/* delta0 is the "drift" between the input frame and
* where it would fall in the output. */
delta0 = sync_ipts - e->next_pts;
--
2.40.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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 04/12] ffools/ffmpeg_filter: stop trying to handle an unreachable state
2023-10-03 15:35 [FFmpeg-devel] [PATCH 01/12] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process() Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 02/12] fftools/ffmpeg_enc: move remaining vsync-related code " Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 03/12] fftools/ffmpeg_enc: simplify adjust_frame_pts_to_encoder_tb() signature Anton Khirnov
@ 2023-10-03 15:35 ` Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 05/12] tests/fate/ffmpeg: add tests for -force_key_frames source Anton Khirnov
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Anton Khirnov @ 2023-10-03 15:35 UTC (permalink / raw)
To: ffmpeg-devel
ifilter_send_eof() will fail if the input has no real or fallback
parameters, so there is no need to handle the case of some inputs being
in EOF state yet having no parameters.
---
fftools/ffmpeg.c | 2 +-
fftools/ffmpeg.h | 2 --
fftools/ffmpeg_filter.c | 10 +++++-----
3 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index fd2ce1c2d0..14f55cbec7 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -944,7 +944,7 @@ static int choose_output(OutputStream **post)
INT64_MIN : ost->last_mux_dts;
}
- if (!ost->initialized && !ost->inputs_done && !ost->finished) {
+ if (!ost->initialized && !ost->finished) {
ost_min = ost;
break;
}
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index b059ecbb9f..2e8f1db9b6 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -583,8 +583,6 @@ typedef struct OutputStream {
// parameters are set in the AVStream.
int initialized;
- int inputs_done;
-
const char *attachment_filename;
int keep_pix_fmt;
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index b6348d7f87..804b9de3dc 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -2076,11 +2076,11 @@ int fg_transcode_step(FilterGraph *graph, InputStream **best_ist)
}
}
- // graph not configured, but all inputs are either initialized or EOF
- for (int i = 0; i < graph->nb_outputs; i++)
- graph->outputs[i]->ost->inputs_done = 1;
-
- return 0;
+ // This state - graph is not configured, but all inputs are either
+ // initialized or EOF - should be unreachable because sending EOF to a
+ // filter without even a fallback format should fail
+ av_assert0(0);
+ return AVERROR_BUG;
}
*best_ist = NULL;
--
2.40.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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 05/12] tests/fate/ffmpeg: add tests for -force_key_frames source
2023-10-03 15:35 [FFmpeg-devel] [PATCH 01/12] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process() Anton Khirnov
` (2 preceding siblings ...)
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 04/12] ffools/ffmpeg_filter: stop trying to handle an unreachable state Anton Khirnov
@ 2023-10-03 15:35 ` Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 06/12] fftools/ffmpeg_enc: unbreak -force_key_frames source_no_drop Anton Khirnov
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Anton Khirnov @ 2023-10-03 15:35 UTC (permalink / raw)
To: ffmpeg-devel
---
tests/fate/ffmpeg.mak | 20 +
tests/ref/fate/force_key_frames-source | 397 +++++++++++++
tests/ref/fate/force_key_frames-source-drop | 22 +
tests/ref/fate/force_key_frames-source-dup | 617 ++++++++++++++++++++
4 files changed, 1056 insertions(+)
create mode 100644 tests/ref/fate/force_key_frames-source
create mode 100644 tests/ref/fate/force_key_frames-source-drop
create mode 100644 tests/ref/fate/force_key_frames-source-dup
diff --git a/tests/fate/ffmpeg.mak b/tests/fate/ffmpeg.mak
index 04500d53a0..835770a924 100644
--- a/tests/fate/ffmpeg.mak
+++ b/tests/fate/ffmpeg.mak
@@ -48,6 +48,26 @@ fate-force_key_frames: CMD = enc_dec \
avi "-c mpeg4 -g 240 -qscale 10 -force_key_frames 0.5,0:00:01.5" \
framecrc "" "-skip_frame nokey"
+# test -force_key_frames source with and without framerate conversion
+# * we don't care about the actual video content, so replace it with
+# a 2x2 black square to speed up encoding
+# * force mpeg2video to only emit keyframes when explicitly requested
+fate-force_key_frames-source: CMD = framecrc -i $(TARGET_SAMPLES)/h264/intra_refresh.h264 \
+ -vf crop=2:2,drawbox=color=black:t=fill \
+ -c:v mpeg2video -g 400 -sc_threshold 99999 \
+ -force_key_frames source
+fate-force_key_frames-source-drop: CMD = framecrc -i $(TARGET_SAMPLES)/h264/intra_refresh.h264 \
+ -vf crop=2:2,drawbox=color=black:t=fill \
+ -c:v mpeg2video -g 400 -sc_threshold 99999 \
+ -force_key_frames source -r 1
+fate-force_key_frames-source-dup: CMD = framecrc -i $(TARGET_SAMPLES)/h264/intra_refresh.h264 \
+ -vf crop=2:2,drawbox=color=black:t=fill \
+ -c:v mpeg2video -g 400 -sc_threshold 99999 \
+ -force_key_frames source -r 39 -force_fps -strict experimental
+
+FATE_SAMPLES_FFMPEG-$(call ENCDEC, MPEG2VIDEO H264, FRAMECRC H264, CROP_FILTER DRAWBOX_FILTER) += \
+ fate-force_key_frames-source fate-force_key_frames-source-drop fate-force_key_frames-source-dup
+
# Tests that the video is properly autorotated using the contained
# display matrix and that the generated file does not contain
# a display matrix any more.
diff --git a/tests/ref/fate/force_key_frames-source b/tests/ref/fate/force_key_frames-source
new file mode 100644
index 0000000000..87a35e2d2c
--- /dev/null
+++ b/tests/ref/fate/force_key_frames-source
@@ -0,0 +1,397 @@
+#tb 0: 1/25
+#media_type 0: video
+#codec_id 0: mpeg2video
+#dimensions 0: 2x2
+#sar 0: 0/1
+0, -1, 0, 1, 57, 0x7db00eb7, S=1, 8
+0, 0, 1, 1, 24, 0x4f1c0660, F=0x0, S=1, 8
+0, 1, 2, 1, 24, 0x53dc06a0, F=0x0, S=1, 8
+0, 2, 3, 1, 24, 0x589c06e0, F=0x0, S=1, 8
+0, 3, 4, 1, 24, 0x4a700621, F=0x0, S=1, 8
+0, 4, 5, 1, 24, 0x4f300661, F=0x0, S=1, 8
+0, 5, 6, 1, 24, 0x53f006a1, F=0x0, S=1, 8
+0, 6, 7, 1, 24, 0x58b006e1, F=0x0, S=1, 8
+0, 7, 8, 1, 24, 0x4a840622, F=0x0, S=1, 8
+0, 8, 9, 1, 24, 0x4f440662, F=0x0, S=1, 8
+0, 9, 10, 1, 24, 0x540406a2, F=0x0, S=1, 8
+0, 10, 11, 1, 24, 0x58c406e2, F=0x0, S=1, 8
+0, 11, 12, 1, 24, 0x4a980623, F=0x0, S=1, 8
+0, 12, 13, 1, 24, 0x4f580663, F=0x0, S=1, 8
+0, 13, 14, 1, 24, 0x541806a3, F=0x0, S=1, 8
+0, 14, 15, 1, 24, 0x58d806e3, F=0x0, S=1, 8
+0, 15, 16, 1, 24, 0x4aac0624, F=0x0, S=1, 8
+0, 16, 17, 1, 24, 0x4f6c0664, F=0x0, S=1, 8
+0, 17, 18, 1, 24, 0x542c06a4, F=0x0, S=1, 8
+0, 18, 19, 1, 24, 0x58ec06e4, F=0x0, S=1, 8
+0, 19, 20, 1, 24, 0x4ac00625, F=0x0, S=1, 8
+0, 20, 21, 1, 24, 0x4f800665, F=0x0, S=1, 8
+0, 21, 22, 1, 24, 0x544006a5, F=0x0, S=1, 8
+0, 22, 23, 1, 24, 0x590006e5, F=0x0, S=1, 8
+0, 23, 24, 1, 24, 0x4ad40626, F=0x0, S=1, 8
+0, 24, 25, 1, 24, 0x4f940666, F=0x0, S=1, 8
+0, 25, 26, 1, 24, 0x545406a6, F=0x0, S=1, 8
+0, 26, 27, 1, 24, 0x591406e6, F=0x0, S=1, 8
+0, 27, 28, 1, 24, 0x4ae80627, F=0x0, S=1, 8
+0, 28, 29, 1, 24, 0x4fa80667, F=0x0, S=1, 8
+0, 29, 30, 1, 24, 0x546806a7, F=0x0, S=1, 8
+0, 30, 31, 1, 24, 0x592806e7, F=0x0, S=1, 8
+0, 31, 32, 1, 24, 0x4afc0628, F=0x0, S=1, 8
+0, 32, 33, 1, 24, 0x4fbc0668, F=0x0, S=1, 8
+0, 33, 34, 1, 24, 0x547c06a8, F=0x0, S=1, 8
+0, 34, 35, 1, 24, 0x593c06e8, F=0x0, S=1, 8
+0, 35, 36, 1, 24, 0x4b100629, F=0x0, S=1, 8
+0, 36, 37, 1, 24, 0x4fd00669, F=0x0, S=1, 8
+0, 37, 38, 1, 24, 0x549006a9, F=0x0, S=1, 8
+0, 38, 39, 1, 24, 0x595006e9, F=0x0, S=1, 8
+0, 39, 40, 1, 24, 0x4b24062a, F=0x0, S=1, 8
+0, 40, 41, 1, 24, 0x4fe4066a, F=0x0, S=1, 8
+0, 41, 42, 1, 24, 0x54a406aa, F=0x0, S=1, 8
+0, 42, 43, 1, 24, 0x596406ea, F=0x0, S=1, 8
+0, 43, 44, 1, 24, 0x4b38062b, F=0x0, S=1, 8
+0, 44, 45, 1, 24, 0x4ff8066b, F=0x0, S=1, 8
+0, 45, 46, 1, 24, 0x54b806ab, F=0x0, S=1, 8
+0, 46, 47, 1, 24, 0x597806eb, F=0x0, S=1, 8
+0, 47, 48, 1, 24, 0x4b4c062c, F=0x0, S=1, 8
+0, 48, 49, 1, 24, 0x500c066c, F=0x0, S=1, 8
+0, 49, 50, 1, 24, 0x54cc06ac, F=0x0, S=1, 8
+0, 50, 51, 1, 24, 0x598c06ec, F=0x0, S=1, 8
+0, 51, 52, 1, 24, 0x4b60062d, F=0x0, S=1, 8
+0, 52, 53, 1, 24, 0x5020066d, F=0x0, S=1, 8
+0, 53, 54, 1, 24, 0x54e006ad, F=0x0, S=1, 8
+0, 54, 55, 1, 24, 0x59a006ed, F=0x0, S=1, 8
+0, 55, 56, 1, 24, 0x4b74062e, F=0x0, S=1, 8
+0, 56, 57, 1, 24, 0x5034066e, F=0x0, S=1, 8
+0, 57, 58, 1, 24, 0x54f406ae, F=0x0, S=1, 8
+0, 58, 59, 1, 24, 0x59b406ee, F=0x0, S=1, 8
+0, 59, 60, 1, 24, 0x4b88062f, F=0x0, S=1, 8
+0, 60, 61, 1, 24, 0x5048066f, F=0x0, S=1, 8
+0, 61, 62, 1, 24, 0x550806af, F=0x0, S=1, 8
+0, 62, 63, 1, 24, 0x59c806ef, F=0x0, S=1, 8
+0, 63, 64, 1, 24, 0x4b9c0630, F=0x0, S=1, 8
+0, 64, 65, 1, 24, 0x505c0670, F=0x0, S=1, 8
+0, 65, 66, 1, 24, 0x551c06b0, F=0x0, S=1, 8
+0, 66, 67, 1, 24, 0x59dc06f0, F=0x0, S=1, 8
+0, 67, 68, 1, 24, 0x4bb00631, F=0x0, S=1, 8
+0, 68, 69, 1, 24, 0x50700671, F=0x0, S=1, 8
+0, 69, 70, 1, 24, 0x553006b1, F=0x0, S=1, 8
+0, 70, 71, 1, 24, 0x59f006f1, F=0x0, S=1, 8
+0, 71, 72, 1, 24, 0x4bc40632, F=0x0, S=1, 8
+0, 72, 73, 1, 24, 0x50840672, F=0x0, S=1, 8
+0, 73, 74, 1, 24, 0x554406b2, F=0x0, S=1, 8
+0, 74, 75, 1, 24, 0x5a0406f2, F=0x0, S=1, 8
+0, 75, 76, 1, 24, 0x4bd80633, F=0x0, S=1, 8
+0, 76, 77, 1, 24, 0x50980673, F=0x0, S=1, 8
+0, 77, 78, 1, 24, 0x555806b3, F=0x0, S=1, 8
+0, 78, 79, 1, 24, 0x5a1806f3, F=0x0, S=1, 8
+0, 79, 80, 1, 24, 0x4bec0634, F=0x0, S=1, 8
+0, 80, 81, 1, 24, 0x50ac0674, F=0x0, S=1, 8
+0, 81, 82, 1, 24, 0x556c06b4, F=0x0, S=1, 8
+0, 82, 83, 1, 24, 0x5a2c06f4, F=0x0, S=1, 8
+0, 83, 84, 1, 24, 0x4c000635, F=0x0, S=1, 8
+0, 84, 85, 1, 24, 0x50c00675, F=0x0, S=1, 8
+0, 85, 86, 1, 24, 0x558006b5, F=0x0, S=1, 8
+0, 86, 87, 1, 24, 0x5a4006f5, F=0x0, S=1, 8
+0, 87, 88, 1, 24, 0x4c140636, F=0x0, S=1, 8
+0, 88, 89, 1, 24, 0x50d40676, F=0x0, S=1, 8
+0, 89, 90, 1, 24, 0x559406b6, F=0x0, S=1, 8
+0, 90, 91, 1, 24, 0x5a5406f6, F=0x0, S=1, 8
+0, 91, 92, 1, 24, 0x4c280637, F=0x0, S=1, 8
+0, 92, 93, 1, 24, 0x50e80677, F=0x0, S=1, 8
+0, 93, 94, 1, 24, 0x55a806b7, F=0x0, S=1, 8
+0, 94, 95, 1, 24, 0x5a6806f7, F=0x0, S=1, 8
+0, 95, 96, 1, 24, 0x4c3c0638, F=0x0, S=1, 8
+0, 96, 97, 1, 24, 0x50fc0678, F=0x0, S=1, 8
+0, 97, 98, 1, 24, 0x55bc06b8, F=0x0, S=1, 8
+0, 98, 99, 1, 24, 0x5a7c06f8, F=0x0, S=1, 8
+0, 99, 100, 1, 24, 0x4c500639, F=0x0, S=1, 8
+0, 100, 101, 1, 24, 0x51100679, F=0x0, S=1, 8
+0, 101, 102, 1, 24, 0x55d006b9, F=0x0, S=1, 8
+0, 102, 103, 1, 24, 0x5a9006f9, F=0x0, S=1, 8
+0, 103, 104, 1, 24, 0x4c64063a, F=0x0, S=1, 8
+0, 104, 105, 1, 24, 0x5124067a, F=0x0, S=1, 8
+0, 105, 106, 1, 24, 0x55e406ba, F=0x0, S=1, 8
+0, 106, 107, 1, 24, 0x5aa406fa, F=0x0, S=1, 8
+0, 107, 108, 1, 57, 0x85a40efb, S=1, 8
+0, 108, 109, 1, 24, 0x4f1c0660, F=0x0, S=1, 8
+0, 109, 110, 1, 24, 0x53dc06a0, F=0x0, S=1, 8
+0, 110, 111, 1, 24, 0x589c06e0, F=0x0, S=1, 8
+0, 111, 112, 1, 24, 0x4a700621, F=0x0, S=1, 8
+0, 112, 113, 1, 24, 0x4f300661, F=0x0, S=1, 8
+0, 113, 114, 1, 24, 0x53f006a1, F=0x0, S=1, 8
+0, 114, 115, 1, 24, 0x58b006e1, F=0x0, S=1, 8
+0, 115, 116, 1, 24, 0x4a840622, F=0x0, S=1, 8
+0, 116, 117, 1, 24, 0x4f440662, F=0x0, S=1, 8
+0, 117, 118, 1, 24, 0x540406a2, F=0x0, S=1, 8
+0, 118, 119, 1, 24, 0x58c406e2, F=0x0, S=1, 8
+0, 119, 120, 1, 24, 0x4a980623, F=0x0, S=1, 8
+0, 120, 121, 1, 24, 0x4f580663, F=0x0, S=1, 8
+0, 121, 122, 1, 24, 0x541806a3, F=0x0, S=1, 8
+0, 122, 123, 1, 24, 0x58d806e3, F=0x0, S=1, 8
+0, 123, 124, 1, 24, 0x4aac0624, F=0x0, S=1, 8
+0, 124, 125, 1, 24, 0x4f6c0664, F=0x0, S=1, 8
+0, 125, 126, 1, 24, 0x542c06a4, F=0x0, S=1, 8
+0, 126, 127, 1, 24, 0x58ec06e4, F=0x0, S=1, 8
+0, 127, 128, 1, 24, 0x4ac00625, F=0x0, S=1, 8
+0, 128, 129, 1, 24, 0x4f800665, F=0x0, S=1, 8
+0, 129, 130, 1, 24, 0x544006a5, F=0x0, S=1, 8
+0, 130, 131, 1, 24, 0x590006e5, F=0x0, S=1, 8
+0, 131, 132, 1, 24, 0x4ad40626, F=0x0, S=1, 8
+0, 132, 133, 1, 24, 0x4f940666, F=0x0, S=1, 8
+0, 133, 134, 1, 24, 0x545406a6, F=0x0, S=1, 8
+0, 134, 135, 1, 24, 0x591406e6, F=0x0, S=1, 8
+0, 135, 136, 1, 24, 0x4ae80627, F=0x0, S=1, 8
+0, 136, 137, 1, 24, 0x4fa80667, F=0x0, S=1, 8
+0, 137, 138, 1, 24, 0x546806a7, F=0x0, S=1, 8
+0, 138, 139, 1, 24, 0x592806e7, F=0x0, S=1, 8
+0, 139, 140, 1, 24, 0x4afc0628, F=0x0, S=1, 8
+0, 140, 141, 1, 24, 0x4fbc0668, F=0x0, S=1, 8
+0, 141, 142, 1, 24, 0x547c06a8, F=0x0, S=1, 8
+0, 142, 143, 1, 24, 0x593c06e8, F=0x0, S=1, 8
+0, 143, 144, 1, 24, 0x4b100629, F=0x0, S=1, 8
+0, 144, 145, 1, 24, 0x4fd00669, F=0x0, S=1, 8
+0, 145, 146, 1, 24, 0x549006a9, F=0x0, S=1, 8
+0, 146, 147, 1, 24, 0x595006e9, F=0x0, S=1, 8
+0, 147, 148, 1, 24, 0x4b24062a, F=0x0, S=1, 8
+0, 148, 149, 1, 24, 0x4fe4066a, F=0x0, S=1, 8
+0, 149, 150, 1, 24, 0x54a406aa, F=0x0, S=1, 8
+0, 150, 151, 1, 24, 0x596406ea, F=0x0, S=1, 8
+0, 151, 152, 1, 24, 0x4b38062b, F=0x0, S=1, 8
+0, 152, 153, 1, 24, 0x4ff8066b, F=0x0, S=1, 8
+0, 153, 154, 1, 24, 0x54b806ab, F=0x0, S=1, 8
+0, 154, 155, 1, 24, 0x597806eb, F=0x0, S=1, 8
+0, 155, 156, 1, 24, 0x4b4c062c, F=0x0, S=1, 8
+0, 156, 157, 1, 24, 0x500c066c, F=0x0, S=1, 8
+0, 157, 158, 1, 24, 0x54cc06ac, F=0x0, S=1, 8
+0, 158, 159, 1, 24, 0x598c06ec, F=0x0, S=1, 8
+0, 159, 160, 1, 24, 0x4b60062d, F=0x0, S=1, 8
+0, 160, 161, 1, 24, 0x5020066d, F=0x0, S=1, 8
+0, 161, 162, 1, 24, 0x54e006ad, F=0x0, S=1, 8
+0, 162, 163, 1, 24, 0x59a006ed, F=0x0, S=1, 8
+0, 163, 164, 1, 24, 0x4b74062e, F=0x0, S=1, 8
+0, 164, 165, 1, 24, 0x5034066e, F=0x0, S=1, 8
+0, 165, 166, 1, 24, 0x54f406ae, F=0x0, S=1, 8
+0, 166, 167, 1, 24, 0x59b406ee, F=0x0, S=1, 8
+0, 167, 168, 1, 24, 0x4b88062f, F=0x0, S=1, 8
+0, 168, 169, 1, 24, 0x5048066f, F=0x0, S=1, 8
+0, 169, 170, 1, 24, 0x550806af, F=0x0, S=1, 8
+0, 170, 171, 1, 24, 0x59c806ef, F=0x0, S=1, 8
+0, 171, 172, 1, 24, 0x4b9c0630, F=0x0, S=1, 8
+0, 172, 173, 1, 24, 0x505c0670, F=0x0, S=1, 8
+0, 173, 174, 1, 24, 0x551c06b0, F=0x0, S=1, 8
+0, 174, 175, 1, 24, 0x59dc06f0, F=0x0, S=1, 8
+0, 175, 176, 1, 24, 0x4bb00631, F=0x0, S=1, 8
+0, 176, 177, 1, 24, 0x50700671, F=0x0, S=1, 8
+0, 177, 178, 1, 24, 0x553006b1, F=0x0, S=1, 8
+0, 178, 179, 1, 24, 0x59f006f1, F=0x0, S=1, 8
+0, 179, 180, 1, 24, 0x4bc40632, F=0x0, S=1, 8
+0, 180, 181, 1, 24, 0x50840672, F=0x0, S=1, 8
+0, 181, 182, 1, 24, 0x554406b2, F=0x0, S=1, 8
+0, 182, 183, 1, 24, 0x5a0406f2, F=0x0, S=1, 8
+0, 183, 184, 1, 24, 0x4bd80633, F=0x0, S=1, 8
+0, 184, 185, 1, 24, 0x50980673, F=0x0, S=1, 8
+0, 185, 186, 1, 24, 0x555806b3, F=0x0, S=1, 8
+0, 186, 187, 1, 24, 0x5a1806f3, F=0x0, S=1, 8
+0, 187, 188, 1, 24, 0x4bec0634, F=0x0, S=1, 8
+0, 188, 189, 1, 24, 0x50ac0674, F=0x0, S=1, 8
+0, 189, 190, 1, 24, 0x556c06b4, F=0x0, S=1, 8
+0, 190, 191, 1, 24, 0x5a2c06f4, F=0x0, S=1, 8
+0, 191, 192, 1, 24, 0x4c000635, F=0x0, S=1, 8
+0, 192, 193, 1, 24, 0x50c00675, F=0x0, S=1, 8
+0, 193, 194, 1, 24, 0x558006b5, F=0x0, S=1, 8
+0, 194, 195, 1, 24, 0x5a4006f5, F=0x0, S=1, 8
+0, 195, 196, 1, 24, 0x4c140636, F=0x0, S=1, 8
+0, 196, 197, 1, 24, 0x50d40676, F=0x0, S=1, 8
+0, 197, 198, 1, 24, 0x559406b6, F=0x0, S=1, 8
+0, 198, 199, 1, 24, 0x5a5406f6, F=0x0, S=1, 8
+0, 199, 200, 1, 24, 0x4c280637, F=0x0, S=1, 8
+0, 200, 201, 1, 24, 0x50e80677, F=0x0, S=1, 8
+0, 201, 202, 1, 24, 0x55a806b7, F=0x0, S=1, 8
+0, 202, 203, 1, 24, 0x5a6806f7, F=0x0, S=1, 8
+0, 203, 204, 1, 24, 0x4c3c0638, F=0x0, S=1, 8
+0, 204, 205, 1, 24, 0x50fc0678, F=0x0, S=1, 8
+0, 205, 206, 1, 24, 0x55bc06b8, F=0x0, S=1, 8
+0, 206, 207, 1, 24, 0x5a7c06f8, F=0x0, S=1, 8
+0, 207, 208, 1, 24, 0x4c500639, F=0x0, S=1, 8
+0, 208, 209, 1, 24, 0x51100679, F=0x0, S=1, 8
+0, 209, 210, 1, 24, 0x55d006b9, F=0x0, S=1, 8
+0, 210, 211, 1, 24, 0x5a9006f9, F=0x0, S=1, 8
+0, 211, 212, 1, 24, 0x4c64063a, F=0x0, S=1, 8
+0, 212, 213, 1, 24, 0x5124067a, F=0x0, S=1, 8
+0, 213, 214, 1, 24, 0x55e406ba, F=0x0, S=1, 8
+0, 214, 215, 1, 24, 0x5aa406fa, F=0x0, S=1, 8
+0, 215, 216, 1, 24, 0x4c78063b, F=0x0, S=1, 8
+0, 216, 217, 1, 24, 0x5138067b, F=0x0, S=1, 8
+0, 217, 218, 1, 24, 0x55f806bb, F=0x0, S=1, 8
+0, 218, 219, 1, 24, 0x5ab806fb, F=0x0, S=1, 8
+0, 219, 220, 1, 24, 0x4c8c063c, F=0x0, S=1, 8
+0, 220, 221, 1, 24, 0x514c067c, F=0x0, S=1, 8
+0, 221, 222, 1, 24, 0x560c06bc, F=0x0, S=1, 8
+0, 222, 223, 1, 24, 0x5acc06fc, F=0x0, S=1, 8
+0, 223, 224, 1, 24, 0x4ca0063d, F=0x0, S=1, 8
+0, 224, 225, 1, 24, 0x5160067d, F=0x0, S=1, 8
+0, 225, 226, 1, 24, 0x562006bd, F=0x0, S=1, 8
+0, 226, 227, 1, 24, 0x5ae006fd, F=0x0, S=1, 8
+0, 227, 228, 1, 24, 0x4cb4063e, F=0x0, S=1, 8
+0, 228, 229, 1, 24, 0x5174067e, F=0x0, S=1, 8
+0, 229, 230, 1, 24, 0x563406be, F=0x0, S=1, 8
+0, 230, 231, 1, 24, 0x5af406fe, F=0x0, S=1, 8
+0, 231, 232, 1, 24, 0x4cc8063f, F=0x0, S=1, 8
+0, 232, 233, 1, 24, 0x5188067f, F=0x0, S=1, 8
+0, 233, 234, 1, 24, 0x564806bf, F=0x0, S=1, 8
+0, 234, 235, 1, 24, 0x5b0806ff, F=0x0, S=1, 8
+0, 235, 236, 1, 24, 0x4cdc0640, F=0x0, S=1, 8
+0, 236, 237, 1, 24, 0x519c0680, F=0x0, S=1, 8
+0, 237, 238, 1, 24, 0x565c06c0, F=0x0, S=1, 8
+0, 238, 239, 1, 24, 0x5b1c0700, F=0x0, S=1, 8
+0, 239, 240, 1, 24, 0x4cf00641, F=0x0, S=1, 8
+0, 240, 241, 1, 24, 0x51b00681, F=0x0, S=1, 8
+0, 241, 242, 1, 24, 0x567006c1, F=0x0, S=1, 8
+0, 242, 243, 1, 24, 0x5b300701, F=0x0, S=1, 8
+0, 243, 244, 1, 24, 0x4d040642, F=0x0, S=1, 8
+0, 244, 245, 1, 24, 0x51c40682, F=0x0, S=1, 8
+0, 245, 246, 1, 24, 0x568406c2, F=0x0, S=1, 8
+0, 246, 247, 1, 24, 0x5b440702, F=0x0, S=1, 8
+0, 247, 248, 1, 24, 0x4d180643, F=0x0, S=1, 8
+0, 248, 249, 1, 24, 0x51d80683, F=0x0, S=1, 8
+0, 249, 250, 1, 24, 0x569806c3, F=0x0, S=1, 8
+0, 250, 251, 1, 24, 0x5b580703, F=0x0, S=1, 8
+0, 251, 252, 1, 24, 0x4d2c0644, F=0x0, S=1, 8
+0, 252, 253, 1, 24, 0x51ec0684, F=0x0, S=1, 8
+0, 253, 254, 1, 24, 0x56ac06c4, F=0x0, S=1, 8
+0, 254, 255, 1, 24, 0x5b6c0704, F=0x0, S=1, 8
+0, 255, 256, 1, 24, 0x4d400645, F=0x0, S=1, 8
+0, 256, 257, 1, 24, 0x52000685, F=0x0, S=1, 8
+0, 257, 258, 1, 24, 0x56c006c5, F=0x0, S=1, 8
+0, 258, 259, 1, 24, 0x5b800705, F=0x0, S=1, 8
+0, 259, 260, 1, 24, 0x4d540646, F=0x0, S=1, 8
+0, 260, 261, 1, 24, 0x52140686, F=0x0, S=1, 8
+0, 261, 262, 1, 24, 0x56d406c6, F=0x0, S=1, 8
+0, 262, 263, 1, 24, 0x5b940706, F=0x0, S=1, 8
+0, 263, 264, 1, 24, 0x4d680647, F=0x0, S=1, 8
+0, 264, 265, 1, 24, 0x52280687, F=0x0, S=1, 8
+0, 265, 266, 1, 24, 0x56e806c7, F=0x0, S=1, 8
+0, 266, 267, 1, 24, 0x5ba80707, F=0x0, S=1, 8
+0, 267, 268, 1, 24, 0x4d7c0648, F=0x0, S=1, 8
+0, 268, 269, 1, 24, 0x523c0688, F=0x0, S=1, 8
+0, 269, 270, 1, 24, 0x56fc06c8, F=0x0, S=1, 8
+0, 270, 271, 1, 24, 0x5bbc0708, F=0x0, S=1, 8
+0, 271, 272, 1, 24, 0x4d900649, F=0x0, S=1, 8
+0, 272, 273, 1, 24, 0x52500689, F=0x0, S=1, 8
+0, 273, 274, 1, 24, 0x571006c9, F=0x0, S=1, 8
+0, 274, 275, 1, 24, 0x5bd00709, F=0x0, S=1, 8
+0, 275, 276, 1, 24, 0x4da4064a, F=0x0, S=1, 8
+0, 276, 277, 1, 24, 0x5264068a, F=0x0, S=1, 8
+0, 277, 278, 1, 24, 0x572406ca, F=0x0, S=1, 8
+0, 278, 279, 1, 24, 0x5be4070a, F=0x0, S=1, 8
+0, 279, 280, 1, 24, 0x4db8064b, F=0x0, S=1, 8
+0, 280, 281, 1, 24, 0x5278068b, F=0x0, S=1, 8
+0, 281, 282, 1, 24, 0x573806cb, F=0x0, S=1, 8
+0, 282, 283, 1, 24, 0x5bf8070b, F=0x0, S=1, 8
+0, 283, 284, 1, 24, 0x4dcc064c, F=0x0, S=1, 8
+0, 284, 285, 1, 24, 0x528c068c, F=0x0, S=1, 8
+0, 285, 286, 1, 24, 0x574c06cc, F=0x0, S=1, 8
+0, 286, 287, 1, 24, 0x5c0c070c, F=0x0, S=1, 8
+0, 287, 288, 1, 24, 0x4de0064d, F=0x0, S=1, 8
+0, 288, 289, 1, 24, 0x52a0068d, F=0x0, S=1, 8
+0, 289, 290, 1, 24, 0x576006cd, F=0x0, S=1, 8
+0, 290, 291, 1, 24, 0x5c20070d, F=0x0, S=1, 8
+0, 291, 292, 1, 24, 0x4df4064e, F=0x0, S=1, 8
+0, 292, 293, 1, 24, 0x52b4068e, F=0x0, S=1, 8
+0, 293, 294, 1, 24, 0x577406ce, F=0x0, S=1, 8
+0, 294, 295, 1, 24, 0x5c34070e, F=0x0, S=1, 8
+0, 295, 296, 1, 24, 0x4e08064f, F=0x0, S=1, 8
+0, 296, 297, 1, 24, 0x52c8068f, F=0x0, S=1, 8
+0, 297, 298, 1, 24, 0x578806cf, F=0x0, S=1, 8
+0, 298, 299, 1, 24, 0x5c48070f, F=0x0, S=1, 8
+0, 299, 300, 1, 24, 0x4e1c0650, F=0x0, S=1, 8
+0, 300, 301, 1, 24, 0x52dc0690, F=0x0, S=1, 8
+0, 301, 302, 1, 24, 0x579c06d0, F=0x0, S=1, 8
+0, 302, 303, 1, 24, 0x5c5c0710, F=0x0, S=1, 8
+0, 303, 304, 1, 24, 0x4e300651, F=0x0, S=1, 8
+0, 304, 305, 1, 24, 0x52f00691, F=0x0, S=1, 8
+0, 305, 306, 1, 24, 0x57b006d1, F=0x0, S=1, 8
+0, 306, 307, 1, 24, 0x5c700711, F=0x0, S=1, 8
+0, 307, 308, 1, 24, 0x4e440652, F=0x0, S=1, 8
+0, 308, 309, 1, 24, 0x53040692, F=0x0, S=1, 8
+0, 309, 310, 1, 24, 0x57c406d2, F=0x0, S=1, 8
+0, 310, 311, 1, 24, 0x5c840712, F=0x0, S=1, 8
+0, 311, 312, 1, 24, 0x4e580653, F=0x0, S=1, 8
+0, 312, 313, 1, 24, 0x53180693, F=0x0, S=1, 8
+0, 313, 314, 1, 24, 0x57d806d3, F=0x0, S=1, 8
+0, 314, 315, 1, 24, 0x5c980713, F=0x0, S=1, 8
+0, 315, 316, 1, 24, 0x4e6c0654, F=0x0, S=1, 8
+0, 316, 317, 1, 24, 0x532c0694, F=0x0, S=1, 8
+0, 317, 318, 1, 24, 0x57ec06d4, F=0x0, S=1, 8
+0, 318, 319, 1, 24, 0x5cac0714, F=0x0, S=1, 8
+0, 319, 320, 1, 24, 0x4e800655, F=0x0, S=1, 8
+0, 320, 321, 1, 24, 0x53400695, F=0x0, S=1, 8
+0, 321, 322, 1, 24, 0x580006d5, F=0x0, S=1, 8
+0, 322, 323, 1, 24, 0x5cc00715, F=0x0, S=1, 8
+0, 323, 324, 1, 24, 0x4e940656, F=0x0, S=1, 8
+0, 324, 325, 1, 24, 0x53540696, F=0x0, S=1, 8
+0, 325, 326, 1, 24, 0x581406d6, F=0x0, S=1, 8
+0, 326, 327, 1, 24, 0x5cd40716, F=0x0, S=1, 8
+0, 327, 328, 1, 24, 0x4ea80657, F=0x0, S=1, 8
+0, 328, 329, 1, 24, 0x53680697, F=0x0, S=1, 8
+0, 329, 330, 1, 24, 0x582806d7, F=0x0, S=1, 8
+0, 330, 331, 1, 24, 0x5ce80717, F=0x0, S=1, 8
+0, 331, 332, 1, 24, 0x4ebc0658, F=0x0, S=1, 8
+0, 332, 333, 1, 24, 0x537c0698, F=0x0, S=1, 8
+0, 333, 334, 1, 24, 0x583c06d8, F=0x0, S=1, 8
+0, 334, 335, 1, 24, 0x5cfc0718, F=0x0, S=1, 8
+0, 335, 336, 1, 24, 0x4ed00659, F=0x0, S=1, 8
+0, 336, 337, 1, 57, 0x899c0f1e, S=1, 8
+0, 337, 338, 1, 24, 0x4f1c0660, F=0x0, S=1, 8
+0, 338, 339, 1, 24, 0x53dc06a0, F=0x0, S=1, 8
+0, 339, 340, 1, 24, 0x589c06e0, F=0x0, S=1, 8
+0, 340, 341, 1, 24, 0x4a700621, F=0x0, S=1, 8
+0, 341, 342, 1, 24, 0x4f300661, F=0x0, S=1, 8
+0, 342, 343, 1, 24, 0x53f006a1, F=0x0, S=1, 8
+0, 343, 344, 1, 24, 0x58b006e1, F=0x0, S=1, 8
+0, 344, 345, 1, 24, 0x4a840622, F=0x0, S=1, 8
+0, 345, 346, 1, 24, 0x4f440662, F=0x0, S=1, 8
+0, 346, 347, 1, 24, 0x540406a2, F=0x0, S=1, 8
+0, 347, 348, 1, 24, 0x58c406e2, F=0x0, S=1, 8
+0, 348, 349, 1, 24, 0x4a980623, F=0x0, S=1, 8
+0, 349, 350, 1, 24, 0x4f580663, F=0x0, S=1, 8
+0, 350, 351, 1, 24, 0x541806a3, F=0x0, S=1, 8
+0, 351, 352, 1, 24, 0x58d806e3, F=0x0, S=1, 8
+0, 352, 353, 1, 24, 0x4aac0624, F=0x0, S=1, 8
+0, 353, 354, 1, 24, 0x4f6c0664, F=0x0, S=1, 8
+0, 354, 355, 1, 24, 0x542c06a4, F=0x0, S=1, 8
+0, 355, 356, 1, 24, 0x58ec06e4, F=0x0, S=1, 8
+0, 356, 357, 1, 24, 0x4ac00625, F=0x0, S=1, 8
+0, 357, 358, 1, 24, 0x4f800665, F=0x0, S=1, 8
+0, 358, 359, 1, 24, 0x544006a5, F=0x0, S=1, 8
+0, 359, 360, 1, 24, 0x590006e5, F=0x0, S=1, 8
+0, 360, 361, 1, 24, 0x4ad40626, F=0x0, S=1, 8
+0, 361, 362, 1, 24, 0x4f940666, F=0x0, S=1, 8
+0, 362, 363, 1, 24, 0x545406a6, F=0x0, S=1, 8
+0, 363, 364, 1, 24, 0x591406e6, F=0x0, S=1, 8
+0, 364, 365, 1, 24, 0x4ae80627, F=0x0, S=1, 8
+0, 365, 366, 1, 24, 0x4fa80667, F=0x0, S=1, 8
+0, 366, 367, 1, 24, 0x546806a7, F=0x0, S=1, 8
+0, 367, 368, 1, 24, 0x592806e7, F=0x0, S=1, 8
+0, 368, 369, 1, 57, 0x9b930fc1, S=1, 8
+0, 369, 370, 1, 24, 0x4f1c0660, F=0x0, S=1, 8
+0, 370, 371, 1, 24, 0x53dc06a0, F=0x0, S=1, 8
+0, 371, 372, 1, 24, 0x589c06e0, F=0x0, S=1, 8
+0, 372, 373, 1, 24, 0x4a700621, F=0x0, S=1, 8
+0, 373, 374, 1, 24, 0x4f300661, F=0x0, S=1, 8
+0, 374, 375, 1, 24, 0x53f006a1, F=0x0, S=1, 8
+0, 375, 376, 1, 24, 0x58b006e1, F=0x0, S=1, 8
+0, 376, 377, 1, 24, 0x4a840622, F=0x0, S=1, 8
+0, 377, 378, 1, 24, 0x4f440662, F=0x0, S=1, 8
+0, 378, 379, 1, 24, 0x540406a2, F=0x0, S=1, 8
+0, 379, 380, 1, 24, 0x58c406e2, F=0x0, S=1, 8
+0, 380, 381, 1, 24, 0x4a980623, F=0x0, S=1, 8
+0, 381, 382, 1, 24, 0x4f580663, F=0x0, S=1, 8
+0, 382, 383, 1, 24, 0x541806a3, F=0x0, S=1, 8
+0, 383, 384, 1, 24, 0x58d806e3, F=0x0, S=1, 8
+0, 384, 385, 1, 24, 0x4aac0624, F=0x0, S=1, 8
+0, 385, 386, 1, 24, 0x4f6c0664, F=0x0, S=1, 8
+0, 386, 387, 1, 24, 0x542c06a4, F=0x0, S=1, 8
+0, 387, 388, 1, 24, 0x58ec06e4, F=0x0, S=1, 8
+0, 388, 389, 1, 24, 0x4ac00625, F=0x0, S=1, 8
+0, 389, 390, 1, 24, 0x4f800665, F=0x0, S=1, 8
+0, 390, 391, 1, 24, 0x544006a5, F=0x0, S=1, 8
diff --git a/tests/ref/fate/force_key_frames-source-drop b/tests/ref/fate/force_key_frames-source-drop
new file mode 100644
index 0000000000..99aa2ae826
--- /dev/null
+++ b/tests/ref/fate/force_key_frames-source-drop
@@ -0,0 +1,22 @@
+#tb 0: 1/1
+#media_type 0: video
+#codec_id 0: mpeg2video
+#dimensions 0: 2x2
+#sar 0: 0/1
+0, -1, 0, 1, 57, 0x80ba0ecd, S=1, 8
+0, 0, 1, 1, 24, 0x4f1c0660, F=0x0, S=1, 8
+0, 1, 2, 1, 24, 0x53dc06a0, F=0x0, S=1, 8
+0, 2, 3, 1, 24, 0x589c06e0, F=0x0, S=1, 8
+0, 3, 4, 1, 24, 0x4a700621, F=0x0, S=1, 8
+0, 4, 5, 1, 24, 0x4f300661, F=0x0, S=1, 8
+0, 5, 6, 1, 24, 0x53f006a1, F=0x0, S=1, 8
+0, 6, 7, 1, 24, 0x58b006e1, F=0x0, S=1, 8
+0, 7, 8, 1, 24, 0x4a840622, F=0x0, S=1, 8
+0, 8, 9, 1, 24, 0x4f440662, F=0x0, S=1, 8
+0, 9, 10, 1, 24, 0x540406a2, F=0x0, S=1, 8
+0, 10, 11, 1, 24, 0x58c406e2, F=0x0, S=1, 8
+0, 11, 12, 1, 24, 0x4a980623, F=0x0, S=1, 8
+0, 12, 13, 1, 24, 0x4f580663, F=0x0, S=1, 8
+0, 13, 14, 1, 24, 0x541806a3, F=0x0, S=1, 8
+0, 14, 15, 1, 24, 0x58d806e3, F=0x0, S=1, 8
+0, 15, 16, 1, 24, 0x4aac0624, F=0x0, S=1, 8
diff --git a/tests/ref/fate/force_key_frames-source-dup b/tests/ref/fate/force_key_frames-source-dup
new file mode 100644
index 0000000000..46fffc21f9
--- /dev/null
+++ b/tests/ref/fate/force_key_frames-source-dup
@@ -0,0 +1,617 @@
+#tb 0: 1/39
+#media_type 0: video
+#codec_id 0: mpeg2video
+#dimensions 0: 2x2
+#sar 0: 0/1
+0, -1, 0, 1, 57, 0x8baa0f1a, S=1, 8
+0, 0, 1, 1, 24, 0x4f1c0660, F=0x0, S=1, 8
+0, 1, 2, 1, 24, 0x53dc06a0, F=0x0, S=1, 8
+0, 2, 3, 1, 24, 0x589c06e0, F=0x0, S=1, 8
+0, 3, 4, 1, 24, 0x4a700621, F=0x0, S=1, 8
+0, 4, 5, 1, 24, 0x4f300661, F=0x0, S=1, 8
+0, 5, 6, 1, 24, 0x53f006a1, F=0x0, S=1, 8
+0, 6, 7, 1, 24, 0x58b006e1, F=0x0, S=1, 8
+0, 7, 8, 1, 24, 0x4a840622, F=0x0, S=1, 8
+0, 8, 9, 1, 24, 0x4f440662, F=0x0, S=1, 8
+0, 9, 10, 1, 24, 0x540406a2, F=0x0, S=1, 8
+0, 10, 11, 1, 24, 0x58c406e2, F=0x0, S=1, 8
+0, 11, 12, 1, 24, 0x4a980623, F=0x0, S=1, 8
+0, 12, 13, 1, 24, 0x4f580663, F=0x0, S=1, 8
+0, 13, 14, 1, 24, 0x541806a3, F=0x0, S=1, 8
+0, 14, 15, 1, 24, 0x58d806e3, F=0x0, S=1, 8
+0, 15, 16, 1, 24, 0x4aac0624, F=0x0, S=1, 8
+0, 16, 17, 1, 24, 0x4f6c0664, F=0x0, S=1, 8
+0, 17, 18, 1, 24, 0x542c06a4, F=0x0, S=1, 8
+0, 18, 19, 1, 24, 0x58ec06e4, F=0x0, S=1, 8
+0, 19, 20, 1, 24, 0x4ac00625, F=0x0, S=1, 8
+0, 20, 21, 1, 24, 0x4f800665, F=0x0, S=1, 8
+0, 21, 22, 1, 24, 0x544006a5, F=0x0, S=1, 8
+0, 22, 23, 1, 24, 0x590006e5, F=0x0, S=1, 8
+0, 23, 24, 1, 24, 0x4ad40626, F=0x0, S=1, 8
+0, 24, 25, 1, 24, 0x4f940666, F=0x0, S=1, 8
+0, 25, 26, 1, 24, 0x545406a6, F=0x0, S=1, 8
+0, 26, 27, 1, 24, 0x591406e6, F=0x0, S=1, 8
+0, 27, 28, 1, 24, 0x4ae80627, F=0x0, S=1, 8
+0, 28, 29, 1, 24, 0x4fa80667, F=0x0, S=1, 8
+0, 29, 30, 1, 24, 0x546806a7, F=0x0, S=1, 8
+0, 30, 31, 1, 24, 0x592806e7, F=0x0, S=1, 8
+0, 31, 32, 1, 24, 0x4afc0628, F=0x0, S=1, 8
+0, 32, 33, 1, 24, 0x4fbc0668, F=0x0, S=1, 8
+0, 33, 34, 1, 24, 0x547c06a8, F=0x0, S=1, 8
+0, 34, 35, 1, 24, 0x593c06e8, F=0x0, S=1, 8
+0, 35, 36, 1, 24, 0x4b100629, F=0x0, S=1, 8
+0, 36, 37, 1, 24, 0x4fd00669, F=0x0, S=1, 8
+0, 37, 38, 1, 24, 0x549006a9, F=0x0, S=1, 8
+0, 38, 39, 1, 24, 0x595006e9, F=0x0, S=1, 8
+0, 39, 40, 1, 24, 0x4b24062a, F=0x0, S=1, 8
+0, 40, 41, 1, 24, 0x4fe4066a, F=0x0, S=1, 8
+0, 41, 42, 1, 24, 0x54a406aa, F=0x0, S=1, 8
+0, 42, 43, 1, 24, 0x596406ea, F=0x0, S=1, 8
+0, 43, 44, 1, 24, 0x4b38062b, F=0x0, S=1, 8
+0, 44, 45, 1, 24, 0x4ff8066b, F=0x0, S=1, 8
+0, 45, 46, 1, 24, 0x54b806ab, F=0x0, S=1, 8
+0, 46, 47, 1, 24, 0x597806eb, F=0x0, S=1, 8
+0, 47, 48, 1, 24, 0x4b4c062c, F=0x0, S=1, 8
+0, 48, 49, 1, 24, 0x500c066c, F=0x0, S=1, 8
+0, 49, 50, 1, 24, 0x54cc06ac, F=0x0, S=1, 8
+0, 50, 51, 1, 24, 0x598c06ec, F=0x0, S=1, 8
+0, 51, 52, 1, 24, 0x4b60062d, F=0x0, S=1, 8
+0, 52, 53, 1, 24, 0x5020066d, F=0x0, S=1, 8
+0, 53, 54, 1, 24, 0x54e006ad, F=0x0, S=1, 8
+0, 54, 55, 1, 24, 0x59a006ed, F=0x0, S=1, 8
+0, 55, 56, 1, 24, 0x4b74062e, F=0x0, S=1, 8
+0, 56, 57, 1, 24, 0x5034066e, F=0x0, S=1, 8
+0, 57, 58, 1, 24, 0x54f406ae, F=0x0, S=1, 8
+0, 58, 59, 1, 24, 0x59b406ee, F=0x0, S=1, 8
+0, 59, 60, 1, 24, 0x4b88062f, F=0x0, S=1, 8
+0, 60, 61, 1, 24, 0x5048066f, F=0x0, S=1, 8
+0, 61, 62, 1, 24, 0x550806af, F=0x0, S=1, 8
+0, 62, 63, 1, 24, 0x59c806ef, F=0x0, S=1, 8
+0, 63, 64, 1, 24, 0x4b9c0630, F=0x0, S=1, 8
+0, 64, 65, 1, 24, 0x505c0670, F=0x0, S=1, 8
+0, 65, 66, 1, 24, 0x551c06b0, F=0x0, S=1, 8
+0, 66, 67, 1, 24, 0x59dc06f0, F=0x0, S=1, 8
+0, 67, 68, 1, 24, 0x4bb00631, F=0x0, S=1, 8
+0, 68, 69, 1, 24, 0x50700671, F=0x0, S=1, 8
+0, 69, 70, 1, 24, 0x553006b1, F=0x0, S=1, 8
+0, 70, 71, 1, 24, 0x59f006f1, F=0x0, S=1, 8
+0, 71, 72, 1, 24, 0x4bc40632, F=0x0, S=1, 8
+0, 72, 73, 1, 24, 0x50840672, F=0x0, S=1, 8
+0, 73, 74, 1, 24, 0x554406b2, F=0x0, S=1, 8
+0, 74, 75, 1, 24, 0x5a0406f2, F=0x0, S=1, 8
+0, 75, 76, 1, 24, 0x4bd80633, F=0x0, S=1, 8
+0, 76, 77, 1, 24, 0x50980673, F=0x0, S=1, 8
+0, 77, 78, 1, 24, 0x555806b3, F=0x0, S=1, 8
+0, 78, 79, 1, 24, 0x5a1806f3, F=0x0, S=1, 8
+0, 79, 80, 1, 24, 0x4bec0634, F=0x0, S=1, 8
+0, 80, 81, 1, 24, 0x50ac0674, F=0x0, S=1, 8
+0, 81, 82, 1, 24, 0x556c06b4, F=0x0, S=1, 8
+0, 82, 83, 1, 24, 0x5a2c06f4, F=0x0, S=1, 8
+0, 83, 84, 1, 24, 0x4c000635, F=0x0, S=1, 8
+0, 84, 85, 1, 24, 0x50c00675, F=0x0, S=1, 8
+0, 85, 86, 1, 24, 0x558006b5, F=0x0, S=1, 8
+0, 86, 87, 1, 24, 0x5a4006f5, F=0x0, S=1, 8
+0, 87, 88, 1, 24, 0x4c140636, F=0x0, S=1, 8
+0, 88, 89, 1, 24, 0x50d40676, F=0x0, S=1, 8
+0, 89, 90, 1, 24, 0x559406b6, F=0x0, S=1, 8
+0, 90, 91, 1, 24, 0x5a5406f6, F=0x0, S=1, 8
+0, 91, 92, 1, 24, 0x4c280637, F=0x0, S=1, 8
+0, 92, 93, 1, 24, 0x50e80677, F=0x0, S=1, 8
+0, 93, 94, 1, 24, 0x55a806b7, F=0x0, S=1, 8
+0, 94, 95, 1, 24, 0x5a6806f7, F=0x0, S=1, 8
+0, 95, 96, 1, 24, 0x4c3c0638, F=0x0, S=1, 8
+0, 96, 97, 1, 24, 0x50fc0678, F=0x0, S=1, 8
+0, 97, 98, 1, 24, 0x55bc06b8, F=0x0, S=1, 8
+0, 98, 99, 1, 24, 0x5a7c06f8, F=0x0, S=1, 8
+0, 99, 100, 1, 24, 0x4c500639, F=0x0, S=1, 8
+0, 100, 101, 1, 24, 0x51100679, F=0x0, S=1, 8
+0, 101, 102, 1, 24, 0x55d006b9, F=0x0, S=1, 8
+0, 102, 103, 1, 24, 0x5a9006f9, F=0x0, S=1, 8
+0, 103, 104, 1, 24, 0x4c64063a, F=0x0, S=1, 8
+0, 104, 105, 1, 24, 0x5124067a, F=0x0, S=1, 8
+0, 105, 106, 1, 24, 0x55e406ba, F=0x0, S=1, 8
+0, 106, 107, 1, 24, 0x5aa406fa, F=0x0, S=1, 8
+0, 107, 108, 1, 24, 0x4c78063b, F=0x0, S=1, 8
+0, 108, 109, 1, 24, 0x5138067b, F=0x0, S=1, 8
+0, 109, 110, 1, 24, 0x55f806bb, F=0x0, S=1, 8
+0, 110, 111, 1, 24, 0x5ab806fb, F=0x0, S=1, 8
+0, 111, 112, 1, 24, 0x4c8c063c, F=0x0, S=1, 8
+0, 112, 113, 1, 24, 0x514c067c, F=0x0, S=1, 8
+0, 113, 114, 1, 24, 0x560c06bc, F=0x0, S=1, 8
+0, 114, 115, 1, 24, 0x5acc06fc, F=0x0, S=1, 8
+0, 115, 116, 1, 24, 0x4ca0063d, F=0x0, S=1, 8
+0, 116, 117, 1, 24, 0x5160067d, F=0x0, S=1, 8
+0, 117, 118, 1, 24, 0x562006bd, F=0x0, S=1, 8
+0, 118, 119, 1, 24, 0x5ae006fd, F=0x0, S=1, 8
+0, 119, 120, 1, 24, 0x4cb4063e, F=0x0, S=1, 8
+0, 120, 121, 1, 24, 0x5174067e, F=0x0, S=1, 8
+0, 121, 122, 1, 24, 0x563406be, F=0x0, S=1, 8
+0, 122, 123, 1, 24, 0x5af406fe, F=0x0, S=1, 8
+0, 123, 124, 1, 24, 0x4cc8063f, F=0x0, S=1, 8
+0, 124, 125, 1, 24, 0x5188067f, F=0x0, S=1, 8
+0, 125, 126, 1, 24, 0x564806bf, F=0x0, S=1, 8
+0, 126, 127, 1, 24, 0x5b0806ff, F=0x0, S=1, 8
+0, 127, 128, 1, 24, 0x4cdc0640, F=0x0, S=1, 8
+0, 128, 129, 1, 24, 0x519c0680, F=0x0, S=1, 8
+0, 129, 130, 1, 24, 0x565c06c0, F=0x0, S=1, 8
+0, 130, 131, 1, 24, 0x5b1c0700, F=0x0, S=1, 8
+0, 131, 132, 1, 24, 0x4cf00641, F=0x0, S=1, 8
+0, 132, 133, 1, 24, 0x51b00681, F=0x0, S=1, 8
+0, 133, 134, 1, 24, 0x567006c1, F=0x0, S=1, 8
+0, 134, 135, 1, 24, 0x5b300701, F=0x0, S=1, 8
+0, 135, 136, 1, 24, 0x4d040642, F=0x0, S=1, 8
+0, 136, 137, 1, 24, 0x51c40682, F=0x0, S=1, 8
+0, 137, 138, 1, 24, 0x568406c2, F=0x0, S=1, 8
+0, 138, 139, 1, 24, 0x5b440702, F=0x0, S=1, 8
+0, 139, 140, 1, 24, 0x4d180643, F=0x0, S=1, 8
+0, 140, 141, 1, 24, 0x51d80683, F=0x0, S=1, 8
+0, 141, 142, 1, 24, 0x569806c3, F=0x0, S=1, 8
+0, 142, 143, 1, 24, 0x5b580703, F=0x0, S=1, 8
+0, 143, 144, 1, 24, 0x4d2c0644, F=0x0, S=1, 8
+0, 144, 145, 1, 24, 0x51ec0684, F=0x0, S=1, 8
+0, 145, 146, 1, 24, 0x56ac06c4, F=0x0, S=1, 8
+0, 146, 147, 1, 24, 0x5b6c0704, F=0x0, S=1, 8
+0, 147, 148, 1, 24, 0x4d400645, F=0x0, S=1, 8
+0, 148, 149, 1, 24, 0x52000685, F=0x0, S=1, 8
+0, 149, 150, 1, 24, 0x56c006c5, F=0x0, S=1, 8
+0, 150, 151, 1, 24, 0x5b800705, F=0x0, S=1, 8
+0, 151, 152, 1, 24, 0x4d540646, F=0x0, S=1, 8
+0, 152, 153, 1, 24, 0x52140686, F=0x0, S=1, 8
+0, 153, 154, 1, 24, 0x56d406c6, F=0x0, S=1, 8
+0, 154, 155, 1, 24, 0x5b940706, F=0x0, S=1, 8
+0, 155, 156, 1, 24, 0x4d680647, F=0x0, S=1, 8
+0, 156, 157, 1, 24, 0x52280687, F=0x0, S=1, 8
+0, 157, 158, 1, 24, 0x56e806c7, F=0x0, S=1, 8
+0, 158, 159, 1, 24, 0x5ba80707, F=0x0, S=1, 8
+0, 159, 160, 1, 24, 0x4d7c0648, F=0x0, S=1, 8
+0, 160, 161, 1, 24, 0x523c0688, F=0x0, S=1, 8
+0, 161, 162, 1, 24, 0x56fc06c8, F=0x0, S=1, 8
+0, 162, 163, 1, 24, 0x5bbc0708, F=0x0, S=1, 8
+0, 163, 164, 1, 24, 0x4d900649, F=0x0, S=1, 8
+0, 164, 165, 1, 24, 0x52500689, F=0x0, S=1, 8
+0, 165, 166, 1, 24, 0x571006c9, F=0x0, S=1, 8
+0, 166, 167, 1, 24, 0x5bd00709, F=0x0, S=1, 8
+0, 167, 168, 1, 57, 0x97cf0f83, S=1, 8
+0, 168, 169, 1, 24, 0x4f1c0660, F=0x0, S=1, 8
+0, 169, 170, 1, 24, 0x53dc06a0, F=0x0, S=1, 8
+0, 170, 171, 1, 24, 0x589c06e0, F=0x0, S=1, 8
+0, 171, 172, 1, 24, 0x4a700621, F=0x0, S=1, 8
+0, 172, 173, 1, 24, 0x4f300661, F=0x0, S=1, 8
+0, 173, 174, 1, 24, 0x53f006a1, F=0x0, S=1, 8
+0, 174, 175, 1, 24, 0x58b006e1, F=0x0, S=1, 8
+0, 175, 176, 1, 24, 0x4a840622, F=0x0, S=1, 8
+0, 176, 177, 1, 24, 0x4f440662, F=0x0, S=1, 8
+0, 177, 178, 1, 24, 0x540406a2, F=0x0, S=1, 8
+0, 178, 179, 1, 24, 0x58c406e2, F=0x0, S=1, 8
+0, 179, 180, 1, 24, 0x4a980623, F=0x0, S=1, 8
+0, 180, 181, 1, 24, 0x4f580663, F=0x0, S=1, 8
+0, 181, 182, 1, 24, 0x541806a3, F=0x0, S=1, 8
+0, 182, 183, 1, 24, 0x58d806e3, F=0x0, S=1, 8
+0, 183, 184, 1, 24, 0x4aac0624, F=0x0, S=1, 8
+0, 184, 185, 1, 24, 0x4f6c0664, F=0x0, S=1, 8
+0, 185, 186, 1, 24, 0x542c06a4, F=0x0, S=1, 8
+0, 186, 187, 1, 24, 0x58ec06e4, F=0x0, S=1, 8
+0, 187, 188, 1, 24, 0x4ac00625, F=0x0, S=1, 8
+0, 188, 189, 1, 24, 0x4f800665, F=0x0, S=1, 8
+0, 189, 190, 1, 24, 0x544006a5, F=0x0, S=1, 8
+0, 190, 191, 1, 24, 0x590006e5, F=0x0, S=1, 8
+0, 191, 192, 1, 24, 0x4ad40626, F=0x0, S=1, 8
+0, 192, 193, 1, 24, 0x4f940666, F=0x0, S=1, 8
+0, 193, 194, 1, 24, 0x545406a6, F=0x0, S=1, 8
+0, 194, 195, 1, 24, 0x591406e6, F=0x0, S=1, 8
+0, 195, 196, 1, 24, 0x4ae80627, F=0x0, S=1, 8
+0, 196, 197, 1, 24, 0x4fa80667, F=0x0, S=1, 8
+0, 197, 198, 1, 24, 0x546806a7, F=0x0, S=1, 8
+0, 198, 199, 1, 24, 0x592806e7, F=0x0, S=1, 8
+0, 199, 200, 1, 24, 0x4afc0628, F=0x0, S=1, 8
+0, 200, 201, 1, 24, 0x4fbc0668, F=0x0, S=1, 8
+0, 201, 202, 1, 24, 0x547c06a8, F=0x0, S=1, 8
+0, 202, 203, 1, 24, 0x593c06e8, F=0x0, S=1, 8
+0, 203, 204, 1, 24, 0x4b100629, F=0x0, S=1, 8
+0, 204, 205, 1, 24, 0x4fd00669, F=0x0, S=1, 8
+0, 205, 206, 1, 24, 0x549006a9, F=0x0, S=1, 8
+0, 206, 207, 1, 24, 0x595006e9, F=0x0, S=1, 8
+0, 207, 208, 1, 24, 0x4b24062a, F=0x0, S=1, 8
+0, 208, 209, 1, 24, 0x4fe4066a, F=0x0, S=1, 8
+0, 209, 210, 1, 24, 0x54a406aa, F=0x0, S=1, 8
+0, 210, 211, 1, 24, 0x596406ea, F=0x0, S=1, 8
+0, 211, 212, 1, 24, 0x4b38062b, F=0x0, S=1, 8
+0, 212, 213, 1, 24, 0x4ff8066b, F=0x0, S=1, 8
+0, 213, 214, 1, 24, 0x54b806ab, F=0x0, S=1, 8
+0, 214, 215, 1, 24, 0x597806eb, F=0x0, S=1, 8
+0, 215, 216, 1, 24, 0x4b4c062c, F=0x0, S=1, 8
+0, 216, 217, 1, 24, 0x500c066c, F=0x0, S=1, 8
+0, 217, 218, 1, 24, 0x54cc06ac, F=0x0, S=1, 8
+0, 218, 219, 1, 24, 0x598c06ec, F=0x0, S=1, 8
+0, 219, 220, 1, 24, 0x4b60062d, F=0x0, S=1, 8
+0, 220, 221, 1, 24, 0x5020066d, F=0x0, S=1, 8
+0, 221, 222, 1, 24, 0x54e006ad, F=0x0, S=1, 8
+0, 222, 223, 1, 24, 0x59a006ed, F=0x0, S=1, 8
+0, 223, 224, 1, 24, 0x4b74062e, F=0x0, S=1, 8
+0, 224, 225, 1, 24, 0x5034066e, F=0x0, S=1, 8
+0, 225, 226, 1, 24, 0x54f406ae, F=0x0, S=1, 8
+0, 226, 227, 1, 24, 0x59b406ee, F=0x0, S=1, 8
+0, 227, 228, 1, 24, 0x4b88062f, F=0x0, S=1, 8
+0, 228, 229, 1, 24, 0x5048066f, F=0x0, S=1, 8
+0, 229, 230, 1, 24, 0x550806af, F=0x0, S=1, 8
+0, 230, 231, 1, 24, 0x59c806ef, F=0x0, S=1, 8
+0, 231, 232, 1, 24, 0x4b9c0630, F=0x0, S=1, 8
+0, 232, 233, 1, 24, 0x505c0670, F=0x0, S=1, 8
+0, 233, 234, 1, 24, 0x551c06b0, F=0x0, S=1, 8
+0, 234, 235, 1, 24, 0x59dc06f0, F=0x0, S=1, 8
+0, 235, 236, 1, 24, 0x4bb00631, F=0x0, S=1, 8
+0, 236, 237, 1, 24, 0x50700671, F=0x0, S=1, 8
+0, 237, 238, 1, 24, 0x553006b1, F=0x0, S=1, 8
+0, 238, 239, 1, 24, 0x59f006f1, F=0x0, S=1, 8
+0, 239, 240, 1, 24, 0x4bc40632, F=0x0, S=1, 8
+0, 240, 241, 1, 24, 0x50840672, F=0x0, S=1, 8
+0, 241, 242, 1, 24, 0x554406b2, F=0x0, S=1, 8
+0, 242, 243, 1, 24, 0x5a0406f2, F=0x0, S=1, 8
+0, 243, 244, 1, 24, 0x4bd80633, F=0x0, S=1, 8
+0, 244, 245, 1, 24, 0x50980673, F=0x0, S=1, 8
+0, 245, 246, 1, 24, 0x555806b3, F=0x0, S=1, 8
+0, 246, 247, 1, 24, 0x5a1806f3, F=0x0, S=1, 8
+0, 247, 248, 1, 24, 0x4bec0634, F=0x0, S=1, 8
+0, 248, 249, 1, 24, 0x50ac0674, F=0x0, S=1, 8
+0, 249, 250, 1, 24, 0x556c06b4, F=0x0, S=1, 8
+0, 250, 251, 1, 24, 0x5a2c06f4, F=0x0, S=1, 8
+0, 251, 252, 1, 24, 0x4c000635, F=0x0, S=1, 8
+0, 252, 253, 1, 24, 0x50c00675, F=0x0, S=1, 8
+0, 253, 254, 1, 24, 0x558006b5, F=0x0, S=1, 8
+0, 254, 255, 1, 24, 0x5a4006f5, F=0x0, S=1, 8
+0, 255, 256, 1, 24, 0x4c140636, F=0x0, S=1, 8
+0, 256, 257, 1, 24, 0x50d40676, F=0x0, S=1, 8
+0, 257, 258, 1, 24, 0x559406b6, F=0x0, S=1, 8
+0, 258, 259, 1, 24, 0x5a5406f6, F=0x0, S=1, 8
+0, 259, 260, 1, 24, 0x4c280637, F=0x0, S=1, 8
+0, 260, 261, 1, 24, 0x50e80677, F=0x0, S=1, 8
+0, 261, 262, 1, 24, 0x55a806b7, F=0x0, S=1, 8
+0, 262, 263, 1, 24, 0x5a6806f7, F=0x0, S=1, 8
+0, 263, 264, 1, 24, 0x4c3c0638, F=0x0, S=1, 8
+0, 264, 265, 1, 24, 0x50fc0678, F=0x0, S=1, 8
+0, 265, 266, 1, 24, 0x55bc06b8, F=0x0, S=1, 8
+0, 266, 267, 1, 24, 0x5a7c06f8, F=0x0, S=1, 8
+0, 267, 268, 1, 24, 0x4c500639, F=0x0, S=1, 8
+0, 268, 269, 1, 24, 0x51100679, F=0x0, S=1, 8
+0, 269, 270, 1, 24, 0x55d006b9, F=0x0, S=1, 8
+0, 270, 271, 1, 24, 0x5a9006f9, F=0x0, S=1, 8
+0, 271, 272, 1, 24, 0x4c64063a, F=0x0, S=1, 8
+0, 272, 273, 1, 24, 0x5124067a, F=0x0, S=1, 8
+0, 273, 274, 1, 24, 0x55e406ba, F=0x0, S=1, 8
+0, 274, 275, 1, 24, 0x5aa406fa, F=0x0, S=1, 8
+0, 275, 276, 1, 24, 0x4c78063b, F=0x0, S=1, 8
+0, 276, 277, 1, 24, 0x5138067b, F=0x0, S=1, 8
+0, 277, 278, 1, 24, 0x55f806bb, F=0x0, S=1, 8
+0, 278, 279, 1, 24, 0x5ab806fb, F=0x0, S=1, 8
+0, 279, 280, 1, 24, 0x4c8c063c, F=0x0, S=1, 8
+0, 280, 281, 1, 24, 0x514c067c, F=0x0, S=1, 8
+0, 281, 282, 1, 24, 0x560c06bc, F=0x0, S=1, 8
+0, 282, 283, 1, 24, 0x5acc06fc, F=0x0, S=1, 8
+0, 283, 284, 1, 24, 0x4ca0063d, F=0x0, S=1, 8
+0, 284, 285, 1, 24, 0x5160067d, F=0x0, S=1, 8
+0, 285, 286, 1, 24, 0x562006bd, F=0x0, S=1, 8
+0, 286, 287, 1, 24, 0x5ae006fd, F=0x0, S=1, 8
+0, 287, 288, 1, 24, 0x4cb4063e, F=0x0, S=1, 8
+0, 288, 289, 1, 24, 0x5174067e, F=0x0, S=1, 8
+0, 289, 290, 1, 24, 0x563406be, F=0x0, S=1, 8
+0, 290, 291, 1, 24, 0x5af406fe, F=0x0, S=1, 8
+0, 291, 292, 1, 24, 0x4cc8063f, F=0x0, S=1, 8
+0, 292, 293, 1, 24, 0x5188067f, F=0x0, S=1, 8
+0, 293, 294, 1, 24, 0x564806bf, F=0x0, S=1, 8
+0, 294, 295, 1, 24, 0x5b0806ff, F=0x0, S=1, 8
+0, 295, 296, 1, 24, 0x4cdc0640, F=0x0, S=1, 8
+0, 296, 297, 1, 24, 0x519c0680, F=0x0, S=1, 8
+0, 297, 298, 1, 24, 0x565c06c0, F=0x0, S=1, 8
+0, 298, 299, 1, 24, 0x5b1c0700, F=0x0, S=1, 8
+0, 299, 300, 1, 24, 0x4cf00641, F=0x0, S=1, 8
+0, 300, 301, 1, 24, 0x51b00681, F=0x0, S=1, 8
+0, 301, 302, 1, 24, 0x567006c1, F=0x0, S=1, 8
+0, 302, 303, 1, 24, 0x5b300701, F=0x0, S=1, 8
+0, 303, 304, 1, 24, 0x4d040642, F=0x0, S=1, 8
+0, 304, 305, 1, 24, 0x51c40682, F=0x0, S=1, 8
+0, 305, 306, 1, 24, 0x568406c2, F=0x0, S=1, 8
+0, 306, 307, 1, 24, 0x5b440702, F=0x0, S=1, 8
+0, 307, 308, 1, 24, 0x4d180643, F=0x0, S=1, 8
+0, 308, 309, 1, 24, 0x51d80683, F=0x0, S=1, 8
+0, 309, 310, 1, 24, 0x569806c3, F=0x0, S=1, 8
+0, 310, 311, 1, 24, 0x5b580703, F=0x0, S=1, 8
+0, 311, 312, 1, 24, 0x4d2c0644, F=0x0, S=1, 8
+0, 312, 313, 1, 24, 0x51ec0684, F=0x0, S=1, 8
+0, 313, 314, 1, 24, 0x56ac06c4, F=0x0, S=1, 8
+0, 314, 315, 1, 24, 0x5b6c0704, F=0x0, S=1, 8
+0, 315, 316, 1, 24, 0x4d400645, F=0x0, S=1, 8
+0, 316, 317, 1, 24, 0x52000685, F=0x0, S=1, 8
+0, 317, 318, 1, 24, 0x56c006c5, F=0x0, S=1, 8
+0, 318, 319, 1, 24, 0x5b800705, F=0x0, S=1, 8
+0, 319, 320, 1, 24, 0x4d540646, F=0x0, S=1, 8
+0, 320, 321, 1, 24, 0x52140686, F=0x0, S=1, 8
+0, 321, 322, 1, 24, 0x56d406c6, F=0x0, S=1, 8
+0, 322, 323, 1, 24, 0x5b940706, F=0x0, S=1, 8
+0, 323, 324, 1, 24, 0x4d680647, F=0x0, S=1, 8
+0, 324, 325, 1, 24, 0x52280687, F=0x0, S=1, 8
+0, 325, 326, 1, 24, 0x56e806c7, F=0x0, S=1, 8
+0, 326, 327, 1, 24, 0x5ba80707, F=0x0, S=1, 8
+0, 327, 328, 1, 24, 0x4d7c0648, F=0x0, S=1, 8
+0, 328, 329, 1, 24, 0x523c0688, F=0x0, S=1, 8
+0, 329, 330, 1, 24, 0x56fc06c8, F=0x0, S=1, 8
+0, 330, 331, 1, 24, 0x5bbc0708, F=0x0, S=1, 8
+0, 331, 332, 1, 24, 0x4d900649, F=0x0, S=1, 8
+0, 332, 333, 1, 24, 0x52500689, F=0x0, S=1, 8
+0, 333, 334, 1, 24, 0x571006c9, F=0x0, S=1, 8
+0, 334, 335, 1, 24, 0x5bd00709, F=0x0, S=1, 8
+0, 335, 336, 1, 24, 0x4da4064a, F=0x0, S=1, 8
+0, 336, 337, 1, 24, 0x5264068a, F=0x0, S=1, 8
+0, 337, 338, 1, 24, 0x572406ca, F=0x0, S=1, 8
+0, 338, 339, 1, 24, 0x5be4070a, F=0x0, S=1, 8
+0, 339, 340, 1, 24, 0x4db8064b, F=0x0, S=1, 8
+0, 340, 341, 1, 24, 0x5278068b, F=0x0, S=1, 8
+0, 341, 342, 1, 24, 0x573806cb, F=0x0, S=1, 8
+0, 342, 343, 1, 24, 0x5bf8070b, F=0x0, S=1, 8
+0, 343, 344, 1, 24, 0x4dcc064c, F=0x0, S=1, 8
+0, 344, 345, 1, 24, 0x528c068c, F=0x0, S=1, 8
+0, 345, 346, 1, 24, 0x574c06cc, F=0x0, S=1, 8
+0, 346, 347, 1, 24, 0x5c0c070c, F=0x0, S=1, 8
+0, 347, 348, 1, 24, 0x4de0064d, F=0x0, S=1, 8
+0, 348, 349, 1, 24, 0x52a0068d, F=0x0, S=1, 8
+0, 349, 350, 1, 24, 0x576006cd, F=0x0, S=1, 8
+0, 350, 351, 1, 24, 0x5c20070d, F=0x0, S=1, 8
+0, 351, 352, 1, 24, 0x4df4064e, F=0x0, S=1, 8
+0, 352, 353, 1, 24, 0x52b4068e, F=0x0, S=1, 8
+0, 353, 354, 1, 24, 0x577406ce, F=0x0, S=1, 8
+0, 354, 355, 1, 24, 0x5c34070e, F=0x0, S=1, 8
+0, 355, 356, 1, 24, 0x4e08064f, F=0x0, S=1, 8
+0, 356, 357, 1, 24, 0x52c8068f, F=0x0, S=1, 8
+0, 357, 358, 1, 24, 0x578806cf, F=0x0, S=1, 8
+0, 358, 359, 1, 24, 0x5c48070f, F=0x0, S=1, 8
+0, 359, 360, 1, 24, 0x4e1c0650, F=0x0, S=1, 8
+0, 360, 361, 1, 24, 0x52dc0690, F=0x0, S=1, 8
+0, 361, 362, 1, 24, 0x579c06d0, F=0x0, S=1, 8
+0, 362, 363, 1, 24, 0x5c5c0710, F=0x0, S=1, 8
+0, 363, 364, 1, 24, 0x4e300651, F=0x0, S=1, 8
+0, 364, 365, 1, 24, 0x52f00691, F=0x0, S=1, 8
+0, 365, 366, 1, 24, 0x57b006d1, F=0x0, S=1, 8
+0, 366, 367, 1, 24, 0x5c700711, F=0x0, S=1, 8
+0, 367, 368, 1, 24, 0x4e440652, F=0x0, S=1, 8
+0, 368, 369, 1, 24, 0x53040692, F=0x0, S=1, 8
+0, 369, 370, 1, 24, 0x57c406d2, F=0x0, S=1, 8
+0, 370, 371, 1, 24, 0x5c840712, F=0x0, S=1, 8
+0, 371, 372, 1, 24, 0x4e580653, F=0x0, S=1, 8
+0, 372, 373, 1, 24, 0x53180693, F=0x0, S=1, 8
+0, 373, 374, 1, 24, 0x57d806d3, F=0x0, S=1, 8
+0, 374, 375, 1, 24, 0x5c980713, F=0x0, S=1, 8
+0, 375, 376, 1, 24, 0x4e6c0654, F=0x0, S=1, 8
+0, 376, 377, 1, 24, 0x532c0694, F=0x0, S=1, 8
+0, 377, 378, 1, 24, 0x57ec06d4, F=0x0, S=1, 8
+0, 378, 379, 1, 24, 0x5cac0714, F=0x0, S=1, 8
+0, 379, 380, 1, 24, 0x4e800655, F=0x0, S=1, 8
+0, 380, 381, 1, 24, 0x53400695, F=0x0, S=1, 8
+0, 381, 382, 1, 24, 0x580006d5, F=0x0, S=1, 8
+0, 382, 383, 1, 24, 0x5cc00715, F=0x0, S=1, 8
+0, 383, 384, 1, 24, 0x4e940656, F=0x0, S=1, 8
+0, 384, 385, 1, 24, 0x53540696, F=0x0, S=1, 8
+0, 385, 386, 1, 24, 0x581406d6, F=0x0, S=1, 8
+0, 386, 387, 1, 24, 0x5cd40716, F=0x0, S=1, 8
+0, 387, 388, 1, 24, 0x4ea80657, F=0x0, S=1, 8
+0, 388, 389, 1, 24, 0x53680697, F=0x0, S=1, 8
+0, 389, 390, 1, 24, 0x582806d7, F=0x0, S=1, 8
+0, 390, 391, 1, 24, 0x5ce80717, F=0x0, S=1, 8
+0, 391, 392, 1, 24, 0x4ebc0658, F=0x0, S=1, 8
+0, 392, 393, 1, 24, 0x537c0698, F=0x0, S=1, 8
+0, 393, 394, 1, 24, 0x583c06d8, F=0x0, S=1, 8
+0, 394, 395, 1, 24, 0x5cfc0718, F=0x0, S=1, 8
+0, 395, 396, 1, 24, 0x4ed00659, F=0x0, S=1, 8
+0, 396, 397, 1, 24, 0x53900699, F=0x0, S=1, 8
+0, 397, 398, 1, 24, 0x585006d9, F=0x0, S=1, 8
+0, 398, 399, 1, 24, 0x5d100719, F=0x0, S=1, 8
+0, 399, 400, 1, 24, 0x4ee4065a, F=0x0, S=1, 8
+0, 400, 401, 1, 24, 0x53a4069a, F=0x0, S=1, 8
+0, 401, 402, 1, 24, 0x586406da, F=0x0, S=1, 8
+0, 402, 403, 1, 24, 0x5d24071a, F=0x0, S=1, 8
+0, 403, 404, 1, 24, 0x4ef8065b, F=0x0, S=1, 8
+0, 404, 405, 1, 24, 0x53b8069b, F=0x0, S=1, 8
+0, 405, 406, 1, 24, 0x587806db, F=0x0, S=1, 8
+0, 406, 407, 1, 24, 0x5d38071b, F=0x0, S=1, 8
+0, 407, 408, 1, 24, 0x4f0c065c, F=0x0, S=1, 8
+0, 408, 409, 1, 24, 0x53cc069c, F=0x0, S=1, 8
+0, 409, 410, 1, 24, 0x588c06dc, F=0x0, S=1, 8
+0, 410, 411, 1, 24, 0x5d4c071c, F=0x0, S=1, 8
+0, 411, 412, 1, 24, 0x4f20065d, F=0x0, S=1, 8
+0, 412, 413, 1, 24, 0x53e0069d, F=0x0, S=1, 8
+0, 413, 414, 1, 24, 0x58a006dd, F=0x0, S=1, 8
+0, 414, 415, 1, 24, 0x5d60071d, F=0x0, S=1, 8
+0, 415, 416, 1, 24, 0x4f34065e, F=0x0, S=1, 8
+0, 416, 417, 1, 24, 0x53f4069e, F=0x0, S=1, 8
+0, 417, 418, 1, 24, 0x58b406de, F=0x0, S=1, 8
+0, 418, 419, 1, 24, 0x5d74071e, F=0x0, S=1, 8
+0, 419, 420, 1, 24, 0x4f48065f, F=0x0, S=1, 8
+0, 420, 421, 1, 24, 0x5408069f, F=0x0, S=1, 8
+0, 421, 422, 1, 24, 0x58c806df, F=0x0, S=1, 8
+0, 422, 423, 1, 24, 0x5d88071f, F=0x0, S=1, 8
+0, 423, 424, 1, 24, 0x4f5c0660, F=0x0, S=1, 8
+0, 424, 425, 1, 24, 0x541c06a0, F=0x0, S=1, 8
+0, 425, 426, 1, 24, 0x58dc06e0, F=0x0, S=1, 8
+0, 426, 427, 1, 24, 0x5d9c0720, F=0x0, S=1, 8
+0, 427, 428, 1, 24, 0x4f700661, F=0x0, S=1, 8
+0, 428, 429, 1, 24, 0x543006a1, F=0x0, S=1, 8
+0, 429, 430, 1, 24, 0x58f006e1, F=0x0, S=1, 8
+0, 430, 431, 1, 24, 0x5db00721, F=0x0, S=1, 8
+0, 431, 432, 1, 24, 0x4f840662, F=0x0, S=1, 8
+0, 432, 433, 1, 24, 0x544406a2, F=0x0, S=1, 8
+0, 433, 434, 1, 24, 0x590406e2, F=0x0, S=1, 8
+0, 434, 435, 1, 24, 0x5dc40722, F=0x0, S=1, 8
+0, 435, 436, 1, 24, 0x4f980663, F=0x0, S=1, 8
+0, 436, 437, 1, 24, 0x545806a3, F=0x0, S=1, 8
+0, 437, 438, 1, 24, 0x591806e3, F=0x0, S=1, 8
+0, 438, 439, 1, 24, 0x5dd80723, F=0x0, S=1, 8
+0, 439, 440, 1, 24, 0x4fac0664, F=0x0, S=1, 8
+0, 440, 441, 1, 24, 0x546c06a4, F=0x0, S=1, 8
+0, 441, 442, 1, 24, 0x592c06e4, F=0x0, S=1, 8
+0, 442, 443, 1, 24, 0x5dec0724, F=0x0, S=1, 8
+0, 443, 444, 1, 24, 0x4fc00665, F=0x0, S=1, 8
+0, 444, 445, 1, 24, 0x548006a5, F=0x0, S=1, 8
+0, 445, 446, 1, 24, 0x594006e5, F=0x0, S=1, 8
+0, 446, 447, 1, 24, 0x5e000725, F=0x0, S=1, 8
+0, 447, 448, 1, 24, 0x4fd40666, F=0x0, S=1, 8
+0, 448, 449, 1, 24, 0x549406a6, F=0x0, S=1, 8
+0, 449, 450, 1, 24, 0x595406e6, F=0x0, S=1, 8
+0, 450, 451, 1, 24, 0x5e140726, F=0x0, S=1, 8
+0, 451, 452, 1, 24, 0x4fe80667, F=0x0, S=1, 8
+0, 452, 453, 1, 24, 0x54a806a7, F=0x0, S=1, 8
+0, 453, 454, 1, 24, 0x596806e7, F=0x0, S=1, 8
+0, 454, 455, 1, 24, 0x5e280727, F=0x0, S=1, 8
+0, 455, 456, 1, 24, 0x4ffc0668, F=0x0, S=1, 8
+0, 456, 457, 1, 24, 0x54bc06a8, F=0x0, S=1, 8
+0, 457, 458, 1, 24, 0x597c06e8, F=0x0, S=1, 8
+0, 458, 459, 1, 24, 0x5e3c0728, F=0x0, S=1, 8
+0, 459, 460, 1, 24, 0x50100669, F=0x0, S=1, 8
+0, 460, 461, 1, 24, 0x54d006a9, F=0x0, S=1, 8
+0, 461, 462, 1, 24, 0x599006e9, F=0x0, S=1, 8
+0, 462, 463, 1, 24, 0x5e500729, F=0x0, S=1, 8
+0, 463, 464, 1, 24, 0x5024066a, F=0x0, S=1, 8
+0, 464, 465, 1, 24, 0x54e406aa, F=0x0, S=1, 8
+0, 465, 466, 1, 24, 0x59a406ea, F=0x0, S=1, 8
+0, 466, 467, 1, 24, 0x5e64072a, F=0x0, S=1, 8
+0, 467, 468, 1, 24, 0x5038066b, F=0x0, S=1, 8
+0, 468, 469, 1, 24, 0x54f806ab, F=0x0, S=1, 8
+0, 469, 470, 1, 24, 0x59b806eb, F=0x0, S=1, 8
+0, 470, 471, 1, 24, 0x5e78072b, F=0x0, S=1, 8
+0, 471, 472, 1, 24, 0x504c066c, F=0x0, S=1, 8
+0, 472, 473, 1, 24, 0x550c06ac, F=0x0, S=1, 8
+0, 473, 474, 1, 24, 0x59cc06ec, F=0x0, S=1, 8
+0, 474, 475, 1, 24, 0x5e8c072c, F=0x0, S=1, 8
+0, 475, 476, 1, 24, 0x5060066d, F=0x0, S=1, 8
+0, 476, 477, 1, 24, 0x552006ad, F=0x0, S=1, 8
+0, 477, 478, 1, 24, 0x59e006ed, F=0x0, S=1, 8
+0, 478, 479, 1, 24, 0x5ea0072d, F=0x0, S=1, 8
+0, 479, 480, 1, 24, 0x5074066e, F=0x0, S=1, 8
+0, 480, 481, 1, 24, 0x553406ae, F=0x0, S=1, 8
+0, 481, 482, 1, 24, 0x59f406ee, F=0x0, S=1, 8
+0, 482, 483, 1, 24, 0x5eb4072e, F=0x0, S=1, 8
+0, 483, 484, 1, 24, 0x5088066f, F=0x0, S=1, 8
+0, 484, 485, 1, 24, 0x554806af, F=0x0, S=1, 8
+0, 485, 486, 1, 24, 0x5a0806ef, F=0x0, S=1, 8
+0, 486, 487, 1, 24, 0x5ec8072f, F=0x0, S=1, 8
+0, 487, 488, 1, 24, 0x509c0670, F=0x0, S=1, 8
+0, 488, 489, 1, 24, 0x555c06b0, F=0x0, S=1, 8
+0, 489, 490, 1, 24, 0x5a1c06f0, F=0x0, S=1, 8
+0, 490, 491, 1, 24, 0x5edc0730, F=0x0, S=1, 8
+0, 491, 492, 1, 24, 0x50b00671, F=0x0, S=1, 8
+0, 492, 493, 1, 24, 0x557006b1, F=0x0, S=1, 8
+0, 493, 494, 1, 24, 0x5a3006f1, F=0x0, S=1, 8
+0, 494, 495, 1, 24, 0x5ef00731, F=0x0, S=1, 8
+0, 495, 496, 1, 24, 0x50c40672, F=0x0, S=1, 8
+0, 496, 497, 1, 24, 0x558406b2, F=0x0, S=1, 8
+0, 497, 498, 1, 24, 0x5a4406f2, F=0x0, S=1, 8
+0, 498, 499, 1, 24, 0x5f040732, F=0x0, S=1, 8
+0, 499, 500, 1, 24, 0x50d80673, F=0x0, S=1, 8
+0, 500, 501, 1, 24, 0x559806b3, F=0x0, S=1, 8
+0, 501, 502, 1, 24, 0x5a5806f3, F=0x0, S=1, 8
+0, 502, 503, 1, 24, 0x5f180733, F=0x0, S=1, 8
+0, 503, 504, 1, 24, 0x50ec0674, F=0x0, S=1, 8
+0, 504, 505, 1, 24, 0x55ac06b4, F=0x0, S=1, 8
+0, 505, 506, 1, 24, 0x5a6c06f4, F=0x0, S=1, 8
+0, 506, 507, 1, 24, 0x5f2c0734, F=0x0, S=1, 8
+0, 507, 508, 1, 24, 0x51000675, F=0x0, S=1, 8
+0, 508, 509, 1, 24, 0x55c006b5, F=0x0, S=1, 8
+0, 509, 510, 1, 24, 0x5a8006f5, F=0x0, S=1, 8
+0, 510, 511, 1, 24, 0x5f400735, F=0x0, S=1, 8
+0, 511, 512, 1, 24, 0x51140676, F=0x0, S=1, 8
+0, 512, 513, 1, 24, 0x55d406b6, F=0x0, S=1, 8
+0, 513, 514, 1, 24, 0x5a9406f6, F=0x0, S=1, 8
+0, 514, 515, 1, 24, 0x5f540736, F=0x0, S=1, 8
+0, 515, 516, 1, 24, 0x51280677, F=0x0, S=1, 8
+0, 516, 517, 1, 24, 0x55e806b7, F=0x0, S=1, 8
+0, 517, 518, 1, 24, 0x5aa806f7, F=0x0, S=1, 8
+0, 518, 519, 1, 24, 0x5f680737, F=0x0, S=1, 8
+0, 519, 520, 1, 24, 0x513c0678, F=0x0, S=1, 8
+0, 520, 521, 1, 24, 0x55fc06b8, F=0x0, S=1, 8
+0, 521, 522, 1, 24, 0x5abc06f8, F=0x0, S=1, 8
+0, 522, 523, 1, 24, 0x5f7c0738, F=0x0, S=1, 8
+0, 523, 524, 1, 24, 0x51500679, F=0x0, S=1, 8
+0, 524, 525, 1, 24, 0x561006b9, F=0x0, S=1, 8
+0, 525, 526, 1, 57, 0x896e0f04, S=1, 8
+0, 526, 527, 1, 24, 0x4f1c0660, F=0x0, S=1, 8
+0, 527, 528, 1, 24, 0x53dc06a0, F=0x0, S=1, 8
+0, 528, 529, 1, 24, 0x589c06e0, F=0x0, S=1, 8
+0, 529, 530, 1, 24, 0x4a700621, F=0x0, S=1, 8
+0, 530, 531, 1, 24, 0x4f300661, F=0x0, S=1, 8
+0, 531, 532, 1, 24, 0x53f006a1, F=0x0, S=1, 8
+0, 532, 533, 1, 24, 0x58b006e1, F=0x0, S=1, 8
+0, 533, 534, 1, 24, 0x4a840622, F=0x0, S=1, 8
+0, 534, 535, 1, 24, 0x4f440662, F=0x0, S=1, 8
+0, 535, 536, 1, 24, 0x540406a2, F=0x0, S=1, 8
+0, 536, 537, 1, 24, 0x58c406e2, F=0x0, S=1, 8
+0, 537, 538, 1, 24, 0x4a980623, F=0x0, S=1, 8
+0, 538, 539, 1, 24, 0x4f580663, F=0x0, S=1, 8
+0, 539, 540, 1, 24, 0x541806a3, F=0x0, S=1, 8
+0, 540, 541, 1, 24, 0x58d806e3, F=0x0, S=1, 8
+0, 541, 542, 1, 24, 0x4aac0624, F=0x0, S=1, 8
+0, 542, 543, 1, 24, 0x4f6c0664, F=0x0, S=1, 8
+0, 543, 544, 1, 24, 0x542c06a4, F=0x0, S=1, 8
+0, 544, 545, 1, 24, 0x58ec06e4, F=0x0, S=1, 8
+0, 545, 546, 1, 24, 0x4ac00625, F=0x0, S=1, 8
+0, 546, 547, 1, 24, 0x4f800665, F=0x0, S=1, 8
+0, 547, 548, 1, 24, 0x544006a5, F=0x0, S=1, 8
+0, 548, 549, 1, 24, 0x590006e5, F=0x0, S=1, 8
+0, 549, 550, 1, 24, 0x4ad40626, F=0x0, S=1, 8
+0, 550, 551, 1, 24, 0x4f940666, F=0x0, S=1, 8
+0, 551, 552, 1, 24, 0x545406a6, F=0x0, S=1, 8
+0, 552, 553, 1, 24, 0x591406e6, F=0x0, S=1, 8
+0, 553, 554, 1, 24, 0x4ae80627, F=0x0, S=1, 8
+0, 554, 555, 1, 24, 0x4fa80667, F=0x0, S=1, 8
+0, 555, 556, 1, 24, 0x546806a7, F=0x0, S=1, 8
+0, 556, 557, 1, 24, 0x592806e7, F=0x0, S=1, 8
+0, 557, 558, 1, 24, 0x4afc0628, F=0x0, S=1, 8
+0, 558, 559, 1, 24, 0x4fbc0668, F=0x0, S=1, 8
+0, 559, 560, 1, 24, 0x547c06a8, F=0x0, S=1, 8
+0, 560, 561, 1, 24, 0x593c06e8, F=0x0, S=1, 8
+0, 561, 562, 1, 24, 0x4b100629, F=0x0, S=1, 8
+0, 562, 563, 1, 24, 0x4fd00669, F=0x0, S=1, 8
+0, 563, 564, 1, 24, 0x549006a9, F=0x0, S=1, 8
+0, 564, 565, 1, 24, 0x595006e9, F=0x0, S=1, 8
+0, 565, 566, 1, 24, 0x4b24062a, F=0x0, S=1, 8
+0, 566, 567, 1, 24, 0x4fe4066a, F=0x0, S=1, 8
+0, 567, 568, 1, 24, 0x54a406aa, F=0x0, S=1, 8
+0, 568, 569, 1, 24, 0x596406ea, F=0x0, S=1, 8
+0, 569, 570, 1, 24, 0x4b38062b, F=0x0, S=1, 8
+0, 570, 571, 1, 24, 0x4ff8066b, F=0x0, S=1, 8
+0, 571, 572, 1, 24, 0x54b806ab, F=0x0, S=1, 8
+0, 572, 573, 1, 24, 0x597806eb, F=0x0, S=1, 8
+0, 573, 574, 1, 24, 0x4b4c062c, F=0x0, S=1, 8
+0, 574, 575, 1, 24, 0x500c066c, F=0x0, S=1, 8
+0, 575, 576, 1, 57, 0x901d0f3f, S=1, 8
+0, 576, 577, 1, 24, 0x4f1c0660, F=0x0, S=1, 8
+0, 577, 578, 1, 24, 0x53dc06a0, F=0x0, S=1, 8
+0, 578, 579, 1, 24, 0x589c06e0, F=0x0, S=1, 8
+0, 579, 580, 1, 24, 0x4a700621, F=0x0, S=1, 8
+0, 580, 581, 1, 24, 0x4f300661, F=0x0, S=1, 8
+0, 581, 582, 1, 24, 0x53f006a1, F=0x0, S=1, 8
+0, 582, 583, 1, 24, 0x58b006e1, F=0x0, S=1, 8
+0, 583, 584, 1, 24, 0x4a840622, F=0x0, S=1, 8
+0, 584, 585, 1, 24, 0x4f440662, F=0x0, S=1, 8
+0, 585, 586, 1, 24, 0x540406a2, F=0x0, S=1, 8
+0, 586, 587, 1, 24, 0x58c406e2, F=0x0, S=1, 8
+0, 587, 588, 1, 24, 0x4a980623, F=0x0, S=1, 8
+0, 588, 589, 1, 24, 0x4f580663, F=0x0, S=1, 8
+0, 589, 590, 1, 24, 0x541806a3, F=0x0, S=1, 8
+0, 590, 591, 1, 24, 0x58d806e3, F=0x0, S=1, 8
+0, 591, 592, 1, 24, 0x4aac0624, F=0x0, S=1, 8
+0, 592, 593, 1, 24, 0x4f6c0664, F=0x0, S=1, 8
+0, 593, 594, 1, 24, 0x542c06a4, F=0x0, S=1, 8
+0, 594, 595, 1, 24, 0x58ec06e4, F=0x0, S=1, 8
+0, 595, 596, 1, 24, 0x4ac00625, F=0x0, S=1, 8
+0, 596, 597, 1, 24, 0x4f800665, F=0x0, S=1, 8
+0, 597, 598, 1, 24, 0x544006a5, F=0x0, S=1, 8
+0, 598, 599, 1, 24, 0x590006e5, F=0x0, S=1, 8
+0, 599, 600, 1, 24, 0x4ad40626, F=0x0, S=1, 8
+0, 600, 601, 1, 24, 0x4f940666, F=0x0, S=1, 8
+0, 601, 602, 1, 24, 0x545406a6, F=0x0, S=1, 8
+0, 602, 603, 1, 24, 0x591406e6, F=0x0, S=1, 8
+0, 603, 604, 1, 24, 0x4ae80627, F=0x0, S=1, 8
+0, 604, 605, 1, 24, 0x4fa80667, F=0x0, S=1, 8
+0, 605, 606, 1, 24, 0x546806a7, F=0x0, S=1, 8
+0, 606, 607, 1, 24, 0x592806e7, F=0x0, S=1, 8
+0, 607, 608, 1, 24, 0x4afc0628, F=0x0, S=1, 8
+0, 608, 609, 1, 24, 0x4fbc0668, F=0x0, S=1, 8
+0, 609, 610, 1, 24, 0x547c06a8, F=0x0, S=1, 8
+0, 610, 611, 1, 24, 0x593c06e8, F=0x0, S=1, 8
--
2.40.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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 06/12] fftools/ffmpeg_enc: unbreak -force_key_frames source_no_drop
2023-10-03 15:35 [FFmpeg-devel] [PATCH 01/12] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process() Anton Khirnov
` (3 preceding siblings ...)
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 05/12] tests/fate/ffmpeg: add tests for -force_key_frames source Anton Khirnov
@ 2023-10-03 15:35 ` Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 07/12] fftools/ffmpeg_enc: merge -force_key_frames source/source_no_drop Anton Khirnov
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Anton Khirnov @ 2023-10-03 15:35 UTC (permalink / raw)
To: ffmpeg-devel
Unlike the 'source' mode, which preserves source keyframe-marking as-is,
the 'source_no_drop' mode attempts to keep track of keyframes dropped by
framerate conversion and mark the next output frame as key in such
cases. However,
* c75be061487 broke this functionality entirely, and made it equivalent
to 'source'
* even before it would only work when the frame immediately following
the dropped keyframe is preserved and not dropped as well
Also, drop a redundant check for 'frame' in setting dropped_keyframe, as
it is redundant with the check on the above line.
---
fftools/ffmpeg_enc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index b928bf208c..42f64a4a49 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -1066,7 +1066,7 @@ finish:
}
ost->last_dropped = *nb_frames == *nb_frames_prev && frame;
- ost->kf.dropped_keyframe = ost->last_dropped && frame && (frame->flags & AV_FRAME_FLAG_KEY);
+ ost->kf.dropped_keyframe |= ost->last_dropped && (frame->flags & AV_FRAME_FLAG_KEY);
}
static enum AVPictureType forced_kf_apply(void *logctx, KeyframeForceCtx *kf,
@@ -1109,8 +1109,9 @@ static enum AVPictureType forced_kf_apply(void *logctx, KeyframeForceCtx *kf,
(in_picture->flags & AV_FRAME_FLAG_KEY) && !dup_idx) {
goto force_keyframe;
} else if (kf->type == KF_FORCE_SOURCE_NO_DROP && !dup_idx) {
+ int dropped_keyframe = kf->dropped_keyframe;
kf->dropped_keyframe = 0;
- if ((in_picture->flags & AV_FRAME_FLAG_KEY) || kf->dropped_keyframe)
+ if ((in_picture->flags & AV_FRAME_FLAG_KEY) || dropped_keyframe)
goto force_keyframe;
}
--
2.40.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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 07/12] fftools/ffmpeg_enc: merge -force_key_frames source/source_no_drop
2023-10-03 15:35 [FFmpeg-devel] [PATCH 01/12] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process() Anton Khirnov
` (4 preceding siblings ...)
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 06/12] fftools/ffmpeg_enc: unbreak -force_key_frames source_no_drop Anton Khirnov
@ 2023-10-03 15:35 ` Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 08/12] fftools/ffmpeg: stop accessing OutputStream.last_dropped in print_report() Anton Khirnov
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Anton Khirnov @ 2023-10-03 15:35 UTC (permalink / raw)
To: ffmpeg-devel
Always use the functionality of the latter, which makes more sense as it
avoids losing keyframes due to vsync code dropping frames.
Deprecate the 'source_no_drop' value, as it is now redundant.
---
doc/ffmpeg.texi | 5 -----
fftools/ffmpeg.h | 3 +++
fftools/ffmpeg_enc.c | 5 +----
fftools/ffmpeg_mux_init.c | 6 +++++-
tests/ref/fate/force_key_frames-source-drop | 22 ++++++++++-----------
5 files changed, 20 insertions(+), 21 deletions(-)
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index d2864ff37e..ea473e14e8 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -1060,7 +1060,6 @@ 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:
@@ -1121,10 +1120,6 @@ starting from second 13:
@item source
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.
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 2e8f1db9b6..eaa663e718 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -58,6 +58,7 @@
#define FFMPEG_OPT_ADRIFT_THRESHOLD 1
#define FFMPEG_OPT_ENC_TIME_BASE_NUM 1
#define FFMPEG_OPT_TOP 1
+#define FFMPEG_OPT_FORCE_KF_SOURCE_NO_DROP 1
enum VideoSyncMethod {
VSYNC_AUTO = -1,
@@ -484,7 +485,9 @@ typedef enum {
enum {
KF_FORCE_SOURCE = 1,
+#if FFMPEG_OPT_FORCE_KF_SOURCE_NO_DROP
KF_FORCE_SOURCE_NO_DROP = 2,
+#endif
};
typedef struct KeyframeForceCtx {
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 42f64a4a49..b1cc60e350 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -1105,10 +1105,7 @@ static enum AVPictureType forced_kf_apply(void *logctx, KeyframeForceCtx *kf,
kf->expr_const_values[FKF_N_FORCED] += 1;
goto force_keyframe;
}
- } else if (kf->type == KF_FORCE_SOURCE &&
- (in_picture->flags & AV_FRAME_FLAG_KEY) && !dup_idx) {
- goto force_keyframe;
- } else if (kf->type == KF_FORCE_SOURCE_NO_DROP && !dup_idx) {
+ } else if (kf->type == KF_FORCE_SOURCE && !dup_idx) {
int dropped_keyframe = kf->dropped_keyframe;
kf->dropped_keyframe = 0;
if ((in_picture->flags & AV_FRAME_FLAG_KEY) || dropped_keyframe)
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index 9d6f442068..f35680e355 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -2509,8 +2509,12 @@ static int process_forced_keyframes(Muxer *mux, const OptionsContext *o)
// parse it only for static kf timings
} else if (!strcmp(forced_keyframes, "source")) {
ost->kf.type = KF_FORCE_SOURCE;
+#if FFMPEG_OPT_FORCE_KF_SOURCE_NO_DROP
} else if (!strcmp(forced_keyframes, "source_no_drop")) {
- ost->kf.type = KF_FORCE_SOURCE_NO_DROP;
+ av_log(ost, AV_LOG_WARNING, "The 'source_no_drop' value for "
+ "-force_key_frames is deprecated, use just 'source'\n");
+ ost->kf.type = KF_FORCE_SOURCE;
+#endif
} else {
int ret = parse_forced_key_frames(ost, &ost->kf, mux, forced_keyframes);
if (ret < 0)
diff --git a/tests/ref/fate/force_key_frames-source-drop b/tests/ref/fate/force_key_frames-source-drop
index 99aa2ae826..220c0f0f88 100644
--- a/tests/ref/fate/force_key_frames-source-drop
+++ b/tests/ref/fate/force_key_frames-source-drop
@@ -9,14 +9,14 @@
0, 2, 3, 1, 24, 0x589c06e0, F=0x0, S=1, 8
0, 3, 4, 1, 24, 0x4a700621, F=0x0, S=1, 8
0, 4, 5, 1, 24, 0x4f300661, F=0x0, S=1, 8
-0, 5, 6, 1, 24, 0x53f006a1, F=0x0, S=1, 8
-0, 6, 7, 1, 24, 0x58b006e1, F=0x0, S=1, 8
-0, 7, 8, 1, 24, 0x4a840622, F=0x0, S=1, 8
-0, 8, 9, 1, 24, 0x4f440662, F=0x0, S=1, 8
-0, 9, 10, 1, 24, 0x540406a2, F=0x0, S=1, 8
-0, 10, 11, 1, 24, 0x58c406e2, F=0x0, S=1, 8
-0, 11, 12, 1, 24, 0x4a980623, F=0x0, S=1, 8
-0, 12, 13, 1, 24, 0x4f580663, F=0x0, S=1, 8
-0, 13, 14, 1, 24, 0x541806a3, F=0x0, S=1, 8
-0, 14, 15, 1, 24, 0x58d806e3, F=0x0, S=1, 8
-0, 15, 16, 1, 24, 0x4aac0624, F=0x0, S=1, 8
+0, 5, 6, 1, 57, 0x7a110e90, S=1, 8
+0, 6, 7, 1, 24, 0x4f1c0660, F=0x0, S=1, 8
+0, 7, 8, 1, 24, 0x53dc06a0, F=0x0, S=1, 8
+0, 8, 9, 1, 24, 0x589c06e0, F=0x0, S=1, 8
+0, 9, 10, 1, 24, 0x4a700621, F=0x0, S=1, 8
+0, 10, 11, 1, 24, 0x4f300661, F=0x0, S=1, 8
+0, 11, 12, 1, 24, 0x53f006a1, F=0x0, S=1, 8
+0, 12, 13, 1, 24, 0x58b006e1, F=0x0, S=1, 8
+0, 13, 14, 1, 24, 0x4a840622, F=0x0, S=1, 8
+0, 14, 15, 1, 57, 0x88850f14, S=1, 8
+0, 15, 16, 1, 57, 0x7aa20e95, S=1, 8
--
2.40.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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 08/12] fftools/ffmpeg: stop accessing OutputStream.last_dropped in print_report()
2023-10-03 15:35 [FFmpeg-devel] [PATCH 01/12] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process() Anton Khirnov
` (5 preceding siblings ...)
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 07/12] fftools/ffmpeg_enc: merge -force_key_frames source/source_no_drop Anton Khirnov
@ 2023-10-03 15:35 ` Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 09/12] fftools/ffmpeg_enc: move framerate conversion state into a separate struct Anton Khirnov
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Anton Khirnov @ 2023-10-03 15:35 UTC (permalink / raw)
To: ffmpeg-devel
That field is used by the framerate code to track whether any output has
been generated for the last input frame(*). Its use in the last
invocation of print_report() is meant to account for the very last
filtered frame being dropped in the number of dropped frames printed in
the log. However, that is a highly inappropriate place to do so, as it
makes assumptions about vsync logic in completely unrelated code. Move
the increment to encoder flush instead.
(*) the name is misleading, as the input frame has not yet been dropped
and may still be output in the future
---
fftools/ffmpeg.c | 3 ---
fftools/ffmpeg_enc.c | 3 +++
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 14f55cbec7..a854589bef 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -566,9 +566,6 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
pts -= copy_ts_first_pts;
}
}
-
- if (is_last_report)
- nb_frames_drop += ost->last_dropped;
}
us = FFABS64U(pts) % AV_TIME_BASE;
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index b1cc60e350..29d0581cc7 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -761,6 +761,9 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame)
if (frame->sample_aspect_ratio.num && !ost->frame_aspect_ratio.num)
enc->sample_aspect_ratio = frame->sample_aspect_ratio;
+ } else if (ost->last_dropped) {
+ ost->nb_frames_drop++;
+ ost->last_dropped = 0;
}
update_benchmark(NULL);
--
2.40.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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 09/12] fftools/ffmpeg_enc: move framerate conversion state into a separate struct
2023-10-03 15:35 [FFmpeg-devel] [PATCH 01/12] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process() Anton Khirnov
` (6 preceding siblings ...)
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 08/12] fftools/ffmpeg: stop accessing OutputStream.last_dropped in print_report() Anton Khirnov
@ 2023-10-03 15:35 ` Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 10/12] fftools/ffmpeg_enc: move fps conversion code to ffmpeg_filter Anton Khirnov
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Anton Khirnov @ 2023-10-03 15:35 UTC (permalink / raw)
To: ffmpeg-devel
Makes it more clear what state is specific to framerate conversion,
which will be useful in the following commit.
---
fftools/ffmpeg_enc.c | 65 ++++++++++++++++++++++++--------------------
1 file changed, 35 insertions(+), 30 deletions(-)
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 29d0581cc7..f7ac054e25 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -41,18 +41,24 @@
#include "libavformat/avformat.h"
-struct Encoder {
- /* predicted pts of the next frame to be encoded */
- int64_t next_pts;
-
+typedef struct FPSConvContext {
AVFrame *last_frame;
/* number of frames emitted by the video-encoding sync code */
- int64_t vsync_frame_number;
+ int64_t frame_number;
/* history of nb_frames_prev, i.e. the number of times the
* previous frame was duplicated by vsync code in recent
* do_video_out() calls */
int64_t frames_prev_hist[3];
+ uint64_t dup_warning;
+} FPSConvContext;
+
+struct Encoder {
+ /* predicted pts of the next frame to be encoded */
+ int64_t next_pts;
+
+ FPSConvContext fps;
+
AVFrame *sq_frame;
// packet for receiving encoded output
@@ -64,8 +70,6 @@ struct Encoder {
// number of packets received from the encoder
uint64_t packets_encoded;
- uint64_t dup_warning;
-
int opened;
};
@@ -76,7 +80,7 @@ void enc_free(Encoder **penc)
if (!enc)
return;
- av_frame_free(&enc->last_frame);
+ av_frame_free(&enc->fps.last_frame);
av_frame_free(&enc->sq_frame);
av_packet_free(&enc->pkt);
@@ -95,17 +99,17 @@ int enc_alloc(Encoder **penc, const AVCodec *codec)
return AVERROR(ENOMEM);
if (codec->type == AVMEDIA_TYPE_VIDEO) {
- enc->last_frame = av_frame_alloc();
- if (!enc->last_frame)
+ enc->fps.last_frame = av_frame_alloc();
+ if (!enc->fps.last_frame)
goto fail;
+
+ enc->fps.dup_warning = 1000;
}
enc->pkt = av_packet_alloc();
if (!enc->pkt)
goto fail;
- enc->dup_warning = 1000;
-
*penc = enc;
return 0;
@@ -966,13 +970,14 @@ static void video_sync_process(OutputFile *of, OutputStream *ost, AVFrame *frame
int64_t *nb_frames, int64_t *nb_frames_prev)
{
Encoder *e = ost->enc;
+ FPSConvContext *fps = &e->fps;
AVCodecContext *enc = ost->enc_ctx;
double delta0, delta, sync_ipts, duration;
if (!frame) {
- *nb_frames_prev = *nb_frames = mid_pred(e->frames_prev_hist[0],
- e->frames_prev_hist[1],
- e->frames_prev_hist[2]);
+ *nb_frames_prev = *nb_frames = mid_pred(fps->frames_prev_hist[0],
+ fps->frames_prev_hist[1],
+ fps->frames_prev_hist[2]);
goto finish;
}
@@ -1006,7 +1011,7 @@ static void video_sync_process(OutputFile *of, OutputStream *ost, AVFrame *frame
switch (ost->vsync_method) {
case VSYNC_VSCFR:
- if (e->vsync_frame_number == 0 && delta0 >= 0.5) {
+ if (fps->frame_number == 0 && delta0 >= 0.5) {
av_log(ost, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0));
delta = duration;
delta0 = 0;
@@ -1014,7 +1019,7 @@ static void video_sync_process(OutputFile *of, OutputStream *ost, AVFrame *frame
}
case VSYNC_CFR:
// FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
- if (frame_drop_threshold && delta < frame_drop_threshold && e->vsync_frame_number) {
+ if (frame_drop_threshold && delta < frame_drop_threshold && fps->frame_number) {
*nb_frames = 0;
} else if (delta < -1.1)
*nb_frames = 0;
@@ -1042,16 +1047,16 @@ static void video_sync_process(OutputFile *of, OutputStream *ost, AVFrame *frame
}
finish:
- memmove(e->frames_prev_hist + 1,
- e->frames_prev_hist,
- sizeof(e->frames_prev_hist[0]) * (FF_ARRAY_ELEMS(e->frames_prev_hist) - 1));
- e->frames_prev_hist[0] = *nb_frames_prev;
+ memmove(fps->frames_prev_hist + 1,
+ fps->frames_prev_hist,
+ sizeof(fps->frames_prev_hist[0]) * (FF_ARRAY_ELEMS(fps->frames_prev_hist) - 1));
+ fps->frames_prev_hist[0] = *nb_frames_prev;
if (*nb_frames_prev == 0 && ost->last_dropped) {
ost->nb_frames_drop++;
av_log(ost, AV_LOG_VERBOSE,
"*** dropping frame %"PRId64" at ts %"PRId64"\n",
- e->vsync_frame_number, e->last_frame->pts);
+ fps->frame_number, fps->last_frame->pts);
}
if (*nb_frames > (*nb_frames_prev && ost->last_dropped) + (*nb_frames > *nb_frames_prev)) {
if (*nb_frames > dts_error_threshold * 30) {
@@ -1062,9 +1067,9 @@ finish:
}
ost->nb_frames_dup += *nb_frames - (*nb_frames_prev && ost->last_dropped) - (*nb_frames > *nb_frames_prev);
av_log(ost, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", *nb_frames - 1);
- if (ost->nb_frames_dup > e->dup_warning) {
- av_log(ost, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", e->dup_warning);
- e->dup_warning *= 10;
+ if (ost->nb_frames_dup > fps->dup_warning) {
+ av_log(ost, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", fps->dup_warning);
+ fps->dup_warning *= 10;
}
}
@@ -1137,8 +1142,8 @@ static int do_video_out(OutputFile *of, OutputStream *ost, AVFrame *frame)
for (i = 0; i < nb_frames; i++) {
AVFrame *in_picture;
- if (i < nb_frames_prev && e->last_frame->buf[0]) {
- in_picture = e->last_frame;
+ if (i < nb_frames_prev && e->fps.last_frame->buf[0]) {
+ in_picture = e->fps.last_frame;
} else
in_picture = frame;
@@ -1167,12 +1172,12 @@ static int do_video_out(OutputFile *of, OutputStream *ost, AVFrame *frame)
return ret;
e->next_pts++;
- e->vsync_frame_number++;
+ e->fps.frame_number++;
}
- av_frame_unref(e->last_frame);
+ av_frame_unref(e->fps.last_frame);
if (frame)
- av_frame_move_ref(e->last_frame, frame);
+ av_frame_move_ref(e->fps.last_frame, frame);
return 0;
}
--
2.40.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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 10/12] fftools/ffmpeg_enc: move fps conversion code to ffmpeg_filter
2023-10-03 15:35 [FFmpeg-devel] [PATCH 01/12] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process() Anton Khirnov
` (7 preceding siblings ...)
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 09/12] fftools/ffmpeg_enc: move framerate conversion state into a separate struct Anton Khirnov
@ 2023-10-03 15:35 ` Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 11/12] fftools/ffmpeg_filter: fail on filtering errors Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 12/12] fftools/ffmpeg_enc: constify the frame passed to enc_open() Anton Khirnov
10 siblings, 0 replies; 12+ messages in thread
From: Anton Khirnov @ 2023-10-03 15:35 UTC (permalink / raw)
To: ffmpeg-devel
Its function is analogous to that of the fps filter, so filtering is a
more appropriate place for this.
The main practical reason for this move is that it places the encoding
sync queue right at the boundary between filters and encoders. This will
be important when switching to threaded scheduling, as the sync queue
involves multiple streams and will thus need to do nontrivial
inter-thread synchronization.
In addition to framerate conversion, the closely-related
* encoder timebase selection
* applying the start_time offset
are also moved to filtering.
---
fftools/ffmpeg.c | 6 +-
fftools/ffmpeg.h | 7 +-
fftools/ffmpeg_enc.c | 370 +++-------------------------------
fftools/ffmpeg_filter.c | 432 ++++++++++++++++++++++++++++++++++++++--
4 files changed, 442 insertions(+), 373 deletions(-)
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index a854589bef..7c33b56cd3 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -536,7 +536,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
ost->file_index, ost->index, q);
}
- if (!vid && ost->type == AVMEDIA_TYPE_VIDEO) {
+ if (!vid && ost->type == AVMEDIA_TYPE_VIDEO && ost->filter) {
float fps;
uint64_t frame_number = atomic_load(&ost->packets_written);
@@ -550,8 +550,8 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
if (is_last_report)
av_bprintf(&buf, "L");
- nb_frames_dup = ost->nb_frames_dup;
- nb_frames_drop = ost->nb_frames_drop;
+ nb_frames_dup = ost->filter->nb_frames_dup;
+ nb_frames_drop = ost->filter->nb_frames_drop;
vid = 1;
}
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index eaa663e718..15790d3e0c 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -302,6 +302,9 @@ typedef struct OutputFilter {
/* pts of the last frame received from this filter, in AV_TIME_BASE_Q */
int64_t last_pts;
+
+ uint64_t nb_frames_dup;
+ uint64_t nb_frames_drop;
} OutputFilter;
typedef struct FilterGraph {
@@ -536,10 +539,6 @@ typedef struct OutputStream {
Encoder *enc;
AVCodecContext *enc_ctx;
- uint64_t nb_frames_dup;
- uint64_t nb_frames_drop;
- int64_t last_dropped;
-
/* video only */
AVRational frame_rate;
AVRational max_frame_rate;
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index f7ac054e25..321554ab5c 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -36,29 +36,9 @@
#include "libavcodec/avcodec.h"
-// FIXME private header, used for mid_pred()
-#include "libavcodec/mathops.h"
-
#include "libavformat/avformat.h"
-typedef struct FPSConvContext {
- AVFrame *last_frame;
- /* number of frames emitted by the video-encoding sync code */
- int64_t frame_number;
- /* history of nb_frames_prev, i.e. the number of times the
- * previous frame was duplicated by vsync code in recent
- * do_video_out() calls */
- int64_t frames_prev_hist[3];
-
- uint64_t dup_warning;
-} FPSConvContext;
-
struct Encoder {
- /* predicted pts of the next frame to be encoded */
- int64_t next_pts;
-
- FPSConvContext fps;
-
AVFrame *sq_frame;
// packet for receiving encoded output
@@ -80,7 +60,6 @@ void enc_free(Encoder **penc)
if (!enc)
return;
- av_frame_free(&enc->fps.last_frame);
av_frame_free(&enc->sq_frame);
av_packet_free(&enc->pkt);
@@ -98,14 +77,6 @@ int enc_alloc(Encoder **penc, const AVCodec *codec)
if (!enc)
return AVERROR(ENOMEM);
- if (codec->type == AVMEDIA_TYPE_VIDEO) {
- enc->fps.last_frame = av_frame_alloc();
- if (!enc->fps.last_frame)
- goto fail;
-
- enc->fps.dup_warning = 1000;
- }
-
enc->pkt = av_packet_alloc();
if (!enc->pkt)
goto fail;
@@ -194,98 +165,6 @@ static int set_encoder_id(OutputFile *of, OutputStream *ost)
return 0;
}
-static int enc_choose_timebase(OutputStream *ost, AVFrame *frame)
-{
- const OutputFile *of = output_files[ost->file_index];
- AVCodecContext *enc = ost->enc_ctx;
- AVRational tb = (AVRational){ 0, 0 };
- AVRational fr;
- FrameData *fd;
-
- if (ost->type == AVMEDIA_TYPE_SUBTITLE) {
- if (ost->enc_timebase.num)
- av_log(ost, AV_LOG_WARNING,
- "-enc_time_base not supported for subtitles, ignoring\n");
- enc->time_base = AV_TIME_BASE_Q;
- return 0;
- }
-
- fd = frame_data(frame);
-
- // apply -enc_time_base
- if (ost->enc_timebase.num == ENC_TIME_BASE_DEMUX &&
- (fd->dec.tb.num <= 0 || fd->dec.tb.den <= 0)) {
- av_log(ost, AV_LOG_ERROR,
- "Demuxing timebase not available - cannot use it for encoding\n");
- return AVERROR(EINVAL);
- }
-
- switch (ost->enc_timebase.num) {
- case 0: break;
- case ENC_TIME_BASE_DEMUX: tb = fd->dec.tb; break;
- case ENC_TIME_BASE_FILTER: tb = frame->time_base; break;
- default: tb = ost->enc_timebase; break;
- }
-
- if (ost->type == AVMEDIA_TYPE_AUDIO) {
- enc->time_base = tb.num ? tb : (AVRational){ 1, frame->sample_rate };
- return 0;
- }
-
- fr = ost->frame_rate;
- if (!fr.num)
- fr = fd->frame_rate_filter;
-
- if (ost->is_cfr) {
- if (!fr.num && !ost->max_frame_rate.num) {
- fr = (AVRational){25, 1};
- av_log(ost, AV_LOG_WARNING,
- "No information "
- "about the input framerate is available. Falling "
- "back to a default value of 25fps. Use the -r option "
- "if you want a different framerate.\n");
- }
-
- if (ost->max_frame_rate.num &&
- (av_q2d(fr) > av_q2d(ost->max_frame_rate) ||
- !fr.den))
- fr = ost->max_frame_rate;
- }
-
- if (fr.num > 0) {
- if (enc->codec->supported_framerates && !ost->force_fps) {
- int idx = av_find_nearest_q_idx(fr, enc->codec->supported_framerates);
- fr = enc->codec->supported_framerates[idx];
- }
- // reduce frame rate for mpeg4 to be within the spec limits
- if (enc->codec_id == AV_CODEC_ID_MPEG4) {
- av_reduce(&fr.num, &fr.den,
- fr.num, fr.den, 65535);
- }
- }
-
- if (av_q2d(fr) > 1e3 && ost->vsync_method != VSYNC_PASSTHROUGH &&
- (ost->vsync_method == VSYNC_CFR || ost->vsync_method == VSYNC_VSCFR ||
- (ost->vsync_method == VSYNC_AUTO && !(of->format->flags & AVFMT_VARIABLE_FPS)))){
- av_log(ost, AV_LOG_WARNING, "Frame rate very high for a muxer not efficiently supporting it.\n"
- "Please consider specifying a lower framerate, a different muxer or "
- "setting vsync/fps_mode to vfr\n");
- }
-
- enc->framerate = fr;
-
- ost->st->avg_frame_rate = fr;
-
- if (!(tb.num > 0 && tb.den > 0))
- tb = av_inv_q(fr);
- if (!(tb.num > 0 && tb.den > 0))
- tb = frame->time_base;
-
- enc->time_base = tb;
-
- return 0;
-}
-
int enc_open(OutputStream *ost, AVFrame *frame)
{
InputStream *ist = ost->ist;
@@ -317,10 +196,11 @@ int enc_open(OutputStream *ost, AVFrame *frame)
dec_ctx = ist->dec_ctx;
}
- ret = enc_choose_timebase(ost, frame);
- if (ret < 0) {
- av_log(ost, AV_LOG_ERROR, "Could not choose a time base for encoding\n");
- return AVERROR(EINVAL);
+ // the timebase is chosen by filtering code
+ if (ost->type == AVMEDIA_TYPE_AUDIO || ost->type == AVMEDIA_TYPE_VIDEO) {
+ enc_ctx->time_base = frame->time_base;
+ enc_ctx->framerate = fd->frame_rate_filter;
+ ost->st->avg_frame_rate = fd->frame_rate_filter;
}
switch (enc_ctx->codec_type) {
@@ -383,6 +263,11 @@ int enc_open(OutputStream *ost, AVFrame *frame)
break;
}
case AVMEDIA_TYPE_SUBTITLE:
+ if (ost->enc_timebase.num)
+ av_log(ost, AV_LOG_WARNING,
+ "-enc_time_base not supported for subtitles, ignoring\n");
+ enc_ctx->time_base = AV_TIME_BASE_Q;
+
if (!enc_ctx->width) {
enc_ctx->width = ost->ist->par->width;
enc_ctx->height = ost->ist->par->height;
@@ -765,9 +650,6 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame)
if (frame->sample_aspect_ratio.num && !ost->frame_aspect_ratio.num)
enc->sample_aspect_ratio = frame->sample_aspect_ratio;
- } else if (ost->last_dropped) {
- ost->nb_frames_drop++;
- ost->last_dropped = 0;
}
update_benchmark(NULL);
@@ -892,7 +774,6 @@ static int submit_encode_frame(OutputFile *of, OutputStream *ost,
static int do_audio_out(OutputFile *of, OutputStream *ost,
AVFrame *frame)
{
- Encoder *e = ost->enc;
AVCodecContext *enc = ost->enc_ctx;
int ret;
@@ -903,183 +784,15 @@ static int do_audio_out(OutputFile *of, OutputStream *ost,
return 0;
}
- if (frame->pts == AV_NOPTS_VALUE)
- frame->pts = e->next_pts;
- else {
- int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
- frame->pts =
- av_rescale_q(frame->pts, frame->time_base, enc->time_base) -
- av_rescale_q(start_time, AV_TIME_BASE_Q, enc->time_base);
- }
- frame->time_base = enc->time_base;
- frame->duration = av_rescale_q(frame->nb_samples, (AVRational){1, frame->sample_rate},
- enc->time_base);
-
if (!check_recording_time(ost, frame->pts, frame->time_base))
return 0;
- e->next_pts = frame->pts + frame->nb_samples;
-
ret = submit_encode_frame(of, ost, frame);
return (ret < 0 && ret != AVERROR_EOF) ? ret : 0;
}
-static double adjust_frame_pts_to_encoder_tb(AVFrame *frame, AVRational tb_dst,
- int64_t start_time)
-{
- double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision
-
- AVRational tb = tb_dst;
- AVRational filter_tb = frame->time_base;
- const int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16);
-
- if (frame->pts == AV_NOPTS_VALUE)
- goto early_exit;
-
- tb.den <<= extra_bits;
- float_pts = av_rescale_q(frame->pts, filter_tb, tb) -
- av_rescale_q(start_time, AV_TIME_BASE_Q, tb);
- float_pts /= 1 << extra_bits;
- // when float_pts is not exactly an integer,
- // avoid exact midpoints to reduce the chance of rounding differences, this
- // can be removed in case the fps code is changed to work with integers
- if (float_pts != llrint(float_pts))
- float_pts += FFSIGN(float_pts) * 1.0 / (1<<17);
-
- frame->pts = av_rescale_q(frame->pts, filter_tb, tb_dst) -
- av_rescale_q(start_time, AV_TIME_BASE_Q, tb_dst);
- frame->time_base = tb_dst;
-
-early_exit:
-
- if (debug_ts) {
- av_log(NULL, AV_LOG_INFO, "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n",
- frame ? av_ts2str(frame->pts) : "NULL",
- av_ts2timestr(frame->pts, &tb_dst),
- float_pts, tb_dst.num, tb_dst.den);
- }
-
- return float_pts;
-}
-
-/* Convert frame timestamps to the encoder timebase and decide how many times
- * should this (and possibly previous) frame be repeated in order to conform to
- * desired target framerate (if any).
- */
-static void video_sync_process(OutputFile *of, OutputStream *ost, AVFrame *frame,
- int64_t *nb_frames, int64_t *nb_frames_prev)
-{
- Encoder *e = ost->enc;
- FPSConvContext *fps = &e->fps;
- AVCodecContext *enc = ost->enc_ctx;
- double delta0, delta, sync_ipts, duration;
-
- if (!frame) {
- *nb_frames_prev = *nb_frames = mid_pred(fps->frames_prev_hist[0],
- fps->frames_prev_hist[1],
- fps->frames_prev_hist[2]);
- goto finish;
- }
-
- duration = frame->duration * av_q2d(frame->time_base) / av_q2d(enc->time_base);
-
- sync_ipts = adjust_frame_pts_to_encoder_tb(frame, enc->time_base,
- of->start_time == AV_NOPTS_VALUE ? 0 : of->start_time);
- /* delta0 is the "drift" between the input frame and
- * where it would fall in the output. */
- delta0 = sync_ipts - e->next_pts;
- delta = delta0 + duration;
-
- // tracks the number of times the PREVIOUS frame should be duplicated,
- // mostly for variable framerate (VFR)
- *nb_frames_prev = 0;
- /* by default, we output a single frame */
- *nb_frames = 1;
-
- if (delta0 < 0 &&
- delta > 0 &&
- ost->vsync_method != VSYNC_PASSTHROUGH &&
- ost->vsync_method != VSYNC_DROP) {
- if (delta0 < -0.6) {
- av_log(ost, AV_LOG_VERBOSE, "Past duration %f too large\n", -delta0);
- } else
- av_log(ost, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0);
- sync_ipts = e->next_pts;
- duration += delta0;
- delta0 = 0;
- }
-
- switch (ost->vsync_method) {
- case VSYNC_VSCFR:
- if (fps->frame_number == 0 && delta0 >= 0.5) {
- av_log(ost, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0));
- delta = duration;
- delta0 = 0;
- e->next_pts = llrint(sync_ipts);
- }
- case VSYNC_CFR:
- // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
- if (frame_drop_threshold && delta < frame_drop_threshold && fps->frame_number) {
- *nb_frames = 0;
- } else if (delta < -1.1)
- *nb_frames = 0;
- else if (delta > 1.1) {
- *nb_frames = llrintf(delta);
- if (delta0 > 1.1)
- *nb_frames_prev = llrintf(delta0 - 0.6);
- }
- frame->duration = 1;
- break;
- case VSYNC_VFR:
- if (delta <= -0.6)
- *nb_frames = 0;
- else if (delta > 0.6)
- e->next_pts = llrint(sync_ipts);
- frame->duration = llrint(duration);
- break;
- case VSYNC_DROP:
- case VSYNC_PASSTHROUGH:
- frame->duration = llrint(duration);
- e->next_pts = llrint(sync_ipts);
- break;
- default:
- av_assert0(0);
- }
-
-finish:
- memmove(fps->frames_prev_hist + 1,
- fps->frames_prev_hist,
- sizeof(fps->frames_prev_hist[0]) * (FF_ARRAY_ELEMS(fps->frames_prev_hist) - 1));
- fps->frames_prev_hist[0] = *nb_frames_prev;
-
- if (*nb_frames_prev == 0 && ost->last_dropped) {
- ost->nb_frames_drop++;
- av_log(ost, AV_LOG_VERBOSE,
- "*** dropping frame %"PRId64" at ts %"PRId64"\n",
- fps->frame_number, fps->last_frame->pts);
- }
- if (*nb_frames > (*nb_frames_prev && ost->last_dropped) + (*nb_frames > *nb_frames_prev)) {
- if (*nb_frames > dts_error_threshold * 30) {
- av_log(ost, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", *nb_frames - 1);
- ost->nb_frames_drop++;
- *nb_frames = 0;
- return;
- }
- ost->nb_frames_dup += *nb_frames - (*nb_frames_prev && ost->last_dropped) - (*nb_frames > *nb_frames_prev);
- av_log(ost, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", *nb_frames - 1);
- if (ost->nb_frames_dup > fps->dup_warning) {
- av_log(ost, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", fps->dup_warning);
- fps->dup_warning *= 10;
- }
- }
-
- ost->last_dropped = *nb_frames == *nb_frames_prev && frame;
- ost->kf.dropped_keyframe |= ost->last_dropped && (frame->flags & AV_FRAME_FLAG_KEY);
-}
-
static enum AVPictureType forced_kf_apply(void *logctx, KeyframeForceCtx *kf,
- AVRational tb, const AVFrame *in_picture,
- int dup_idx)
+ AVRational tb, const AVFrame *in_picture)
{
double pts_time;
@@ -1113,11 +826,8 @@ static enum AVPictureType forced_kf_apply(void *logctx, KeyframeForceCtx *kf,
kf->expr_const_values[FKF_N_FORCED] += 1;
goto force_keyframe;
}
- } else if (kf->type == KF_FORCE_SOURCE && !dup_idx) {
- int dropped_keyframe = kf->dropped_keyframe;
- kf->dropped_keyframe = 0;
- if ((in_picture->flags & AV_FRAME_FLAG_KEY) || dropped_keyframe)
- goto force_keyframe;
+ } else if (kf->type == KF_FORCE_SOURCE && (in_picture->flags & AV_FRAME_FLAG_KEY)) {
+ goto force_keyframe;
}
return AV_PICTURE_TYPE_NONE;
@@ -1128,58 +838,26 @@ force_keyframe:
}
/* May modify/reset frame */
-static int do_video_out(OutputFile *of, OutputStream *ost, AVFrame *frame)
+static int do_video_out(OutputFile *of, OutputStream *ost, AVFrame *in_picture)
{
int ret;
- Encoder *e = ost->enc;
AVCodecContext *enc = ost->enc_ctx;
- int64_t nb_frames, nb_frames_prev, i;
- video_sync_process(of, ost, frame,
- &nb_frames, &nb_frames_prev);
+ if (!check_recording_time(ost, in_picture->pts, ost->enc_ctx->time_base))
+ return 0;
- /* duplicates frame if needed */
- for (i = 0; i < nb_frames; i++) {
- AVFrame *in_picture;
-
- if (i < nb_frames_prev && e->fps.last_frame->buf[0]) {
- in_picture = e->fps.last_frame;
- } else
- in_picture = frame;
-
- if (!in_picture)
- return 0;
-
- in_picture->pts = e->next_pts;
-
- if (!check_recording_time(ost, in_picture->pts, ost->enc_ctx->time_base))
- return 0;
-
- in_picture->quality = enc->global_quality;
- in_picture->pict_type = forced_kf_apply(ost, &ost->kf, enc->time_base, in_picture, i);
+ in_picture->quality = enc->global_quality;
+ in_picture->pict_type = forced_kf_apply(ost, &ost->kf, enc->time_base, in_picture);
#if FFMPEG_OPT_TOP
- if (ost->top_field_first >= 0) {
- in_picture->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
- in_picture->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * (!!ost->top_field_first);
- }
+ if (ost->top_field_first >= 0) {
+ in_picture->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
+ in_picture->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * (!!ost->top_field_first);
+ }
#endif
- ret = submit_encode_frame(of, ost, in_picture);
- if (ret == AVERROR_EOF)
- break;
- else if (ret < 0)
- return ret;
-
- e->next_pts++;
- e->fps.frame_number++;
- }
-
- av_frame_unref(e->fps.last_frame);
- if (frame)
- av_frame_move_ref(e->fps.last_frame, frame);
-
- return 0;
+ ret = submit_encode_frame(of, ost, in_picture);
+ return (ret == AVERROR_EOF) ? 0 : ret;
}
int enc_frame(OutputStream *ost, AVFrame *frame)
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 804b9de3dc..0df284c334 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -38,6 +38,9 @@
#include "libavutil/samplefmt.h"
#include "libavutil/timestamp.h"
+// FIXME private header, used for mid_pred()
+#include "libavcodec/mathops.h"
+
typedef struct FilterGraphPriv {
FilterGraph fg;
@@ -54,6 +57,8 @@ typedef struct FilterGraphPriv {
// frame for temporarily holding output from the filtergraph
AVFrame *frame;
+ // frame for sending output to the encoder
+ AVFrame *frame_enc;
} FilterGraphPriv;
static FilterGraphPriv *fgp_from_fg(FilterGraph *fg)
@@ -134,6 +139,26 @@ static InputFilterPriv *ifp_from_ifilter(InputFilter *ifilter)
return (InputFilterPriv*)ifilter;
}
+typedef struct FPSConvContext {
+ AVFrame *last_frame;
+ /* number of frames emitted by the video-encoding sync code */
+ int64_t frame_number;
+ /* history of nb_frames_prev, i.e. the number of times the
+ * previous frame was duplicated by vsync code in recent
+ * do_video_out() calls */
+ int64_t frames_prev_hist[3];
+
+ uint64_t dup_warning;
+
+ int last_dropped;
+ int dropped_keyframe;
+
+ AVRational framerate;
+ AVRational framerate_max;
+ const AVRational *framerate_supported;
+ int framerate_clip;
+} FPSConvContext;
+
typedef struct OutputFilterPriv {
OutputFilter ofilter;
@@ -145,7 +170,13 @@ typedef struct OutputFilterPriv {
int sample_rate;
AVChannelLayout ch_layout;
- AVRational time_base;
+ // time base in which the output is sent to our downstream
+ // does not need to match the filtersink's timebase
+ AVRational tb_out;
+ // at least one frame with the above timebase was sent
+ // to our downstream, so it cannot change anymore
+ int tb_out_locked;
+
AVRational sample_aspect_ratio;
// those are only set if no format is specified and the encoder gives us multiple options
@@ -154,6 +185,12 @@ typedef struct OutputFilterPriv {
const AVChannelLayout *ch_layouts;
const int *sample_rates;
+ AVRational enc_timebase;
+ // offset for output timestamps, in AV_TIME_BASE_Q
+ int64_t ts_offset;
+ int64_t next_pts;
+ FPSConvContext fps;
+
// set to 1 after at least one frame passed through this output
int got_frame;
} OutputFilterPriv;
@@ -627,6 +664,7 @@ static int set_channel_layout(OutputFilterPriv *f, OutputStream *ost)
int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost)
{
+ const OutputFile *of = output_files[ost->file_index];
OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
FilterGraph *fg = ofilter->graph;
FilterGraphPriv *fgp = fgp_from_fg(fg);
@@ -637,6 +675,9 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost)
ofilter->ost = ost;
av_freep(&ofilter->linklabel);
+ ofp->ts_offset = of->start_time == AV_NOPTS_VALUE ? 0 : of->start_time;
+ ofp->enc_timebase = ost->enc_timebase;
+
switch (ost->enc_ctx->codec_type) {
case AVMEDIA_TYPE_VIDEO:
ofp->width = ost->enc_ctx->width;
@@ -673,6 +714,21 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost)
fgp->disable_conversions |= ost->keep_pix_fmt;
+ ofp->fps.last_frame = av_frame_alloc();
+ if (!ofp->fps.last_frame)
+ return AVERROR(ENOMEM);
+
+ ofp->fps.framerate = ost->frame_rate;
+ ofp->fps.framerate_max = ost->max_frame_rate;
+ ofp->fps.framerate_supported = ost->force_fps ?
+ NULL : c->supported_framerates;
+
+ // reduce frame rate for mpeg4 to be within the spec limits
+ if (c->id == AV_CODEC_ID_MPEG4)
+ ofp->fps.framerate_clip = 65535;
+
+ ofp->fps.dup_warning = 1000;
+
break;
case AVMEDIA_TYPE_AUDIO:
if (ost->enc_ctx->sample_fmt != AV_SAMPLE_FMT_NONE) {
@@ -777,6 +833,8 @@ void fg_free(FilterGraph **pfg)
OutputFilter *ofilter = fg->outputs[j];
OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
+ av_frame_free(&ofp->fps.last_frame);
+
av_freep(&ofilter->linklabel);
av_freep(&ofilter->name);
av_channel_layout_uninit(&ofp->ch_layout);
@@ -786,6 +844,7 @@ void fg_free(FilterGraph **pfg)
av_freep(&fgp->graph_desc);
av_frame_free(&fgp->frame);
+ av_frame_free(&fgp->frame_enc);
av_freep(pfg);
}
@@ -828,8 +887,9 @@ int fg_create(FilterGraph **pfg, char *graph_desc)
snprintf(fgp->log_name, sizeof(fgp->log_name), "fc#%d", fg->index);
- fgp->frame = av_frame_alloc();
- if (!fgp->frame)
+ fgp->frame = av_frame_alloc();
+ fgp->frame_enc = av_frame_alloc();
+ if (!fgp->frame || !fgp->frame_enc)
return AVERROR(ENOMEM);
/* this graph is only used for determining the kinds of inputs
@@ -1630,7 +1690,16 @@ static int configure_filtergraph(FilterGraph *fg)
ofp->width = av_buffersink_get_w(sink);
ofp->height = av_buffersink_get_h(sink);
- ofp->time_base = av_buffersink_get_time_base(sink);
+ // If the timing parameters are not locked yet, get the tentative values
+ // here but don't lock them. They will only be used if no output frames
+ // are ever produced.
+ if (!ofp->tb_out_locked) {
+ AVRational fr = av_buffersink_get_frame_rate(sink);
+ if (ofp->fps.framerate.num <= 0 && ofp->fps.framerate.den <= 0 &&
+ fr.num > 0 && fr.den > 0)
+ ofp->fps.framerate = fr;
+ ofp->tb_out = av_buffersink_get_time_base(sink);
+ }
ofp->sample_aspect_ratio = av_buffersink_get_sample_aspect_ratio(sink);
ofp->sample_rate = av_buffersink_get_sample_rate(sink);
@@ -1765,6 +1834,313 @@ void fg_send_command(FilterGraph *fg, double time, const char *target,
}
}
+static int choose_out_timebase(OutputFilterPriv *ofp, AVFrame *frame)
+{
+ OutputFilter *ofilter = &ofp->ofilter;
+ FPSConvContext *fps = &ofp->fps;
+ AVRational tb = (AVRational){ 0, 0 };
+ AVRational fr;
+ FrameData *fd;
+
+ fd = frame_data(frame);
+
+ // apply -enc_time_base
+ if (ofp->enc_timebase.num == ENC_TIME_BASE_DEMUX &&
+ (fd->dec.tb.num <= 0 || fd->dec.tb.den <= 0)) {
+ av_log(ofilter->ost, AV_LOG_ERROR,
+ "Demuxing timebase not available - cannot use it for encoding\n");
+ return AVERROR(EINVAL);
+ }
+
+ switch (ofp->enc_timebase.num) {
+ case 0: break;
+ case ENC_TIME_BASE_DEMUX: tb = fd->dec.tb; break;
+ case ENC_TIME_BASE_FILTER: tb = frame->time_base; break;
+ default: tb = ofp->enc_timebase; break;
+ }
+
+ if (ofilter->type == AVMEDIA_TYPE_AUDIO) {
+ tb = tb.num ? tb : (AVRational){ 1, frame->sample_rate };
+ goto finish;
+ }
+
+ fr = fps->framerate;
+ if (!fr.num) {
+ AVRational fr_sink = av_buffersink_get_frame_rate(ofp->filter);
+ if (fr_sink.num > 0 && fr_sink.den > 0)
+ fr = fr_sink;
+ }
+
+ if (ofilter->ost->is_cfr) {
+ if (!fr.num && !fps->framerate_max.num) {
+ fr = (AVRational){25, 1};
+ av_log(ofilter->ost, AV_LOG_WARNING,
+ "No information "
+ "about the input framerate is available. Falling "
+ "back to a default value of 25fps. Use the -r option "
+ "if you want a different framerate.\n");
+ }
+
+ if (fps->framerate_max.num &&
+ (av_q2d(fr) > av_q2d(fps->framerate_max) ||
+ !fr.den))
+ fr = fps->framerate_max;
+ }
+
+ if (fr.num > 0) {
+ if (fps->framerate_supported) {
+ int idx = av_find_nearest_q_idx(fr, fps->framerate_supported);
+ fr = fps->framerate_supported[idx];
+ }
+ if (fps->framerate_clip) {
+ av_reduce(&fr.num, &fr.den,
+ fr.num, fr.den, fps->framerate_clip);
+ }
+ }
+
+ if (!(tb.num > 0 && tb.den > 0))
+ tb = av_inv_q(fr);
+ if (!(tb.num > 0 && tb.den > 0))
+ tb = frame->time_base;
+
+finish:
+ ofp->tb_out = tb;
+ fps->framerate = fr;
+ ofp->tb_out_locked = 1;
+
+ return 0;
+}
+
+static double adjust_frame_pts_to_encoder_tb(AVFrame *frame, AVRational tb_dst,
+ int64_t start_time)
+{
+ double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision
+
+ AVRational tb = tb_dst;
+ AVRational filter_tb = frame->time_base;
+ const int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16);
+
+ if (frame->pts == AV_NOPTS_VALUE)
+ goto early_exit;
+
+ tb.den <<= extra_bits;
+ float_pts = av_rescale_q(frame->pts, filter_tb, tb) -
+ av_rescale_q(start_time, AV_TIME_BASE_Q, tb);
+ float_pts /= 1 << extra_bits;
+ // when float_pts is not exactly an integer,
+ // avoid exact midpoints to reduce the chance of rounding differences, this
+ // can be removed in case the fps code is changed to work with integers
+ if (float_pts != llrint(float_pts))
+ float_pts += FFSIGN(float_pts) * 1.0 / (1<<17);
+
+ frame->pts = av_rescale_q(frame->pts, filter_tb, tb_dst) -
+ av_rescale_q(start_time, AV_TIME_BASE_Q, tb_dst);
+ frame->time_base = tb_dst;
+
+early_exit:
+
+ if (debug_ts) {
+ av_log(NULL, AV_LOG_INFO, "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n",
+ frame ? av_ts2str(frame->pts) : "NULL",
+ av_ts2timestr(frame->pts, &tb_dst),
+ float_pts, tb_dst.num, tb_dst.den);
+ }
+
+ return float_pts;
+}
+
+/* Convert frame timestamps to the encoder timebase and decide how many times
+ * should this (and possibly previous) frame be repeated in order to conform to
+ * desired target framerate (if any).
+ */
+static void video_sync_process(OutputFilterPriv *ofp, AVFrame *frame,
+ int64_t *nb_frames, int64_t *nb_frames_prev)
+{
+ OutputFilter *ofilter = &ofp->ofilter;
+ OutputStream *ost = ofilter->ost;
+ FPSConvContext *fps = &ofp->fps;
+ double delta0, delta, sync_ipts, duration;
+
+ if (!frame) {
+ *nb_frames_prev = *nb_frames = mid_pred(fps->frames_prev_hist[0],
+ fps->frames_prev_hist[1],
+ fps->frames_prev_hist[2]);
+
+ if (!*nb_frames && fps->last_dropped) {
+ ofilter->nb_frames_drop++;
+ fps->last_dropped++;
+ }
+
+ goto finish;
+ }
+
+ duration = frame->duration * av_q2d(frame->time_base) / av_q2d(ofp->tb_out);
+
+ sync_ipts = adjust_frame_pts_to_encoder_tb(frame, ofp->tb_out, ofp->ts_offset);
+ /* delta0 is the "drift" between the input frame and
+ * where it would fall in the output. */
+ delta0 = sync_ipts - ofp->next_pts;
+ delta = delta0 + duration;
+
+ // tracks the number of times the PREVIOUS frame should be duplicated,
+ // mostly for variable framerate (VFR)
+ *nb_frames_prev = 0;
+ /* by default, we output a single frame */
+ *nb_frames = 1;
+
+ if (delta0 < 0 &&
+ delta > 0 &&
+ ost->vsync_method != VSYNC_PASSTHROUGH &&
+ ost->vsync_method != VSYNC_DROP) {
+ if (delta0 < -0.6) {
+ av_log(ost, AV_LOG_VERBOSE, "Past duration %f too large\n", -delta0);
+ } else
+ av_log(ost, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0);
+ sync_ipts = ofp->next_pts;
+ duration += delta0;
+ delta0 = 0;
+ }
+
+ switch (ost->vsync_method) {
+ case VSYNC_VSCFR:
+ if (fps->frame_number == 0 && delta0 >= 0.5) {
+ av_log(ost, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0));
+ delta = duration;
+ delta0 = 0;
+ ofp->next_pts = llrint(sync_ipts);
+ }
+ case VSYNC_CFR:
+ // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
+ if (frame_drop_threshold && delta < frame_drop_threshold && fps->frame_number) {
+ *nb_frames = 0;
+ } else if (delta < -1.1)
+ *nb_frames = 0;
+ else if (delta > 1.1) {
+ *nb_frames = llrintf(delta);
+ if (delta0 > 1.1)
+ *nb_frames_prev = llrintf(delta0 - 0.6);
+ }
+ frame->duration = 1;
+ break;
+ case VSYNC_VFR:
+ if (delta <= -0.6)
+ *nb_frames = 0;
+ else if (delta > 0.6)
+ ofp->next_pts = llrint(sync_ipts);
+ frame->duration = llrint(duration);
+ break;
+ case VSYNC_DROP:
+ case VSYNC_PASSTHROUGH:
+ ofp->next_pts = llrint(sync_ipts);
+ frame->duration = llrint(duration);
+ break;
+ default:
+ av_assert0(0);
+ }
+
+finish:
+ memmove(fps->frames_prev_hist + 1,
+ fps->frames_prev_hist,
+ sizeof(fps->frames_prev_hist[0]) * (FF_ARRAY_ELEMS(fps->frames_prev_hist) - 1));
+ fps->frames_prev_hist[0] = *nb_frames_prev;
+
+ if (*nb_frames_prev == 0 && fps->last_dropped) {
+ ofilter->nb_frames_drop++;
+ av_log(ost, AV_LOG_VERBOSE,
+ "*** dropping frame %"PRId64" at ts %"PRId64"\n",
+ fps->frame_number, fps->last_frame->pts);
+ }
+ if (*nb_frames > (*nb_frames_prev && fps->last_dropped) + (*nb_frames > *nb_frames_prev)) {
+ if (*nb_frames > dts_error_threshold * 30) {
+ av_log(ost, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", *nb_frames - 1);
+ ofilter->nb_frames_drop++;
+ *nb_frames = 0;
+ return;
+ }
+ ofilter->nb_frames_dup += *nb_frames - (*nb_frames_prev && fps->last_dropped) - (*nb_frames > *nb_frames_prev);
+ av_log(ost, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", *nb_frames - 1);
+ if (ofilter->nb_frames_dup > fps->dup_warning) {
+ av_log(ost, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", fps->dup_warning);
+ fps->dup_warning *= 10;
+ }
+ }
+
+ fps->last_dropped = *nb_frames == *nb_frames_prev && frame;
+ fps->dropped_keyframe |= fps->last_dropped && (frame->flags & AV_FRAME_FLAG_KEY);
+}
+
+static int fg_output_frame(OutputFilterPriv *ofp, AVFrame *frame)
+{
+ FilterGraphPriv *fgp = fgp_from_fg(ofp->ofilter.graph);
+ OutputStream *ost = ofp->ofilter.ost;
+ AVFrame *frame_prev = ofp->fps.last_frame;
+ enum AVMediaType type = ofp->ofilter.type;
+
+ int64_t nb_frames = 1, nb_frames_prev = 0;
+
+ if (type == AVMEDIA_TYPE_VIDEO)
+ video_sync_process(ofp, frame, &nb_frames, &nb_frames_prev);
+
+ for (int64_t i = 0; i < nb_frames; i++) {
+ AVFrame *frame_out;
+ int ret;
+
+ if (type == AVMEDIA_TYPE_VIDEO) {
+ AVFrame *frame_in = (i < nb_frames_prev && frame_prev->buf[0]) ?
+ frame_prev : frame;
+ if (!frame_in)
+ break;
+
+ frame_out = fgp->frame_enc;
+ ret = av_frame_ref(frame_out, frame_in);
+ if (ret < 0)
+ return ret;
+
+ frame_out->pts = ofp->next_pts;
+
+ if (ofp->fps.dropped_keyframe) {
+ frame_out->flags |= AV_FRAME_FLAG_KEY;
+ ofp->fps.dropped_keyframe = 0;
+ }
+ } else {
+ frame->pts = (frame->pts == AV_NOPTS_VALUE) ? ofp->next_pts :
+ av_rescale_q(frame->pts, frame->time_base, ofp->tb_out) -
+ av_rescale_q(ofp->ts_offset, AV_TIME_BASE_Q, ofp->tb_out);
+
+ frame->time_base = ofp->tb_out;
+ frame->duration = av_rescale_q(frame->nb_samples,
+ (AVRational){ 1, frame->sample_rate },
+ ofp->tb_out);
+
+ ofp->next_pts = frame->pts + frame->duration;
+
+ frame_out = frame;
+ }
+
+ ret = enc_frame(ost, frame_out);
+ av_frame_unref(frame_out);
+ if (ret < 0)
+ return ret;
+
+ if (type == AVMEDIA_TYPE_VIDEO) {
+ ofp->fps.frame_number++;
+ ofp->next_pts++;
+
+ if (i == nb_frames_prev && frame)
+ frame->flags &= ~AV_FRAME_FLAG_KEY;
+ }
+
+ ofp->got_frame = 1;
+ }
+
+ if (frame && frame_prev) {
+ av_frame_unref(frame_prev);
+ av_frame_move_ref(frame_prev, frame);
+ }
+
+ return 0;
+}
+
static int fg_output_step(OutputFilterPriv *ofp, int flush)
{
FilterGraphPriv *fgp = fgp_from_fg(ofp->ofilter.graph);
@@ -1782,9 +2158,8 @@ static int fg_output_step(OutputFilterPriv *ofp, int flush)
"Error in av_buffersink_get_frame_flags(): %s\n", av_err2str(ret));
} else if (flush && ret == AVERROR_EOF && ofp->got_frame &&
av_buffersink_get_type(filter) == AVMEDIA_TYPE_VIDEO) {
- ret = enc_frame(ost, NULL);
- if (ret < 0)
- return ret;
+ ret = fg_output_frame(ofp, NULL);
+ return (ret < 0) ? ret : 1;
}
return 1;
@@ -1794,14 +2169,26 @@ static int fg_output_step(OutputFilterPriv *ofp, int flush)
return 0;
}
+ frame->time_base = av_buffersink_get_time_base(filter);
+
if (frame->pts != AV_NOPTS_VALUE) {
- AVRational tb = av_buffersink_get_time_base(filter);
- ost->filter->last_pts = av_rescale_q(frame->pts, tb, AV_TIME_BASE_Q);
- frame->time_base = tb;
+ ost->filter->last_pts = av_rescale_q(frame->pts, frame->time_base,
+ AV_TIME_BASE_Q);
if (debug_ts)
av_log(fgp, AV_LOG_INFO, "filter_raw -> pts:%s pts_time:%s time_base:%d/%d\n",
- av_ts2str(frame->pts), av_ts2timestr(frame->pts, &tb), tb.num, tb.den);
+ av_ts2str(frame->pts), av_ts2timestr(frame->pts, &frame->time_base),
+ frame->time_base.num, frame->time_base.den);
+ }
+
+ // Choose the output timebase the first time we get a frame.
+ if (!ofp->tb_out_locked) {
+ ret = choose_out_timebase(ofp, frame);
+ if (ret < 0) {
+ av_log(ost, AV_LOG_ERROR, "Could not choose an output time base\n");
+ av_frame_unref(frame);
+ return ret;
+ }
}
fd = frame_data(frame);
@@ -1816,22 +2203,20 @@ static int fg_output_step(OutputFilterPriv *ofp, int flush)
fd->bits_per_raw_sample = 0;
if (ost->type == AVMEDIA_TYPE_VIDEO) {
- AVRational fr = av_buffersink_get_frame_rate(filter);
- if (fr.num > 0 && fr.den > 0) {
- fd->frame_rate_filter = fr;
-
- if (!frame->duration)
+ if (!frame->duration) {
+ AVRational fr = av_buffersink_get_frame_rate(filter);
+ if (fr.num > 0 && fr.den > 0)
frame->duration = av_rescale_q(1, av_inv_q(fr), frame->time_base);
}
+
+ fd->frame_rate_filter = ofp->fps.framerate;
}
- ret = enc_frame(ost, frame);
+ ret = fg_output_frame(ofp, frame);
av_frame_unref(frame);
if (ret < 0)
return ret;
- ofp->got_frame = 1;
-
return 0;
}
@@ -2098,8 +2483,9 @@ int fg_transcode_step(FilterGraph *graph, InputStream **best_ist)
// at least initialize the encoder with a dummy frame
if (!ofp->got_frame) {
AVFrame *frame = fgp->frame;
+ FrameData *fd;
- frame->time_base = ofp->time_base;
+ frame->time_base = ofp->tb_out;
frame->format = ofp->format;
frame->width = ofp->width;
@@ -2113,6 +2499,12 @@ int fg_transcode_step(FilterGraph *graph, InputStream **best_ist)
return ret;
}
+ fd = frame_data(frame);
+ if (!fd)
+ return AVERROR(ENOMEM);
+
+ fd->frame_rate_filter = ofp->fps.framerate;
+
av_assert0(!frame->buf[0]);
av_log(ofilter->ost, AV_LOG_WARNING,
--
2.40.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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 11/12] fftools/ffmpeg_filter: fail on filtering errors
2023-10-03 15:35 [FFmpeg-devel] [PATCH 01/12] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process() Anton Khirnov
` (8 preceding siblings ...)
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 10/12] fftools/ffmpeg_enc: move fps conversion code to ffmpeg_filter Anton Khirnov
@ 2023-10-03 15:35 ` Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 12/12] fftools/ffmpeg_enc: constify the frame passed to enc_open() Anton Khirnov
10 siblings, 0 replies; 12+ messages in thread
From: Anton Khirnov @ 2023-10-03 15:35 UTC (permalink / raw)
To: ffmpeg-devel
These should be considered serious errors - don't just print a log
message and continue as if nothing happened.
---
fftools/ffmpeg_filter.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 0df284c334..129487cf88 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -2152,17 +2152,17 @@ static int fg_output_step(OutputFilterPriv *ofp, int flush)
ret = av_buffersink_get_frame_flags(filter, frame,
AV_BUFFERSINK_FLAG_NO_REQUEST);
- if (ret < 0) {
- if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
- av_log(fgp, AV_LOG_WARNING,
- "Error in av_buffersink_get_frame_flags(): %s\n", av_err2str(ret));
- } else if (flush && ret == AVERROR_EOF && ofp->got_frame &&
- av_buffersink_get_type(filter) == AVMEDIA_TYPE_VIDEO) {
- ret = fg_output_frame(ofp, NULL);
- return (ret < 0) ? ret : 1;
- }
-
+ if (flush && ret == AVERROR_EOF && ofp->got_frame &&
+ ost->type == AVMEDIA_TYPE_VIDEO) {
+ ret = fg_output_frame(ofp, NULL);
+ return (ret < 0) ? ret : 1;
+ } else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
return 1;
+ } else if (ret < 0) {
+ av_log(fgp, AV_LOG_WARNING,
+ "Error in retrieving a frame from the filtergraph: %s\n",
+ av_err2str(ret));
+ return ret;
}
if (ost->finished) {
av_frame_unref(frame);
--
2.40.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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 12/12] fftools/ffmpeg_enc: constify the frame passed to enc_open()
2023-10-03 15:35 [FFmpeg-devel] [PATCH 01/12] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process() Anton Khirnov
` (9 preceding siblings ...)
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 11/12] fftools/ffmpeg_filter: fail on filtering errors Anton Khirnov
@ 2023-10-03 15:35 ` Anton Khirnov
10 siblings, 0 replies; 12+ messages in thread
From: Anton Khirnov @ 2023-10-03 15:35 UTC (permalink / raw)
To: ffmpeg-devel
---
fftools/ffmpeg.h | 2 +-
fftools/ffmpeg_enc.c | 7 +++----
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 15790d3e0c..0983d026cd 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -817,7 +817,7 @@ int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof);
int enc_alloc(Encoder **penc, const AVCodec *codec);
void enc_free(Encoder **penc);
-int enc_open(OutputStream *ost, AVFrame *frame);
+int enc_open(OutputStream *ost, const AVFrame *frame);
int enc_subtitle(OutputFile *of, OutputStream *ost, const AVSubtitle *sub);
int enc_frame(OutputStream *ost, AVFrame *frame);
int enc_flush(void);
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 321554ab5c..c300a11f28 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -165,7 +165,7 @@ static int set_encoder_id(OutputFile *of, OutputStream *ost)
return 0;
}
-int enc_open(OutputStream *ost, AVFrame *frame)
+int enc_open(OutputStream *ost, const AVFrame *frame)
{
InputStream *ist = ost->ist;
Encoder *e = ost->enc;
@@ -183,9 +183,8 @@ int enc_open(OutputStream *ost, AVFrame *frame)
av_assert0(frame || (enc->type != AVMEDIA_TYPE_VIDEO && enc->type != AVMEDIA_TYPE_AUDIO));
if (frame) {
- fd = frame_data(frame);
- if (!fd)
- return AVERROR(ENOMEM);
+ av_assert0(frame->opaque_ref);
+ fd = (FrameData*)frame->opaque_ref->data;
}
ret = set_encoder_id(output_files[ost->file_index], ost);
--
2.40.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] 12+ messages in thread
end of thread, other threads:[~2023-10-03 15:37 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-03 15:35 [FFmpeg-devel] [PATCH 01/12] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process() Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 02/12] fftools/ffmpeg_enc: move remaining vsync-related code " Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 03/12] fftools/ffmpeg_enc: simplify adjust_frame_pts_to_encoder_tb() signature Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 04/12] ffools/ffmpeg_filter: stop trying to handle an unreachable state Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 05/12] tests/fate/ffmpeg: add tests for -force_key_frames source Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 06/12] fftools/ffmpeg_enc: unbreak -force_key_frames source_no_drop Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 07/12] fftools/ffmpeg_enc: merge -force_key_frames source/source_no_drop Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 08/12] fftools/ffmpeg: stop accessing OutputStream.last_dropped in print_report() Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 09/12] fftools/ffmpeg_enc: move framerate conversion state into a separate struct Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 10/12] fftools/ffmpeg_enc: move fps conversion code to ffmpeg_filter Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 11/12] fftools/ffmpeg_filter: fail on filtering errors Anton Khirnov
2023-10-03 15:35 ` [FFmpeg-devel] [PATCH 12/12] fftools/ffmpeg_enc: constify the frame passed to enc_open() Anton Khirnov
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