diff options
Diffstat (limited to 'fftools/ffmpeg_opt.c')
-rw-r--r-- | fftools/ffmpeg_opt.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index e08455478f..ac7fe3b27a 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -235,6 +235,7 @@ static void init_options(OptionsContext *o) o->chapters_input_file = INT_MAX; o->accurate_seek = 1; o->thread_queue_size = -1; + o->input_sync_ref = -1; } static int show_hwaccels(void *optctx, const char *opt, const char *arg) @@ -287,6 +288,58 @@ static int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, in return 0; } +static int apply_sync_offsets(void) +{ + for (int i = 0; i < nb_input_files; i++) { + InputFile *ref, *self = input_files[i]; + int64_t adjustment; + int64_t self_start_time, ref_start_time, self_seek_start, ref_seek_start; + int start_times_set = 1; + + if (self->input_sync_ref == -1 || self->input_sync_ref == i) continue; + if (self->input_sync_ref >= nb_input_files || self->input_sync_ref < -1) { + av_log(NULL, AV_LOG_FATAL, "-isync for input %d references non-existent input %d.\n", i, self->input_sync_ref); + exit_program(1); + } + + if (copy_ts && !start_at_zero) { + av_log(NULL, AV_LOG_FATAL, "Use of -isync requires that start_at_zero be set if copyts is set.\n"); + exit_program(1); + } + + ref = input_files[self->input_sync_ref]; + if (ref->input_sync_ref != -1 && ref->input_sync_ref != self->input_sync_ref) { + av_log(NULL, AV_LOG_ERROR, "-isync for input %d references a resynced input %d. Sync not set.\n", i, self->input_sync_ref); + continue; + } + + if (self->ctx->start_time_realtime != AV_NOPTS_VALUE && ref->ctx->start_time_realtime != AV_NOPTS_VALUE) { + self_start_time = self->ctx->start_time_realtime; + ref_start_time = ref->ctx->start_time_realtime; + } else if (self->ctx->start_time != AV_NOPTS_VALUE && ref->ctx->start_time != AV_NOPTS_VALUE) { + self_start_time = self->ctx->start_time; + ref_start_time = ref->ctx->start_time; + } else { + start_times_set = 0; + } + + if (start_times_set) { + self_seek_start = self->start_time == AV_NOPTS_VALUE ? 0 : self->start_time; + ref_seek_start = ref->start_time == AV_NOPTS_VALUE ? 0 : ref->start_time; + + adjustment = (self_start_time - ref_start_time) + !copy_ts*(self_seek_start - ref_seek_start) + ref->input_ts_offset; + + self->ts_offset += adjustment; + + av_log(NULL, AV_LOG_INFO, "Adjusted ts offset for Input #%d by %"PRId64" us to sync with Input #%d.\n", i, adjustment, self->input_sync_ref); + } else { + av_log(NULL, AV_LOG_INFO, "Unable to identify start times for Inputs #%d and %d both. No sync adjustment made.\n", i, self->input_sync_ref); + } + } + + return 0; +} + static int opt_filter_threads(void *optctx, const char *opt, const char *arg) { av_free(filter_nbthreads); @@ -1305,6 +1358,7 @@ static int open_input_file(OptionsContext *o, const char *filename) f->ist_index = nb_input_streams - ic->nb_streams; f->start_time = o->start_time; f->recording_time = o->recording_time; + f->input_sync_ref = o->input_sync_ref; f->input_ts_offset = o->input_ts_offset; f->ts_offset = o->input_ts_offset - (copy_ts ? (start_at_zero && ic->start_time != AV_NOPTS_VALUE ? ic->start_time : 0) : timestamp); f->nb_streams = ic->nb_streams; @@ -3489,6 +3543,8 @@ int ffmpeg_parse_options(int argc, char **argv) goto fail; } + apply_sync_offsets(); + /* create the complex filtergraphs */ ret = init_complex_filters(); if (ret < 0) { @@ -3603,6 +3659,9 @@ const OptionDef options[] = { { "accurate_seek", OPT_BOOL | OPT_OFFSET | OPT_EXPERT | OPT_INPUT, { .off = OFFSET(accurate_seek) }, "enable/disable accurate seeking with -ss" }, + { "isync", HAS_ARG | OPT_INT | OPT_OFFSET | + OPT_EXPERT | OPT_INPUT, { .off = OFFSET(input_sync_ref) }, + "Indicate the input index for sync reference", "sync ref" }, { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_EXPERT | OPT_INPUT, { .off = OFFSET(input_ts_offset) }, "set the input ts offset", "time_off" }, |