FFmpegKit Linux API 6.0
Loading...
Searching...
No Matches
fftools_ffmpeg_demux.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2023 ARTHENICA LTD
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/*
22 * This file is the modified version of ffmpeg_demux.c file living in ffmpeg source code under the fftools folder. We
23 * manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
24 * by us to develop ffmpeg-kit library.
25 *
26 * ffmpeg-kit changes by ARTHENICA LTD
27 *
28 * 07.2023
29 * --------------------------------------------------------
30 * - FFmpeg 6.0 changes migrated
31 * - fftools_ prefix added to the file name
32 * - fftools_ffmpeg_mux.h include added
33 */
34
35#include <float.h>
36#include <stdint.h>
37
38#include "fftools_ffmpeg.h"
39#include "fftools_ffmpeg_mux.h"
40
41#include "libavutil/avassert.h"
42#include "libavutil/avstring.h"
43#include "libavutil/display.h"
44#include "libavutil/error.h"
45#include "libavutil/intreadwrite.h"
46#include "libavutil/opt.h"
47#include "libavutil/parseutils.h"
48#include "libavutil/pixdesc.h"
49#include "libavutil/time.h"
50#include "libavutil/timestamp.h"
51#include "libavutil/thread.h"
52#include "libavutil/threadmessage.h"
53
54#include "libavcodec/packet.h"
55
56#include "libavformat/avformat.h"
57
58static const char *const opt_name_discard[] = {"discard", NULL};
59static const char *const opt_name_reinit_filters[] = {"reinit_filter", NULL};
60static const char *const opt_name_fix_sub_duration[] = {"fix_sub_duration", NULL};
61static const char *const opt_name_canvas_sizes[] = {"canvas_size", NULL};
62static const char *const opt_name_guess_layout_max[] = {"guess_layout_max", NULL};
63static const char *const opt_name_ts_scale[] = {"itsscale", NULL};
64static const char *const opt_name_hwaccels[] = {"hwaccel", NULL};
65static const char *const opt_name_hwaccel_devices[] = {"hwaccel_device", NULL};
66static const char *const opt_name_hwaccel_output_formats[] = {"hwaccel_output_format", NULL};
67static const char *const opt_name_autorotate[] = {"autorotate", NULL};
68static const char *const opt_name_display_rotations[] = {"display_rotation", NULL};
69static const char *const opt_name_display_hflips[] = {"display_hflip", NULL};
70static const char *const opt_name_display_vflips[] = {"display_vflip", NULL};
71
72typedef struct Demuxer {
74
75 /* number of times input stream should be looped */
76 int loop;
77 /* actual duration of the longest stream in a file at the moment when
78 * looping happens */
79 int64_t duration;
80 /* time base of the duration */
81 AVRational time_base;
82
83 /* number of streams that the user was warned of */
85
86 AVThreadMessageQueue *in_thread_queue;
88 pthread_t thread;
91
92typedef struct DemuxMsg {
93 AVPacket *pkt;
95
96 // repeat_pict from the demuxer-internal parser
99
101{
102 return (Demuxer*)f;
103}
104
105static void report_new_stream(Demuxer *d, const AVPacket *pkt)
106{
107 AVStream *st = d->f.ctx->streams[pkt->stream_index];
108
109 if (pkt->stream_index < d->nb_streams_warn)
110 return;
111 av_log(NULL, AV_LOG_WARNING,
112 "New %s stream %d:%d at pos:%"PRId64" and DTS:%ss\n",
113 av_get_media_type_string(st->codecpar->codec_type),
114 d->f.index, pkt->stream_index,
115 pkt->pos, av_ts2timestr(pkt->dts, &st->time_base));
116 d->nb_streams_warn = pkt->stream_index + 1;
117}
118
120 int64_t last_duration)
121{
122 /* the total duration of the stream, max_pts - min_pts is
123 * the duration of the stream without the last frame */
124 if (ist->max_pts > ist->min_pts &&
125 ist->max_pts - (uint64_t)ist->min_pts < INT64_MAX - last_duration)
126 last_duration += ist->max_pts - ist->min_pts;
127
128 if (!d->duration ||
129 av_compare_ts(d->duration, d->time_base,
130 last_duration, ist->st->time_base) < 0) {
131 d->duration = last_duration;
132 d->time_base = ist->st->time_base;
133 }
134}
135
137{
138 InputFile *ifile = &d->f;
139 AVFormatContext *is = ifile->ctx;
140 InputStream *ist;
141 int ret;
142
143 ret = avformat_seek_file(is, -1, INT64_MIN, is->start_time, is->start_time, 0);
144 if (ret < 0)
145 return ret;
146
147 if (ifile->audio_duration_queue_size) {
148 /* duration is the length of the last frame in a stream
149 * when audio stream is present we don't care about
150 * last video frame length because it's not defined exactly */
151 int got_durations = 0;
152
153 while (got_durations < ifile->audio_duration_queue_size) {
155 ret = av_thread_message_queue_recv(ifile->audio_duration_queue, &dur, 0);
156 if (ret < 0)
157 return ret;
158 got_durations++;
159
160 ist = ifile->streams[dur.stream_idx];
162 }
163 } else {
164 for (int i = 0; i < ifile->nb_streams; i++) {
165 int64_t duration = 0;
166 ist = ifile->streams[i];
167
168 if (ist->framerate.num) {
169 duration = av_rescale_q(1, av_inv_q(ist->framerate), ist->st->time_base);
170 } else if (ist->st->avg_frame_rate.num) {
171 duration = av_rescale_q(1, av_inv_q(ist->st->avg_frame_rate), ist->st->time_base);
172 } else {
173 duration = 1;
174 }
175
176 ifile_duration_update(d, ist, duration);
177 }
178 }
179
180 if (d->loop > 0)
181 d->loop--;
182
183 return ret;
184}
185
186static void ts_fixup(Demuxer *d, AVPacket *pkt, int *repeat_pict)
187{
188 InputFile *ifile = &d->f;
189 InputStream *ist = ifile->streams[pkt->stream_index];
190 const int64_t start_time = ifile->start_time_effective;
191 int64_t duration;
192
193 if (debug_ts) {
194 av_log(NULL, AV_LOG_INFO, "demuxer -> ist_index:%d:%d type:%s "
195 "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s\n",
196 ifile->index, pkt->stream_index,
197 av_get_media_type_string(ist->st->codecpar->codec_type),
198 av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ist->st->time_base),
199 av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ist->st->time_base),
200 av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ist->st->time_base));
201 }
202
203 if (!ist->wrap_correction_done && start_time != AV_NOPTS_VALUE &&
204 ist->st->pts_wrap_bits < 64) {
205 int64_t stime, stime2;
206
207 stime = av_rescale_q(start_time, AV_TIME_BASE_Q, ist->st->time_base);
208 stime2= stime + (1ULL<<ist->st->pts_wrap_bits);
209 ist->wrap_correction_done = 1;
210
211 if(stime2 > stime && pkt->dts != AV_NOPTS_VALUE && pkt->dts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) {
212 pkt->dts -= 1ULL<<ist->st->pts_wrap_bits;
213 ist->wrap_correction_done = 0;
214 }
215 if(stime2 > stime && pkt->pts != AV_NOPTS_VALUE && pkt->pts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) {
216 pkt->pts -= 1ULL<<ist->st->pts_wrap_bits;
217 ist->wrap_correction_done = 0;
218 }
219 }
220
221 if (pkt->dts != AV_NOPTS_VALUE)
222 pkt->dts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
223 if (pkt->pts != AV_NOPTS_VALUE)
224 pkt->pts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
225
226 if (pkt->pts != AV_NOPTS_VALUE)
227 pkt->pts *= ist->ts_scale;
228 if (pkt->dts != AV_NOPTS_VALUE)
229 pkt->dts *= ist->ts_scale;
230
231 duration = av_rescale_q(d->duration, d->time_base, ist->st->time_base);
232 if (pkt->pts != AV_NOPTS_VALUE) {
233 pkt->pts += duration;
234 ist->max_pts = FFMAX(pkt->pts, ist->max_pts);
235 ist->min_pts = FFMIN(pkt->pts, ist->min_pts);
236 }
237
238 if (pkt->dts != AV_NOPTS_VALUE)
239 pkt->dts += duration;
240
241 *repeat_pict = -1;
242 if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
243 av_stream_get_parser(ist->st))
244 *repeat_pict = av_stream_get_parser(ist->st)->repeat_pict;
245}
246
248{
249 char name[16];
250 snprintf(name, sizeof(name), "dmx%d:%s", f->index, f->ctx->iformat->name);
251 ff_thread_setname(name);
252}
253
254static void *input_thread(void *arg)
255{
256 Demuxer *d = arg;
257 InputFile *f = &d->f;
258 AVPacket *pkt;
259 unsigned flags = d->non_blocking ? AV_THREAD_MESSAGE_NONBLOCK : 0;
260 int ret = 0;
261
262 pkt = av_packet_alloc();
263 if (!pkt) {
264 ret = AVERROR(ENOMEM);
265 goto finish;
266 }
267
269
270 while (1) {
271 DemuxMsg msg = { NULL };
272
273 ret = av_read_frame(f->ctx, pkt);
274
275 if (ret == AVERROR(EAGAIN)) {
276 av_usleep(10000);
277 continue;
278 }
279 if (ret < 0) {
280 if (d->loop) {
281 /* signal looping to the consumer thread */
282 msg.looping = 1;
283 ret = av_thread_message_queue_send(d->in_thread_queue, &msg, 0);
284 if (ret >= 0)
285 ret = seek_to_start(d);
286 if (ret >= 0)
287 continue;
288
289 /* fallthrough to the error path */
290 }
291
292 if (ret == AVERROR_EOF)
293 av_log(NULL, AV_LOG_VERBOSE, "EOF in input file %d\n", f->index);
294 else
295 av_log(NULL, AV_LOG_ERROR, "Error demuxing input file %d: %s\n",
296 f->index, av_err2str(ret));
297
298 break;
299 }
300
301 if (do_pkt_dump) {
302 av_pkt_dump_log2(NULL, AV_LOG_INFO, pkt, do_hex_dump,
303 f->ctx->streams[pkt->stream_index]);
304 }
305
306 /* the following test is needed in case new streams appear
307 dynamically in stream : we ignore them */
308 if (pkt->stream_index >= f->nb_streams) {
309 report_new_stream(d, pkt);
310 av_packet_unref(pkt);
311 continue;
312 }
313
314 if (pkt->flags & AV_PKT_FLAG_CORRUPT) {
315 av_log(NULL, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING,
316 "%s: corrupt input packet in stream %d\n",
317 f->ctx->url, pkt->stream_index);
318 if (exit_on_error) {
319 av_packet_unref(pkt);
320 ret = AVERROR_INVALIDDATA;
321 break;
322 }
323 }
324
325 ts_fixup(d, pkt, &msg.repeat_pict);
326
327 msg.pkt = av_packet_alloc();
328 if (!msg.pkt) {
329 av_packet_unref(pkt);
330 ret = AVERROR(ENOMEM);
331 break;
332 }
333 av_packet_move_ref(msg.pkt, pkt);
334 ret = av_thread_message_queue_send(d->in_thread_queue, &msg, flags);
335 if (flags && ret == AVERROR(EAGAIN)) {
336 flags = 0;
337 ret = av_thread_message_queue_send(d->in_thread_queue, &msg, flags);
338 av_log(f->ctx, AV_LOG_WARNING,
339 "Thread message queue blocking; consider raising the "
340 "thread_queue_size option (current value: %d)\n",
341 d->thread_queue_size);
342 }
343 if (ret < 0) {
344 if (ret != AVERROR_EOF)
345 av_log(f->ctx, AV_LOG_ERROR,
346 "Unable to send packet to main thread: %s\n",
347 av_err2str(ret));
348 av_packet_free(&msg.pkt);
349 break;
350 }
351 }
352
353finish:
354 av_assert0(ret < 0);
355 av_thread_message_queue_set_err_recv(d->in_thread_queue, ret);
356
357 av_packet_free(&pkt);
358
359 av_log(NULL, AV_LOG_VERBOSE, "Terminating demuxer thread %d\n", f->index);
360
361 return NULL;
362}
363
364static void thread_stop(Demuxer *d)
365{
366 InputFile *f = &d->f;
367 DemuxMsg msg;
368
369 if (!d->in_thread_queue)
370 return;
371 av_thread_message_queue_set_err_send(d->in_thread_queue, AVERROR_EOF);
372 while (av_thread_message_queue_recv(d->in_thread_queue, &msg, 0) >= 0)
373 av_packet_free(&msg.pkt);
374
375 pthread_join(d->thread, NULL);
376 av_thread_message_queue_free(&d->in_thread_queue);
377 av_thread_message_queue_free(&f->audio_duration_queue);
378}
379
381{
382 int ret;
383 InputFile *f = &d->f;
384
385 if (d->thread_queue_size <= 0)
386 d->thread_queue_size = (nb_input_files > 1 ? 8 : 1);
387
388 if (nb_input_files > 1 &&
389 (f->ctx->pb ? !f->ctx->pb->seekable :
390 strcmp(f->ctx->iformat->name, "lavfi")))
391 d->non_blocking = 1;
392 ret = av_thread_message_queue_alloc(&d->in_thread_queue,
393 d->thread_queue_size, sizeof(DemuxMsg));
394 if (ret < 0)
395 return ret;
396
397 if (d->loop) {
398 int nb_audio_dec = 0;
399
400 for (int i = 0; i < f->nb_streams; i++) {
401 InputStream *ist = f->streams[i];
402 nb_audio_dec += !!(ist->decoding_needed &&
403 ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO);
404 }
405
406 if (nb_audio_dec) {
407 ret = av_thread_message_queue_alloc(&f->audio_duration_queue,
408 nb_audio_dec, sizeof(LastFrameDuration));
409 if (ret < 0)
410 goto fail;
411 f->audio_duration_queue_size = nb_audio_dec;
412 }
413 }
414
415 if ((ret = pthread_create(&d->thread, NULL, input_thread, d))) {
416 av_log(NULL, AV_LOG_ERROR, "pthread_create failed: %s. Try to increase `ulimit -v` or decrease `ulimit -s`.\n", strerror(ret));
417 ret = AVERROR(ret);
418 goto fail;
419 }
420
421 return 0;
422fail:
423 av_thread_message_queue_free(&d->in_thread_queue);
424 return ret;
425}
426
427int ifile_get_packet(InputFile *f, AVPacket **pkt)
428{
430 InputStream *ist;
431 DemuxMsg msg;
432 int ret;
433
434 if (!d->in_thread_queue) {
435 ret = thread_start(d);
436 if (ret < 0)
437 return ret;
438 }
439
440 if (f->readrate || f->rate_emu) {
441 int i;
442 int64_t file_start = copy_ts * (
443 (f->start_time_effective != AV_NOPTS_VALUE ? f->start_time_effective * !start_at_zero : 0) +
444 (f->start_time != AV_NOPTS_VALUE ? f->start_time : 0)
445 );
446 float scale = f->rate_emu ? 1.0 : f->readrate;
447 for (i = 0; i < f->nb_streams; i++) {
448 InputStream *ist = f->streams[i];
449 int64_t stream_ts_offset, pts, now;
450 if (!ist->nb_packets || (ist->decoding_needed && !ist->got_output)) continue;
451 stream_ts_offset = FFMAX(ist->first_dts != AV_NOPTS_VALUE ? ist->first_dts : 0, file_start);
452 pts = av_rescale(ist->dts, 1000000, AV_TIME_BASE);
453 now = (av_gettime_relative() - ist->start) * scale + stream_ts_offset;
454 if (pts > now)
455 return AVERROR(EAGAIN);
456 }
457 }
458
459 ret = av_thread_message_queue_recv(d->in_thread_queue, &msg,
460 d->non_blocking ?
461 AV_THREAD_MESSAGE_NONBLOCK : 0);
462 if (ret < 0)
463 return ret;
464 if (msg.looping)
465 return 1;
466
467 ist = f->streams[msg.pkt->stream_index];
469
470 *pkt = msg.pkt;
471 return 0;
472}
473
474static void ist_free(InputStream **pist)
475{
476 InputStream *ist = *pist;
477
478 if (!ist)
479 return;
480
481 av_frame_free(&ist->decoded_frame);
482 av_packet_free(&ist->pkt);
483 av_dict_free(&ist->decoder_opts);
484 avsubtitle_free(&ist->prev_sub.subtitle);
485 av_frame_free(&ist->sub2video.frame);
486 av_freep(&ist->filters);
487 av_freep(&ist->hwaccel_device);
488 av_freep(&ist->dts_buffer);
489
490 avcodec_free_context(&ist->dec_ctx);
491 avcodec_parameters_free(&ist->par);
492
493 av_freep(pist);
494}
495
497{
498 InputFile *f = *pf;
500
501 if (!f)
502 return;
503
504 thread_stop(d);
505
506 for (int i = 0; i < f->nb_streams; i++)
507 ist_free(&f->streams[i]);
508 av_freep(&f->streams);
509
510 avformat_close_input(&f->ctx);
511
512 av_freep(pf);
513}
514
515static const AVCodec *choose_decoder(const OptionsContext *o, AVFormatContext *s, AVStream *st,
516 enum HWAccelID hwaccel_id, enum AVHWDeviceType hwaccel_device_type)
517
518{
519 char *codec_name = NULL;
520
521 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
522 if (codec_name) {
523 const AVCodec *codec = find_codec_or_die(NULL, codec_name, st->codecpar->codec_type, 0);
524 st->codecpar->codec_id = codec->id;
525 if (recast_media && st->codecpar->codec_type != codec->type)
526 st->codecpar->codec_type = codec->type;
527 return codec;
528 } else {
529 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
530 hwaccel_id == HWACCEL_GENERIC &&
531 hwaccel_device_type != AV_HWDEVICE_TYPE_NONE) {
532 const AVCodec *c;
533 void *i = NULL;
534
535 while ((c = av_codec_iterate(&i))) {
536 const AVCodecHWConfig *config;
537
538 if (c->id != st->codecpar->codec_id ||
539 !av_codec_is_decoder(c))
540 continue;
541
542 for (int j = 0; (config = avcodec_get_hw_config(c, j)); j++) {
543 if (config->device_type == hwaccel_device_type) {
544 av_log(NULL, AV_LOG_VERBOSE, "Selecting decoder '%s' because of requested hwaccel method %s\n",
545 c->name, av_hwdevice_get_type_name(hwaccel_device_type));
546 return c;
547 }
548 }
549 }
550 }
551
552 return avcodec_find_decoder(st->codecpar->codec_id);
553 }
554}
555
557{
558 AVCodecContext *dec = ist->dec_ctx;
559
560 if (dec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
561 char layout_name[256];
562
563 if (dec->ch_layout.nb_channels > ist->guess_layout_max)
564 return 0;
565 av_channel_layout_default(&dec->ch_layout, dec->ch_layout.nb_channels);
566 if (dec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
567 return 0;
568 av_channel_layout_describe(&dec->ch_layout, layout_name, sizeof(layout_name));
569 av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Input Stream "
570 "#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);
571 }
572 return 1;
573}
574
576 AVFormatContext *ctx, AVStream *st)
577{
578 double rotation = DBL_MAX;
579 int hflip = -1, vflip = -1;
580 int hflip_set = 0, vflip_set = 0, rotation_set = 0;
581 int32_t *buf;
582
583 MATCH_PER_STREAM_OPT(display_rotations, dbl, rotation, ctx, st);
584 MATCH_PER_STREAM_OPT(display_hflips, i, hflip, ctx, st);
585 MATCH_PER_STREAM_OPT(display_vflips, i, vflip, ctx, st);
586
587 rotation_set = rotation != DBL_MAX;
588 hflip_set = hflip != -1;
589 vflip_set = vflip != -1;
590
591 if (!rotation_set && !hflip_set && !vflip_set)
592 return;
593
594 buf = (int32_t *)av_stream_new_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, sizeof(int32_t) * 9);
595 if (!buf) {
596 av_log(NULL, AV_LOG_FATAL, "Failed to generate a display matrix!\n");
597 exit_program(1);
598 }
599
600 av_display_rotation_set(buf,
601 rotation_set ? -(rotation) : -0.0f);
602
603 av_display_matrix_flip(buf,
604 hflip_set ? hflip : 0,
605 vflip_set ? vflip : 0);
606}
607
608/* Add all the streams from the given input file to the demuxer */
610{
611 InputFile *f = &d->f;
612 AVFormatContext *ic = f->ctx;
613 int i, ret;
614
615 for (i = 0; i < ic->nb_streams; i++) {
616 AVStream *st = ic->streams[i];
617 AVCodecParameters *par = st->codecpar;
618 InputStream *ist;
619 char *framerate = NULL, *hwaccel_device = NULL;
620 const char *hwaccel = NULL;
621 char *hwaccel_output_format = NULL;
622 char *codec_tag = NULL;
623 char *next;
624 char *discard_str = NULL;
625 const AVClass *cc = avcodec_get_class();
626 const AVOption *discard_opt = av_opt_find(&cc, "skip_frame", NULL,
627 0, AV_OPT_SEARCH_FAKE_OBJ);
628
629 ist = ALLOC_ARRAY_ELEM(f->streams, f->nb_streams);
630 ist->st = st;
631 ist->file_index = f->index;
632 ist->discard = 1;
633 st->discard = AVDISCARD_ALL;
634 ist->nb_samples = 0;
635 ist->first_dts = AV_NOPTS_VALUE;
636 ist->min_pts = INT64_MAX;
637 ist->max_pts = INT64_MIN;
638
639 ist->ts_scale = 1.0;
640 MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
641
642 ist->autorotate = 1;
643 MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
644
645 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
646 if (codec_tag) {
647 uint32_t tag = strtol(codec_tag, &next, 0);
648 if (*next)
649 tag = AV_RL32(codec_tag);
650 st->codecpar->codec_tag = tag;
651 }
652
653 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
655
656 MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
657 MATCH_PER_STREAM_OPT(hwaccel_output_formats, str,
658 hwaccel_output_format, ic, st);
659
660 if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "cuvid")) {
661 av_log(NULL, AV_LOG_WARNING,
662 "WARNING: defaulting hwaccel_output_format to cuda for compatibility "
663 "with old commandlines. This behaviour is DEPRECATED and will be removed "
664 "in the future. Please explicitly set \"-hwaccel_output_format cuda\".\n");
665 ist->hwaccel_output_format = AV_PIX_FMT_CUDA;
666 } else if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "qsv")) {
667 av_log(NULL, AV_LOG_WARNING,
668 "WARNING: defaulting hwaccel_output_format to qsv for compatibility "
669 "with old commandlines. This behaviour is DEPRECATED and will be removed "
670 "in the future. Please explicitly set \"-hwaccel_output_format qsv\".\n");
671 ist->hwaccel_output_format = AV_PIX_FMT_QSV;
672 } else if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "mediacodec")) {
673 // There is no real AVHWFrameContext implementation. Set
674 // hwaccel_output_format to avoid av_hwframe_transfer_data error.
675 ist->hwaccel_output_format = AV_PIX_FMT_MEDIACODEC;
676 } else if (hwaccel_output_format) {
677 ist->hwaccel_output_format = av_get_pix_fmt(hwaccel_output_format);
678 if (ist->hwaccel_output_format == AV_PIX_FMT_NONE) {
679 av_log(NULL, AV_LOG_FATAL, "Unrecognised hwaccel output "
680 "format: %s", hwaccel_output_format);
681 }
682 } else {
683 ist->hwaccel_output_format = AV_PIX_FMT_NONE;
684 }
685
686 if (hwaccel) {
687 // The NVDEC hwaccels use a CUDA device, so remap the name here.
688 if (!strcmp(hwaccel, "nvdec") || !strcmp(hwaccel, "cuvid"))
689 hwaccel = "cuda";
690
691 if (!strcmp(hwaccel, "none"))
693 else if (!strcmp(hwaccel, "auto"))
695 else {
696 enum AVHWDeviceType type = av_hwdevice_find_type_by_name(hwaccel);
697 if (type != AV_HWDEVICE_TYPE_NONE) {
699 ist->hwaccel_device_type = type;
700 }
701
702 if (!ist->hwaccel_id) {
703 av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n",
704 hwaccel);
705 av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: ");
706 type = AV_HWDEVICE_TYPE_NONE;
707 while ((type = av_hwdevice_iterate_types(type)) !=
708 AV_HWDEVICE_TYPE_NONE)
709 av_log(NULL, AV_LOG_FATAL, "%s ",
710 av_hwdevice_get_type_name(type));
711 av_log(NULL, AV_LOG_FATAL, "\n");
712 exit_program(1);
713 }
714 }
715 }
716
717 MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st);
718 if (hwaccel_device) {
719 ist->hwaccel_device = av_strdup(hwaccel_device);
720 if (!ist->hwaccel_device)
721 report_and_exit(AVERROR(ENOMEM));
722 }
723
724 ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
725 }
726
727 ist->dec = choose_decoder(o, ic, st, ist->hwaccel_id, ist->hwaccel_device_type);
728 ist->decoder_opts = filter_codec_opts(o->g->codec_opts, ist->st->codecpar->codec_id, ic, st, ist->dec);
729
730 ist->reinit_filters = -1;
731 MATCH_PER_STREAM_OPT(reinit_filters, i, ist->reinit_filters, ic, st);
732
733 MATCH_PER_STREAM_OPT(discard, str, discard_str, ic, st);
734 ist->user_set_discard = AVDISCARD_NONE;
735
736 if ((o->video_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) ||
737 (o->audio_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) ||
738 (o->subtitle_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) ||
739 (o->data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA))
740 ist->user_set_discard = AVDISCARD_ALL;
741
742 if (discard_str && av_opt_eval_int(&cc, discard_opt, discard_str, &ist->user_set_discard) < 0) {
743 av_log(NULL, AV_LOG_ERROR, "Error parsing discard %s.\n",
744 discard_str);
745 exit_program(1);
746 }
747
748 ist->filter_in_rescale_delta_last = AV_NOPTS_VALUE;
749 ist->prev_pkt_pts = AV_NOPTS_VALUE;
750
751 ist->dec_ctx = avcodec_alloc_context3(ist->dec);
752 if (!ist->dec_ctx)
753 report_and_exit(AVERROR(ENOMEM));
754
755 ret = avcodec_parameters_to_context(ist->dec_ctx, par);
756 if (ret < 0) {
757 av_log(NULL, AV_LOG_ERROR, "Error initializing the decoder context.\n");
758 exit_program(1);
759 }
760
761 ist->decoded_frame = av_frame_alloc();
762 if (!ist->decoded_frame)
763 report_and_exit(AVERROR(ENOMEM));
764
765 ist->pkt = av_packet_alloc();
766 if (!ist->pkt)
767 report_and_exit(AVERROR(ENOMEM));
768
769 if (o->bitexact)
770 ist->dec_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
771
772 switch (par->codec_type) {
773 case AVMEDIA_TYPE_VIDEO:
774 // avformat_find_stream_info() doesn't set this for us anymore.
775 ist->dec_ctx->framerate = st->avg_frame_rate;
776
777 MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
778 if (framerate && av_parse_video_rate(&ist->framerate,
779 framerate) < 0) {
780 av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
781 framerate);
782 exit_program(1);
783 }
784
785 ist->top_field_first = -1;
786 MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st);
787
788 ist->framerate_guessed = av_guess_frame_rate(ic, st, NULL);
789
790 break;
791 case AVMEDIA_TYPE_AUDIO:
792 ist->guess_layout_max = INT_MAX;
793 MATCH_PER_STREAM_OPT(guess_layout_max, i, ist->guess_layout_max, ic, st);
795 break;
796 case AVMEDIA_TYPE_DATA:
797 case AVMEDIA_TYPE_SUBTITLE: {
798 char *canvas_size = NULL;
799 MATCH_PER_STREAM_OPT(fix_sub_duration, i, ist->fix_sub_duration, ic, st);
800 MATCH_PER_STREAM_OPT(canvas_sizes, str, canvas_size, ic, st);
801 if (canvas_size &&
802 av_parse_video_size(&ist->dec_ctx->width, &ist->dec_ctx->height, canvas_size) < 0) {
803 av_log(NULL, AV_LOG_FATAL, "Invalid canvas size: %s.\n", canvas_size);
804 exit_program(1);
805 }
806 break;
807 }
808 case AVMEDIA_TYPE_ATTACHMENT:
809 case AVMEDIA_TYPE_UNKNOWN:
810 break;
811 default:
812 abort();
813 }
814
815 ist->par = avcodec_parameters_alloc();
816 if (!ist->par)
817 report_and_exit(AVERROR(ENOMEM));
818
819 ret = avcodec_parameters_from_context(ist->par, ist->dec_ctx);
820 if (ret < 0) {
821 av_log(NULL, AV_LOG_ERROR, "Error initializing the decoder context.\n");
822 exit_program(1);
823 }
824 }
825}
826
827static void dump_attachment(AVStream *st, const char *filename)
828{
829 int ret;
830 AVIOContext *out = NULL;
831 const AVDictionaryEntry *e;
832
833 if (!st->codecpar->extradata_size) {
834 av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
835 nb_input_files - 1, st->index);
836 return;
837 }
838 if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
839 filename = e->value;
840 if (!*filename) {
841 av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
842 "in stream #%d:%d.\n", nb_input_files - 1, st->index);
843 exit_program(1);
844 }
845
846 assert_file_overwrite(filename);
847
848 if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
849 av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
850 filename);
851 exit_program(1);
852 }
853
854 avio_write(out, st->codecpar->extradata, st->codecpar->extradata_size);
855 avio_flush(out);
856 avio_close(out);
857}
858
859int ifile_open(const OptionsContext *o, const char *filename)
860{
861 Demuxer *d;
862 InputFile *f;
863 AVFormatContext *ic;
864 const AVInputFormat *file_iformat = NULL;
865 int err, i, ret;
866 int64_t timestamp;
867 AVDictionary *unused_opts = NULL;
868 const AVDictionaryEntry *e = NULL;
869 char * video_codec_name = NULL;
870 char * audio_codec_name = NULL;
871 char *subtitle_codec_name = NULL;
872 char * data_codec_name = NULL;
873 int scan_all_pmts_set = 0;
874
875 int64_t start_time = o->start_time;
876 int64_t start_time_eof = o->start_time_eof;
877 int64_t stop_time = o->stop_time;
878 int64_t recording_time = o->recording_time;
879
880 if (stop_time != INT64_MAX && recording_time != INT64_MAX) {
881 stop_time = INT64_MAX;
882 av_log(NULL, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
883 }
884
885 if (stop_time != INT64_MAX && recording_time == INT64_MAX) {
886 int64_t start = start_time == AV_NOPTS_VALUE ? 0 : start_time;
887 if (stop_time <= start) {
888 av_log(NULL, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n");
889 exit_program(1);
890 } else {
891 recording_time = stop_time - start;
892 }
893 }
894
895 if (o->format) {
896 if (!(file_iformat = av_find_input_format(o->format))) {
897 av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
898 exit_program(1);
899 }
900 }
901
902 if (!strcmp(filename, "-"))
903 filename = "fd:";
904
905 stdin_interaction &= strncmp(filename, "pipe:", 5) &&
906 strcmp(filename, "fd:") &&
907 strcmp(filename, "/dev/stdin");
908
909 /* get default parameters from command line */
910 ic = avformat_alloc_context();
911 if (!ic)
912 report_and_exit(AVERROR(ENOMEM));
913 if (o->nb_audio_sample_rate) {
914 av_dict_set_int(&o->g->format_opts, "sample_rate", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i, 0);
915 }
916 if (o->nb_audio_channels) {
917 const AVClass *priv_class;
918 if (file_iformat && (priv_class = file_iformat->priv_class) &&
919 av_opt_find(&priv_class, "ch_layout", NULL, 0,
920 AV_OPT_SEARCH_FAKE_OBJ)) {
921 char buf[32];
922 snprintf(buf, sizeof(buf), "%dC", o->audio_channels[o->nb_audio_channels - 1].u.i);
923 av_dict_set(&o->g->format_opts, "ch_layout", buf, 0);
924 }
925 }
926 if (o->nb_audio_ch_layouts) {
927 const AVClass *priv_class;
928 if (file_iformat && (priv_class = file_iformat->priv_class) &&
929 av_opt_find(&priv_class, "ch_layout", NULL, 0,
930 AV_OPT_SEARCH_FAKE_OBJ)) {
931 av_dict_set(&o->g->format_opts, "ch_layout", o->audio_ch_layouts[o->nb_audio_ch_layouts - 1].u.str, 0);
932 }
933 }
934 if (o->nb_frame_rates) {
935 const AVClass *priv_class;
936 /* set the format-level framerate option;
937 * this is important for video grabbers, e.g. x11 */
938 if (file_iformat && (priv_class = file_iformat->priv_class) &&
939 av_opt_find(&priv_class, "framerate", NULL, 0,
940 AV_OPT_SEARCH_FAKE_OBJ)) {
941 av_dict_set(&o->g->format_opts, "framerate",
942 o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
943 }
944 }
945 if (o->nb_frame_sizes) {
946 av_dict_set(&o->g->format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
947 }
948 if (o->nb_frame_pix_fmts)
949 av_dict_set(&o->g->format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
950
951 MATCH_PER_TYPE_OPT(codec_names, str, video_codec_name, ic, "v");
952 MATCH_PER_TYPE_OPT(codec_names, str, audio_codec_name, ic, "a");
953 MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, ic, "s");
954 MATCH_PER_TYPE_OPT(codec_names, str, data_codec_name, ic, "d");
955
956 if (video_codec_name)
957 ic->video_codec = find_codec_or_die(NULL, video_codec_name , AVMEDIA_TYPE_VIDEO , 0);
958 if (audio_codec_name)
959 ic->audio_codec = find_codec_or_die(NULL, audio_codec_name , AVMEDIA_TYPE_AUDIO , 0);
960 if (subtitle_codec_name)
961 ic->subtitle_codec = find_codec_or_die(NULL, subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0);
962 if (data_codec_name)
963 ic->data_codec = find_codec_or_die(NULL, data_codec_name , AVMEDIA_TYPE_DATA , 0);
964
965 ic->video_codec_id = video_codec_name ? ic->video_codec->id : AV_CODEC_ID_NONE;
966 ic->audio_codec_id = audio_codec_name ? ic->audio_codec->id : AV_CODEC_ID_NONE;
967 ic->subtitle_codec_id = subtitle_codec_name ? ic->subtitle_codec->id : AV_CODEC_ID_NONE;
968 ic->data_codec_id = data_codec_name ? ic->data_codec->id : AV_CODEC_ID_NONE;
969
970 ic->flags |= AVFMT_FLAG_NONBLOCK;
971 if (o->bitexact)
972 ic->flags |= AVFMT_FLAG_BITEXACT;
973 ic->interrupt_callback = int_cb;
974
975 if (!av_dict_get(o->g->format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
976 av_dict_set(&o->g->format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
977 scan_all_pmts_set = 1;
978 }
979 /* open the input file with generic avformat function */
980 err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
981 if (err < 0) {
982 print_error(filename, err);
983 if (err == AVERROR_PROTOCOL_NOT_FOUND)
984 av_log(NULL, AV_LOG_ERROR, "Did you mean file:%s?\n", filename);
985 exit_program(1);
986 }
987 if (scan_all_pmts_set)
988 av_dict_set(&o->g->format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
991
992 /* apply forced codec ids */
993 for (i = 0; i < ic->nb_streams; i++)
994 choose_decoder(o, ic, ic->streams[i], HWACCEL_NONE, AV_HWDEVICE_TYPE_NONE);
995
996 if (o->find_stream_info) {
997 AVDictionary **opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
998 int orig_nb_streams = ic->nb_streams;
999
1000 /* If not enough info to get the stream parameters, we decode the
1001 first frames to get it. (used in mpeg case for example) */
1002 ret = avformat_find_stream_info(ic, opts);
1003
1004 for (i = 0; i < orig_nb_streams; i++)
1005 av_dict_free(&opts[i]);
1006 av_freep(&opts);
1007
1008 if (ret < 0) {
1009 av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
1010 if (ic->nb_streams == 0) {
1011 avformat_close_input(&ic);
1012 exit_program(1);
1013 }
1014 }
1015 }
1016
1017 if (start_time != AV_NOPTS_VALUE && start_time_eof != AV_NOPTS_VALUE) {
1018 av_log(NULL, AV_LOG_WARNING, "Cannot use -ss and -sseof both, using -ss for %s\n", filename);
1019 start_time_eof = AV_NOPTS_VALUE;
1020 }
1021
1022 if (start_time_eof != AV_NOPTS_VALUE) {
1023 if (start_time_eof >= 0) {
1024 av_log(NULL, AV_LOG_ERROR, "-sseof value must be negative; aborting\n");
1025 exit_program(1);
1026 }
1027 if (ic->duration > 0) {
1028 start_time = start_time_eof + ic->duration;
1029 if (start_time < 0) {
1030 av_log(NULL, AV_LOG_WARNING, "-sseof value seeks to before start of file %s; ignored\n", filename);
1031 start_time = AV_NOPTS_VALUE;
1032 }
1033 } else
1034 av_log(NULL, AV_LOG_WARNING, "Cannot use -sseof, duration of %s not known\n", filename);
1035 }
1036 timestamp = (start_time == AV_NOPTS_VALUE) ? 0 : start_time;
1037 /* add the stream start time */
1038 if (!o->seek_timestamp && ic->start_time != AV_NOPTS_VALUE)
1039 timestamp += ic->start_time;
1040
1041 /* if seeking requested, we execute it */
1042 if (start_time != AV_NOPTS_VALUE) {
1043 int64_t seek_timestamp = timestamp;
1044
1045 if (!(ic->iformat->flags & AVFMT_SEEK_TO_PTS)) {
1046 int dts_heuristic = 0;
1047 for (i=0; i<ic->nb_streams; i++) {
1048 const AVCodecParameters *par = ic->streams[i]->codecpar;
1049 if (par->video_delay) {
1050 dts_heuristic = 1;
1051 break;
1052 }
1053 }
1054 if (dts_heuristic) {
1055 seek_timestamp -= 3*AV_TIME_BASE / 23;
1056 }
1057 }
1058 ret = avformat_seek_file(ic, -1, INT64_MIN, seek_timestamp, seek_timestamp, 0);
1059 if (ret < 0) {
1060 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
1061 filename, (double)timestamp / AV_TIME_BASE);
1062 }
1063 }
1064
1066 f = &d->f;
1067
1068 f->ctx = ic;
1069 f->index = nb_input_files - 1;
1070 f->start_time = start_time;
1071 f->recording_time = recording_time;
1074 f->ts_offset = o->input_ts_offset - (copy_ts ? (start_at_zero && ic->start_time != AV_NOPTS_VALUE ? ic->start_time : 0) : timestamp);
1075 f->rate_emu = o->rate_emu;
1077 d->loop = o->loop;
1078 d->duration = 0;
1079 d->time_base = (AVRational){ 1, 1 };
1080
1081 f->readrate = o->readrate ? o->readrate : 0.0;
1082 if (f->readrate < 0.0f) {
1083 av_log(NULL, AV_LOG_ERROR, "Option -readrate for Input #%d is %0.3f; it must be non-negative.\n", f->index, f->readrate);
1084 exit_program(1);
1085 }
1086 if (f->readrate && f->rate_emu) {
1087 av_log(NULL, AV_LOG_WARNING, "Both -readrate and -re set for Input #%d. Using -readrate %0.3f.\n", f->index, f->readrate);
1088 f->rate_emu = 0;
1089 }
1090
1091 d->thread_queue_size = o->thread_queue_size;
1092
1093 /* update the current parameters so that they match the one of the input stream */
1094 add_input_streams(o, d);
1095
1096 /* dump the file content */
1097 av_dump_format(ic, f->index, filename, 0);
1098
1099 /* check if all codec options have been used */
1100 unused_opts = strip_specifiers(o->g->codec_opts);
1101 for (i = 0; i < f->nb_streams; i++) {
1102 e = NULL;
1103 while ((e = av_dict_iterate(f->streams[i]->decoder_opts, e)))
1104 av_dict_set(&unused_opts, e->key, NULL, 0);
1105 }
1106
1107 e = NULL;
1108 while ((e = av_dict_iterate(unused_opts, e))) {
1109 const AVClass *class = avcodec_get_class();
1110 const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
1111 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
1112 const AVClass *fclass = avformat_get_class();
1113 const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0,
1114 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
1115 if (!option || foption)
1116 continue;
1117
1118
1119 if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) {
1120 av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
1121 "input file #%d (%s) is not a decoding option.\n", e->key,
1122 option->help ? option->help : "", f->index,
1123 filename);
1124 exit_program(1);
1125 }
1126
1127 av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
1128 "input file #%d (%s) has not been used for any stream. The most "
1129 "likely reason is either wrong type (e.g. a video option with "
1130 "no video streams) or that it is a private option of some decoder "
1131 "which was not actually used for any stream.\n", e->key,
1132 option->help ? option->help : "", f->index, filename);
1133 }
1134 av_dict_free(&unused_opts);
1135
1136 for (i = 0; i < o->nb_dump_attachment; i++) {
1137 int j;
1138
1139 for (j = 0; j < ic->nb_streams; j++) {
1140 AVStream *st = ic->streams[j];
1141
1142 if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
1144 }
1145 }
1146
1147 return 0;
1148}
void exit_program(int ret)
void print_error(const char *filename, int err)
void report_and_exit(int ret)
int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
void * allocate_array_elem(void *ptr, size_t elem_size, int *nb_elems)
AVDictionary * filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id, AVFormatContext *s, AVStream *st, const AVCodec *codec)
AVDictionary ** setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
#define ALLOC_ARRAY_ELEM(array, nb_elems)
__thread const AVIOInterruptCB int_cb
__thread int nb_input_files
__thread int recast_media
__thread InputFile ** input_files
void remove_avoptions(AVDictionary **a, AVDictionary *b)
void assert_avoptions(AVDictionary *m)
HWAccelID
@ HWACCEL_NONE
@ HWACCEL_GENERIC
@ HWACCEL_AUTO
__thread int copy_ts
__thread int stdin_interaction
AVDictionary * strip_specifiers(const AVDictionary *dict)
__thread int start_at_zero
void assert_file_overwrite(const char *filename)
__thread int exit_on_error
const AVCodec * find_codec_or_die(void *logctx, const char *name, enum AVMediaType type, int encoder)
__thread int do_hex_dump
__thread int do_pkt_dump
__thread int debug_ts
static int seek_to_start(Demuxer *d)
static void * input_thread(void *arg)
static void thread_set_name(InputFile *f)
static const char *const opt_name_fix_sub_duration[]
static const char *const opt_name_canvas_sizes[]
static const char *const opt_name_autorotate[]
static const AVCodec * choose_decoder(const OptionsContext *o, AVFormatContext *s, AVStream *st, enum HWAccelID hwaccel_id, enum AVHWDeviceType hwaccel_device_type)
static void add_input_streams(const OptionsContext *o, Demuxer *d)
static const char *const opt_name_hwaccels[]
static const char *const opt_name_display_rotations[]
static const char *const opt_name_hwaccel_devices[]
int ifile_get_packet(InputFile *f, AVPacket **pkt)
static void ifile_duration_update(Demuxer *d, InputStream *ist, int64_t last_duration)
static const char *const opt_name_discard[]
static const char *const opt_name_display_vflips[]
static int thread_start(Demuxer *d)
static Demuxer * demuxer_from_ifile(InputFile *f)
static const char *const opt_name_reinit_filters[]
static void thread_stop(Demuxer *d)
static void dump_attachment(AVStream *st, const char *filename)
static const char *const opt_name_guess_layout_max[]
int ifile_open(const OptionsContext *o, const char *filename)
static void report_new_stream(Demuxer *d, const AVPacket *pkt)
static const char *const opt_name_display_hflips[]
static void ist_free(InputStream **pist)
static const char *const opt_name_hwaccel_output_formats[]
void ifile_close(InputFile **pf)
static void add_display_matrix_to_stream(const OptionsContext *o, AVFormatContext *ctx, AVStream *st)
static const char *const opt_name_ts_scale[]
static void ts_fixup(Demuxer *d, AVPacket *pkt, int *repeat_pict)
static int guess_input_channel_layout(InputStream *ist)
#define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)
#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)
pthread_t thread
AVThreadMessageQueue * in_thread_queue
AVRational time_base
int64_t ts_offset
AVFormatContext * ctx
int64_t input_ts_offset
AVThreadMessageQueue * audio_duration_queue
int64_t recording_time
int64_t start_time_effective
int audio_duration_queue_size
InputStream ** streams
int64_t start_time
enum AVPixelFormat hwaccel_pix_fmt
AVFrame * decoded_frame
int64_t * dts_buffer
int64_t dts
dts of the last packet read for this stream (in AV_TIME_BASE units)
enum AVPixelFormat hwaccel_output_format
AVCodecContext * dec_ctx
enum HWAccelID hwaccel_id
int64_t filter_in_rescale_delta_last
AVCodecParameters * par
AVPacket * pkt
int64_t first_dts
dts of the first packet read for this stream (in AV_TIME_BASE units)
struct InputStream::@3 prev_sub
struct InputStream::sub2video sub2video
AVStream * st
InputFilter ** filters
uint64_t nb_packets
AVSubtitle subtitle
char * hwaccel_device
AVRational framerate_guessed
int64_t prev_pkt_pts
AVDictionary * decoder_opts
const AVCodec * dec
enum AVHWDeviceType hwaccel_device_type
int64_t nb_samples
AVRational framerate
AVDictionary * codec_opts
AVDictionary * format_opts
SpecifierOpt * frame_pix_fmts
SpecifierOpt * dump_attachment
const char * format
int64_t input_ts_offset
SpecifierOpt * audio_sample_rate
SpecifierOpt * frame_sizes
SpecifierOpt * audio_channels
SpecifierOpt * frame_rates
SpecifierOpt * audio_ch_layouts
OptionGroup * g
union SpecifierOpt::@0 u