|
|
|
@ -90,6 +90,12 @@ typedef struct Demuxer { |
|
|
|
|
|
|
|
|
|
int64_t wallclock_start; |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Extra timestamp offset added by discontinuity handling. |
|
|
|
|
*/ |
|
|
|
|
int64_t ts_offset_discont; |
|
|
|
|
int64_t last_ts; |
|
|
|
|
|
|
|
|
|
/* number of times input stream should be looped */ |
|
|
|
|
int loop; |
|
|
|
|
/* actual duration of the longest stream in a file at the moment when
|
|
|
|
@ -205,9 +211,10 @@ static int seek_to_start(Demuxer *d) |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void ts_discontinuity_detect(InputFile *ifile, InputStream *ist, |
|
|
|
|
static void ts_discontinuity_detect(Demuxer *d, InputStream *ist, |
|
|
|
|
AVPacket *pkt) |
|
|
|
|
{ |
|
|
|
|
InputFile *ifile = &d->f; |
|
|
|
|
DemuxStream *ds = ds_from_ist(ist); |
|
|
|
|
const int fmt_is_discont = ifile->ctx->iformat->flags & AVFMT_TS_DISCONT; |
|
|
|
|
int disable_discontinuity_correction = copy_ts; |
|
|
|
@ -228,13 +235,13 @@ static void ts_discontinuity_detect(InputFile *ifile, InputStream *ist, |
|
|
|
|
if (fmt_is_discont) { |
|
|
|
|
if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE || |
|
|
|
|
pkt_dts + AV_TIME_BASE/10 < ds->dts) { |
|
|
|
|
ifile->ts_offset_discont -= delta; |
|
|
|
|
d->ts_offset_discont -= delta; |
|
|
|
|
av_log(NULL, AV_LOG_WARNING, |
|
|
|
|
"timestamp discontinuity for stream #%d:%d " |
|
|
|
|
"(id=%d, type=%s): %"PRId64", new offset= %"PRId64"\n", |
|
|
|
|
ist->file_index, ist->st->index, ist->st->id, |
|
|
|
|
av_get_media_type_string(ist->par->codec_type), |
|
|
|
|
delta, ifile->ts_offset_discont); |
|
|
|
|
delta, d->ts_offset_discont); |
|
|
|
|
pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, pkt->time_base); |
|
|
|
|
if (pkt->pts != AV_NOPTS_VALUE) |
|
|
|
|
pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, pkt->time_base); |
|
|
|
@ -258,26 +265,26 @@ static void ts_discontinuity_detect(InputFile *ifile, InputStream *ist, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else if (ds->next_dts == AV_NOPTS_VALUE && !copy_ts && |
|
|
|
|
fmt_is_discont && ifile->last_ts != AV_NOPTS_VALUE) { |
|
|
|
|
int64_t delta = pkt_dts - ifile->last_ts; |
|
|
|
|
fmt_is_discont && d->last_ts != AV_NOPTS_VALUE) { |
|
|
|
|
int64_t delta = pkt_dts - d->last_ts; |
|
|
|
|
if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE) { |
|
|
|
|
ifile->ts_offset_discont -= delta; |
|
|
|
|
d->ts_offset_discont -= delta; |
|
|
|
|
av_log(NULL, AV_LOG_DEBUG, |
|
|
|
|
"Inter stream timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", |
|
|
|
|
delta, ifile->ts_offset_discont); |
|
|
|
|
delta, d->ts_offset_discont); |
|
|
|
|
pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, pkt->time_base); |
|
|
|
|
if (pkt->pts != AV_NOPTS_VALUE) |
|
|
|
|
pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, pkt->time_base); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ifile->last_ts = av_rescale_q(pkt->dts, pkt->time_base, AV_TIME_BASE_Q); |
|
|
|
|
d->last_ts = av_rescale_q(pkt->dts, pkt->time_base, AV_TIME_BASE_Q); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void ts_discontinuity_process(InputFile *ifile, InputStream *ist, |
|
|
|
|
static void ts_discontinuity_process(Demuxer *d, InputStream *ist, |
|
|
|
|
AVPacket *pkt) |
|
|
|
|
{ |
|
|
|
|
int64_t offset = av_rescale_q(ifile->ts_offset_discont, AV_TIME_BASE_Q, |
|
|
|
|
int64_t offset = av_rescale_q(d->ts_offset_discont, AV_TIME_BASE_Q, |
|
|
|
|
pkt->time_base); |
|
|
|
|
|
|
|
|
|
// apply previously-detected timestamp-discontinuity offset
|
|
|
|
@ -291,7 +298,7 @@ static void ts_discontinuity_process(InputFile *ifile, InputStream *ist, |
|
|
|
|
if ((ist->par->codec_type == AVMEDIA_TYPE_VIDEO || |
|
|
|
|
ist->par->codec_type == AVMEDIA_TYPE_AUDIO) && |
|
|
|
|
pkt->dts != AV_NOPTS_VALUE) |
|
|
|
|
ts_discontinuity_detect(ifile, ist, pkt); |
|
|
|
|
ts_discontinuity_detect(d, ist, pkt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int ist_dts_update(DemuxStream *ds, AVPacket *pkt) |
|
|
|
@ -429,7 +436,7 @@ static int ts_fixup(Demuxer *d, AVPacket *pkt) |
|
|
|
|
SHOW_TS_DEBUG("demuxer+tsfixup"); |
|
|
|
|
|
|
|
|
|
// detect and try to correct for timestamp discontinuities
|
|
|
|
|
ts_discontinuity_process(ifile, ist, pkt); |
|
|
|
|
ts_discontinuity_process(d, ist, pkt); |
|
|
|
|
|
|
|
|
|
// update estimated/predicted dts
|
|
|
|
|
ret = ist_dts_update(ds, pkt); |
|
|
|
|