History

fftools/ffmpeg: move packet timestamp processing to demuxer thread

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.

Anton Khirnov committed 4 years ago

Commit 6ded80a1 parent 3b2bece2 files · +57 −52Browse files

Unified · Split

2 files
  1. fftools/ffmpeg.c +0 −52
  2. fftools/ffmpeg_demux.c +57 −0
fftools/ffmpeg.c+0−52
@@ -3792,7 +3792,6 @@ static int process_input(int file_index) · 3791 unmodified lines
3792 InputStream *ist;3792 InputStream *ist;
3793 AVPacket *pkt;3793 AVPacket *pkt;
3794 int ret, i, j;3794 int ret, i, j;
3795 int64_t duration;
3796 3795
3797 is = ifile->ctx;3796 is = ifile->ctx;
3798 ret = ifile_get_packet(ifile, &pkt);3797 ret = ifile_get_packet(ifile, &pkt);
@@ -3847,37 +3846,6 @@ static int process_input(int file_index) · 48 unmodified lines
3847 if (ist->discard)3846 if (ist->discard)
3848 goto discard_packet;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 /* add the stream-global side data to the first packet */3849 /* add the stream-global side data to the first packet */
3882 if (ist->nb_packets == 1) {3850 if (ist->nb_packets == 1) {
3883 for (i = 0; i < ist->st->nb_side_data; i++) {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 // detect and try to correct for timestamp discontinuities3869 // detect and try to correct for timestamp discontinuities
3922 ts_discontinuity_process(ifile, ist, pkt);3870 ts_discontinuity_process(ifile, ist, pkt);
3923 3871
fftools/ffmpeg_demux.c+57−0
@@ -114,6 +114,61 @@ static int seek_to_start(InputFile *ifile) · 113 unmodified lines
114 return ret;114 return ret;
115}115}
116 116
117static 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
117static void *input_thread(void *arg)172static void *input_thread(void *arg)
118{173{
119 InputFile *f = arg;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 msg.pkt = av_packet_alloc();236 msg.pkt = av_packet_alloc();
180 if (!msg.pkt) {237 if (!msg.pkt) {
181 av_packet_unref(pkt);238 av_packet_unref(pkt);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t