mirror of https://git.ffmpeg.org/ffmpeg.git
ffmpeg: fix implementation of updated input start time
The current adjustment of input start times just adjusts the tsoffset. And it does so, by resetting the tsoffset to nullify the new start time. This leads to breakage of -copyts, ignoring of input_ts_offset, breaking of -isync as well as breaking wrap correction. Fixed by taking cognizance of these parameters, and by correcting start times just before sync offsets are applied.
This commit is contained in:
parent
93faba449c
commit
5ccd4d3060
|
@ -1813,7 +1813,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
|
||||||
start_time = 0;
|
start_time = 0;
|
||||||
if (copy_ts) {
|
if (copy_ts) {
|
||||||
start_time += f->start_time != AV_NOPTS_VALUE ? f->start_time : 0;
|
start_time += f->start_time != AV_NOPTS_VALUE ? f->start_time : 0;
|
||||||
start_time += start_at_zero ? 0 : f->ctx->start_time;
|
start_time += start_at_zero ? 0 : f->start_time_effective;
|
||||||
}
|
}
|
||||||
if (ist->pts >= f->recording_time + start_time) {
|
if (ist->pts >= f->recording_time + start_time) {
|
||||||
close_output_stream(ost);
|
close_output_stream(ost);
|
||||||
|
|
|
@ -443,7 +443,10 @@ typedef struct InputFile {
|
||||||
int ist_index; /* index of first stream in input_streams */
|
int ist_index; /* index of first stream in input_streams */
|
||||||
int64_t input_ts_offset;
|
int64_t input_ts_offset;
|
||||||
int input_sync_ref;
|
int input_sync_ref;
|
||||||
|
/**
|
||||||
|
* Effective format start time based on enabled streams.
|
||||||
|
*/
|
||||||
|
int64_t start_time_effective;
|
||||||
int64_t ts_offset;
|
int64_t ts_offset;
|
||||||
/**
|
/**
|
||||||
* Extra timestamp offset added by discontinuity handling.
|
* Extra timestamp offset added by discontinuity handling.
|
||||||
|
|
|
@ -170,7 +170,7 @@ static void ts_fixup(Demuxer *d, AVPacket *pkt, int *repeat_pict)
|
||||||
{
|
{
|
||||||
InputFile *ifile = &d->f;
|
InputFile *ifile = &d->f;
|
||||||
InputStream *ist = input_streams[ifile->ist_index + pkt->stream_index];
|
InputStream *ist = input_streams[ifile->ist_index + pkt->stream_index];
|
||||||
const int64_t start_time = ifile->ctx->start_time;
|
const int64_t start_time = ifile->start_time_effective;
|
||||||
int64_t duration;
|
int64_t duration;
|
||||||
|
|
||||||
if (debug_ts) {
|
if (debug_ts) {
|
||||||
|
@ -422,7 +422,7 @@ int ifile_get_packet(InputFile *f, AVPacket **pkt)
|
||||||
if (f->readrate || f->rate_emu) {
|
if (f->readrate || f->rate_emu) {
|
||||||
int i;
|
int i;
|
||||||
int64_t file_start = copy_ts * (
|
int64_t file_start = copy_ts * (
|
||||||
(f->ctx->start_time != AV_NOPTS_VALUE ? f->ctx->start_time * !start_at_zero : 0) +
|
(f->start_time_effective != AV_NOPTS_VALUE ? f->start_time_effective * !start_at_zero : 0) +
|
||||||
(f->start_time != AV_NOPTS_VALUE ? f->start_time : 0)
|
(f->start_time != AV_NOPTS_VALUE ? f->start_time : 0)
|
||||||
);
|
);
|
||||||
float scale = f->rate_emu ? 1.0 : f->readrate;
|
float scale = f->rate_emu ? 1.0 : f->readrate;
|
||||||
|
|
|
@ -202,13 +202,15 @@ int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_id
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Correct input file start times based on enabled streams */
|
||||||
static void correct_input_start_times(void)
|
static void correct_input_start_times(void)
|
||||||
{
|
{
|
||||||
// Correct starttime based on the enabled streams
|
|
||||||
for (int i = 0; i < nb_input_files; i++) {
|
for (int i = 0; i < nb_input_files; i++) {
|
||||||
InputFile *ifile = input_files[i];
|
InputFile *ifile = input_files[i];
|
||||||
AVFormatContext *is = ifile->ctx;
|
AVFormatContext *is = ifile->ctx;
|
||||||
int64_t new_start_time = INT64_MAX;
|
int64_t new_start_time = INT64_MAX, diff, abs_start_seek;
|
||||||
|
|
||||||
|
ifile->start_time_effective = is->start_time;
|
||||||
|
|
||||||
if (is->start_time == AV_NOPTS_VALUE ||
|
if (is->start_time == AV_NOPTS_VALUE ||
|
||||||
!(is->iformat->flags & AVFMT_TS_DISCONT))
|
!(is->iformat->flags & AVFMT_TS_DISCONT))
|
||||||
|
@ -220,9 +222,20 @@ static void correct_input_start_times(void)
|
||||||
continue;
|
continue;
|
||||||
new_start_time = FFMIN(new_start_time, av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q));
|
new_start_time = FFMIN(new_start_time, av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q));
|
||||||
}
|
}
|
||||||
if (new_start_time > is->start_time) {
|
|
||||||
av_log(is, AV_LOG_VERBOSE, "Correcting start time by %"PRId64"\n", new_start_time - is->start_time);
|
diff = new_start_time - is->start_time;
|
||||||
ifile->ts_offset = -new_start_time;
|
if (diff) {
|
||||||
|
av_log(NULL, AV_LOG_VERBOSE, "Correcting start time of Input #%d by %"PRId64" us.\n", i, diff);
|
||||||
|
ifile->start_time_effective = new_start_time;
|
||||||
|
if (copy_ts && start_at_zero)
|
||||||
|
ifile->ts_offset = -new_start_time;
|
||||||
|
else if (!copy_ts) {
|
||||||
|
abs_start_seek = is->start_time + (ifile->start_time != AV_NOPTS_VALUE) ? ifile->start_time : 0;
|
||||||
|
ifile->ts_offset = abs_start_seek > new_start_time ? -abs_start_seek : -new_start_time;
|
||||||
|
} else if (copy_ts)
|
||||||
|
ifile->ts_offset = 0;
|
||||||
|
|
||||||
|
ifile->ts_offset += ifile->input_ts_offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,9 +268,9 @@ static int apply_sync_offsets(void)
|
||||||
if (self->ctx->start_time_realtime != AV_NOPTS_VALUE && ref->ctx->start_time_realtime != AV_NOPTS_VALUE) {
|
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;
|
self_start_time = self->ctx->start_time_realtime;
|
||||||
ref_start_time = ref->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) {
|
} else if (self->start_time_effective != AV_NOPTS_VALUE && ref->start_time_effective != AV_NOPTS_VALUE) {
|
||||||
self_start_time = self->ctx->start_time;
|
self_start_time = self->start_time_effective;
|
||||||
ref_start_time = ref->ctx->start_time;
|
ref_start_time = ref->start_time_effective;
|
||||||
} else {
|
} else {
|
||||||
start_times_set = 0;
|
start_times_set = 0;
|
||||||
}
|
}
|
||||||
|
@ -1277,8 +1290,6 @@ int ffmpeg_parse_options(int argc, char **argv)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
apply_sync_offsets();
|
|
||||||
|
|
||||||
/* create the complex filtergraphs */
|
/* create the complex filtergraphs */
|
||||||
ret = init_complex_filters();
|
ret = init_complex_filters();
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -1295,6 +1306,8 @@ int ffmpeg_parse_options(int argc, char **argv)
|
||||||
|
|
||||||
correct_input_start_times();
|
correct_input_start_times();
|
||||||
|
|
||||||
|
apply_sync_offsets();
|
||||||
|
|
||||||
check_filter_outputs();
|
check_filter_outputs();
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
Loading…
Reference in New Issue