Discontinuity detection/correction is left in the main thread, as it is entangled with InputStream.next_dts and related variables, which may be set by decoding code. Fixes races e.g. in fate-ffmpeg-streamloop after aae9de0cb2887e6e0bbfda6ffdf85ab77d3390f0.
Unified · Split
| @@ -3792,7 +3792,6 @@ static int process_input(int file_index) · 3791 unmodified lines | ||
| 3792 | 3792 | InputStream *ist; |
| 3793 | 3793 | AVPacket *pkt; |
| 3794 | 3794 | int ret, i, j; |
| 3795 | − int64_t duration; | |
| 3796 | 3795 | |
| 3797 | 3796 | is = ifile->ctx; |
| 3798 | 3797 | ret = ifile_get_packet(ifile, &pkt); |
| @@ -3847,37 +3846,6 @@ static int process_input(int file_index) · 48 unmodified lines | ||
| 3847 | 3846 | if (ist->discard) |
| 3848 | 3847 | goto discard_packet; |
| 3849 | 3848 | |
| 3850 | − if (debug_ts) { | |
| 3851 | − av_log(NULL, AV_LOG_INFO, "demuxer -> ist_index:%d type:%s " | |
| 3852 | − "next_dts:%s next_dts_time:%s next_pts:%s next_pts_time:%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", | |
| 3853 | − ifile->ist_index + pkt->stream_index, | |
| 3854 | − av_get_media_type_string(ist->st->codecpar->codec_type), | |
| 3855 | − av_ts2str(ist->next_dts), av_ts2timestr(ist->next_dts, &AV_TIME_BASE_Q), | |
| 3856 | − av_ts2str(ist->next_pts), av_ts2timestr(ist->next_pts, &AV_TIME_BASE_Q), | |
| 3857 | − av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ist->st->time_base), | |
| 3858 | − av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ist->st->time_base), | |
| 3859 | − av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ist->st->time_base), | |
| 3860 | − av_ts2str(input_files[ist->file_index]->ts_offset), | |
| 3861 | − av_ts2timestr(input_files[ist->file_index]->ts_offset, &AV_TIME_BASE_Q)); | |
| 3862 | − } | |
| 3863 | − | |
| 3864 | − if(!ist->wrap_correction_done && is->start_time != AV_NOPTS_VALUE && ist->st->pts_wrap_bits < 64){ | |
| 3865 | − int64_t stime, stime2; | |
| 3866 | − | |
| 3867 | − stime = av_rescale_q(is->start_time, AV_TIME_BASE_Q, ist->st->time_base); | |
| 3868 | − stime2= stime + (1ULL<<ist->st->pts_wrap_bits); | |
| 3869 | − ist->wrap_correction_done = 1; | |
| 3870 | − | |
| 3871 | − if(stime2 > stime && pkt->dts != AV_NOPTS_VALUE && pkt->dts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) { | |
| 3872 | − pkt->dts -= 1ULL<<ist->st->pts_wrap_bits; | |
| 3873 | − ist->wrap_correction_done = 0; | |
| 3874 | − } | |
| 3875 | − if(stime2 > stime && pkt->pts != AV_NOPTS_VALUE && pkt->pts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) { | |
| 3876 | − pkt->pts -= 1ULL<<ist->st->pts_wrap_bits; | |
| 3877 | − ist->wrap_correction_done = 0; | |
| 3878 | − } | |
| 3879 | − } | |
| 3880 | − | |
| 3881 | 3849 | /* add the stream-global side data to the first packet */ |
| 3882 | 3850 | if (ist->nb_packets == 1) { |
| 3883 | 3851 | for (i = 0; i < ist->st->nb_side_data; i++) { |
| @@ -3898,26 +3866,6 @@ static int process_input(int file_index) · 14 unmodified lines | ||
| 3898 | 3866 | } |
| 3899 | 3867 | } |
| 3900 | 3868 | |
| 3901 | − if (pkt->dts != AV_NOPTS_VALUE) | |
| 3902 | − pkt->dts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base); | |
| 3903 | − if (pkt->pts != AV_NOPTS_VALUE) | |
| 3904 | − pkt->pts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base); | |
| 3905 | − | |
| 3906 | − if (pkt->pts != AV_NOPTS_VALUE) | |
| 3907 | − pkt->pts *= ist->ts_scale; | |
| 3908 | − if (pkt->dts != AV_NOPTS_VALUE) | |
| 3909 | − pkt->dts *= ist->ts_scale; | |
| 3910 | − | |
| 3911 | − duration = av_rescale_q(ifile->duration, ifile->time_base, ist->st->time_base); | |
| 3912 | − if (pkt->pts != AV_NOPTS_VALUE) { | |
| 3913 | − pkt->pts += duration; | |
| 3914 | − ist->max_pts = FFMAX(pkt->pts, ist->max_pts); | |
| 3915 | − ist->min_pts = FFMIN(pkt->pts, ist->min_pts); | |
| 3916 | − } | |
| 3917 | − | |
| 3918 | − if (pkt->dts != AV_NOPTS_VALUE) | |
| 3919 | − pkt->dts += duration; | |
| 3920 | − | |
| 3921 | 3869 | // detect and try to correct for timestamp discontinuities |
| 3922 | 3870 | ts_discontinuity_process(ifile, ist, pkt); |
| 3923 | 3871 | |
| @@ -114,6 +114,61 @@ static int seek_to_start(InputFile *ifile) · 113 unmodified lines | ||
| 114 | 114 | return ret; |
| 115 | 115 | } |
| 116 | 116 | |
| 117 | +static void ts_fixup(InputFile *ifile, AVPacket *pkt) | |
| 118 | +{ | |
| 119 | + InputStream *ist = input_streams[ifile->ist_index + pkt->stream_index]; | |
| 120 | + const int64_t start_time = ifile->ctx->start_time; | |
| 121 | + int64_t duration; | |
| 122 | + | |
| 123 | + if (debug_ts) { | |
| 124 | + av_log(NULL, AV_LOG_INFO, "demuxer -> ist_index:%d type:%s " | |
| 125 | + "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s\n", | |
| 126 | + ifile->ist_index + pkt->stream_index, | |
| 127 | + av_get_media_type_string(ist->st->codecpar->codec_type), | |
| 128 | + av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ist->st->time_base), | |
| 129 | + av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ist->st->time_base), | |
| 130 | + av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ist->st->time_base)); | |
| 131 | + } | |
| 132 | + | |
| 133 | + if (!ist->wrap_correction_done && start_time != AV_NOPTS_VALUE && | |
| 134 | + ist->st->pts_wrap_bits < 64) { | |
| 135 | + int64_t stime, stime2; | |
| 136 | + | |
| 137 | + stime = av_rescale_q(start_time, AV_TIME_BASE_Q, ist->st->time_base); | |
| 138 | + stime2= stime + (1ULL<<ist->st->pts_wrap_bits); | |
| 139 | + ist->wrap_correction_done = 1; | |
| 140 | + | |
| 141 | + if(stime2 > stime && pkt->dts != AV_NOPTS_VALUE && pkt->dts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) { | |
| 142 | + pkt->dts -= 1ULL<<ist->st->pts_wrap_bits; | |
| 143 | + ist->wrap_correction_done = 0; | |
| 144 | + } | |
| 145 | + if(stime2 > stime && pkt->pts != AV_NOPTS_VALUE && pkt->pts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) { | |
| 146 | + pkt->pts -= 1ULL<<ist->st->pts_wrap_bits; | |
| 147 | + ist->wrap_correction_done = 0; | |
| 148 | + } | |
| 149 | + } | |
| 150 | + | |
| 151 | + if (pkt->dts != AV_NOPTS_VALUE) | |
| 152 | + pkt->dts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base); | |
| 153 | + if (pkt->pts != AV_NOPTS_VALUE) | |
| 154 | + pkt->pts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base); | |
| 155 | + | |
| 156 | + if (pkt->pts != AV_NOPTS_VALUE) | |
| 157 | + pkt->pts *= ist->ts_scale; | |
| 158 | + if (pkt->dts != AV_NOPTS_VALUE) | |
| 159 | + pkt->dts *= ist->ts_scale; | |
| 160 | + | |
| 161 | + duration = av_rescale_q(ifile->duration, ifile->time_base, ist->st->time_base); | |
| 162 | + if (pkt->pts != AV_NOPTS_VALUE) { | |
| 163 | + pkt->pts += duration; | |
| 164 | + ist->max_pts = FFMAX(pkt->pts, ist->max_pts); | |
| 165 | + ist->min_pts = FFMIN(pkt->pts, ist->min_pts); | |
| 166 | + } | |
| 167 | + | |
| 168 | + if (pkt->dts != AV_NOPTS_VALUE) | |
| 169 | + pkt->dts += duration; | |
| 170 | +} | |
| 171 | + | |
| 117 | 172 | static void *input_thread(void *arg) |
| 118 | 173 | { |
| 119 | 174 | InputFile *f = arg; |
| @@ -176,6 +231,8 @@ static void *input_thread(void *arg) · 56 unmodified lines | ||
| 176 | 231 | } |
| 177 | 232 | } |
| 178 | 233 | |
| 234 | + ts_fixup(f, pkt); | |
| 235 | + | |
| 179 | 236 | msg.pkt = av_packet_alloc(); |
| 180 | 237 | if (!msg.pkt) { |
| 181 | 238 | av_packet_unref(pkt); |