History

avfilter/framesync: add a new option to set how to sync streams based on secondary input timestamps

Include two values for it, a default one that sets/keeps the current behavior, where the frame event generated by the primary input will have a timestamp equal or higher than frames in secondary input, plus a new one where the secondary input frame will be that with the absolute closest timestamp to that of the frame event one. Addresses ticket #9689, where the new optional behavior produces better frame syncronization.

James Almer committed 4 years ago

Commit 0c3e3fd1 parent d9315542 files · +42 −0Browse files

Showing the changes to libavfilter/framesync.c (1 of 2 files). Show all

Unified · Split

libavfilter/framesync.c+19−0
@@ -42,6 +42,13 @@ static const AVOption framesync_options[] = { · 41 unmodified lines
4242 { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, "eof_action" },
4343 { "shortest", "force termination when the shortest input terminates", OFFSET(opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
4444 { "repeatlast", "extend last frame of secondary streams beyond EOF", OFFSET(opt_repeatlast), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },
45+ { "ts_sync_mode", "How strictly to sync streams based on secondary input timestamps",
46+ OFFSET(opt_ts_sync_mode), AV_OPT_TYPE_INT, { .i64 = TS_DEFAULT },
47+ TS_DEFAULT, TS_NEAREST, .flags = FLAGS, "ts_sync_mode" },
48+ { "default", "Frame from secondary input with the nearest lower or equal timestamp to the primary input frame",
49+ 0, AV_OPT_TYPE_CONST, { .i64 = TS_DEFAULT }, .flags = FLAGS, "ts_sync_mode" },
50+ { "nearest", "Frame from secondary input with the absolute nearest timestamp to the primary input frame",
51+ 0, AV_OPT_TYPE_CONST, { .i64 = TS_NEAREST }, .flags = FLAGS, "ts_sync_mode" },
4552 { NULL }
4653 };
4754 static const AVClass framesync_class = {
@@ -110,6 +117,14 @@ static void framesync_sync_level_update(FFFrameSync *fs) · 62 unmodified lines
110117 av_assert0(level <= fs->sync_level);
111118 if (level < fs->sync_level)
112119 av_log(fs, AV_LOG_VERBOSE, "Sync level %u\n", level);
120+ if (fs->opt_ts_sync_mode > TS_DEFAULT) {
121+ for (i = 0; i < fs->nb_in; i++) {
122+ if (fs->in[i].sync < level)
123+ fs->in[i].ts_mode = fs->opt_ts_sync_mode;
124+ else
125+ fs->in[i].ts_mode = TS_DEFAULT;
126+ }
127+ }
113128 if (level)
114129 fs->sync_level = level;
115130 else
@@ -187,6 +202,10 @@ static int framesync_advance(FFFrameSync *fs) · 71 unmodified lines
187202 }
188203 for (i = 0; i < fs->nb_in; i++) {
189204 if (fs->in[i].pts_next == pts ||
205+ (fs->in[i].ts_mode == TS_NEAREST &&
206+ fs->in[i].have_next &&
207+ fs->in[i].pts_next != INT64_MAX && fs->in[i].pts != AV_NOPTS_VALUE &&
208+ fs->in[i].pts_next - pts < pts - fs->in[i].pts) ||
190209 (fs->in[i].before == EXT_INFINITY &&
191210 fs->in[i].state == STATE_BOF)) {
192211 av_frame_free(&fs->in[i].frame);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t