FFmpegKit Android API 6.0
Loading...
Searching...
No Matches
fftools_ffmpeg_opt.c
Go to the documentation of this file.
1/*
2 * ffmpeg option parsing
3 * Copyright (c) 2018-2020 Taner Sener
4 * Copyright (c) 2023 ARTHENICA LTD
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23/*
24 * This file is the modified version of ffmpeg_opt.c file living in ffmpeg source code under the fftools folder. We
25 * manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
26 * by us to develop mobile-ffmpeg and later ffmpeg-kit libraries.
27 *
28 * ffmpeg-kit changes by ARTHENICA LTD
29 *
30 * 07.2023
31 * --------------------------------------------------------
32 * - FFmpeg 6.0 changes migrated
33 * - include fftools_ffmpeg_mux.h added
34 * - fftools header names updated
35 *
36 * mobile-ffmpeg / ffmpeg-kit changes by Taner Sener
37 *
38 * 08.2020
39 * --------------------------------------------------------
40 * - read_file renamed as fftools_read_file
41 *
42 * 01.2020
43 * --------------------------------------------------------
44 * - ffprobe support (added ffmpeg_ prefix to options used by ffmpeg, logs with AV_LOG_INFO level migrated to
45 * use AV_LOG_STDERR)
46 *
47 * 12.2019
48 * --------------------------------------------------------
49 * - concurrent execution support ("__thread" specifier added to variables used by multiple threads, static keyword
50 * removed from methods called by both ffmpeg and ffprobe, options replaced with global_options, options definition
51 * deleted)
52 *
53 * 08.2018
54 * --------------------------------------------------------
55 * - fftools_ prefix added to file name and parent headers
56 *
57 * 07.2018
58 * --------------------------------------------------------
59 * - parentheses placed around assignments in condition to prevent -Wparentheses warning
60 */
61
62#include "config.h"
63
64#include <stdint.h>
65
66#if HAVE_SYS_RESOURCE_H
67#include <sys/time.h>
68#include <sys/resource.h>
69#endif
70
71#include "fftools_ffmpeg.h"
72#include "fftools_ffmpeg_mux.h"
73#include "fftools_cmdutils.h"
74#include "fftools_opt_common.h"
75#include "fftools_sync_queue.h"
76
77#include "libavformat/avformat.h"
78
79#include "libavcodec/avcodec.h"
80#include "libavcodec/bsf.h"
81
82#include "libavfilter/avfilter.h"
83
84#include "libavutil/avassert.h"
85#include "libavutil/avstring.h"
86#include "libavutil/avutil.h"
87#include "libavutil/bprint.h"
88#include "libavutil/channel_layout.h"
89#include "libavutil/display.h"
90#include "libavutil/intreadwrite.h"
91#include "libavutil/fifo.h"
92#include "libavutil/mathematics.h"
93#include "libavutil/opt.h"
94#include "libavutil/parseutils.h"
95#include "libavutil/pixdesc.h"
96#include "libavutil/pixfmt.h"
97
98const char *const opt_name_codec_names[] = {"c", "codec", "acodec", "vcodec", "scodec", "dcodec", NULL};
99const char *const opt_name_frame_rates[] = {"r", NULL};
100const char *const opt_name_codec_tags[] = {"tag", "atag", "vtag", "stag", NULL};
101const char *const opt_name_top_field_first[] = {"top", NULL};
102
104
105__thread char *vstats_filename;
106__thread char *sdp_filename;
107
108__thread float audio_drift_threshold = 0.1;
109__thread float dts_delta_threshold = 10;
110__thread float dts_error_threshold = 3600*30;
111
113__thread float frame_drop_threshold = 0;
114__thread int do_benchmark = 0;
115__thread int do_benchmark_all = 0;
116__thread int do_hex_dump = 0;
117__thread int do_pkt_dump = 0;
118__thread int copy_ts = 0;
119__thread int start_at_zero = 0;
120__thread int copy_tb = -1;
121__thread int debug_ts = 0;
122__thread int exit_on_error = 0;
123__thread int abort_on_flags = 0;
124__thread int print_stats = -1;
125__thread int qp_hist = 0;
126__thread int stdin_interaction = 1;
127__thread float max_error_rate = 2.0/3;
128__thread char *filter_nbthreads = NULL;
130__thread int vstats_version = 2;
131__thread int auto_conversion_filters = 1;
132__thread int64_t stats_period = 500000;
133
134
135__thread int file_overwrite = 0;
136__thread int no_file_overwrite = 0;
137#if FFMPEG_OPT_PSNR
138__thread int do_psnr = 0;
139#endif
140__thread int ignore_unknown_streams = 0;
141__thread int copy_unknown_streams = 0;
142__thread int recast_media = 0;
143
144extern __thread OptionDef *ffmpeg_options;
145
147{
148 const OptionDef *po = ffmpeg_options;
149 int i;
150
151 /* all OPT_SPEC and OPT_STRING can be freed in generic way */
152 while (po->name) {
153 void *dst = (uint8_t*)o + po->u.off;
154
155 if (po->flags & OPT_SPEC) {
156 SpecifierOpt **so = dst;
157 int i, *count = (int*)(so + 1);
158 for (i = 0; i < *count; i++) {
159 av_freep(&(*so)[i].specifier);
160 if (po->flags & OPT_STRING)
161 av_freep(&(*so)[i].u.str);
162 }
163 av_freep(so);
164 *count = 0;
165 } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
166 av_freep(dst);
167 po++;
168 }
169
170 for (i = 0; i < o->nb_stream_maps; i++)
171 av_freep(&o->stream_maps[i].linklabel);
172 av_freep(&o->stream_maps);
173#if FFMPEG_OPT_MAP_CHANNEL
174 av_freep(&o->audio_channel_maps);
175#endif
176 av_freep(&o->streamid_map);
177 av_freep(&o->attachments);
178}
179
181{
182 memset(o, 0, sizeof(*o));
183
184 o->stop_time = INT64_MAX;
185 o->mux_max_delay = 0.7;
186 o->start_time = AV_NOPTS_VALUE;
187 o->start_time_eof = AV_NOPTS_VALUE;
188 o->recording_time = INT64_MAX;
189 o->limit_filesize = INT64_MAX;
190 o->chapters_input_file = INT_MAX;
191 o->accurate_seek = 1;
192 o->thread_queue_size = -1;
193 o->input_sync_ref = -1;
194 o->find_stream_info = 1;
195 o->shortest_buf_duration = 10.f;
196}
197
198int show_hwaccels(void *optctx, const char *opt, const char *arg)
199{
200 enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE;
201
202 av_log(NULL, AV_LOG_STDERR, "Hardware acceleration methods:\n");
203 while ((type = av_hwdevice_iterate_types(type)) !=
204 AV_HWDEVICE_TYPE_NONE)
205 av_log(NULL, AV_LOG_STDERR, "%s\n", av_hwdevice_get_type_name(type));
206 av_log(NULL, AV_LOG_STDERR, "\n");
207 return 0;
208}
209
210/* return a copy of the input with the stream specifiers removed from the keys */
211AVDictionary *strip_specifiers(const AVDictionary *dict)
212{
213 const AVDictionaryEntry *e = NULL;
214 AVDictionary *ret = NULL;
215
216 while ((e = av_dict_iterate(dict, e))) {
217 char *p = strchr(e->key, ':');
218
219 if (p)
220 *p = 0;
221 av_dict_set(&ret, e->key, e->value, 0);
222 if (p)
223 *p = ':';
224 }
225 return ret;
226}
227
228int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global)
229{
230 if (!av_strcasecmp(arg, "cfr")) *vsync_var = VSYNC_CFR;
231 else if (!av_strcasecmp(arg, "vfr")) *vsync_var = VSYNC_VFR;
232 else if (!av_strcasecmp(arg, "passthrough")) *vsync_var = VSYNC_PASSTHROUGH;
233 else if (!av_strcasecmp(arg, "drop")) *vsync_var = VSYNC_DROP;
234 else if (!is_global && !av_strcasecmp(arg, "auto")) *vsync_var = VSYNC_AUTO;
235 else if (!is_global) {
236 av_log(NULL, AV_LOG_FATAL, "Invalid value %s specified for fps_mode of #%d:%d.\n", arg, file_idx, st_idx);
237 exit_program(1);
238 }
239
240 if (is_global && *vsync_var == VSYNC_AUTO) {
242 av_log(NULL, AV_LOG_WARNING, "Passing a number to -vsync is deprecated,"
243 " use a string argument as described in the manual.\n");
244 }
245 return 0;
246}
247
248/* Correct input file start times based on enabled streams */
250{
251 for (int i = 0; i < nb_input_files; i++) {
252 InputFile *ifile = input_files[i];
253 AVFormatContext *is = ifile->ctx;
254 int64_t new_start_time = INT64_MAX, diff, abs_start_seek;
255
256 ifile->start_time_effective = is->start_time;
257
258 if (is->start_time == AV_NOPTS_VALUE ||
259 !(is->iformat->flags & AVFMT_TS_DISCONT))
260 continue;
261
262 for (int j = 0; j < is->nb_streams; j++) {
263 AVStream *st = is->streams[j];
264 if(st->discard == AVDISCARD_ALL || st->start_time == AV_NOPTS_VALUE)
265 continue;
266 new_start_time = FFMIN(new_start_time, av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q));
267 }
268
269 diff = new_start_time - is->start_time;
270 if (diff) {
271 av_log(NULL, AV_LOG_VERBOSE, "Correcting start time of Input #%d by %"PRId64" us.\n", i, diff);
272 ifile->start_time_effective = new_start_time;
273 if (copy_ts && start_at_zero)
274 ifile->ts_offset = -new_start_time;
275 else if (!copy_ts) {
276 abs_start_seek = is->start_time + ((ifile->start_time != AV_NOPTS_VALUE) ? ifile->start_time : 0);
277 ifile->ts_offset = abs_start_seek > new_start_time ? -abs_start_seek : -new_start_time;
278 } else if (copy_ts)
279 ifile->ts_offset = 0;
280
281 ifile->ts_offset += ifile->input_ts_offset;
282 }
283 }
284}
285
287{
288 for (int i = 0; i < nb_input_files; i++) {
289 InputFile *ref, *self = input_files[i];
290 int64_t adjustment;
291 int64_t self_start_time, ref_start_time, self_seek_start, ref_seek_start;
292 int start_times_set = 1;
293
294 if (self->input_sync_ref == -1 || self->input_sync_ref == i) continue;
295 if (self->input_sync_ref >= nb_input_files || self->input_sync_ref < -1) {
296 av_log(NULL, AV_LOG_FATAL, "-isync for input %d references non-existent input %d.\n", i, self->input_sync_ref);
297 exit_program(1);
298 }
299
300 if (copy_ts && !start_at_zero) {
301 av_log(NULL, AV_LOG_FATAL, "Use of -isync requires that start_at_zero be set if copyts is set.\n");
302 exit_program(1);
303 }
304
305 ref = input_files[self->input_sync_ref];
306 if (ref->input_sync_ref != -1 && ref->input_sync_ref != self->input_sync_ref) {
307 av_log(NULL, AV_LOG_ERROR, "-isync for input %d references a resynced input %d. Sync not set.\n", i, self->input_sync_ref);
308 continue;
309 }
310
311 if (self->ctx->start_time_realtime != AV_NOPTS_VALUE && ref->ctx->start_time_realtime != AV_NOPTS_VALUE) {
312 self_start_time = self->ctx->start_time_realtime;
313 ref_start_time = ref->ctx->start_time_realtime;
314 } else if (self->start_time_effective != AV_NOPTS_VALUE && ref->start_time_effective != AV_NOPTS_VALUE) {
315 self_start_time = self->start_time_effective;
316 ref_start_time = ref->start_time_effective;
317 } else {
318 start_times_set = 0;
319 }
320
321 if (start_times_set) {
322 self_seek_start = self->start_time == AV_NOPTS_VALUE ? 0 : self->start_time;
323 ref_seek_start = ref->start_time == AV_NOPTS_VALUE ? 0 : ref->start_time;
324
325 adjustment = (self_start_time - ref_start_time) + !copy_ts*(self_seek_start - ref_seek_start) + ref->input_ts_offset;
326
327 self->ts_offset += adjustment;
328
329 av_log(NULL, AV_LOG_INFO, "Adjusted ts offset for Input #%d by %"PRId64" us to sync with Input #%d.\n", i, adjustment, self->input_sync_ref);
330 } else {
331 av_log(NULL, AV_LOG_INFO, "Unable to identify start times for Inputs #%d and %d both. No sync adjustment made.\n", i, self->input_sync_ref);
332 }
333 }
334
335 return 0;
336}
337
338int opt_filter_threads(void *optctx, const char *opt, const char *arg)
339{
340 av_free(filter_nbthreads);
341 filter_nbthreads = av_strdup(arg);
342 return 0;
343}
344
345int opt_abort_on(void *optctx, const char *opt, const char *arg)
346{
347 static const AVOption opts[] = {
348 { "abort_on" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, (double)INT64_MAX, .unit = "flags" },
349 { "empty_output" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT }, .unit = "flags" },
350 { "empty_output_stream", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM }, .unit = "flags" },
351 { NULL },
352 };
353 static const AVClass class = {
354 .class_name = "",
355 .item_name = av_default_item_name,
356 .option = opts,
357 .version = LIBAVUTIL_VERSION_INT,
358 };
359 const AVClass *pclass = &class;
360
361 return av_opt_eval_flags(&pclass, &opts[0], arg, &abort_on_flags);
362}
363
364int opt_stats_period(void *optctx, const char *opt, const char *arg)
365{
366 int64_t user_stats_period = parse_time_or_die(opt, arg, 1);
367
368 if (user_stats_period <= 0) {
369 av_log(NULL, AV_LOG_ERROR, "stats_period %s must be positive.\n", arg);
370 return AVERROR(EINVAL);
371 }
372
373 stats_period = user_stats_period;
374 av_log(NULL, AV_LOG_INFO, "ffmpeg stats and -progress period set to %s.\n", arg);
375
376 return 0;
377}
378
379int opt_audio_codec(void *optctx, const char *opt, const char *arg)
380{
381 OptionsContext *o = optctx;
382 return parse_option(o, "codec:a", arg, ffmpeg_options);
383}
384
385int opt_video_codec(void *optctx, const char *opt, const char *arg)
386{
387 OptionsContext *o = optctx;
388 return parse_option(o, "codec:v", arg, ffmpeg_options);
389}
390
391int opt_subtitle_codec(void *optctx, const char *opt, const char *arg)
392{
393 OptionsContext *o = optctx;
394 return parse_option(o, "codec:s", arg, ffmpeg_options);
395}
396
397int opt_data_codec(void *optctx, const char *opt, const char *arg)
398{
399 OptionsContext *o = optctx;
400 return parse_option(o, "codec:d", arg, ffmpeg_options);
401}
402
403int opt_map(void *optctx, const char *opt, const char *arg)
404{
405 OptionsContext *o = optctx;
406 StreamMap *m = NULL;
407 int i, negative = 0, file_idx, disabled = 0;
408#if FFMPEG_OPT_MAP_SYNC
409 char *sync;
410#endif
411 char *map, *p;
412 char *allow_unused;
413
414 if (*arg == '-') {
415 negative = 1;
416 arg++;
417 }
418 map = av_strdup(arg);
419 if (!map)
420 return AVERROR(ENOMEM);
421
422#if FFMPEG_OPT_MAP_SYNC
423 /* parse sync stream first, just pick first matching stream */
424 if ((sync = strchr(map, ','))) {
425 *sync = 0;
426 av_log(NULL, AV_LOG_WARNING, "Specifying a sync stream is deprecated and has no effect\n");
427 }
428#endif
429
430
431 if (map[0] == '[') {
432 /* this mapping refers to lavfi output */
433 const char *c = map + 1;
435 m = &o->stream_maps[o->nb_stream_maps - 1];
436 m->linklabel = av_get_token(&c, "]");
437 if (!m->linklabel) {
438 av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
439 exit_program(1);
440 }
441 } else {
442 if ((allow_unused = strchr(map, '?')))
443 *allow_unused = 0;
444 file_idx = strtol(map, &p, 0);
445 if (file_idx >= nb_input_files || file_idx < 0) {
446 av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
447 exit_program(1);
448 }
449 if (negative)
450 /* disable some already defined maps */
451 for (i = 0; i < o->nb_stream_maps; i++) {
452 m = &o->stream_maps[i];
453 if (file_idx == m->file_index &&
455 input_files[m->file_index]->ctx->streams[m->stream_index],
456 *p == ':' ? p + 1 : p) > 0)
457 m->disabled = 1;
458 }
459 else
460 for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
461 if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
462 *p == ':' ? p + 1 : p) <= 0)
463 continue;
464 if (input_files[file_idx]->streams[i]->user_set_discard == AVDISCARD_ALL) {
465 disabled = 1;
466 continue;
467 }
469 m = &o->stream_maps[o->nb_stream_maps - 1];
470
471 m->file_index = file_idx;
472 m->stream_index = i;
473 }
474 }
475
476 if (!m) {
477 if (allow_unused) {
478 av_log(NULL, AV_LOG_VERBOSE, "Stream map '%s' matches no streams; ignoring.\n", arg);
479 } else if (disabled) {
480 av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches disabled streams.\n"
481 "To ignore this, add a trailing '?' to the map.\n", arg);
482 exit_program(1);
483 } else {
484 av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n"
485 "To ignore this, add a trailing '?' to the map.\n", arg);
486 exit_program(1);
487 }
488 }
489
490 av_freep(&map);
491 return 0;
492}
493
494int opt_attach(void *optctx, const char *opt, const char *arg)
495{
496 OptionsContext *o = optctx;
498 o->attachments[o->nb_attachments - 1] = arg;
499 return 0;
500}
501
502#if FFMPEG_OPT_MAP_CHANNEL
503int opt_map_channel(void *optctx, const char *opt, const char *arg)
504{
505 OptionsContext *o = optctx;
506 int n;
507 AVStream *st;
509 char *allow_unused;
510 char *mapchan;
511
512 av_log(NULL, AV_LOG_WARNING,
513 "The -%s option is deprecated and will be removed. "
514 "It can be replaced by the 'pan' filter, or in some cases by "
515 "combinations of 'channelsplit', 'channelmap', 'amerge' filters.\n", opt);
516
517 mapchan = av_strdup(arg);
518 if (!mapchan)
519 return AVERROR(ENOMEM);
520
523
524 /* muted channel syntax */
525 n = sscanf(arg, "%d:%d.%d", &m->channel_idx, &m->ofile_idx, &m->ostream_idx);
526 if ((n == 1 || n == 3) && m->channel_idx == -1) {
527 m->file_idx = m->stream_idx = -1;
528 if (n == 1)
529 m->ofile_idx = m->ostream_idx = -1;
530 av_free(mapchan);
531 return 0;
532 }
533
534 /* normal syntax */
535 n = sscanf(arg, "%d.%d.%d:%d.%d",
536 &m->file_idx, &m->stream_idx, &m->channel_idx,
537 &m->ofile_idx, &m->ostream_idx);
538
539 if (n != 3 && n != 5) {
540 av_log(NULL, AV_LOG_FATAL, "Syntax error, mapchan usage: "
541 "[file.stream.channel|-1][:syncfile:syncstream]\n");
542 exit_program(1);
543 }
544
545 if (n != 5) // only file.stream.channel specified
546 m->ofile_idx = m->ostream_idx = -1;
547
548 /* check input */
549 if (m->file_idx < 0 || m->file_idx >= nb_input_files) {
550 av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file index: %d\n",
551 m->file_idx);
552 exit_program(1);
553 }
554 if (m->stream_idx < 0 ||
556 av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file stream index #%d.%d\n",
557 m->file_idx, m->stream_idx);
558 exit_program(1);
559 }
560 st = input_files[m->file_idx]->ctx->streams[m->stream_idx];
561 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
562 av_log(NULL, AV_LOG_FATAL, "mapchan: stream #%d.%d is not an audio stream.\n",
563 m->file_idx, m->stream_idx);
564 exit_program(1);
565 }
566 /* allow trailing ? to map_channel */
567 if ((allow_unused = strchr(mapchan, '?')))
568 *allow_unused = 0;
569 if (m->channel_idx < 0 || m->channel_idx >= st->codecpar->ch_layout.nb_channels ||
570 input_files[m->file_idx]->streams[m->stream_idx]->user_set_discard == AVDISCARD_ALL) {
571 if (allow_unused) {
572 av_log(NULL, AV_LOG_VERBOSE, "mapchan: invalid audio channel #%d.%d.%d\n",
573 m->file_idx, m->stream_idx, m->channel_idx);
574 } else {
575 av_log(NULL, AV_LOG_FATAL, "mapchan: invalid audio channel #%d.%d.%d\n"
576 "To ignore this, add a trailing '?' to the map_channel.\n",
577 m->file_idx, m->stream_idx, m->channel_idx);
578 exit_program(1);
579 }
580
581 }
582 av_free(mapchan);
583 return 0;
584}
585#endif
586
587int opt_sdp_file(void *optctx, const char *opt, const char *arg)
588{
589 av_free(sdp_filename);
590 sdp_filename = av_strdup(arg);
591 return 0;
592}
593
594#if CONFIG_VAAPI
595int opt_vaapi_device(void *optctx, const char *opt, const char *arg)
596{
597 const char *prefix = "vaapi:";
598 char *tmp;
599 int err;
600 tmp = av_asprintf("%s%s", prefix, arg);
601 if (!tmp)
602 return AVERROR(ENOMEM);
603 err = hw_device_init_from_string(tmp, NULL);
604 av_free(tmp);
605 return err;
606}
607#endif
608
609#if CONFIG_QSV
610int opt_qsv_device(void *optctx, const char *opt, const char *arg)
611{
612 const char *prefix = "qsv=__qsv_device:hw_any,child_device=";
613 int err;
614 char *tmp = av_asprintf("%s%s", prefix, arg);
615
616 if (!tmp)
617 return AVERROR(ENOMEM);
618
619 err = hw_device_init_from_string(tmp, NULL);
620 av_free(tmp);
621
622 return err;
623}
624#endif
625
626int opt_init_hw_device(void *optctx, const char *opt, const char *arg)
627{
628 if (!strcmp(arg, "list")) {
629 enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE;
630 av_log(NULL, AV_LOG_STDERR, "Supported hardware device types:\n");
631 while ((type = av_hwdevice_iterate_types(type)) !=
632 AV_HWDEVICE_TYPE_NONE)
633 av_log(NULL, AV_LOG_STDERR, "%s\n", av_hwdevice_get_type_name(type));
634 av_log(NULL, AV_LOG_STDERR, "\n");
635 exit_program(0);
636 } else {
637 return hw_device_init_from_string(arg, NULL);
638 }
639}
640
641int opt_filter_hw_device(void *optctx, const char *opt, const char *arg)
642{
643 if (filter_hw_device) {
644 av_log(NULL, AV_LOG_ERROR, "Only one filter device can be used.\n");
645 return AVERROR(EINVAL);
646 }
648 if (!filter_hw_device) {
649 av_log(NULL, AV_LOG_ERROR, "Invalid filter device %s.\n", arg);
650 return AVERROR(EINVAL);
651 }
652 return 0;
653}
654
655int opt_recording_timestamp(void *optctx, const char *opt, const char *arg)
656{
657 OptionsContext *o = optctx;
658 char buf[128];
659 int64_t recording_timestamp = parse_time_or_die(opt, arg, 0) / 1E6;
660 struct tm time = *gmtime((time_t*)&recording_timestamp);
661 if (!strftime(buf, sizeof(buf), "creation_time=%Y-%m-%dT%H:%M:%S%z", &time))
662 return -1;
663 parse_option(o, "metadata", buf, ffmpeg_options);
664
665 av_log(NULL, AV_LOG_WARNING, "%s is deprecated, set the 'creation_time' metadata "
666 "tag instead.\n", opt);
667 return 0;
668}
669
670const AVCodec *find_codec_or_die(void *logctx, const char *name,
671 enum AVMediaType type, int encoder)
672{
673 const AVCodecDescriptor *desc;
674 const char *codec_string = encoder ? "encoder" : "decoder";
675 const AVCodec *codec;
676
677 codec = encoder ?
678 avcodec_find_encoder_by_name(name) :
679 avcodec_find_decoder_by_name(name);
680
681 if (!codec && (desc = avcodec_descriptor_get_by_name(name))) {
682 codec = encoder ? avcodec_find_encoder(desc->id) :
683 avcodec_find_decoder(desc->id);
684 if (codec)
685 av_log(logctx, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n",
686 codec_string, codec->name, desc->name);
687 }
688
689 if (!codec) {
690 av_log(logctx, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
691 exit_program(1);
692 }
693 if (codec->type != type && !recast_media) {
694 av_log(logctx, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
695 exit_program(1);
696 }
697 return codec;
698}
699
700void assert_file_overwrite(const char *filename)
701{
702 const char *proto_name = avio_find_protocol_name(filename);
703
705 av_log(NULL, AV_LOG_FATAL, "Error, both -y and -n supplied. Exiting.\n");
706 exit_program(1);
707 }
708
709 if (!file_overwrite) {
710 if (proto_name && !strcmp(proto_name, "file") && avio_check(filename, 0) == 0) {
712 av_log(NULL, AV_LOG_FATAL, "File '%s' already exists. Overwrite? [y/N] ", filename);
713 term_exit();
714 signal(SIGINT, SIG_DFL);
715 if (!read_yesno()) {
716 av_log(NULL, AV_LOG_FATAL, "Not overwriting - exiting\n");
717 exit_program(1);
718 }
719 term_init();
720 }
721 else {
722 av_log(NULL, AV_LOG_FATAL, "File '%s' already exists. Exiting.\n", filename);
723 exit_program(1);
724 }
725 }
726 }
727
728 if (proto_name && !strcmp(proto_name, "file")) {
729 for (int i = 0; i < nb_input_files; i++) {
730 InputFile *file = input_files[i];
731 if (file->ctx->iformat->flags & AVFMT_NOFILE)
732 continue;
733 if (!strcmp(filename, file->ctx->url)) {
734 av_log(NULL, AV_LOG_FATAL, "Output %s same as Input #%d - exiting\n", filename, i);
735 av_log(NULL, AV_LOG_WARNING, "FFmpeg cannot edit existing files in-place.\n");
736 exit_program(1);
737 }
738 }
739 }
740}
741
742/* read file contents into a string */
743char *file_read(const char *filename)
744{
745 AVIOContext *pb = NULL;
746 int ret = avio_open(&pb, filename, AVIO_FLAG_READ);
747 AVBPrint bprint;
748 char *str;
749
750 if (ret < 0) {
751 av_log(NULL, AV_LOG_ERROR, "Error opening file %s.\n", filename);
752 return NULL;
753 }
754
755 av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
756 ret = avio_read_to_bprint(pb, &bprint, SIZE_MAX);
757 avio_closep(&pb);
758 if (ret < 0) {
759 av_bprint_finalize(&bprint, NULL);
760 return NULL;
761 }
762 ret = av_bprint_finalize(&bprint, &str);
763 if (ret < 0)
764 return NULL;
765 return str;
766}
767
768/* arg format is "output-stream-index:streamid-value". */
769int opt_streamid(void *optctx, const char *opt, const char *arg)
770{
771 OptionsContext *o = optctx;
772 int idx;
773 char *p;
774 char idx_str[16];
775
776 av_strlcpy(idx_str, arg, sizeof(idx_str));
777 p = strchr(idx_str, ':');
778 if (!p) {
779 av_log(NULL, AV_LOG_FATAL,
780 "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
781 arg, opt);
782 exit_program(1);
783 }
784 *p++ = '\0';
785 idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, MAX_STREAMS-1);
786 o->streamid_map = grow_array(o->streamid_map, sizeof(*o->streamid_map), &o->nb_streamid_map, idx+1);
787 o->streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
788 return 0;
789}
790
792{
793 int i, ret = 0;
794
795 for (i = 0; i < nb_filtergraphs; i++) {
797 if (ret < 0)
798 return ret;
799 }
800 return 0;
801}
802
803int opt_target(void *optctx, const char *opt, const char *arg)
804{
805 const OptionDef *options = ffmpeg_options;
806 OptionsContext *o = optctx;
807 enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
808 static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" };
809
810 if (!strncmp(arg, "pal-", 4)) {
811 norm = PAL;
812 arg += 4;
813 } else if (!strncmp(arg, "ntsc-", 5)) {
814 norm = NTSC;
815 arg += 5;
816 } else if (!strncmp(arg, "film-", 5)) {
817 norm = FILM;
818 arg += 5;
819 } else {
820 /* Try to determine PAL/NTSC by peeking in the input files */
821 if (nb_input_files) {
822 int i, j;
823 for (j = 0; j < nb_input_files; j++) {
824 for (i = 0; i < input_files[j]->nb_streams; i++) {
825 AVStream *st = input_files[j]->ctx->streams[i];
826 int64_t fr;
827 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
828 continue;
829 fr = st->time_base.den * 1000LL / st->time_base.num;
830 if (fr == 25000) {
831 norm = PAL;
832 break;
833 } else if ((fr == 29970) || (fr == 23976)) {
834 norm = NTSC;
835 break;
836 }
837 }
838 if (norm != UNKNOWN)
839 break;
840 }
841 }
842 if (norm != UNKNOWN)
843 av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
844 }
845
846 if (norm == UNKNOWN) {
847 av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
848 av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
849 av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
850 exit_program(1);
851 }
852
853 if (!strcmp(arg, "vcd")) {
854 opt_video_codec(o, "c:v", "mpeg1video");
855 opt_audio_codec(o, "c:a", "mp2");
856 parse_option(o, "f", "vcd", options);
857
858 parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
859 parse_option(o, "r", frame_rates[norm], options);
860 opt_default(NULL, "g", norm == PAL ? "15" : "18");
861
862 opt_default(NULL, "b:v", "1150000");
863 opt_default(NULL, "maxrate:v", "1150000");
864 opt_default(NULL, "minrate:v", "1150000");
865 opt_default(NULL, "bufsize:v", "327680"); // 40*1024*8;
866
867 opt_default(NULL, "b:a", "224000");
868 parse_option(o, "ar", "44100", options);
869 parse_option(o, "ac", "2", options);
870
871 opt_default(NULL, "packetsize", "2324");
872 opt_default(NULL, "muxrate", "1411200"); // 2352 * 75 * 8;
873
874 /* We have to offset the PTS, so that it is consistent with the SCR.
875 SCR starts at 36000, but the first two packs contain only padding
876 and the first pack from the other stream, respectively, may also have
877 been written before.
878 So the real data starts at SCR 36000+3*1200. */
879 o->mux_preload = (36000 + 3 * 1200) / 90000.0; // 0.44
880 } else if (!strcmp(arg, "svcd")) {
881
882 opt_video_codec(o, "c:v", "mpeg2video");
883 opt_audio_codec(o, "c:a", "mp2");
884 parse_option(o, "f", "svcd", options);
885
886 parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
887 parse_option(o, "r", frame_rates[norm], options);
888 parse_option(o, "pix_fmt", "yuv420p", options);
889 opt_default(NULL, "g", norm == PAL ? "15" : "18");
890
891 opt_default(NULL, "b:v", "2040000");
892 opt_default(NULL, "maxrate:v", "2516000");
893 opt_default(NULL, "minrate:v", "0"); // 1145000;
894 opt_default(NULL, "bufsize:v", "1835008"); // 224*1024*8;
895 opt_default(NULL, "scan_offset", "1");
896
897 opt_default(NULL, "b:a", "224000");
898 parse_option(o, "ar", "44100", options);
899
900 opt_default(NULL, "packetsize", "2324");
901
902 } else if (!strcmp(arg, "dvd")) {
903
904 opt_video_codec(o, "c:v", "mpeg2video");
905 opt_audio_codec(o, "c:a", "ac3");
906 parse_option(o, "f", "dvd", options);
907
908 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
909 parse_option(o, "r", frame_rates[norm], options);
910 parse_option(o, "pix_fmt", "yuv420p", options);
911 opt_default(NULL, "g", norm == PAL ? "15" : "18");
912
913 opt_default(NULL, "b:v", "6000000");
914 opt_default(NULL, "maxrate:v", "9000000");
915 opt_default(NULL, "minrate:v", "0"); // 1500000;
916 opt_default(NULL, "bufsize:v", "1835008"); // 224*1024*8;
917
918 opt_default(NULL, "packetsize", "2048"); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
919 opt_default(NULL, "muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
920
921 opt_default(NULL, "b:a", "448000");
922 parse_option(o, "ar", "48000", options);
923
924 } else if (!strncmp(arg, "dv", 2)) {
925
926 parse_option(o, "f", "dv", options);
927
928 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
929 parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
930 norm == PAL ? "yuv420p" : "yuv411p", options);
931 parse_option(o, "r", frame_rates[norm], options);
932
933 parse_option(o, "ar", "48000", options);
934 parse_option(o, "ac", "2", options);
935
936 } else {
937 av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg);
938 return AVERROR(EINVAL);
939 }
940
941 av_dict_copy(&o->g->codec_opts, codec_opts, AV_DICT_DONT_OVERWRITE);
942 av_dict_copy(&o->g->format_opts, format_opts, AV_DICT_DONT_OVERWRITE);
943
944 return 0;
945}
946
947int opt_vstats_file(void *optctx, const char *opt, const char *arg)
948{
949 av_free (vstats_filename);
950 vstats_filename = av_strdup (arg);
951 return 0;
952}
953
954int opt_vstats(void *optctx, const char *opt, const char *arg)
955{
956 char filename[40];
957 time_t today2 = time(NULL);
958 struct tm *today = localtime(&today2);
959
960 if (!today) { // maybe tomorrow
961 av_log(NULL, AV_LOG_FATAL, "Unable to get current time: %s\n", strerror(errno));
962 exit_program(1);
963 }
964
965 snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
966 today->tm_sec);
967 return opt_vstats_file(NULL, opt, filename);
968}
969
970int opt_video_frames(void *optctx, const char *opt, const char *arg)
971{
972 OptionsContext *o = optctx;
973 return parse_option(o, "frames:v", arg, ffmpeg_options);
974}
975
976int opt_audio_frames(void *optctx, const char *opt, const char *arg)
977{
978 OptionsContext *o = optctx;
979 return parse_option(o, "frames:a", arg, ffmpeg_options);
980}
981
982int opt_data_frames(void *optctx, const char *opt, const char *arg)
983{
984 OptionsContext *o = optctx;
985 return parse_option(o, "frames:d", arg, ffmpeg_options);
986}
987
988int opt_default_new(OptionsContext *o, const char *opt, const char *arg)
989{
990 int ret;
991 AVDictionary *cbak = codec_opts;
992 AVDictionary *fbak = format_opts;
993 codec_opts = NULL;
994 format_opts = NULL;
995
996 ret = opt_default(NULL, opt, arg);
997
998 av_dict_copy(&o->g->codec_opts , codec_opts, 0);
999 av_dict_copy(&o->g->format_opts, format_opts, 0);
1000 av_dict_free(&codec_opts);
1001 av_dict_free(&format_opts);
1002 codec_opts = cbak;
1003 format_opts = fbak;
1004
1005 return ret;
1006}
1007
1008int opt_preset(void *optctx, const char *opt, const char *arg)
1009{
1010 OptionsContext *o = optctx;
1011 FILE *f=NULL;
1012 char filename[1000], line[1000], tmp_line[1000];
1013 const char *codec_name = NULL;
1014
1015 tmp_line[0] = *opt;
1016 tmp_line[1] = 0;
1017 MATCH_PER_TYPE_OPT(codec_names, str, codec_name, NULL, tmp_line);
1018
1019 if (!(f = get_preset_file(filename, sizeof(filename), arg, *opt == 'f', codec_name))) {
1020 if(!strncmp(arg, "libx264-lossless", strlen("libx264-lossless"))){
1021 av_log(NULL, AV_LOG_FATAL, "Please use -preset <speed> -qp 0\n");
1022 }else
1023 av_log(NULL, AV_LOG_FATAL, "File for preset '%s' not found\n", arg);
1024 exit_program(1);
1025 }
1026
1027 while (fgets(line, sizeof(line), f)) {
1028 char *key = tmp_line, *value, *endptr;
1029
1030 if (strcspn(line, "#\n\r") == 0)
1031 continue;
1032 av_strlcpy(tmp_line, line, sizeof(tmp_line));
1033 if (!av_strtok(key, "=", &value) ||
1034 !av_strtok(value, "\r\n", &endptr)) {
1035 av_log(NULL, AV_LOG_FATAL, "%s: Invalid syntax: '%s'\n", filename, line);
1036 exit_program(1);
1037 }
1038 av_log(NULL, AV_LOG_DEBUG, "ffpreset[%s]: set '%s' = '%s'\n", filename, key, value);
1039
1040 if (!strcmp(key, "acodec")) opt_audio_codec (o, key, value);
1041 else if (!strcmp(key, "vcodec")) opt_video_codec (o, key, value);
1042 else if (!strcmp(key, "scodec")) opt_subtitle_codec(o, key, value);
1043 else if (!strcmp(key, "dcodec")) opt_data_codec (o, key, value);
1044 else if (opt_default_new(o, key, value) < 0) {
1045 av_log(NULL, AV_LOG_FATAL, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n",
1046 filename, line, key, value);
1047 exit_program(1);
1048 }
1049 }
1050
1051 fclose(f);
1052
1053 return 0;
1054}
1055
1056int opt_old2new(void *optctx, const char *opt, const char *arg)
1057{
1058 OptionsContext *o = optctx;
1059 int ret;
1060 char *s = av_asprintf("%s:%c", opt + 1, *opt);
1061 if (!s)
1062 return AVERROR(ENOMEM);
1063 ret = parse_option(o, s, arg, ffmpeg_options);
1064 av_free(s);
1065 return ret;
1066}
1067
1068int opt_bitrate(void *optctx, const char *opt, const char *arg)
1069{
1070 OptionsContext *o = optctx;
1071
1072 if(!strcmp(opt, "ab")){
1073 av_dict_set(&o->g->codec_opts, "b:a", arg, 0);
1074 return 0;
1075 } else if(!strcmp(opt, "b")){
1076 av_log(NULL, AV_LOG_WARNING, "Please use -b:a or -b:v, -b is ambiguous\n");
1077 av_dict_set(&o->g->codec_opts, "b:v", arg, 0);
1078 return 0;
1079 }
1080 av_dict_set(&o->g->codec_opts, opt, arg, 0);
1081 return 0;
1082}
1083
1084int opt_qscale(void *optctx, const char *opt, const char *arg)
1085{
1086 OptionDef *options = ffmpeg_options;
1087 OptionsContext *o = optctx;
1088 char *s;
1089 int ret;
1090 if(!strcmp(opt, "qscale")){
1091 av_log(NULL, AV_LOG_WARNING, "Please use -q:a or -q:v, -qscale is ambiguous\n");
1092 return parse_option(o, "q:v", arg, options);
1093 }
1094 s = av_asprintf("q%s", opt + 6);
1095 if (!s)
1096 return AVERROR(ENOMEM);
1097 ret = parse_option(o, s, arg, options);
1098 av_free(s);
1099 return ret;
1100}
1101
1102int opt_profile(void *optctx, const char *opt, const char *arg)
1103{
1104 OptionsContext *o = optctx;
1105 if(!strcmp(opt, "profile")){
1106 av_log(NULL, AV_LOG_WARNING, "Please use -profile:a or -profile:v, -profile is ambiguous\n");
1107 av_dict_set(&o->g->codec_opts, "profile:v", arg, 0);
1108 return 0;
1109 }
1110 av_dict_set(&o->g->codec_opts, opt, arg, 0);
1111 return 0;
1112}
1113
1114int opt_video_filters(void *optctx, const char *opt, const char *arg)
1115{
1116 OptionsContext *o = optctx;
1117 return parse_option(o, "filter:v", arg, ffmpeg_options);
1118}
1119
1120int opt_audio_filters(void *optctx, const char *opt, const char *arg)
1121{
1122 OptionsContext *o = optctx;
1123 return parse_option(o, "filter:a", arg, ffmpeg_options);
1124}
1125
1126int opt_vsync(void *optctx, const char *opt, const char *arg)
1127{
1128 av_log(NULL, AV_LOG_WARNING, "-vsync is deprecated. Use -fps_mode\n");
1129 parse_and_set_vsync(arg, &video_sync_method, -1, -1, 1);
1130 return 0;
1131}
1132
1133int opt_timecode(void *optctx, const char *opt, const char *arg)
1134{
1135 OptionsContext *o = optctx;
1136 int ret;
1137 char *tcr = av_asprintf("timecode=%s", arg);
1138 if (!tcr)
1139 return AVERROR(ENOMEM);
1140 ret = parse_option(o, "metadata:g", tcr, ffmpeg_options);
1141 if (ret >= 0)
1142 ret = av_dict_set(&o->g->codec_opts, "gop_timecode", arg, 0);
1143 av_free(tcr);
1144 return ret;
1145}
1146
1147int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
1148{
1149 OptionsContext *o = optctx;
1150 return parse_option(o, "q:a", arg, ffmpeg_options);
1151}
1152
1153int opt_filter_complex(void *optctx, const char *opt, const char *arg)
1154{
1156
1157 fg->index = nb_filtergraphs - 1;
1158 fg->graph_desc = av_strdup(arg);
1159 if (!fg->graph_desc)
1160 return AVERROR(ENOMEM);
1161
1162 return 0;
1163}
1164
1165int opt_filter_complex_script(void *optctx, const char *opt, const char *arg)
1166{
1167 FilterGraph *fg;
1168 char *graph_desc = file_read(arg);
1169 if (!graph_desc)
1170 return AVERROR(EINVAL);
1171
1173 fg->index = nb_filtergraphs - 1;
1174 fg->graph_desc = graph_desc;
1175
1176 return 0;
1177}
1178
1179void show_help_default_ffmpeg(const char *opt, const char *arg)
1180{
1181 OptionDef *options = ffmpeg_options;
1182 /* per-file options have at least one of those set */
1183 const int per_file = OPT_SPEC | OPT_OFFSET | OPT_PERFILE;
1184 int show_advanced = 0, show_avoptions = 0;
1185
1186 if (opt && *opt) {
1187 if (!strcmp(opt, "long"))
1188 show_advanced = 1;
1189 else if (!strcmp(opt, "full"))
1190 show_advanced = show_avoptions = 1;
1191 else
1192 av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);
1193 }
1194
1195 show_usage();
1196
1197 av_log(NULL, AV_LOG_STDERR, "Getting help:\n"
1198 " -h -- print basic options\n"
1199 " -h long -- print more options\n"
1200 " -h full -- print all options (including all format and codec specific options, very long)\n"
1201 " -h type=name -- print all options for the named decoder/encoder/demuxer/muxer/filter/bsf/protocol\n"
1202 " See man %s for detailed description of the options.\n"
1203 "\n", program_name);
1204
1205 show_help_options(options, "Print help / information / capabilities:",
1206 OPT_EXIT, 0, 0);
1207
1208 show_help_options(options, "Global options (affect whole program "
1209 "instead of just one file):",
1210 0, per_file | OPT_EXIT | OPT_EXPERT, 0);
1211 if (show_advanced)
1212 show_help_options(options, "Advanced global options:", OPT_EXPERT,
1213 per_file | OPT_EXIT, 0);
1214
1215 show_help_options(options, "Per-file main options:", 0,
1217 OPT_EXIT, per_file);
1218 if (show_advanced)
1219 show_help_options(options, "Advanced per-file options:",
1221
1222 show_help_options(options, "Video options:",
1224 if (show_advanced)
1225 show_help_options(options, "Advanced Video options:",
1227
1228 show_help_options(options, "Audio options:",
1230 if (show_advanced)
1231 show_help_options(options, "Advanced Audio options:",
1233 show_help_options(options, "Subtitle options:",
1234 OPT_SUBTITLE, 0, 0);
1235 av_log(NULL, AV_LOG_STDERR, "\n");
1236
1237 if (show_avoptions) {
1238 int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
1239 show_help_children(avcodec_get_class(), flags);
1240 show_help_children(avformat_get_class(), flags);
1241#if CONFIG_SWSCALE
1242 show_help_children(sws_get_class(), flags);
1243#endif
1244#if CONFIG_SWRESAMPLE
1245 show_help_children(swr_get_class(), AV_OPT_FLAG_AUDIO_PARAM);
1246#endif
1247 show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM);
1248 show_help_children(av_bsf_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_BSF_PARAM);
1249 }
1250}
1251
1252void show_usage(void)
1253{
1254 av_log(NULL, AV_LOG_INFO, "Hyper fast Audio and Video encoder\n");
1255 av_log(NULL, AV_LOG_INFO, "usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
1256 av_log(NULL, AV_LOG_INFO, "\n");
1257}
1258
1262};
1263
1264static const OptionGroupDef groups[] = {
1265 [GROUP_OUTFILE] = { "output url", NULL, OPT_OUTPUT },
1266 [GROUP_INFILE] = { "input url", "i", OPT_INPUT },
1267};
1268
1269int open_files(OptionGroupList *l, const char *inout,
1270 int (*open_file)(const OptionsContext*, const char*))
1271{
1272 int i, ret;
1273
1274 for (i = 0; i < l->nb_groups; i++) {
1275 OptionGroup *g = &l->groups[i];
1277
1278 init_options(&o);
1279 o.g = g;
1280
1281 ret = parse_optgroup(&o, g);
1282 if (ret < 0) {
1283 av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
1284 "%s.\n", inout, g->arg);
1285 uninit_options(&o);
1286 return ret;
1287 }
1288
1289 av_log(NULL, AV_LOG_DEBUG, "Opening an %s file: %s.\n", inout, g->arg);
1290 ret = open_file(&o, g->arg);
1291 uninit_options(&o);
1292 if (ret < 0) {
1293 av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n",
1294 inout, g->arg);
1295 return ret;
1296 }
1297 av_log(NULL, AV_LOG_DEBUG, "Successfully opened the file.\n");
1298 }
1299
1300 return 0;
1301}
1302
1303int ffmpeg_parse_options(int argc, char **argv)
1304{
1305 OptionParseContext octx;
1306 int ret;
1307
1308 memset(&octx, 0, sizeof(octx));
1309
1310 /* split the commandline into an internal representation */
1311 ret = split_commandline(&octx, argc, argv, ffmpeg_options, groups,
1312 FF_ARRAY_ELEMS(groups));
1313 if (ret < 0) {
1314 av_log(NULL, AV_LOG_FATAL, "Error splitting the argument list: ");
1315 goto fail;
1316 }
1317
1318 /* apply global options */
1319 ret = parse_optgroup(NULL, &octx.global_opts);
1320 if (ret < 0) {
1321 av_log(NULL, AV_LOG_FATAL, "Error parsing global options: ");
1322 goto fail;
1323 }
1324
1325 /* configure terminal and setup signal handlers */
1326 term_init();
1327
1328 /* open input files */
1329 ret = open_files(&octx.groups[GROUP_INFILE], "input", ifile_open);
1330 if (ret < 0) {
1331 av_log(NULL, AV_LOG_FATAL, "Error opening input files: ");
1332 goto fail;
1333 }
1334
1335 /* create the complex filtergraphs */
1336 ret = init_complex_filters();
1337 if (ret < 0) {
1338 av_log(NULL, AV_LOG_FATAL, "Error initializing complex filters.\n");
1339 goto fail;
1340 }
1341
1342 /* open output files */
1343 ret = open_files(&octx.groups[GROUP_OUTFILE], "output", of_open);
1344 if (ret < 0) {
1345 av_log(NULL, AV_LOG_FATAL, "Error opening output files: ");
1346 goto fail;
1347 }
1348
1350
1352
1354
1355fail:
1356 uninit_parse_context(&octx);
1357 if (ret < 0) {
1358 av_log(NULL, AV_LOG_FATAL, "%s\n", av_err2str(ret));
1359 }
1360 return ret;
1361}
1362
1363int opt_progress(void *optctx, const char *opt, const char *arg)
1364{
1365 AVIOContext *avio = NULL;
1366 int ret;
1367
1368 if (!strcmp(arg, "-"))
1369 arg = "pipe:";
1370 ret = avio_open2(&avio, arg, AVIO_FLAG_WRITE, &int_cb, NULL);
1371 if (ret < 0) {
1372 av_log(NULL, AV_LOG_ERROR, "Failed to open progress URL \"%s\": %s\n",
1373 arg, av_err2str(ret));
1374 return ret;
1375 }
1376 progress_avio = avio;
1377 return 0;
1378}
1379
1380int opt_timelimit(void *optctx, const char *opt, const char *arg)
1381{
1382#if HAVE_SETRLIMIT
1383 int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
1384 struct rlimit rl = { lim, lim + 1 };
1385 if (setrlimit(RLIMIT_CPU, &rl))
1386 perror("setrlimit");
1387#else
1388 av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
1389#endif
1390 return 0;
1391}
void exit_program(int ret)
void show_help_children(const AVClass *class, int flags)
__thread AVDictionary * codec_opts
int parse_option(void *optctx, const char *opt, const char *arg, const OptionDef *options)
void show_help_options(const OptionDef *options, const char *msg, int req_flags, int rej_flags, int alt_flags)
__thread AVDictionary * format_opts
int opt_default(void *optctx, const char *opt, const char *arg)
int read_yesno(void)
int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
__thread char * program_name
void uninit_parse_context(OptionParseContext *octx)
int split_commandline(OptionParseContext *octx, int argc, char *argv[], const OptionDef *options, const OptionGroupDef *groups, int nb_groups)
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
FILE * get_preset_file(char *filename, size_t filename_size, const char *preset_name, int is_path, const char *codec_name)
void * grow_array(void *array, int elem_size, int *size, int new_size)
int parse_optgroup(void *optctx, OptionGroup *g)
double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
#define OPT_VIDEO
#define OPT_SPEC
#define OPT_INT64
#define OPT_PERFILE
#define OPT_INT
#define ALLOC_ARRAY_ELEM(array, nb_elems)
#define AV_LOG_STDERR
#define OPT_INPUT
#define OPT_STRING
#define GROW_ARRAY(array, nb_elems)
#define OPT_AUDIO
#define OPT_SUBTITLE
#define OPT_EXPERT
#define OPT_EXIT
#define OPT_OUTPUT
#define OPT_OFFSET
__thread const AVIOInterruptCB int_cb
void term_exit(void)
__thread int nb_input_files
__thread AVIOContext * progress_avio
__thread InputFile ** input_files
__thread FilterGraph ** filtergraphs
__thread int nb_filtergraphs
void term_init(void)
int of_open(const OptionsContext *o, const char *filename)
#define MAX_STREAMS
HWDevice * hw_device_get_by_name(const char *name)
int ifile_open(const OptionsContext *o, const char *filename)
VideoSyncMethod
@ VSYNC_VFR
@ VSYNC_AUTO
@ VSYNC_PASSTHROUGH
@ VSYNC_CFR
@ VSYNC_DROP
#define ABORT_ON_FLAG_EMPTY_OUTPUT
int hw_device_init_from_string(const char *arg, HWDevice **dev)
void check_filter_outputs(void)
#define ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM
int init_complex_filtergraph(FilterGraph *fg)
#define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)
__thread float dts_delta_threshold
void uninit_options(OptionsContext *o)
__thread int copy_tb
int opt_sdp_file(void *optctx, const char *opt, const char *arg)
int opt_timecode(void *optctx, const char *opt, const char *arg)
__thread OptionDef * ffmpeg_options
int opt_vstats_file(void *optctx, const char *opt, const char *arg)
__thread int64_t stats_period
int opt_data_codec(void *optctx, const char *opt, const char *arg)
int opt_streamid(void *optctx, const char *opt, const char *arg)
int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global)
int opt_qscale(void *optctx, const char *opt, const char *arg)
int opt_filter_complex_script(void *optctx, const char *opt, const char *arg)
__thread char * sdp_filename
__thread enum VideoSyncMethod video_sync_method
const char *const opt_name_top_field_first[]
int opt_filter_complex(void *optctx, const char *opt, const char *arg)
int opt_vsync(void *optctx, const char *opt, const char *arg)
__thread int print_stats
__thread int filter_complex_nbthreads
int apply_sync_offsets(void)
__thread int abort_on_flags
const char *const opt_name_codec_tags[]
__thread float max_error_rate
__thread int recast_media
__thread int copy_ts
__thread int stdin_interaction
int opt_subtitle_codec(void *optctx, const char *opt, const char *arg)
__thread float dts_error_threshold
const char *const opt_name_frame_rates[]
int opt_profile(void *optctx, const char *opt, const char *arg)
int opt_abort_on(void *optctx, const char *opt, const char *arg)
void show_usage(void)
__thread int copy_unknown_streams
int opt_video_codec(void *optctx, const char *opt, const char *arg)
int opt_data_frames(void *optctx, const char *opt, const char *arg)
int open_files(OptionGroupList *l, const char *inout, int(*open_file)(const OptionsContext *, const char *))
int opt_video_filters(void *optctx, const char *opt, const char *arg)
__thread char * filter_nbthreads
AVDictionary * strip_specifiers(const AVDictionary *dict)
int opt_attach(void *optctx, const char *opt, const char *arg)
__thread int do_benchmark
int opt_filter_hw_device(void *optctx, const char *opt, const char *arg)
__thread float frame_drop_threshold
__thread int vstats_version
__thread char * vstats_filename
int opt_audio_frames(void *optctx, const char *opt, const char *arg)
__thread int no_file_overwrite
int opt_target(void *optctx, const char *opt, const char *arg)
int init_complex_filters(void)
__thread int file_overwrite
int opt_map(void *optctx, const char *opt, const char *arg)
__thread float audio_drift_threshold
@ GROUP_OUTFILE
@ GROUP_INFILE
__thread int do_benchmark_all
int opt_vstats(void *optctx, const char *opt, const char *arg)
__thread int start_at_zero
int opt_video_frames(void *optctx, const char *opt, const char *arg)
int opt_timelimit(void *optctx, const char *opt, const char *arg)
void assert_file_overwrite(const char *filename)
int opt_audio_filters(void *optctx, const char *opt, const char *arg)
__thread int exit_on_error
int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
int ffmpeg_parse_options(int argc, char **argv)
int opt_filter_threads(void *optctx, const char *opt, const char *arg)
void correct_input_start_times(void)
int show_hwaccels(void *optctx, const char *opt, const char *arg)
__thread HWDevice * filter_hw_device
int opt_preset(void *optctx, const char *opt, const char *arg)
const AVCodec * find_codec_or_die(void *logctx, const char *name, enum AVMediaType type, int encoder)
int opt_old2new(void *optctx, const char *opt, const char *arg)
int opt_stats_period(void *optctx, const char *opt, const char *arg)
__thread int qp_hist
int opt_bitrate(void *optctx, const char *opt, const char *arg)
const char *const opt_name_codec_names[]
int opt_default_new(OptionsContext *o, const char *opt, const char *arg)
__thread int do_psnr
__thread int do_hex_dump
__thread int do_pkt_dump
void init_options(OptionsContext *o)
__thread int debug_ts
int opt_map_channel(void *optctx, const char *opt, const char *arg)
int opt_progress(void *optctx, const char *opt, const char *arg)
int opt_audio_codec(void *optctx, const char *opt, const char *arg)
int opt_recording_timestamp(void *optctx, const char *opt, const char *arg)
__thread int auto_conversion_filters
char * file_read(const char *filename)
void show_help_default_ffmpeg(const char *opt, const char *arg)
__thread int ignore_unknown_streams
int opt_init_hw_device(void *optctx, const char *opt, const char *arg)
static const OptionGroupDef groups[]
const char * graph_desc
int64_t ts_offset
AVFormatContext * ctx
int64_t input_ts_offset
int64_t start_time_effective
InputStream ** streams
int64_t start_time
union OptionDef::@1 u
const char * name
AVDictionary * codec_opts
const char * arg
AVDictionary * format_opts
OptionGroup * groups
OptionGroupList * groups
StreamMap * stream_maps
float shortest_buf_duration
const char ** attachments
AudioChannelMap * audio_channel_maps
OptionGroup * g
char * linklabel