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, | 3697 | static void ts_discontinuity_detect(InputFile *ifile, InputStream *ist, |
| 3698 | AVPacket *pkt) | 3698 | AVPacket *pkt) |
| 3699 | { | 3699 | { |
| 3700 | const int fmt_is_discont = ifile->ctx->iformat->flags & AVFMT_TS_DISCONT; | 3700 | const int fmt_is_discont = ifile->ctx->iformat->flags & AVFMT_TS_DISCONT; |
| 3701 | int disable_discontinuity_correction = copy_ts; | 3701 | int disable_discontinuity_correction = copy_ts; |
| @@ -3716,13 +3716,13 @@ static void ts_discontinuity_process(InputFile *ifile, InputStream *ist, · 14 unmodified lines | |||
| 3716 | if (fmt_is_discont) { | 3716 | if (fmt_is_discont) { |
| 3717 | if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE || | 3717 | if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE || |
| 3718 | pkt_dts + AV_TIME_BASE/10 < FFMAX(ist->pts, ist->dts)) { | 3718 | pkt_dts + AV_TIME_BASE/10 < FFMAX(ist->pts, ist->dts)) { |
| 3719 | ifile->ts_offset -= delta; | 3719 | ifile->ts_offset_discont -= delta; |
| 3720 | av_log(NULL, AV_LOG_DEBUG, | 3720 | av_log(NULL, AV_LOG_DEBUG, |
| 3721 | "timestamp discontinuity for stream #%d:%d " | 3721 | "timestamp discontinuity for stream #%d:%d " |
| 3722 | "(id=%d, type=%s): %"PRId64", new offset= %"PRId64"\n", | 3722 | "(id=%d, type=%s): %"PRId64", new offset= %"PRId64"\n", |
| 3723 | ist->file_index, ist->st->index, ist->st->id, | 3723 | ist->file_index, ist->st->index, ist->st->id, |
| 3724 | av_get_media_type_string(ist->st->codecpar->codec_type), | 3724 | av_get_media_type_string(ist->st->codecpar->codec_type), |
| 3725 | delta, ifile->ts_offset); | 3725 | delta, ifile->ts_offset_discont); |
| 3726 | pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); | 3726 | pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); |
| 3727 | if (pkt->pts != AV_NOPTS_VALUE) | 3727 | if (pkt->pts != AV_NOPTS_VALUE) |
| 3728 | pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); | 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 | fmt_is_discont && ifile->last_ts != AV_NOPTS_VALUE) { | 3745 | fmt_is_discont && ifile->last_ts != AV_NOPTS_VALUE) { |
| 3746 | int64_t delta = pkt_dts - ifile->last_ts; | 3746 | int64_t delta = pkt_dts - ifile->last_ts; |
| 3747 | if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE) { | 3747 | if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE) { |
| 3748 | ifile->ts_offset -= delta; | 3748 | ifile->ts_offset_discont -= delta; |
| 3749 | av_log(NULL, AV_LOG_DEBUG, | 3749 | av_log(NULL, AV_LOG_DEBUG, |
| 3750 | "Inter stream timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", | 3750 | "Inter stream timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", |
| 3751 | delta, ifile->ts_offset); | 3751 | delta, ifile->ts_offset_discont); |
| 3752 | pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); | 3752 | pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); |
| 3753 | if (pkt->pts != AV_NOPTS_VALUE) | 3753 | if (pkt->pts != AV_NOPTS_VALUE) |
| 3754 | pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); | 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 | ifile->last_ts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); | 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 | * Return | 3782 | * Return |
| 3763 | * - 0 -- one packet was read and processed | 3783 | * - 0 -- one packet was read and processed |
| @@ -3898,11 +3918,8 @@ static int process_input(int file_index) · 134 unmodified lines | |||
| 3898 | if (pkt->dts != AV_NOPTS_VALUE) | 3918 | if (pkt->dts != AV_NOPTS_VALUE) |
| 3899 | pkt->dts += duration; | 3919 | pkt->dts += duration; |
| 3900 | 3920 | ||
| 3901 | // detect and correct timestamp discontinuities for audio/video | 3921 | // detect and try to correct for timestamp discontinuities |
| 3902 | if ((ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || | 3922 | ts_discontinuity_process(ifile, ist, pkt); |
| 3903 | ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) && | ||
| 3904 | pkt->dts != AV_NOPTS_VALUE) | ||
| 3905 | ts_discontinuity_process(ifile, ist, pkt); | ||
| 3906 | 3923 | ||
| 3907 | if (debug_ts) { | 3924 | if (debug_ts) { |
| 3908 | 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", | 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 | int input_sync_ref; | 427 | int input_sync_ref; |
| 428 | 428 | ||
| 429 | int64_t ts_offset; | 429 | int64_t ts_offset; |
| 430 | /** | ||
| 431 | * Extra timestamp offset added by discontinuity handling. | ||
| 432 | */ | ||
| 433 | int64_t ts_offset_discont; | ||
| 430 | int64_t last_ts; | 434 | int64_t last_ts; |
| 431 | int64_t start_time; /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */ | 435 | int64_t start_time; /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */ |
| 432 | int64_t recording_time; | 436 | int64_t recording_time; |