This will allow to move normal offset handling to demuxer thread, since discontinuities currently have to be processed in the main thread, as the code uses some decoder-produced values.
Unified · Split
| @@ -3694,8 +3694,8 @@ static void decode_flush(InputFile *ifile) · 3693 unmodified lines | ||
| 3694 | 3694 | } |
| 3695 | 3695 | } |
| 3696 | 3696 | |
| 3697 | −static void ts_discontinuity_process(InputFile *ifile, InputStream *ist, | |
| 3698 | − AVPacket *pkt) | |
| 3697 | +static void ts_discontinuity_detect(InputFile *ifile, InputStream *ist, | |
| 3698 | + AVPacket *pkt) | |
| 3699 | 3699 | { |
| 3700 | 3700 | const int fmt_is_discont = ifile->ctx->iformat->flags & AVFMT_TS_DISCONT; |
| 3701 | 3701 | int disable_discontinuity_correction = copy_ts; |
| @@ -3716,13 +3716,13 @@ static void ts_discontinuity_process(InputFile *ifile, InputStream *ist, · 14 unmodified lines | ||
| 3716 | 3716 | if (fmt_is_discont) { |
| 3717 | 3717 | if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE || |
| 3718 | 3718 | pkt_dts + AV_TIME_BASE/10 < FFMAX(ist->pts, ist->dts)) { |
| 3719 | − ifile->ts_offset -= delta; | |
| 3719 | + ifile->ts_offset_discont -= delta; | |
| 3720 | 3720 | av_log(NULL, AV_LOG_DEBUG, |
| 3721 | 3721 | "timestamp discontinuity for stream #%d:%d " |
| 3722 | 3722 | "(id=%d, type=%s): %"PRId64", new offset= %"PRId64"\n", |
| 3723 | 3723 | ist->file_index, ist->st->index, ist->st->id, |
| 3724 | 3724 | av_get_media_type_string(ist->st->codecpar->codec_type), |
| 3725 | − delta, ifile->ts_offset); | |
| 3725 | + delta, ifile->ts_offset_discont); | |
| 3726 | 3726 | pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); |
| 3727 | 3727 | if (pkt->pts != AV_NOPTS_VALUE) |
| 3728 | 3728 | pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); |
| @@ -3745,10 +3745,10 @@ static void ts_discontinuity_process(InputFile *ifile, InputStream *ist, · 16 unmodified lines | ||
| 3745 | 3745 | fmt_is_discont && ifile->last_ts != AV_NOPTS_VALUE) { |
| 3746 | 3746 | int64_t delta = pkt_dts - ifile->last_ts; |
| 3747 | 3747 | if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE) { |
| 3748 | − ifile->ts_offset -= delta; | |
| 3748 | + ifile->ts_offset_discont -= delta; | |
| 3749 | 3749 | av_log(NULL, AV_LOG_DEBUG, |
| 3750 | 3750 | "Inter stream timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", |
| 3751 | − delta, ifile->ts_offset); | |
| 3751 | + delta, ifile->ts_offset_discont); | |
| 3752 | 3752 | pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); |
| 3753 | 3753 | if (pkt->pts != AV_NOPTS_VALUE) |
| 3754 | 3754 | pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); |
| @@ -3758,6 +3758,26 @@ static void ts_discontinuity_process(InputFile *ifile, InputStream *ist, · 3 unmodified lines | ||
| 3758 | 3758 | ifile->last_ts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); |
| 3759 | 3759 | } |
| 3760 | 3760 | |
| 3761 | +static void ts_discontinuity_process(InputFile *ifile, InputStream *ist, | |
| 3762 | + AVPacket *pkt) | |
| 3763 | +{ | |
| 3764 | + int64_t offset = av_rescale_q(ifile->ts_offset_discont, AV_TIME_BASE_Q, | |
| 3765 | + ist->st->time_base); | |
| 3766 | + | |
| 3767 | + // apply previously-detected timestamp-discontinuity offset | |
| 3768 | + // (to all streams, not just audio/video) | |
| 3769 | + if (pkt->dts != AV_NOPTS_VALUE) | |
| 3770 | + pkt->dts += offset; | |
| 3771 | + if (pkt->pts != AV_NOPTS_VALUE) | |
| 3772 | + pkt->pts += offset; | |
| 3773 | + | |
| 3774 | + // detect timestamp discontinuities for audio/video | |
| 3775 | + if ((ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || | |
| 3776 | + ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) && | |
| 3777 | + pkt->dts != AV_NOPTS_VALUE) | |
| 3778 | + ts_discontinuity_detect(ifile, ist, pkt); | |
| 3779 | +} | |
| 3780 | + | |
| 3761 | 3781 | /* |
| 3762 | 3782 | * Return |
| 3763 | 3783 | * - 0 -- one packet was read and processed |
| @@ -3898,11 +3918,8 @@ static int process_input(int file_index) · 134 unmodified lines | ||
| 3898 | 3918 | if (pkt->dts != AV_NOPTS_VALUE) |
| 3899 | 3919 | pkt->dts += duration; |
| 3900 | 3920 | |
| 3901 | − // detect and correct timestamp discontinuities for audio/video | |
| 3902 | − if ((ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || | |
| 3903 | − ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) && | |
| 3904 | − pkt->dts != AV_NOPTS_VALUE) | |
| 3905 | − ts_discontinuity_process(ifile, ist, pkt); | |
| 3921 | + // detect and try to correct for timestamp discontinuities | |
| 3922 | + ts_discontinuity_process(ifile, ist, pkt); | |
| 3906 | 3923 | |
| 3907 | 3924 | if (debug_ts) { |
| 3908 | 3925 | av_log(NULL, AV_LOG_INFO, "demuxer+ffmpeg -> ist_index:%d type:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s off:%s off_time:%s\n", |
| @@ -427,6 +427,10 @@ typedef struct InputFile { · 426 unmodified lines | ||
| 427 | 427 | int input_sync_ref; |
| 428 | 428 | |
| 429 | 429 | int64_t ts_offset; |
| 430 | + /** | |
| 431 | + * Extra timestamp offset added by discontinuity handling. | |
| 432 | + */ | |
| 433 | + int64_t ts_offset_discont; | |
| 430 | 434 | int64_t last_ts; |
| 431 | 435 | int64_t start_time; /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */ |
| 432 | 436 | int64_t recording_time; |