FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_demux.c
Date: 2022-10-02 18:56:10
Exec Total Coverage
Lines: 163 220 74.1%
Branches: 114 158 72.2%

Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "ffmpeg.h"
20
21 #include "libavutil/avassert.h"
22 #include "libavutil/error.h"
23 #include "libavutil/time.h"
24 #include "libavutil/timestamp.h"
25 #include "libavutil/thread.h"
26 #include "libavutil/threadmessage.h"
27
28 #include "libavcodec/packet.h"
29
30 #include "libavformat/avformat.h"
31
32 typedef struct DemuxMsg {
33 AVPacket *pkt;
34 int looping;
35
36 // repeat_pict from the demuxer-internal parser
37 int repeat_pict;
38 } DemuxMsg;
39
40 static void report_new_stream(InputFile *file, const AVPacket *pkt)
41 {
42 AVStream *st = file->ctx->streams[pkt->stream_index];
43
44 if (pkt->stream_index < file->nb_streams_warn)
45 return;
46 av_log(file->ctx, AV_LOG_WARNING,
47 "New %s stream %d:%d at pos:%"PRId64" and DTS:%ss\n",
48 av_get_media_type_string(st->codecpar->codec_type),
49 file->index, pkt->stream_index,
50 pkt->pos, av_ts2timestr(pkt->dts, &st->time_base));
51 file->nb_streams_warn = pkt->stream_index + 1;
52 }
53
54 6 static void ifile_duration_update(InputFile *f, InputStream *ist,
55 int64_t last_duration)
56 {
57 /* the total duration of the stream, max_pts - min_pts is
58 * the duration of the stream without the last frame */
59
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (ist->max_pts > ist->min_pts &&
60
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 ist->max_pts - (uint64_t)ist->min_pts < INT64_MAX - last_duration)
61 6 last_duration += ist->max_pts - ist->min_pts;
62
63
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
10 if (!f->duration ||
64 4 av_compare_ts(f->duration, f->time_base,
65 4 last_duration, ist->st->time_base) < 0) {
66 6 f->duration = last_duration;
67 6 f->time_base = ist->st->time_base;
68 }
69 6 }
70
71 6 static int seek_to_start(InputFile *ifile)
72 {
73 6 AVFormatContext *is = ifile->ctx;
74 InputStream *ist;
75 int ret;
76
77 6 ret = avformat_seek_file(is, -1, INT64_MIN, is->start_time, is->start_time, 0);
78
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0)
79 return ret;
80
81
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ifile->audio_duration_queue_size) {
82 /* duration is the length of the last frame in a stream
83 * when audio stream is present we don't care about
84 * last video frame length because it's not defined exactly */
85 int got_durations = 0;
86
87 while (got_durations < ifile->audio_duration_queue_size) {
88 LastFrameDuration dur;
89 ret = av_thread_message_queue_recv(ifile->audio_duration_queue, &dur, 0);
90 if (ret < 0)
91 return ret;
92 got_durations++;
93
94 ist = input_streams[ifile->ist_index + dur.stream_idx];
95 ifile_duration_update(ifile, ist, dur.duration);
96 }
97 } else {
98
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 for (int i = 0; i < ifile->nb_streams; i++) {
99 6 int64_t duration = 0;
100 6 ist = input_streams[ifile->ist_index + i];
101
102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ist->framerate.num) {
103 duration = av_rescale_q(1, av_inv_q(ist->framerate), ist->st->time_base);
104
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 } else if (ist->st->avg_frame_rate.num) {
105 2 duration = av_rescale_q(1, av_inv_q(ist->st->avg_frame_rate), ist->st->time_base);
106 } else {
107 4 duration = 1;
108 }
109
110 6 ifile_duration_update(ifile, ist, duration);
111 }
112 }
113
114
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (ifile->loop > 0)
115 6 ifile->loop--;
116
117 6 return ret;
118 }
119
120 452618 static void ts_fixup(InputFile *ifile, AVPacket *pkt, int *repeat_pict)
121 {
122 452618 InputStream *ist = input_streams[ifile->ist_index + pkt->stream_index];
123 452618 const int64_t start_time = ifile->ctx->start_time;
124 int64_t duration;
125
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 452618 times.
452618 if (debug_ts) {
127 av_log(NULL, AV_LOG_INFO, "demuxer -> ist_index:%d type:%s "
128 "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s\n",
129 ifile->ist_index + pkt->stream_index,
130 av_get_media_type_string(ist->st->codecpar->codec_type),
131 av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ist->st->time_base),
132 av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ist->st->time_base),
133 av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ist->st->time_base));
134 }
135
136
4/4
✓ Branch 0 taken 400572 times.
✓ Branch 1 taken 52046 times.
✓ Branch 2 taken 268465 times.
✓ Branch 3 taken 132107 times.
452618 if (!ist->wrap_correction_done && start_time != AV_NOPTS_VALUE &&
137
2/2
✓ Branch 0 taken 363 times.
✓ Branch 1 taken 268102 times.
268465 ist->st->pts_wrap_bits < 64) {
138 int64_t stime, stime2;
139
140 363 stime = av_rescale_q(start_time, AV_TIME_BASE_Q, ist->st->time_base);
141 363 stime2= stime + (1ULL<<ist->st->pts_wrap_bits);
142 363 ist->wrap_correction_done = 1;
143
144
5/6
✓ Branch 0 taken 331 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 294 times.
✓ Branch 3 taken 37 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 294 times.
363 if(stime2 > stime && pkt->dts != AV_NOPTS_VALUE && pkt->dts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) {
145 pkt->dts -= 1ULL<<ist->st->pts_wrap_bits;
146 ist->wrap_correction_done = 0;
147 }
148
5/6
✓ Branch 0 taken 331 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 287 times.
✓ Branch 3 taken 44 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 287 times.
363 if(stime2 > stime && pkt->pts != AV_NOPTS_VALUE && pkt->pts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) {
149 pkt->pts -= 1ULL<<ist->st->pts_wrap_bits;
150 ist->wrap_correction_done = 0;
151 }
152 }
153
154
2/2
✓ Branch 0 taken 414141 times.
✓ Branch 1 taken 38477 times.
452618 if (pkt->dts != AV_NOPTS_VALUE)
155 414141 pkt->dts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
156
2/2
✓ Branch 0 taken 412036 times.
✓ Branch 1 taken 40582 times.
452618 if (pkt->pts != AV_NOPTS_VALUE)
157 412036 pkt->pts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
158
159
2/2
✓ Branch 0 taken 412036 times.
✓ Branch 1 taken 40582 times.
452618 if (pkt->pts != AV_NOPTS_VALUE)
160 412036 pkt->pts *= ist->ts_scale;
161
2/2
✓ Branch 0 taken 414141 times.
✓ Branch 1 taken 38477 times.
452618 if (pkt->dts != AV_NOPTS_VALUE)
162 414141 pkt->dts *= ist->ts_scale;
163
164 452618 duration = av_rescale_q(ifile->duration, ifile->time_base, ist->st->time_base);
165
2/2
✓ Branch 0 taken 412036 times.
✓ Branch 1 taken 40582 times.
452618 if (pkt->pts != AV_NOPTS_VALUE) {
166 412036 pkt->pts += duration;
167 412036 ist->max_pts = FFMAX(pkt->pts, ist->max_pts);
168 412036 ist->min_pts = FFMIN(pkt->pts, ist->min_pts);
169 }
170
171
2/2
✓ Branch 0 taken 414141 times.
✓ Branch 1 taken 38477 times.
452618 if (pkt->dts != AV_NOPTS_VALUE)
172 414141 pkt->dts += duration;
173
174 452618 *repeat_pict = -1;
175
4/4
✓ Branch 0 taken 128036 times.
✓ Branch 1 taken 324582 times.
✓ Branch 2 taken 57080 times.
✓ Branch 3 taken 70956 times.
580654 if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
176 128036 av_stream_get_parser(ist->st))
177 57080 *repeat_pict = av_stream_get_parser(ist->st)->repeat_pict;
178 452618 }
179
180 6454 static void *input_thread(void *arg)
181 {
182 6454 InputFile *f = arg;
183 AVPacket *pkt;
184 6454 unsigned flags = f->non_blocking ? AV_THREAD_MESSAGE_NONBLOCK : 0;
185 6454 int ret = 0;
186
187 6454 pkt = av_packet_alloc();
188
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6454 times.
6454 if (!pkt) {
189 ret = AVERROR(ENOMEM);
190 goto finish;
191 }
192
193 449545 while (1) {
194 455999 DemuxMsg msg = { NULL };
195
196 455999 ret = av_read_frame(f->ctx, pkt);
197
198
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 455998 times.
455999 if (ret == AVERROR(EAGAIN)) {
199 1 av_usleep(10000);
200 7 continue;
201 }
202
2/2
✓ Branch 0 taken 3380 times.
✓ Branch 1 taken 452618 times.
455998 if (ret < 0) {
203
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3374 times.
3380 if (f->loop) {
204 /* signal looping to the consumer thread */
205 6 msg.looping = 1;
206 6 ret = av_thread_message_queue_send(f->in_thread_queue, &msg, 0);
207
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (ret >= 0)
208 6 ret = seek_to_start(f);
209
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (ret >= 0)
210 6 continue;
211
212 /* fallthrough to the error path */
213 }
214
215 6454 break;
216 }
217
218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 452618 times.
452618 if (do_pkt_dump) {
219 av_pkt_dump_log2(NULL, AV_LOG_INFO, pkt, do_hex_dump,
220 f->ctx->streams[pkt->stream_index]);
221 }
222
223 /* the following test is needed in case new streams appear
224 dynamically in stream : we ignore them */
225
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 452618 times.
452618 if (pkt->stream_index >= f->nb_streams) {
226 report_new_stream(f, pkt);
227 av_packet_unref(pkt);
228 continue;
229 }
230
231
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 452510 times.
452618 if (pkt->flags & AV_PKT_FLAG_CORRUPT) {
232 108 av_log(NULL, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING,
233 "%s: corrupt input packet in stream %d\n",
234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 f->ctx->url, pkt->stream_index);
235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (exit_on_error) {
236 av_packet_unref(pkt);
237 ret = AVERROR_INVALIDDATA;
238 break;
239 }
240 }
241
242 452618 ts_fixup(f, pkt, &msg.repeat_pict);
243
244 452618 msg.pkt = av_packet_alloc();
245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 452618 times.
452618 if (!msg.pkt) {
246 av_packet_unref(pkt);
247 ret = AVERROR(ENOMEM);
248 break;
249 }
250 452618 av_packet_move_ref(msg.pkt, pkt);
251 452618 ret = av_thread_message_queue_send(f->in_thread_queue, &msg, flags);
252
4/4
✓ Branch 0 taken 5603 times.
✓ Branch 1 taken 447015 times.
✓ Branch 2 taken 2600 times.
✓ Branch 3 taken 3003 times.
452618 if (flags && ret == AVERROR(EAGAIN)) {
253 2600 flags = 0;
254 2600 ret = av_thread_message_queue_send(f->in_thread_queue, &msg, flags);
255 2600 av_log(f->ctx, AV_LOG_WARNING,
256 "Thread message queue blocking; consider raising the "
257 "thread_queue_size option (current value: %d)\n",
258 f->thread_queue_size);
259 }
260
2/2
✓ Branch 0 taken 3080 times.
✓ Branch 1 taken 449538 times.
452618 if (ret < 0) {
261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3080 times.
3080 if (ret != AVERROR_EOF)
262 av_log(f->ctx, AV_LOG_ERROR,
263 "Unable to send packet to main thread: %s\n",
264 av_err2str(ret));
265 3080 av_packet_free(&msg.pkt);
266 3080 break;
267 }
268 }
269
270 6454 finish:
271
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6454 times.
6454 av_assert0(ret < 0);
272 6454 av_thread_message_queue_set_err_recv(f->in_thread_queue, ret);
273
274 6454 av_packet_free(&pkt);
275
276 6454 return NULL;
277 }
278
279 19362 static void free_input_thread(int i)
280 {
281 19362 InputFile *f = input_files[i];
282 DemuxMsg msg;
283
284
3/4
✓ Branch 0 taken 19362 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12908 times.
✓ Branch 3 taken 6454 times.
19362 if (!f || !f->in_thread_queue)
285 12908 return;
286 6454 av_thread_message_queue_set_err_send(f->in_thread_queue, AVERROR_EOF);
287
2/2
✓ Branch 1 taken 3526 times.
✓ Branch 2 taken 6454 times.
9980 while (av_thread_message_queue_recv(f->in_thread_queue, &msg, 0) >= 0)
288 3526 av_packet_free(&msg.pkt);
289
290 6454 pthread_join(f->thread, NULL);
291 6454 av_thread_message_queue_free(&f->in_thread_queue);
292 6454 av_thread_message_queue_free(&f->audio_duration_queue);
293 }
294
295 19264 void free_input_threads(void)
296 {
297 int i;
298
299
2/2
✓ Branch 0 taken 19362 times.
✓ Branch 1 taken 19264 times.
38626 for (i = 0; i < nb_input_files; i++)
300 19362 free_input_thread(i);
301 19264 }
302
303 6454 static int init_input_thread(int i)
304 {
305 int ret;
306 6454 InputFile *f = input_files[i];
307
308
1/2
✓ Branch 0 taken 6454 times.
✗ Branch 1 not taken.
6454 if (f->thread_queue_size <= 0)
309
2/2
✓ Branch 0 taken 159 times.
✓ Branch 1 taken 6295 times.
6454 f->thread_queue_size = (nb_input_files > 1 ? 8 : 1);
310
311
4/4
✓ Branch 0 taken 3823 times.
✓ Branch 1 taken 2631 times.
✓ Branch 2 taken 2604 times.
✓ Branch 3 taken 3850 times.
9085 if (f->ctx->pb ? !f->ctx->pb->seekable :
312 2631 strcmp(f->ctx->iformat->name, "lavfi"))
313 2604 f->non_blocking = 1;
314 6454 ret = av_thread_message_queue_alloc(&f->in_thread_queue,
315 6454 f->thread_queue_size, sizeof(DemuxMsg));
316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6454 times.
6454 if (ret < 0)
317 return ret;
318
319
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6452 times.
6454 if (f->loop) {
320 2 int nb_audio_dec = 0;
321
322
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 for (int i = 0; i < f->nb_streams; i++) {
323 2 InputStream *ist = input_streams[f->ist_index + i];
324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 nb_audio_dec += !!(ist->decoding_needed &&
325 ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO);
326 }
327
328
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (nb_audio_dec) {
329 ret = av_thread_message_queue_alloc(&f->audio_duration_queue,
330 nb_audio_dec, sizeof(LastFrameDuration));
331 if (ret < 0)
332 goto fail;
333 f->audio_duration_queue_size = nb_audio_dec;
334 }
335 }
336
337
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6454 times.
6454 if ((ret = pthread_create(&f->thread, NULL, input_thread, f))) {
338 av_log(NULL, AV_LOG_ERROR, "pthread_create failed: %s. Try to increase `ulimit -v` or decrease `ulimit -s`.\n", strerror(ret));
339 ret = AVERROR(ret);
340 goto fail;
341 }
342
343 6454 return 0;
344 fail:
345 av_thread_message_queue_free(&f->in_thread_queue);
346 return ret;
347 }
348
349 6421 int init_input_threads(void)
350 {
351 int i, ret;
352
353
2/2
✓ Branch 0 taken 6454 times.
✓ Branch 1 taken 6421 times.
12875 for (i = 0; i < nb_input_files; i++) {
354 6454 ret = init_input_thread(i);
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6454 times.
6454 if (ret < 0)
356 return ret;
357 }
358 6421 return 0;
359 }
360
361 453938 int ifile_get_packet(InputFile *f, AVPacket **pkt)
362 {
363 InputStream *ist;
364 DemuxMsg msg;
365 int ret;
366
367
3/4
✓ Branch 0 taken 453938 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 702 times.
✓ Branch 3 taken 453236 times.
453938 if (f->readrate || f->rate_emu) {
368 int i;
369 1404 int64_t file_start = copy_ts * (
370
1/2
✓ Branch 0 taken 702 times.
✗ Branch 1 not taken.
702 (f->ctx->start_time != AV_NOPTS_VALUE ? f->ctx->start_time * !start_at_zero : 0) +
371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 702 times.
702 (f->start_time != AV_NOPTS_VALUE ? f->start_time : 0)
372 );
373
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 702 times.
702 float scale = f->rate_emu ? 1.0 : f->readrate;
374
2/2
✓ Branch 0 taken 702 times.
✓ Branch 1 taken 217 times.
919 for (i = 0; i < f->nb_streams; i++) {
375 702 InputStream *ist = input_streams[f->ist_index + i];
376 int64_t stream_ts_offset, pts, now;
377
4/6
✓ Branch 0 taken 701 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 701 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 701 times.
702 if (!ist->nb_packets || (ist->decoding_needed && !ist->got_output)) continue;
378
1/2
✓ Branch 0 taken 701 times.
✗ Branch 1 not taken.
701 stream_ts_offset = FFMAX(ist->first_dts != AV_NOPTS_VALUE ? ist->first_dts : 0, file_start);
379 701 pts = av_rescale(ist->dts, 1000000, AV_TIME_BASE);
380 701 now = (av_gettime_relative() - ist->start) * scale + stream_ts_offset;
381
2/2
✓ Branch 0 taken 485 times.
✓ Branch 1 taken 216 times.
701 if (pts > now)
382 485 return AVERROR(EAGAIN);
383 }
384 }
385
386 453453 ret = av_thread_message_queue_recv(f->in_thread_queue, &msg,
387 453453 f->non_blocking ?
388 AV_THREAD_MESSAGE_NONBLOCK : 0);
389
2/2
✓ Branch 0 taken 7435 times.
✓ Branch 1 taken 446018 times.
453453 if (ret < 0)
390 7435 return ret;
391
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 446012 times.
446018 if (msg.looping)
392 6 return 1;
393
394 446012 ist = input_streams[f->ist_index + msg.pkt->stream_index];
395 446012 ist->last_pkt_repeat_pict = msg.repeat_pict;
396
397 446012 *pkt = msg.pkt;
398 446012 return 0;
399 }
400