• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ffmpeg option parsing
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 #include "config.h"
22 
23 #include <stdint.h>
24 
25 #if HAVE_SYS_RESOURCE_H
26 #include <sys/time.h>
27 #include <sys/resource.h>
28 #endif
29 
30 #include "ffmpeg.h"
31 #include "fopen_utf8.h"
32 #include "cmdutils.h"
33 #include "opt_common.h"
34 
35 #include "libavformat/avformat.h"
36 
37 #include "libavcodec/avcodec.h"
38 #include "libavcodec/bsf.h"
39 
40 #include "libavfilter/avfilter.h"
41 
42 #include "libavutil/avassert.h"
43 #include "libavutil/avstring.h"
44 #include "libavutil/avutil.h"
45 #include "libavutil/bprint.h"
46 #include "libavutil/channel_layout.h"
47 #include "libavutil/getenv_utf8.h"
48 #include "libavutil/intreadwrite.h"
49 #include "libavutil/fifo.h"
50 #include "libavutil/mathematics.h"
51 #include "libavutil/opt.h"
52 #include "libavutil/parseutils.h"
53 #include "libavutil/pixdesc.h"
54 #include "libavutil/pixfmt.h"
55 
56 #define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
57 
58 #define SPECIFIER_OPT_FMT_str  "%s"
59 #define SPECIFIER_OPT_FMT_i    "%i"
60 #define SPECIFIER_OPT_FMT_i64  "%"PRId64
61 #define SPECIFIER_OPT_FMT_ui64 "%"PRIu64
62 #define SPECIFIER_OPT_FMT_f    "%f"
63 #define SPECIFIER_OPT_FMT_dbl  "%lf"
64 
65 static const char *const opt_name_codec_names[]               = {"c", "codec", "acodec", "vcodec", "scodec", "dcodec", NULL};
66 static const char *const opt_name_audio_channels[]            = {"ac", NULL};
67 static const char *const opt_name_audio_ch_layouts[]          = {"channel_layout", "ch_layout", NULL};
68 static const char *const opt_name_audio_sample_rate[]         = {"ar", NULL};
69 static const char *const opt_name_frame_rates[]               = {"r", NULL};
70 static const char *const opt_name_max_frame_rates[]           = {"fpsmax", NULL};
71 static const char *const opt_name_frame_sizes[]               = {"s", NULL};
72 static const char *const opt_name_frame_pix_fmts[]            = {"pix_fmt", NULL};
73 static const char *const opt_name_ts_scale[]                  = {"itsscale", NULL};
74 static const char *const opt_name_hwaccels[]                  = {"hwaccel", NULL};
75 static const char *const opt_name_hwaccel_devices[]           = {"hwaccel_device", NULL};
76 static const char *const opt_name_hwaccel_output_formats[]    = {"hwaccel_output_format", NULL};
77 static const char *const opt_name_autorotate[]                = {"autorotate", NULL};
78 static const char *const opt_name_autoscale[]                 = {"autoscale", NULL};
79 static const char *const opt_name_max_frames[]                = {"frames", "aframes", "vframes", "dframes", NULL};
80 static const char *const opt_name_bitstream_filters[]         = {"bsf", "absf", "vbsf", NULL};
81 static const char *const opt_name_codec_tags[]                = {"tag", "atag", "vtag", "stag", NULL};
82 static const char *const opt_name_sample_fmts[]               = {"sample_fmt", NULL};
83 static const char *const opt_name_qscale[]                    = {"q", "qscale", NULL};
84 static const char *const opt_name_forced_key_frames[]         = {"forced_key_frames", NULL};
85 static const char *const opt_name_fps_mode[]                  = {"fps_mode", NULL};
86 static const char *const opt_name_force_fps[]                 = {"force_fps", NULL};
87 static const char *const opt_name_frame_aspect_ratios[]       = {"aspect", NULL};
88 static const char *const opt_name_rc_overrides[]              = {"rc_override", NULL};
89 static const char *const opt_name_intra_matrices[]            = {"intra_matrix", NULL};
90 static const char *const opt_name_inter_matrices[]            = {"inter_matrix", NULL};
91 static const char *const opt_name_chroma_intra_matrices[]     = {"chroma_intra_matrix", NULL};
92 static const char *const opt_name_top_field_first[]           = {"top", NULL};
93 static const char *const opt_name_presets[]                   = {"pre", "apre", "vpre", "spre", NULL};
94 static const char *const opt_name_copy_initial_nonkeyframes[] = {"copyinkf", NULL};
95 static const char *const opt_name_copy_prior_start[]          = {"copypriorss", NULL};
96 static const char *const opt_name_filters[]                   = {"filter", "af", "vf", NULL};
97 static const char *const opt_name_filter_scripts[]            = {"filter_script", NULL};
98 static const char *const opt_name_reinit_filters[]            = {"reinit_filter", NULL};
99 static const char *const opt_name_fix_sub_duration[]          = {"fix_sub_duration", NULL};
100 static const char *const opt_name_canvas_sizes[]              = {"canvas_size", NULL};
101 static const char *const opt_name_pass[]                      = {"pass", NULL};
102 static const char *const opt_name_passlogfiles[]              = {"passlogfile", NULL};
103 static const char *const opt_name_max_muxing_queue_size[]     = {"max_muxing_queue_size", NULL};
104 static const char *const opt_name_muxing_queue_data_threshold[] = {"muxing_queue_data_threshold", NULL};
105 static const char *const opt_name_guess_layout_max[]          = {"guess_layout_max", NULL};
106 static const char *const opt_name_apad[]                      = {"apad", NULL};
107 static const char *const opt_name_discard[]                   = {"discard", NULL};
108 static const char *const opt_name_disposition[]               = {"disposition", NULL};
109 static const char *const opt_name_time_bases[]                = {"time_base", NULL};
110 static const char *const opt_name_enc_time_bases[]            = {"enc_time_base", NULL};
111 static const char *const opt_name_bits_per_raw_sample[]       = {"bits_per_raw_sample", NULL};
112 
113 #define WARN_MULTIPLE_OPT_USAGE(name, type, so, st)\
114 {\
115     char namestr[128] = "";\
116     const char *spec = so->specifier && so->specifier[0] ? so->specifier : "";\
117     for (i = 0; opt_name_##name[i]; i++)\
118         av_strlcatf(namestr, sizeof(namestr), "-%s%s", opt_name_##name[i], opt_name_##name[i+1] ? (opt_name_##name[i+2] ? ", " : " or ") : "");\
119     av_log(NULL, AV_LOG_WARNING, "Multiple %s options specified for stream %d, only the last option '-%s%s%s "SPECIFIER_OPT_FMT_##type"' will be used.\n",\
120            namestr, st->index, opt_name_##name[0], spec[0] ? ":" : "", spec, so->u.type);\
121 }
122 
123 #define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
124 {\
125     int i, ret, matches = 0;\
126     SpecifierOpt *so;\
127     for (i = 0; i < o->nb_ ## name; i++) {\
128         char *spec = o->name[i].specifier;\
129         if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0) {\
130             outvar = o->name[i].u.type;\
131             so = &o->name[i];\
132             matches++;\
133         } else if (ret < 0)\
134             exit_program(1);\
135     }\
136     if (matches > 1)\
137        WARN_MULTIPLE_OPT_USAGE(name, type, so, st);\
138 }
139 
140 #define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)\
141 {\
142     int i;\
143     for (i = 0; i < o->nb_ ## name; i++) {\
144         char *spec = o->name[i].specifier;\
145         if (!strcmp(spec, mediatype))\
146             outvar = o->name[i].u.type;\
147     }\
148 }
149 
150 HWDevice *filter_hw_device;
151 
152 char *vstats_filename;
153 char *sdp_filename;
154 
155 float audio_drift_threshold = 0.1;
156 float dts_delta_threshold   = 10;
157 float dts_error_threshold   = 3600*30;
158 
159 int audio_volume      = 256;
160 int audio_sync_method = 0;
161 enum VideoSyncMethod video_sync_method = VSYNC_AUTO;
162 float frame_drop_threshold = 0;
163 int do_benchmark      = 0;
164 int do_benchmark_all  = 0;
165 int do_hex_dump       = 0;
166 int do_pkt_dump       = 0;
167 int copy_ts           = 0;
168 int start_at_zero     = 0;
169 int copy_tb           = -1;
170 int debug_ts          = 0;
171 int exit_on_error     = 0;
172 int abort_on_flags    = 0;
173 int print_stats       = -1;
174 int qp_hist           = 0;
175 int stdin_interaction = 1;
176 float max_error_rate  = 2.0/3;
177 char *filter_nbthreads;
178 int filter_complex_nbthreads = 0;
179 int vstats_version = 2;
180 int auto_conversion_filters = 1;
181 int64_t stats_period = 500000;
182 
183 
184 static int file_overwrite     = 0;
185 static int no_file_overwrite  = 0;
186 static int do_psnr            = 0;
187 static int input_stream_potentially_available = 0;
188 static int ignore_unknown_streams = 0;
189 static int copy_unknown_streams = 0;
190 static int recast_media = 0;
191 static int find_stream_info = 1;
192 
uninit_options(OptionsContext * o)193 static void uninit_options(OptionsContext *o)
194 {
195     const OptionDef *po = options;
196     int i;
197 
198     /* all OPT_SPEC and OPT_STRING can be freed in generic way */
199     while (po->name) {
200         void *dst = (uint8_t*)o + po->u.off;
201 
202         if (po->flags & OPT_SPEC) {
203             SpecifierOpt **so = dst;
204             int i, *count = (int*)(so + 1);
205             for (i = 0; i < *count; i++) {
206                 av_freep(&(*so)[i].specifier);
207                 if (po->flags & OPT_STRING)
208                     av_freep(&(*so)[i].u.str);
209             }
210             av_freep(so);
211             *count = 0;
212         } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
213             av_freep(dst);
214         po++;
215     }
216 
217     for (i = 0; i < o->nb_stream_maps; i++)
218         av_freep(&o->stream_maps[i].linklabel);
219     av_freep(&o->stream_maps);
220     av_freep(&o->audio_channel_maps);
221     av_freep(&o->streamid_map);
222     av_freep(&o->attachments);
223 }
224 
init_options(OptionsContext * o)225 static void init_options(OptionsContext *o)
226 {
227     memset(o, 0, sizeof(*o));
228 
229     o->stop_time = INT64_MAX;
230     o->mux_max_delay  = 0.7;
231     o->start_time     = AV_NOPTS_VALUE;
232     o->start_time_eof = AV_NOPTS_VALUE;
233     o->recording_time = INT64_MAX;
234     o->limit_filesize = UINT64_MAX;
235     o->chapters_input_file = INT_MAX;
236     o->accurate_seek  = 1;
237     o->thread_queue_size = -1;
238     o->input_sync_ref = -1;
239 }
240 
show_hwaccels(void * optctx,const char * opt,const char * arg)241 static int show_hwaccels(void *optctx, const char *opt, const char *arg)
242 {
243     enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE;
244 
245     printf("Hardware acceleration methods:\n");
246     while ((type = av_hwdevice_iterate_types(type)) !=
247            AV_HWDEVICE_TYPE_NONE)
248         printf("%s\n", av_hwdevice_get_type_name(type));
249     printf("\n");
250     return 0;
251 }
252 
253 /* return a copy of the input with the stream specifiers removed from the keys */
strip_specifiers(AVDictionary * dict)254 static AVDictionary *strip_specifiers(AVDictionary *dict)
255 {
256     const AVDictionaryEntry *e = NULL;
257     AVDictionary    *ret = NULL;
258 
259     while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
260         char *p = strchr(e->key, ':');
261 
262         if (p)
263             *p = 0;
264         av_dict_set(&ret, e->key, e->value, 0);
265         if (p)
266             *p = ':';
267     }
268     return ret;
269 }
270 
parse_and_set_vsync(const char * arg,int * vsync_var,int file_idx,int st_idx,int is_global)271 static int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global)
272 {
273     if      (!av_strcasecmp(arg, "cfr"))         *vsync_var = VSYNC_CFR;
274     else if (!av_strcasecmp(arg, "vfr"))         *vsync_var = VSYNC_VFR;
275     else if (!av_strcasecmp(arg, "passthrough")) *vsync_var = VSYNC_PASSTHROUGH;
276     else if (!av_strcasecmp(arg, "drop"))        *vsync_var = VSYNC_DROP;
277     else if (!is_global && !av_strcasecmp(arg, "auto"))  *vsync_var = VSYNC_AUTO;
278     else if (!is_global) {
279         av_log(NULL, AV_LOG_FATAL, "Invalid value %s specified for fps_mode of #%d:%d.\n", arg, file_idx, st_idx);
280         exit_program(1);
281     }
282 
283     if (is_global && *vsync_var == VSYNC_AUTO) {
284         video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
285         av_log(NULL, AV_LOG_WARNING, "Passing a number to -vsync is deprecated,"
286                " use a string argument as described in the manual.\n");
287     }
288     return 0;
289 }
290 
apply_sync_offsets(void)291 static int apply_sync_offsets(void)
292 {
293     for (int i = 0; i < nb_input_files; i++) {
294         InputFile *ref, *self = input_files[i];
295         int64_t adjustment;
296         int64_t self_start_time, ref_start_time, self_seek_start, ref_seek_start;
297         int start_times_set = 1;
298 
299         if (self->input_sync_ref == -1 || self->input_sync_ref == i) continue;
300         if (self->input_sync_ref >= nb_input_files || self->input_sync_ref < -1) {
301             av_log(NULL, AV_LOG_FATAL, "-isync for input %d references non-existent input %d.\n", i, self->input_sync_ref);
302             exit_program(1);
303         }
304 
305         if (copy_ts && !start_at_zero) {
306             av_log(NULL, AV_LOG_FATAL, "Use of -isync requires that start_at_zero be set if copyts is set.\n");
307             exit_program(1);
308         }
309 
310         ref = input_files[self->input_sync_ref];
311         if (ref->input_sync_ref != -1 && ref->input_sync_ref != self->input_sync_ref) {
312             av_log(NULL, AV_LOG_ERROR, "-isync for input %d references a resynced input %d. Sync not set.\n", i, self->input_sync_ref);
313             continue;
314         }
315 
316         if (self->ctx->start_time_realtime != AV_NOPTS_VALUE && ref->ctx->start_time_realtime != AV_NOPTS_VALUE) {
317             self_start_time = self->ctx->start_time_realtime;
318             ref_start_time  =  ref->ctx->start_time_realtime;
319         } else if (self->ctx->start_time != AV_NOPTS_VALUE && ref->ctx->start_time != AV_NOPTS_VALUE) {
320             self_start_time = self->ctx->start_time;
321             ref_start_time  =  ref->ctx->start_time;
322         } else {
323             start_times_set = 0;
324         }
325 
326         if (start_times_set) {
327             self_seek_start = self->start_time == AV_NOPTS_VALUE ? 0 : self->start_time;
328             ref_seek_start  =  ref->start_time == AV_NOPTS_VALUE ? 0 :  ref->start_time;
329 
330             adjustment = (self_start_time - ref_start_time) + !copy_ts*(self_seek_start - ref_seek_start) + ref->input_ts_offset;
331 
332             self->ts_offset += adjustment;
333 
334             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);
335         } else {
336             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);
337         }
338     }
339 
340     return 0;
341 }
342 
opt_filter_threads(void * optctx,const char * opt,const char * arg)343 static int opt_filter_threads(void *optctx, const char *opt, const char *arg)
344 {
345     av_free(filter_nbthreads);
346     filter_nbthreads = av_strdup(arg);
347     return 0;
348 }
349 
opt_abort_on(void * optctx,const char * opt,const char * arg)350 static int opt_abort_on(void *optctx, const char *opt, const char *arg)
351 {
352     static const AVOption opts[] = {
353         { "abort_on"           , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX,           .unit = "flags" },
354         { "empty_output"       , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT        }, .unit = "flags" },
355         { "empty_output_stream", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM }, .unit = "flags" },
356         { NULL },
357     };
358     static const AVClass class = {
359         .class_name = "",
360         .item_name  = av_default_item_name,
361         .option     = opts,
362         .version    = LIBAVUTIL_VERSION_INT,
363     };
364     const AVClass *pclass = &class;
365 
366     return av_opt_eval_flags(&pclass, &opts[0], arg, &abort_on_flags);
367 }
368 
opt_stats_period(void * optctx,const char * opt,const char * arg)369 static int opt_stats_period(void *optctx, const char *opt, const char *arg)
370 {
371     int64_t user_stats_period = parse_time_or_die(opt, arg, 1);
372 
373     if (user_stats_period <= 0) {
374         av_log(NULL, AV_LOG_ERROR, "stats_period %s must be positive.\n", arg);
375         return AVERROR(EINVAL);
376     }
377 
378     stats_period = user_stats_period;
379     av_log(NULL, AV_LOG_INFO, "ffmpeg stats and -progress period set to %s.\n", arg);
380 
381     return 0;
382 }
383 
opt_audio_codec(void * optctx,const char * opt,const char * arg)384 static int opt_audio_codec(void *optctx, const char *opt, const char *arg)
385 {
386     OptionsContext *o = optctx;
387     return parse_option(o, "codec:a", arg, options);
388 }
389 
opt_video_codec(void * optctx,const char * opt,const char * arg)390 static int opt_video_codec(void *optctx, const char *opt, const char *arg)
391 {
392     OptionsContext *o = optctx;
393     return parse_option(o, "codec:v", arg, options);
394 }
395 
opt_subtitle_codec(void * optctx,const char * opt,const char * arg)396 static int opt_subtitle_codec(void *optctx, const char *opt, const char *arg)
397 {
398     OptionsContext *o = optctx;
399     return parse_option(o, "codec:s", arg, options);
400 }
401 
opt_data_codec(void * optctx,const char * opt,const char * arg)402 static int opt_data_codec(void *optctx, const char *opt, const char *arg)
403 {
404     OptionsContext *o = optctx;
405     return parse_option(o, "codec:d", arg, options);
406 }
407 
opt_map(void * optctx,const char * opt,const char * arg)408 static int opt_map(void *optctx, const char *opt, const char *arg)
409 {
410     OptionsContext *o = optctx;
411     StreamMap *m = NULL;
412     int i, negative = 0, file_idx, disabled = 0;
413     int sync_file_idx = -1, sync_stream_idx = 0;
414     char *p, *sync;
415     char *map;
416     char *allow_unused;
417 
418     if (*arg == '-') {
419         negative = 1;
420         arg++;
421     }
422     map = av_strdup(arg);
423     if (!map)
424         return AVERROR(ENOMEM);
425 
426     /* parse sync stream first, just pick first matching stream */
427     if (sync = strchr(map, ',')) {
428         *sync = 0;
429         sync_file_idx = strtol(sync + 1, &sync, 0);
430         if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
431             av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
432             exit_program(1);
433         }
434         if (*sync)
435             sync++;
436         for (i = 0; i < input_files[sync_file_idx]->nb_streams; i++)
437             if (check_stream_specifier(input_files[sync_file_idx]->ctx,
438                                        input_files[sync_file_idx]->ctx->streams[i], sync) == 1) {
439                 sync_stream_idx = i;
440                 break;
441             }
442         if (i == input_files[sync_file_idx]->nb_streams) {
443             av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
444                                        "match any streams.\n", arg);
445             exit_program(1);
446         }
447         if (input_streams[input_files[sync_file_idx]->ist_index + sync_stream_idx]->user_set_discard == AVDISCARD_ALL) {
448             av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s matches a disabled input "
449                                        "stream.\n", arg);
450             exit_program(1);
451         }
452     }
453 
454 
455     if (map[0] == '[') {
456         /* this mapping refers to lavfi output */
457         const char *c = map + 1;
458         GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
459         m = &o->stream_maps[o->nb_stream_maps - 1];
460         m->linklabel = av_get_token(&c, "]");
461         if (!m->linklabel) {
462             av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
463             exit_program(1);
464         }
465     } else {
466         if (allow_unused = strchr(map, '?'))
467             *allow_unused = 0;
468         file_idx = strtol(map, &p, 0);
469         if (file_idx >= nb_input_files || file_idx < 0) {
470             av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
471             exit_program(1);
472         }
473         if (negative)
474             /* disable some already defined maps */
475             for (i = 0; i < o->nb_stream_maps; i++) {
476                 m = &o->stream_maps[i];
477                 if (file_idx == m->file_index &&
478                     check_stream_specifier(input_files[m->file_index]->ctx,
479                                            input_files[m->file_index]->ctx->streams[m->stream_index],
480                                            *p == ':' ? p + 1 : p) > 0)
481                     m->disabled = 1;
482             }
483         else
484             for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
485                 if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
486                             *p == ':' ? p + 1 : p) <= 0)
487                     continue;
488                 if (input_streams[input_files[file_idx]->ist_index + i]->user_set_discard == AVDISCARD_ALL) {
489                     disabled = 1;
490                     continue;
491                 }
492                 GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
493                 m = &o->stream_maps[o->nb_stream_maps - 1];
494 
495                 m->file_index   = file_idx;
496                 m->stream_index = i;
497 
498                 if (sync_file_idx >= 0) {
499                     m->sync_file_index   = sync_file_idx;
500                     m->sync_stream_index = sync_stream_idx;
501                 } else {
502                     m->sync_file_index   = file_idx;
503                     m->sync_stream_index = i;
504                 }
505             }
506     }
507 
508     if (!m) {
509         if (allow_unused) {
510             av_log(NULL, AV_LOG_VERBOSE, "Stream map '%s' matches no streams; ignoring.\n", arg);
511         } else if (disabled) {
512             av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches disabled streams.\n"
513                                        "To ignore this, add a trailing '?' to the map.\n", arg);
514             exit_program(1);
515         } else {
516             av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n"
517                                        "To ignore this, add a trailing '?' to the map.\n", arg);
518             exit_program(1);
519         }
520     }
521 
522     av_freep(&map);
523     return 0;
524 }
525 
opt_attach(void * optctx,const char * opt,const char * arg)526 static int opt_attach(void *optctx, const char *opt, const char *arg)
527 {
528     OptionsContext *o = optctx;
529     GROW_ARRAY(o->attachments, o->nb_attachments);
530     o->attachments[o->nb_attachments - 1] = arg;
531     return 0;
532 }
533 
opt_map_channel(void * optctx,const char * opt,const char * arg)534 static int opt_map_channel(void *optctx, const char *opt, const char *arg)
535 {
536     OptionsContext *o = optctx;
537     int n;
538     AVStream *st;
539     AudioChannelMap *m;
540     char *allow_unused;
541     char *mapchan;
542     mapchan = av_strdup(arg);
543     if (!mapchan)
544         return AVERROR(ENOMEM);
545 
546     GROW_ARRAY(o->audio_channel_maps, o->nb_audio_channel_maps);
547     m = &o->audio_channel_maps[o->nb_audio_channel_maps - 1];
548 
549     /* muted channel syntax */
550     n = sscanf(arg, "%d:%d.%d", &m->channel_idx, &m->ofile_idx, &m->ostream_idx);
551     if ((n == 1 || n == 3) && m->channel_idx == -1) {
552         m->file_idx = m->stream_idx = -1;
553         if (n == 1)
554             m->ofile_idx = m->ostream_idx = -1;
555         av_free(mapchan);
556         return 0;
557     }
558 
559     /* normal syntax */
560     n = sscanf(arg, "%d.%d.%d:%d.%d",
561                &m->file_idx,  &m->stream_idx, &m->channel_idx,
562                &m->ofile_idx, &m->ostream_idx);
563 
564     if (n != 3 && n != 5) {
565         av_log(NULL, AV_LOG_FATAL, "Syntax error, mapchan usage: "
566                "[file.stream.channel|-1][:syncfile:syncstream]\n");
567         exit_program(1);
568     }
569 
570     if (n != 5) // only file.stream.channel specified
571         m->ofile_idx = m->ostream_idx = -1;
572 
573     /* check input */
574     if (m->file_idx < 0 || m->file_idx >= nb_input_files) {
575         av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file index: %d\n",
576                m->file_idx);
577         exit_program(1);
578     }
579     if (m->stream_idx < 0 ||
580         m->stream_idx >= input_files[m->file_idx]->nb_streams) {
581         av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file stream index #%d.%d\n",
582                m->file_idx, m->stream_idx);
583         exit_program(1);
584     }
585     st = input_files[m->file_idx]->ctx->streams[m->stream_idx];
586     if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
587         av_log(NULL, AV_LOG_FATAL, "mapchan: stream #%d.%d is not an audio stream.\n",
588                m->file_idx, m->stream_idx);
589         exit_program(1);
590     }
591     /* allow trailing ? to map_channel */
592     if (allow_unused = strchr(mapchan, '?'))
593         *allow_unused = 0;
594     if (m->channel_idx < 0 || m->channel_idx >= st->codecpar->ch_layout.nb_channels ||
595         input_streams[input_files[m->file_idx]->ist_index + m->stream_idx]->user_set_discard == AVDISCARD_ALL) {
596         if (allow_unused) {
597             av_log(NULL, AV_LOG_VERBOSE, "mapchan: invalid audio channel #%d.%d.%d\n",
598                     m->file_idx, m->stream_idx, m->channel_idx);
599         } else {
600             av_log(NULL, AV_LOG_FATAL,  "mapchan: invalid audio channel #%d.%d.%d\n"
601                     "To ignore this, add a trailing '?' to the map_channel.\n",
602                     m->file_idx, m->stream_idx, m->channel_idx);
603             exit_program(1);
604         }
605 
606     }
607     av_free(mapchan);
608     return 0;
609 }
610 
opt_sdp_file(void * optctx,const char * opt,const char * arg)611 static int opt_sdp_file(void *optctx, const char *opt, const char *arg)
612 {
613     av_free(sdp_filename);
614     sdp_filename = av_strdup(arg);
615     return 0;
616 }
617 
618 #if CONFIG_VAAPI
opt_vaapi_device(void * optctx,const char * opt,const char * arg)619 static int opt_vaapi_device(void *optctx, const char *opt, const char *arg)
620 {
621     const char *prefix = "vaapi:";
622     char *tmp;
623     int err;
624     tmp = av_asprintf("%s%s", prefix, arg);
625     if (!tmp)
626         return AVERROR(ENOMEM);
627     err = hw_device_init_from_string(tmp, NULL);
628     av_free(tmp);
629     return err;
630 }
631 #endif
632 
633 #if CONFIG_QSV
opt_qsv_device(void * optctx,const char * opt,const char * arg)634 static int opt_qsv_device(void *optctx, const char *opt, const char *arg)
635 {
636     const char *prefix = "qsv=__qsv_device:hw_any,child_device=";
637     int err;
638     char *tmp = av_asprintf("%s%s", prefix, arg);
639 
640     if (!tmp)
641         return AVERROR(ENOMEM);
642 
643     err = hw_device_init_from_string(tmp, NULL);
644     av_free(tmp);
645 
646     return err;
647 }
648 #endif
649 
opt_init_hw_device(void * optctx,const char * opt,const char * arg)650 static int opt_init_hw_device(void *optctx, const char *opt, const char *arg)
651 {
652     if (!strcmp(arg, "list")) {
653         enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE;
654         printf("Supported hardware device types:\n");
655         while ((type = av_hwdevice_iterate_types(type)) !=
656                AV_HWDEVICE_TYPE_NONE)
657             printf("%s\n", av_hwdevice_get_type_name(type));
658         printf("\n");
659         exit_program(0);
660     } else {
661         return hw_device_init_from_string(arg, NULL);
662     }
663 }
664 
opt_filter_hw_device(void * optctx,const char * opt,const char * arg)665 static int opt_filter_hw_device(void *optctx, const char *opt, const char *arg)
666 {
667     if (filter_hw_device) {
668         av_log(NULL, AV_LOG_ERROR, "Only one filter device can be used.\n");
669         return AVERROR(EINVAL);
670     }
671     filter_hw_device = hw_device_get_by_name(arg);
672     if (!filter_hw_device) {
673         av_log(NULL, AV_LOG_ERROR, "Invalid filter device %s.\n", arg);
674         return AVERROR(EINVAL);
675     }
676     return 0;
677 }
678 
679 /**
680  * Parse a metadata specifier passed as 'arg' parameter.
681  * @param arg  metadata string to parse
682  * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
683  * @param index for type c/p, chapter/program index is written here
684  * @param stream_spec for type s, the stream specifier is written here
685  */
parse_meta_type(char * arg,char * type,int * index,const char ** stream_spec)686 static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec)
687 {
688     if (*arg) {
689         *type = *arg;
690         switch (*arg) {
691         case 'g':
692             break;
693         case 's':
694             if (*(++arg) && *arg != ':') {
695                 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
696                 exit_program(1);
697             }
698             *stream_spec = *arg == ':' ? arg + 1 : "";
699             break;
700         case 'c':
701         case 'p':
702             if (*(++arg) == ':')
703                 *index = strtol(++arg, NULL, 0);
704             break;
705         default:
706             av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
707             exit_program(1);
708         }
709     } else
710         *type = 'g';
711 }
712 
copy_metadata(char * outspec,char * inspec,AVFormatContext * oc,AVFormatContext * ic,OptionsContext * o)713 static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o)
714 {
715     AVDictionary **meta_in = NULL;
716     AVDictionary **meta_out = NULL;
717     int i, ret = 0;
718     char type_in, type_out;
719     const char *istream_spec = NULL, *ostream_spec = NULL;
720     int idx_in = 0, idx_out = 0;
721 
722     parse_meta_type(inspec,  &type_in,  &idx_in,  &istream_spec);
723     parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec);
724 
725     if (!ic) {
726         if (type_out == 'g' || !*outspec)
727             o->metadata_global_manual = 1;
728         if (type_out == 's' || !*outspec)
729             o->metadata_streams_manual = 1;
730         if (type_out == 'c' || !*outspec)
731             o->metadata_chapters_manual = 1;
732         return 0;
733     }
734 
735     if (type_in == 'g' || type_out == 'g')
736         o->metadata_global_manual = 1;
737     if (type_in == 's' || type_out == 's')
738         o->metadata_streams_manual = 1;
739     if (type_in == 'c' || type_out == 'c')
740         o->metadata_chapters_manual = 1;
741 
742     /* ic is NULL when just disabling automatic mappings */
743     if (!ic)
744         return 0;
745 
746 #define METADATA_CHECK_INDEX(index, nb_elems, desc)\
747     if ((index) < 0 || (index) >= (nb_elems)) {\
748         av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
749                 (desc), (index));\
750         exit_program(1);\
751     }
752 
753 #define SET_DICT(type, meta, context, index)\
754         switch (type) {\
755         case 'g':\
756             meta = &context->metadata;\
757             break;\
758         case 'c':\
759             METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
760             meta = &context->chapters[index]->metadata;\
761             break;\
762         case 'p':\
763             METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
764             meta = &context->programs[index]->metadata;\
765             break;\
766         case 's':\
767             break; /* handled separately below */ \
768         default: av_assert0(0);\
769         }\
770 
771     SET_DICT(type_in, meta_in, ic, idx_in);
772     SET_DICT(type_out, meta_out, oc, idx_out);
773 
774     /* for input streams choose first matching stream */
775     if (type_in == 's') {
776         for (i = 0; i < ic->nb_streams; i++) {
777             if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
778                 meta_in = &ic->streams[i]->metadata;
779                 break;
780             } else if (ret < 0)
781                 exit_program(1);
782         }
783         if (!meta_in) {
784             av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match  any streams.\n", istream_spec);
785             exit_program(1);
786         }
787     }
788 
789     if (type_out == 's') {
790         for (i = 0; i < oc->nb_streams; i++) {
791             if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
792                 meta_out = &oc->streams[i]->metadata;
793                 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
794             } else if (ret < 0)
795                 exit_program(1);
796         }
797     } else
798         av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
799 
800     return 0;
801 }
802 
opt_recording_timestamp(void * optctx,const char * opt,const char * arg)803 static int opt_recording_timestamp(void *optctx, const char *opt, const char *arg)
804 {
805     OptionsContext *o = optctx;
806     char buf[128];
807     int64_t recording_timestamp = parse_time_or_die(opt, arg, 0) / 1E6;
808     struct tm time = *gmtime((time_t*)&recording_timestamp);
809     if (!strftime(buf, sizeof(buf), "creation_time=%Y-%m-%dT%H:%M:%S%z", &time))
810         return -1;
811     parse_option(o, "metadata", buf, options);
812 
813     av_log(NULL, AV_LOG_WARNING, "%s is deprecated, set the 'creation_time' metadata "
814                                  "tag instead.\n", opt);
815     return 0;
816 }
817 
find_codec_or_die(const char * name,enum AVMediaType type,int encoder)818 static const AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
819 {
820     const AVCodecDescriptor *desc;
821     const char *codec_string = encoder ? "encoder" : "decoder";
822     const AVCodec *codec;
823 
824     codec = encoder ?
825         avcodec_find_encoder_by_name(name) :
826         avcodec_find_decoder_by_name(name);
827 
828     if (!codec && (desc = avcodec_descriptor_get_by_name(name))) {
829         codec = encoder ? avcodec_find_encoder(desc->id) :
830                           avcodec_find_decoder(desc->id);
831         if (codec)
832             av_log(NULL, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n",
833                    codec_string, codec->name, desc->name);
834     }
835 
836     if (!codec) {
837         av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
838         exit_program(1);
839     }
840     if (codec->type != type && !recast_media) {
841         av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
842         exit_program(1);
843     }
844     return codec;
845 }
846 
choose_decoder(OptionsContext * o,AVFormatContext * s,AVStream * st)847 static const AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
848 {
849     char *codec_name = NULL;
850 
851     MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
852     if (codec_name) {
853         const AVCodec *codec = find_codec_or_die(codec_name, st->codecpar->codec_type, 0);
854         st->codecpar->codec_id = codec->id;
855         if (recast_media && st->codecpar->codec_type != codec->type)
856             st->codecpar->codec_type = codec->type;
857         return codec;
858     } else
859         return avcodec_find_decoder(st->codecpar->codec_id);
860 }
861 
862 /* Add all the streams from the given input file to the global
863  * list of input streams. */
add_input_streams(OptionsContext * o,AVFormatContext * ic)864 static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
865 {
866     int i, ret;
867 
868     for (i = 0; i < ic->nb_streams; i++) {
869         AVStream *st = ic->streams[i];
870         AVCodecParameters *par = st->codecpar;
871         InputStream *ist;
872         char *framerate = NULL, *hwaccel_device = NULL;
873         const char *hwaccel = NULL;
874         char *hwaccel_output_format = NULL;
875         char *codec_tag = NULL;
876         char *next;
877         char *discard_str = NULL;
878         const AVClass *cc = avcodec_get_class();
879         const AVOption *discard_opt = av_opt_find(&cc, "skip_frame", NULL,
880                                                   0, AV_OPT_SEARCH_FAKE_OBJ);
881 
882         ist = ALLOC_ARRAY_ELEM(input_streams, nb_input_streams);
883         ist->st = st;
884         ist->file_index = nb_input_files;
885         ist->discard = 1;
886         st->discard  = AVDISCARD_ALL;
887         ist->nb_samples = 0;
888         ist->first_dts = AV_NOPTS_VALUE;
889         ist->min_pts = INT64_MAX;
890         ist->max_pts = INT64_MIN;
891 
892         ist->ts_scale = 1.0;
893         MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
894 
895         ist->autorotate = 1;
896         MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
897 
898         MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
899         if (codec_tag) {
900             uint32_t tag = strtol(codec_tag, &next, 0);
901             if (*next) {
902                 uint8_t buf[4] = { 0 };
903                 memcpy(buf, codec_tag, FFMIN(sizeof(buf), strlen(codec_tag)));
904                 tag = AV_RL32(buf);
905             }
906             st->codecpar->codec_tag = tag;
907         }
908 
909         ist->dec = choose_decoder(o, ic, st);
910         ist->decoder_opts = filter_codec_opts(o->g->codec_opts, ist->st->codecpar->codec_id, ic, st, ist->dec);
911 
912         ist->reinit_filters = -1;
913         MATCH_PER_STREAM_OPT(reinit_filters, i, ist->reinit_filters, ic, st);
914 
915         MATCH_PER_STREAM_OPT(discard, str, discard_str, ic, st);
916         ist->user_set_discard = AVDISCARD_NONE;
917 
918         if ((o->video_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) ||
919             (o->audio_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) ||
920             (o->subtitle_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) ||
921             (o->data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA))
922                 ist->user_set_discard = AVDISCARD_ALL;
923 
924         if (discard_str && av_opt_eval_int(&cc, discard_opt, discard_str, &ist->user_set_discard) < 0) {
925             av_log(NULL, AV_LOG_ERROR, "Error parsing discard %s.\n",
926                     discard_str);
927             exit_program(1);
928         }
929 
930         ist->filter_in_rescale_delta_last = AV_NOPTS_VALUE;
931         ist->prev_pkt_pts = AV_NOPTS_VALUE;
932 
933         ist->dec_ctx = avcodec_alloc_context3(ist->dec);
934         if (!ist->dec_ctx) {
935             av_log(NULL, AV_LOG_ERROR, "Error allocating the decoder context.\n");
936             exit_program(1);
937         }
938 
939         ret = avcodec_parameters_to_context(ist->dec_ctx, par);
940         if (ret < 0) {
941             av_log(NULL, AV_LOG_ERROR, "Error initializing the decoder context.\n");
942             exit_program(1);
943         }
944 
945         ist->decoded_frame = av_frame_alloc();
946         if (!ist->decoded_frame)
947             exit_program(1);
948 
949         ist->pkt = av_packet_alloc();
950         if (!ist->pkt)
951             exit_program(1);
952 
953         if (o->bitexact)
954             ist->dec_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
955 
956         switch (par->codec_type) {
957         case AVMEDIA_TYPE_VIDEO:
958             if(!ist->dec)
959                 ist->dec = avcodec_find_decoder(par->codec_id);
960 
961             // avformat_find_stream_info() doesn't set this for us anymore.
962             ist->dec_ctx->framerate = st->avg_frame_rate;
963 
964             MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
965             if (framerate && av_parse_video_rate(&ist->framerate,
966                                                  framerate) < 0) {
967                 av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
968                        framerate);
969                 exit_program(1);
970             }
971 
972             ist->top_field_first = -1;
973             MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st);
974 
975             MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
976             MATCH_PER_STREAM_OPT(hwaccel_output_formats, str,
977                                  hwaccel_output_format, ic, st);
978 
979             if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "cuvid")) {
980                 av_log(NULL, AV_LOG_WARNING,
981                     "WARNING: defaulting hwaccel_output_format to cuda for compatibility "
982                     "with old commandlines. This behaviour is DEPRECATED and will be removed "
983                     "in the future. Please explicitly set \"-hwaccel_output_format cuda\".\n");
984                 ist->hwaccel_output_format = AV_PIX_FMT_CUDA;
985             } else if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "qsv")) {
986                 av_log(NULL, AV_LOG_WARNING,
987                     "WARNING: defaulting hwaccel_output_format to qsv for compatibility "
988                     "with old commandlines. This behaviour is DEPRECATED and will be removed "
989                     "in the future. Please explicitly set \"-hwaccel_output_format qsv\".\n");
990                 ist->hwaccel_output_format = AV_PIX_FMT_QSV;
991             } else if (hwaccel_output_format) {
992                 ist->hwaccel_output_format = av_get_pix_fmt(hwaccel_output_format);
993                 if (ist->hwaccel_output_format == AV_PIX_FMT_NONE) {
994                     av_log(NULL, AV_LOG_FATAL, "Unrecognised hwaccel output "
995                            "format: %s", hwaccel_output_format);
996                 }
997             } else {
998                 ist->hwaccel_output_format = AV_PIX_FMT_NONE;
999             }
1000 
1001             if (hwaccel) {
1002                 // The NVDEC hwaccels use a CUDA device, so remap the name here.
1003                 if (!strcmp(hwaccel, "nvdec") || !strcmp(hwaccel, "cuvid"))
1004                     hwaccel = "cuda";
1005 
1006                 if (!strcmp(hwaccel, "none"))
1007                     ist->hwaccel_id = HWACCEL_NONE;
1008                 else if (!strcmp(hwaccel, "auto"))
1009                     ist->hwaccel_id = HWACCEL_AUTO;
1010                 else {
1011                     enum AVHWDeviceType type = av_hwdevice_find_type_by_name(hwaccel);
1012                     if (type != AV_HWDEVICE_TYPE_NONE) {
1013                         ist->hwaccel_id = HWACCEL_GENERIC;
1014                         ist->hwaccel_device_type = type;
1015                     }
1016 
1017                     if (!ist->hwaccel_id) {
1018                         av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n",
1019                                hwaccel);
1020                         av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: ");
1021                         type = AV_HWDEVICE_TYPE_NONE;
1022                         while ((type = av_hwdevice_iterate_types(type)) !=
1023                                AV_HWDEVICE_TYPE_NONE)
1024                             av_log(NULL, AV_LOG_FATAL, "%s ",
1025                                    av_hwdevice_get_type_name(type));
1026                         av_log(NULL, AV_LOG_FATAL, "\n");
1027                         exit_program(1);
1028                     }
1029                 }
1030             }
1031 
1032             MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st);
1033             if (hwaccel_device) {
1034                 ist->hwaccel_device = av_strdup(hwaccel_device);
1035                 if (!ist->hwaccel_device)
1036                     exit_program(1);
1037             }
1038 
1039             ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
1040 
1041             break;
1042         case AVMEDIA_TYPE_AUDIO:
1043             ist->guess_layout_max = INT_MAX;
1044             MATCH_PER_STREAM_OPT(guess_layout_max, i, ist->guess_layout_max, ic, st);
1045             guess_input_channel_layout(ist);
1046             break;
1047         case AVMEDIA_TYPE_DATA:
1048         case AVMEDIA_TYPE_SUBTITLE: {
1049             char *canvas_size = NULL;
1050             if(!ist->dec)
1051                 ist->dec = avcodec_find_decoder(par->codec_id);
1052             MATCH_PER_STREAM_OPT(fix_sub_duration, i, ist->fix_sub_duration, ic, st);
1053             MATCH_PER_STREAM_OPT(canvas_sizes, str, canvas_size, ic, st);
1054             if (canvas_size &&
1055                 av_parse_video_size(&ist->dec_ctx->width, &ist->dec_ctx->height, canvas_size) < 0) {
1056                 av_log(NULL, AV_LOG_FATAL, "Invalid canvas size: %s.\n", canvas_size);
1057                 exit_program(1);
1058             }
1059             break;
1060         }
1061         case AVMEDIA_TYPE_ATTACHMENT:
1062         case AVMEDIA_TYPE_UNKNOWN:
1063             break;
1064         default:
1065             abort();
1066         }
1067 
1068         ret = avcodec_parameters_from_context(par, ist->dec_ctx);
1069         if (ret < 0) {
1070             av_log(NULL, AV_LOG_ERROR, "Error initializing the decoder context.\n");
1071             exit_program(1);
1072         }
1073     }
1074 }
1075 
assert_file_overwrite(const char * filename)1076 static void assert_file_overwrite(const char *filename)
1077 {
1078     const char *proto_name = avio_find_protocol_name(filename);
1079 
1080     if (file_overwrite && no_file_overwrite) {
1081         fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n");
1082         exit_program(1);
1083     }
1084 
1085     if (!file_overwrite) {
1086         if (proto_name && !strcmp(proto_name, "file") && avio_check(filename, 0) == 0) {
1087             if (stdin_interaction && !no_file_overwrite) {
1088                 fprintf(stderr,"File '%s' already exists. Overwrite? [y/N] ", filename);
1089                 fflush(stderr);
1090                 term_exit();
1091                 signal(SIGINT, SIG_DFL);
1092                 if (!read_yesno()) {
1093                     av_log(NULL, AV_LOG_FATAL, "Not overwriting - exiting\n");
1094                     exit_program(1);
1095                 }
1096                 term_init();
1097             }
1098             else {
1099                 av_log(NULL, AV_LOG_FATAL, "File '%s' already exists. Exiting.\n", filename);
1100                 exit_program(1);
1101             }
1102         }
1103     }
1104 
1105     if (proto_name && !strcmp(proto_name, "file")) {
1106         for (int i = 0; i < nb_input_files; i++) {
1107              InputFile *file = input_files[i];
1108              if (file->ctx->iformat->flags & AVFMT_NOFILE)
1109                  continue;
1110              if (!strcmp(filename, file->ctx->url)) {
1111                  av_log(NULL, AV_LOG_FATAL, "Output %s same as Input #%d - exiting\n", filename, i);
1112                  av_log(NULL, AV_LOG_WARNING, "FFmpeg cannot edit existing files in-place.\n");
1113                  exit_program(1);
1114              }
1115         }
1116     }
1117 }
1118 
dump_attachment(AVStream * st,const char * filename)1119 static void dump_attachment(AVStream *st, const char *filename)
1120 {
1121     int ret;
1122     AVIOContext *out = NULL;
1123     const AVDictionaryEntry *e;
1124 
1125     if (!st->codecpar->extradata_size) {
1126         av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
1127                nb_input_files - 1, st->index);
1128         return;
1129     }
1130     if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
1131         filename = e->value;
1132     if (!*filename) {
1133         av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
1134                "in stream #%d:%d.\n", nb_input_files - 1, st->index);
1135         exit_program(1);
1136     }
1137 
1138     assert_file_overwrite(filename);
1139 
1140     if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
1141         av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
1142                filename);
1143         exit_program(1);
1144     }
1145 
1146     avio_write(out, st->codecpar->extradata, st->codecpar->extradata_size);
1147     avio_flush(out);
1148     avio_close(out);
1149 }
1150 
open_input_file(OptionsContext * o,const char * filename)1151 static int open_input_file(OptionsContext *o, const char *filename)
1152 {
1153     InputFile *f;
1154     AVFormatContext *ic;
1155     const AVInputFormat *file_iformat = NULL;
1156     int err, i, ret;
1157     int64_t timestamp;
1158     AVDictionary *unused_opts = NULL;
1159     const AVDictionaryEntry *e = NULL;
1160     char *   video_codec_name = NULL;
1161     char *   audio_codec_name = NULL;
1162     char *subtitle_codec_name = NULL;
1163     char *    data_codec_name = NULL;
1164     int scan_all_pmts_set = 0;
1165 
1166     if (o->stop_time != INT64_MAX && o->recording_time != INT64_MAX) {
1167         o->stop_time = INT64_MAX;
1168         av_log(NULL, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
1169     }
1170 
1171     if (o->stop_time != INT64_MAX && o->recording_time == INT64_MAX) {
1172         int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time;
1173         if (o->stop_time <= start_time) {
1174             av_log(NULL, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n");
1175             exit_program(1);
1176         } else {
1177             o->recording_time = o->stop_time - start_time;
1178         }
1179     }
1180 
1181     if (o->format) {
1182         if (!(file_iformat = av_find_input_format(o->format))) {
1183             av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
1184             exit_program(1);
1185         }
1186     }
1187 
1188     if (!strcmp(filename, "-"))
1189         filename = "pipe:";
1190 
1191     stdin_interaction &= strncmp(filename, "pipe:", 5) &&
1192                          strcmp(filename, "/dev/stdin");
1193 
1194     /* get default parameters from command line */
1195     ic = avformat_alloc_context();
1196     if (!ic) {
1197         print_error(filename, AVERROR(ENOMEM));
1198         exit_program(1);
1199     }
1200     if (o->nb_audio_sample_rate) {
1201         av_dict_set_int(&o->g->format_opts, "sample_rate", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i, 0);
1202     }
1203     if (o->nb_audio_channels) {
1204         const AVClass *priv_class;
1205         if (file_iformat && (priv_class = file_iformat->priv_class) &&
1206             av_opt_find(&priv_class, "ch_layout", NULL, 0,
1207                         AV_OPT_SEARCH_FAKE_OBJ)) {
1208             char buf[32];
1209             snprintf(buf, sizeof(buf), "%dC", o->audio_channels[o->nb_audio_channels - 1].u.i);
1210             av_dict_set(&o->g->format_opts, "ch_layout", buf, 0);
1211         }
1212     }
1213     if (o->nb_audio_ch_layouts) {
1214         const AVClass *priv_class;
1215         if (file_iformat && (priv_class = file_iformat->priv_class) &&
1216             av_opt_find(&priv_class, "ch_layout", NULL, 0,
1217                         AV_OPT_SEARCH_FAKE_OBJ)) {
1218             av_dict_set(&o->g->format_opts, "ch_layout", o->audio_ch_layouts[o->nb_audio_ch_layouts - 1].u.str, 0);
1219         }
1220     }
1221     if (o->nb_frame_rates) {
1222         const AVClass *priv_class;
1223         /* set the format-level framerate option;
1224          * this is important for video grabbers, e.g. x11 */
1225         if (file_iformat && (priv_class = file_iformat->priv_class) &&
1226             av_opt_find(&priv_class, "framerate", NULL, 0,
1227                         AV_OPT_SEARCH_FAKE_OBJ)) {
1228             av_dict_set(&o->g->format_opts, "framerate",
1229                         o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
1230         }
1231     }
1232     if (o->nb_frame_sizes) {
1233         av_dict_set(&o->g->format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
1234     }
1235     if (o->nb_frame_pix_fmts)
1236         av_dict_set(&o->g->format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
1237 
1238     MATCH_PER_TYPE_OPT(codec_names, str,    video_codec_name, ic, "v");
1239     MATCH_PER_TYPE_OPT(codec_names, str,    audio_codec_name, ic, "a");
1240     MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, ic, "s");
1241     MATCH_PER_TYPE_OPT(codec_names, str,     data_codec_name, ic, "d");
1242 
1243     if (video_codec_name)
1244         ic->video_codec    = find_codec_or_die(video_codec_name   , AVMEDIA_TYPE_VIDEO   , 0);
1245     if (audio_codec_name)
1246         ic->audio_codec    = find_codec_or_die(audio_codec_name   , AVMEDIA_TYPE_AUDIO   , 0);
1247     if (subtitle_codec_name)
1248         ic->subtitle_codec = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0);
1249     if (data_codec_name)
1250         ic->data_codec     = find_codec_or_die(data_codec_name    , AVMEDIA_TYPE_DATA    , 0);
1251 
1252     ic->video_codec_id     = video_codec_name    ? ic->video_codec->id    : AV_CODEC_ID_NONE;
1253     ic->audio_codec_id     = audio_codec_name    ? ic->audio_codec->id    : AV_CODEC_ID_NONE;
1254     ic->subtitle_codec_id  = subtitle_codec_name ? ic->subtitle_codec->id : AV_CODEC_ID_NONE;
1255     ic->data_codec_id      = data_codec_name     ? ic->data_codec->id     : AV_CODEC_ID_NONE;
1256 
1257     ic->flags |= AVFMT_FLAG_NONBLOCK;
1258     if (o->bitexact)
1259         ic->flags |= AVFMT_FLAG_BITEXACT;
1260     ic->interrupt_callback = int_cb;
1261 
1262     if (!av_dict_get(o->g->format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
1263         av_dict_set(&o->g->format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
1264         scan_all_pmts_set = 1;
1265     }
1266     /* open the input file with generic avformat function */
1267     err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
1268     if (err < 0) {
1269         print_error(filename, err);
1270         if (err == AVERROR_PROTOCOL_NOT_FOUND)
1271             av_log(NULL, AV_LOG_ERROR, "Did you mean file:%s?\n", filename);
1272         exit_program(1);
1273     }
1274     if (scan_all_pmts_set)
1275         av_dict_set(&o->g->format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
1276     remove_avoptions(&o->g->format_opts, o->g->codec_opts);
1277     assert_avoptions(o->g->format_opts);
1278 
1279     /* apply forced codec ids */
1280     for (i = 0; i < ic->nb_streams; i++)
1281         choose_decoder(o, ic, ic->streams[i]);
1282 
1283     if (find_stream_info) {
1284         AVDictionary **opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
1285         int orig_nb_streams = ic->nb_streams;
1286 
1287         /* If not enough info to get the stream parameters, we decode the
1288            first frames to get it. (used in mpeg case for example) */
1289         ret = avformat_find_stream_info(ic, opts);
1290 
1291         for (i = 0; i < orig_nb_streams; i++)
1292             av_dict_free(&opts[i]);
1293         av_freep(&opts);
1294 
1295         if (ret < 0) {
1296             av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
1297             if (ic->nb_streams == 0) {
1298                 avformat_close_input(&ic);
1299                 exit_program(1);
1300             }
1301         }
1302     }
1303 
1304     if (o->start_time != AV_NOPTS_VALUE && o->start_time_eof != AV_NOPTS_VALUE) {
1305         av_log(NULL, AV_LOG_WARNING, "Cannot use -ss and -sseof both, using -ss for %s\n", filename);
1306         o->start_time_eof = AV_NOPTS_VALUE;
1307     }
1308 
1309     if (o->start_time_eof != AV_NOPTS_VALUE) {
1310         if (o->start_time_eof >= 0) {
1311             av_log(NULL, AV_LOG_ERROR, "-sseof value must be negative; aborting\n");
1312             exit_program(1);
1313         }
1314         if (ic->duration > 0) {
1315             o->start_time = o->start_time_eof + ic->duration;
1316             if (o->start_time < 0) {
1317                 av_log(NULL, AV_LOG_WARNING, "-sseof value seeks to before start of file %s; ignored\n", filename);
1318                 o->start_time = AV_NOPTS_VALUE;
1319             }
1320         } else
1321             av_log(NULL, AV_LOG_WARNING, "Cannot use -sseof, duration of %s not known\n", filename);
1322     }
1323     timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
1324     /* add the stream start time */
1325     if (!o->seek_timestamp && ic->start_time != AV_NOPTS_VALUE)
1326         timestamp += ic->start_time;
1327 
1328     /* if seeking requested, we execute it */
1329     if (o->start_time != AV_NOPTS_VALUE) {
1330         int64_t seek_timestamp = timestamp;
1331 
1332         if (!(ic->iformat->flags & AVFMT_SEEK_TO_PTS)) {
1333             int dts_heuristic = 0;
1334             for (i=0; i<ic->nb_streams; i++) {
1335                 const AVCodecParameters *par = ic->streams[i]->codecpar;
1336                 if (par->video_delay) {
1337                     dts_heuristic = 1;
1338                     break;
1339                 }
1340             }
1341             if (dts_heuristic) {
1342                 seek_timestamp -= 3*AV_TIME_BASE / 23;
1343             }
1344         }
1345         ret = avformat_seek_file(ic, -1, INT64_MIN, seek_timestamp, seek_timestamp, 0);
1346         if (ret < 0) {
1347             av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
1348                    filename, (double)timestamp / AV_TIME_BASE);
1349         }
1350     }
1351 
1352     /* update the current parameters so that they match the one of the input stream */
1353     add_input_streams(o, ic);
1354 
1355     /* dump the file content */
1356     av_dump_format(ic, nb_input_files, filename, 0);
1357 
1358     f = ALLOC_ARRAY_ELEM(input_files, nb_input_files);
1359 
1360     f->ctx        = ic;
1361     f->ist_index  = nb_input_streams - ic->nb_streams;
1362     f->start_time = o->start_time;
1363     f->recording_time = o->recording_time;
1364     f->input_sync_ref = o->input_sync_ref;
1365     f->input_ts_offset = o->input_ts_offset;
1366     f->ts_offset  = o->input_ts_offset - (copy_ts ? (start_at_zero && ic->start_time != AV_NOPTS_VALUE ? ic->start_time : 0) : timestamp);
1367     f->nb_streams = ic->nb_streams;
1368     f->rate_emu   = o->rate_emu;
1369     f->accurate_seek = o->accurate_seek;
1370     f->loop = o->loop;
1371     f->duration = 0;
1372     f->time_base = (AVRational){ 1, 1 };
1373 
1374     f->readrate = o->readrate ? o->readrate : 0.0;
1375     if (f->readrate < 0.0f) {
1376         av_log(NULL, AV_LOG_ERROR, "Option -readrate for Input #%d is %0.3f; it must be non-negative.\n", nb_input_files, f->readrate);
1377         exit_program(1);
1378     }
1379     if (f->readrate && f->rate_emu) {
1380         av_log(NULL, AV_LOG_WARNING, "Both -readrate and -re set for Input #%d. Using -readrate %0.3f.\n", nb_input_files, f->readrate);
1381         f->rate_emu = 0;
1382     }
1383 
1384     f->pkt = av_packet_alloc();
1385     if (!f->pkt)
1386         exit_program(1);
1387 #if HAVE_THREADS
1388     f->thread_queue_size = o->thread_queue_size;
1389 #endif
1390 
1391     /* check if all codec options have been used */
1392     unused_opts = strip_specifiers(o->g->codec_opts);
1393     for (i = f->ist_index; i < nb_input_streams; i++) {
1394         e = NULL;
1395         while ((e = av_dict_get(input_streams[i]->decoder_opts, "", e,
1396                                 AV_DICT_IGNORE_SUFFIX)))
1397             av_dict_set(&unused_opts, e->key, NULL, 0);
1398     }
1399 
1400     e = NULL;
1401     while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
1402         const AVClass *class = avcodec_get_class();
1403         const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
1404                                              AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
1405         const AVClass *fclass = avformat_get_class();
1406         const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0,
1407                                              AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
1408         if (!option || foption)
1409             continue;
1410 
1411 
1412         if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) {
1413             av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
1414                    "input file #%d (%s) is not a decoding option.\n", e->key,
1415                    option->help ? option->help : "", nb_input_files - 1,
1416                    filename);
1417             exit_program(1);
1418         }
1419 
1420         av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
1421                "input file #%d (%s) has not been used for any stream. The most "
1422                "likely reason is either wrong type (e.g. a video option with "
1423                "no video streams) or that it is a private option of some decoder "
1424                "which was not actually used for any stream.\n", e->key,
1425                option->help ? option->help : "", nb_input_files - 1, filename);
1426     }
1427     av_dict_free(&unused_opts);
1428 
1429     for (i = 0; i < o->nb_dump_attachment; i++) {
1430         int j;
1431 
1432         for (j = 0; j < ic->nb_streams; j++) {
1433             AVStream *st = ic->streams[j];
1434 
1435             if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
1436                 dump_attachment(st, o->dump_attachment[i].u.str);
1437         }
1438     }
1439 
1440     input_stream_potentially_available = 1;
1441 
1442     return 0;
1443 }
1444 
get_line(AVIOContext * s,AVBPrint * bprint)1445 static char *get_line(AVIOContext *s, AVBPrint *bprint)
1446 {
1447     char c;
1448 
1449     while ((c = avio_r8(s)) && c != '\n')
1450         av_bprint_chars(bprint, c, 1);
1451 
1452     if (!av_bprint_is_complete(bprint)) {
1453         av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
1454         exit_program(1);
1455     }
1456     return bprint->str;
1457 }
1458 
get_preset_file_2(const char * preset_name,const char * codec_name,AVIOContext ** s)1459 static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
1460 {
1461     int i, ret = -1;
1462     char filename[1000];
1463     char *env_avconv_datadir = getenv_utf8("AVCONV_DATADIR");
1464     char *env_home = getenv_utf8("HOME");
1465     const char *base[3] = { env_avconv_datadir,
1466                             env_home,
1467                             AVCONV_DATADIR,
1468                             };
1469 
1470     for (i = 0; i < FF_ARRAY_ELEMS(base) && ret < 0; i++) {
1471         if (!base[i])
1472             continue;
1473         if (codec_name) {
1474             snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
1475                      i != 1 ? "" : "/.avconv", codec_name, preset_name);
1476             ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
1477         }
1478         if (ret < 0) {
1479             snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
1480                      i != 1 ? "" : "/.avconv", preset_name);
1481             ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
1482         }
1483     }
1484     freeenv_utf8(env_home);
1485     freeenv_utf8(env_avconv_datadir);
1486     return ret;
1487 }
1488 
choose_encoder(OptionsContext * o,AVFormatContext * s,OutputStream * ost)1489 static int choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
1490 {
1491     enum AVMediaType type = ost->st->codecpar->codec_type;
1492     char *codec_name = NULL;
1493 
1494     if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_SUBTITLE) {
1495         MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
1496         if (!codec_name) {
1497             ost->st->codecpar->codec_id = av_guess_codec(s->oformat, NULL, s->url,
1498                                                          NULL, ost->st->codecpar->codec_type);
1499             ost->enc = avcodec_find_encoder(ost->st->codecpar->codec_id);
1500             if (!ost->enc) {
1501                 av_log(NULL, AV_LOG_FATAL, "Automatic encoder selection failed for "
1502                        "output stream #%d:%d. Default encoder for format %s (codec %s) is "
1503                        "probably disabled. Please choose an encoder manually.\n",
1504                        ost->file_index, ost->index, s->oformat->name,
1505                        avcodec_get_name(ost->st->codecpar->codec_id));
1506                 return AVERROR_ENCODER_NOT_FOUND;
1507             }
1508         } else if (!strcmp(codec_name, "copy"))
1509             ost->stream_copy = 1;
1510         else {
1511             ost->enc = find_codec_or_die(codec_name, ost->st->codecpar->codec_type, 1);
1512             ost->st->codecpar->codec_id = ost->enc->id;
1513         }
1514         ost->encoding_needed = !ost->stream_copy;
1515     } else {
1516         /* no encoding supported for other media types */
1517         ost->stream_copy     = 1;
1518         ost->encoding_needed = 0;
1519     }
1520 
1521     return 0;
1522 }
1523 
new_output_stream(OptionsContext * o,AVFormatContext * oc,enum AVMediaType type,int source_index)1524 static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type, int source_index)
1525 {
1526     OutputStream *ost;
1527     AVStream *st = avformat_new_stream(oc, NULL);
1528     int idx      = oc->nb_streams - 1, ret = 0;
1529     const char *bsfs = NULL, *time_base = NULL;
1530     char *next, *codec_tag = NULL;
1531     double qscale = -1;
1532     int i;
1533 
1534     if (!st) {
1535         av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
1536         exit_program(1);
1537     }
1538 
1539     if (oc->nb_streams - 1 < o->nb_streamid_map)
1540         st->id = o->streamid_map[oc->nb_streams - 1];
1541 
1542     ost = ALLOC_ARRAY_ELEM(output_streams, nb_output_streams);
1543 
1544     ost->file_index = nb_output_files - 1;
1545     ost->index      = idx;
1546     ost->st         = st;
1547     ost->forced_kf_ref_pts = AV_NOPTS_VALUE;
1548     st->codecpar->codec_type = type;
1549 
1550     ret = choose_encoder(o, oc, ost);
1551     if (ret < 0) {
1552         av_log(NULL, AV_LOG_FATAL, "Error selecting an encoder for stream "
1553                "%d:%d\n", ost->file_index, ost->index);
1554         exit_program(1);
1555     }
1556 
1557     ost->enc_ctx = avcodec_alloc_context3(ost->enc);
1558     if (!ost->enc_ctx) {
1559         av_log(NULL, AV_LOG_ERROR, "Error allocating the encoding context.\n");
1560         exit_program(1);
1561     }
1562     ost->enc_ctx->codec_type = type;
1563 
1564     ost->ref_par = avcodec_parameters_alloc();
1565     if (!ost->ref_par) {
1566         av_log(NULL, AV_LOG_ERROR, "Error allocating the encoding parameters.\n");
1567         exit_program(1);
1568     }
1569 
1570     ost->filtered_frame = av_frame_alloc();
1571     if (!ost->filtered_frame)
1572         exit_program(1);
1573 
1574     ost->pkt = av_packet_alloc();
1575     if (!ost->pkt)
1576         exit_program(1);
1577 
1578     if (ost->enc) {
1579         AVIOContext *s = NULL;
1580         char *buf = NULL, *arg = NULL, *preset = NULL;
1581 
1582         ost->encoder_opts  = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
1583 
1584         MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
1585         ost->autoscale = 1;
1586         MATCH_PER_STREAM_OPT(autoscale, i, ost->autoscale, oc, st);
1587         if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
1588             AVBPrint bprint;
1589             av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
1590             do  {
1591                 av_bprint_clear(&bprint);
1592                 buf = get_line(s, &bprint);
1593                 if (!buf[0] || buf[0] == '#')
1594                     continue;
1595                 if (!(arg = strchr(buf, '='))) {
1596                     av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
1597                     exit_program(1);
1598                 }
1599                 *arg++ = 0;
1600                 av_dict_set(&ost->encoder_opts, buf, arg, AV_DICT_DONT_OVERWRITE);
1601             } while (!s->eof_reached);
1602             av_bprint_finalize(&bprint, NULL);
1603             avio_closep(&s);
1604         }
1605         if (ret) {
1606             av_log(NULL, AV_LOG_FATAL,
1607                    "Preset %s specified for stream %d:%d, but could not be opened.\n",
1608                    preset, ost->file_index, ost->index);
1609             exit_program(1);
1610         }
1611     } else {
1612         ost->encoder_opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
1613     }
1614 
1615 
1616     if (o->bitexact)
1617         ost->enc_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
1618 
1619     MATCH_PER_STREAM_OPT(time_bases, str, time_base, oc, st);
1620     if (time_base) {
1621         AVRational q;
1622         if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 ||
1623             q.num <= 0 || q.den <= 0) {
1624             av_log(NULL, AV_LOG_FATAL, "Invalid time base: %s\n", time_base);
1625             exit_program(1);
1626         }
1627         st->time_base = q;
1628     }
1629 
1630     MATCH_PER_STREAM_OPT(enc_time_bases, str, time_base, oc, st);
1631     if (time_base) {
1632         AVRational q;
1633         if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 ||
1634             q.den <= 0) {
1635             av_log(NULL, AV_LOG_FATAL, "Invalid time base: %s\n", time_base);
1636             exit_program(1);
1637         }
1638         ost->enc_timebase = q;
1639     }
1640 
1641     ost->max_frames = INT64_MAX;
1642     MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
1643     for (i = 0; i<o->nb_max_frames; i++) {
1644         char *p = o->max_frames[i].specifier;
1645         if (!*p && type != AVMEDIA_TYPE_VIDEO) {
1646             av_log(NULL, AV_LOG_WARNING, "Applying unspecific -frames to non video streams, maybe you meant -vframes ?\n");
1647             break;
1648         }
1649     }
1650 
1651     ost->copy_prior_start = -1;
1652     MATCH_PER_STREAM_OPT(copy_prior_start, i, ost->copy_prior_start, oc ,st);
1653 
1654     MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st);
1655     if (bsfs && *bsfs) {
1656         ret = av_bsf_list_parse_str(bsfs, &ost->bsf_ctx);
1657         if (ret < 0) {
1658             av_log(NULL, AV_LOG_ERROR, "Error parsing bitstream filter sequence '%s': %s\n", bsfs, av_err2str(ret));
1659             exit_program(1);
1660         }
1661     }
1662 
1663     MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
1664     if (codec_tag) {
1665         uint32_t tag = strtol(codec_tag, &next, 0);
1666         if (*next) {
1667             uint8_t buf[4] = { 0 };
1668             memcpy(buf, codec_tag, FFMIN(sizeof(buf), strlen(codec_tag)));
1669             tag = AV_RL32(buf);
1670         }
1671         ost->st->codecpar->codec_tag =
1672         ost->enc_ctx->codec_tag = tag;
1673     }
1674 
1675     MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
1676     if (qscale >= 0) {
1677         ost->enc_ctx->flags |= AV_CODEC_FLAG_QSCALE;
1678         ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale;
1679     }
1680 
1681     MATCH_PER_STREAM_OPT(disposition, str, ost->disposition, oc, st);
1682     ost->disposition = av_strdup(ost->disposition);
1683 
1684     ost->max_muxing_queue_size = 128;
1685     MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ost->max_muxing_queue_size, oc, st);
1686 
1687     ost->muxing_queue_data_size = 0;
1688 
1689     ost->muxing_queue_data_threshold = 50*1024*1024;
1690     MATCH_PER_STREAM_OPT(muxing_queue_data_threshold, i, ost->muxing_queue_data_threshold, oc, st);
1691 
1692     MATCH_PER_STREAM_OPT(bits_per_raw_sample, i, ost->bits_per_raw_sample,
1693                          oc, st);
1694 
1695     if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1696         ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1697 
1698     av_dict_copy(&ost->sws_dict, o->g->sws_dict, 0);
1699 
1700     av_dict_copy(&ost->swr_opts, o->g->swr_opts, 0);
1701     if (ost->enc && av_get_exact_bits_per_sample(ost->enc->id) == 24)
1702         av_dict_set(&ost->swr_opts, "output_sample_bits", "24", 0);
1703 
1704     ost->source_index = source_index;
1705     if (source_index >= 0) {
1706         ost->sync_ist = input_streams[source_index];
1707         input_streams[source_index]->discard = 0;
1708         input_streams[source_index]->st->discard = input_streams[source_index]->user_set_discard;
1709     }
1710     ost->last_mux_dts = AV_NOPTS_VALUE;
1711 
1712     ost->muxing_queue = av_fifo_alloc2(8, sizeof(AVPacket*), 0);
1713     if (!ost->muxing_queue)
1714         exit_program(1);
1715 
1716     MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i,
1717                          ost->copy_initial_nonkeyframes, oc, st);
1718 
1719     return ost;
1720 }
1721 
parse_matrix_coeffs(uint16_t * dest,const char * str)1722 static void parse_matrix_coeffs(uint16_t *dest, const char *str)
1723 {
1724     int i;
1725     const char *p = str;
1726     for (i = 0;; i++) {
1727         dest[i] = atoi(p);
1728         if (i == 63)
1729             break;
1730         p = strchr(p, ',');
1731         if (!p) {
1732             av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
1733             exit_program(1);
1734         }
1735         p++;
1736     }
1737 }
1738 
1739 /* read file contents into a string */
read_file(const char * filename)1740 static char *read_file(const char *filename)
1741 {
1742     AVIOContext *pb      = NULL;
1743     int ret = avio_open(&pb, filename, AVIO_FLAG_READ);
1744     AVBPrint bprint;
1745     char *str;
1746 
1747     if (ret < 0) {
1748         av_log(NULL, AV_LOG_ERROR, "Error opening file %s.\n", filename);
1749         return NULL;
1750     }
1751 
1752     av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
1753     ret = avio_read_to_bprint(pb, &bprint, SIZE_MAX);
1754     avio_closep(&pb);
1755     if (ret < 0) {
1756         av_bprint_finalize(&bprint, NULL);
1757         return NULL;
1758     }
1759     ret = av_bprint_finalize(&bprint, &str);
1760     if (ret < 0)
1761         return NULL;
1762     return str;
1763 }
1764 
get_ost_filters(OptionsContext * o,AVFormatContext * oc,OutputStream * ost)1765 static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc,
1766                              OutputStream *ost)
1767 {
1768     AVStream *st = ost->st;
1769 
1770     if (ost->filters_script && ost->filters) {
1771         av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
1772                "output stream #%d:%d.\n", nb_output_files, st->index);
1773         exit_program(1);
1774     }
1775 
1776     if (ost->filters_script)
1777         return read_file(ost->filters_script);
1778     else if (ost->filters)
1779         return av_strdup(ost->filters);
1780 
1781     return av_strdup(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ?
1782                      "null" : "anull");
1783 }
1784 
check_streamcopy_filters(OptionsContext * o,AVFormatContext * oc,const OutputStream * ost,enum AVMediaType type)1785 static void check_streamcopy_filters(OptionsContext *o, AVFormatContext *oc,
1786                                      const OutputStream *ost, enum AVMediaType type)
1787 {
1788     if (ost->filters_script || ost->filters) {
1789         av_log(NULL, AV_LOG_ERROR,
1790                "%s '%s' was defined for %s output stream %d:%d but codec copy was selected.\n"
1791                "Filtering and streamcopy cannot be used together.\n",
1792                ost->filters ? "Filtergraph" : "Filtergraph script",
1793                ost->filters ? ost->filters : ost->filters_script,
1794                av_get_media_type_string(type), ost->file_index, ost->index);
1795         exit_program(1);
1796     }
1797 }
1798 
new_video_stream(OptionsContext * o,AVFormatContext * oc,int source_index)1799 static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
1800 {
1801     AVStream *st;
1802     OutputStream *ost;
1803     AVCodecContext *video_enc;
1804     char *frame_rate = NULL, *max_frame_rate = NULL, *frame_aspect_ratio = NULL;
1805 
1806     ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO, source_index);
1807     st  = ost->st;
1808     video_enc = ost->enc_ctx;
1809 
1810     MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
1811     if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
1812         av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
1813         exit_program(1);
1814     }
1815 
1816     MATCH_PER_STREAM_OPT(max_frame_rates, str, max_frame_rate, oc, st);
1817     if (max_frame_rate && av_parse_video_rate(&ost->max_frame_rate, max_frame_rate) < 0) {
1818         av_log(NULL, AV_LOG_FATAL, "Invalid maximum framerate value: %s\n", max_frame_rate);
1819         exit_program(1);
1820     }
1821 
1822     if (frame_rate && max_frame_rate) {
1823         av_log(NULL, AV_LOG_ERROR, "Only one of -fpsmax and -r can be set for a stream.\n");
1824         exit_program(1);
1825     }
1826 
1827     if ((frame_rate || max_frame_rate) &&
1828         video_sync_method == VSYNC_PASSTHROUGH)
1829         av_log(NULL, AV_LOG_ERROR, "Using -vsync passthrough and -r/-fpsmax can produce invalid output files\n");
1830 
1831     MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
1832     if (frame_aspect_ratio) {
1833         AVRational q;
1834         if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 ||
1835             q.num <= 0 || q.den <= 0) {
1836             av_log(NULL, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio);
1837             exit_program(1);
1838         }
1839         ost->frame_aspect_ratio = q;
1840     }
1841 
1842     MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
1843     MATCH_PER_STREAM_OPT(filters,        str, ost->filters,        oc, st);
1844 
1845     if (!ost->stream_copy) {
1846         const char *p = NULL;
1847         char *frame_size = NULL;
1848         char *frame_pix_fmt = NULL;
1849         char *intra_matrix = NULL, *inter_matrix = NULL;
1850         char *chroma_intra_matrix = NULL;
1851         int do_pass = 0;
1852         int i;
1853 
1854         MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
1855         if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
1856             av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
1857             exit_program(1);
1858         }
1859 
1860         MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
1861         if (frame_pix_fmt && *frame_pix_fmt == '+') {
1862             ost->keep_pix_fmt = 1;
1863             if (!*++frame_pix_fmt)
1864                 frame_pix_fmt = NULL;
1865         }
1866         if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == AV_PIX_FMT_NONE) {
1867             av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
1868             exit_program(1);
1869         }
1870         st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
1871 
1872         MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
1873         if (intra_matrix) {
1874             if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
1875                 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
1876                 exit_program(1);
1877             }
1878             parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
1879         }
1880         MATCH_PER_STREAM_OPT(chroma_intra_matrices, str, chroma_intra_matrix, oc, st);
1881         if (chroma_intra_matrix) {
1882             uint16_t *p = av_mallocz(sizeof(*video_enc->chroma_intra_matrix) * 64);
1883             if (!p) {
1884                 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
1885                 exit_program(1);
1886             }
1887             video_enc->chroma_intra_matrix = p;
1888             parse_matrix_coeffs(p, chroma_intra_matrix);
1889         }
1890         MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
1891         if (inter_matrix) {
1892             if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
1893                 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
1894                 exit_program(1);
1895             }
1896             parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
1897         }
1898 
1899         MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
1900         for (i = 0; p; i++) {
1901             int start, end, q;
1902             int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
1903             if (e != 3) {
1904                 av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
1905                 exit_program(1);
1906             }
1907             video_enc->rc_override =
1908                 av_realloc_array(video_enc->rc_override,
1909                                  i + 1, sizeof(RcOverride));
1910             if (!video_enc->rc_override) {
1911                 av_log(NULL, AV_LOG_FATAL, "Could not (re)allocate memory for rc_override.\n");
1912                 exit_program(1);
1913             }
1914             video_enc->rc_override[i].start_frame = start;
1915             video_enc->rc_override[i].end_frame   = end;
1916             if (q > 0) {
1917                 video_enc->rc_override[i].qscale         = q;
1918                 video_enc->rc_override[i].quality_factor = 1.0;
1919             }
1920             else {
1921                 video_enc->rc_override[i].qscale         = 0;
1922                 video_enc->rc_override[i].quality_factor = -q/100.0;
1923             }
1924             p = strchr(p, '/');
1925             if (p) p++;
1926         }
1927         video_enc->rc_override_count = i;
1928 
1929         if (do_psnr)
1930             video_enc->flags|= AV_CODEC_FLAG_PSNR;
1931 
1932         /* two pass mode */
1933         MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
1934         if (do_pass) {
1935             if (do_pass & 1) {
1936                 video_enc->flags |= AV_CODEC_FLAG_PASS1;
1937                 av_dict_set(&ost->encoder_opts, "flags", "+pass1", AV_DICT_APPEND);
1938             }
1939             if (do_pass & 2) {
1940                 video_enc->flags |= AV_CODEC_FLAG_PASS2;
1941                 av_dict_set(&ost->encoder_opts, "flags", "+pass2", AV_DICT_APPEND);
1942             }
1943         }
1944 
1945         MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
1946         if (ost->logfile_prefix &&
1947             !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
1948             exit_program(1);
1949 
1950         if (do_pass) {
1951             char logfilename[1024];
1952             FILE *f;
1953 
1954             snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
1955                      ost->logfile_prefix ? ost->logfile_prefix :
1956                                            DEFAULT_PASS_LOGFILENAME_PREFIX,
1957                      nb_output_streams - 1);
1958             if (!strcmp(ost->enc->name, "libx264")) {
1959                 av_dict_set(&ost->encoder_opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
1960             } else {
1961                 if (video_enc->flags & AV_CODEC_FLAG_PASS2) {
1962                     char  *logbuffer = read_file(logfilename);
1963 
1964                     if (!logbuffer) {
1965                         av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
1966                                logfilename);
1967                         exit_program(1);
1968                     }
1969                     video_enc->stats_in = logbuffer;
1970                 }
1971                 if (video_enc->flags & AV_CODEC_FLAG_PASS1) {
1972                     f = fopen_utf8(logfilename, "wb");
1973                     if (!f) {
1974                         av_log(NULL, AV_LOG_FATAL,
1975                                "Cannot write log file '%s' for pass-1 encoding: %s\n",
1976                                logfilename, strerror(errno));
1977                         exit_program(1);
1978                     }
1979                     ost->logfile = f;
1980                 }
1981             }
1982         }
1983 
1984         MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
1985         if (ost->forced_keyframes)
1986             ost->forced_keyframes = av_strdup(ost->forced_keyframes);
1987 
1988         MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
1989 
1990         ost->top_field_first = -1;
1991         MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
1992 
1993         ost->vsync_method = video_sync_method;
1994         MATCH_PER_STREAM_OPT(fps_mode, str, ost->fps_mode, oc, st);
1995         if (ost->fps_mode)
1996             parse_and_set_vsync(ost->fps_mode, &ost->vsync_method, ost->file_index, ost->index, 0);
1997 
1998         if (ost->vsync_method == VSYNC_AUTO) {
1999             if (!strcmp(oc->oformat->name, "avi")) {
2000                 ost->vsync_method = VSYNC_VFR;
2001             } else {
2002                 ost->vsync_method = (oc->oformat->flags & AVFMT_VARIABLE_FPS)       ?
2003                                      ((oc->oformat->flags & AVFMT_NOTIMESTAMPS) ?
2004                                       VSYNC_PASSTHROUGH : VSYNC_VFR)                :
2005                                      VSYNC_CFR;
2006             }
2007 
2008             if (ost->source_index >= 0 && ost->vsync_method == VSYNC_CFR) {
2009                 const InputStream *ist = input_streams[ost->source_index];
2010                 const InputFile *ifile = input_files[ist->file_index];
2011 
2012                 if (ifile->nb_streams == 1 && ifile->input_ts_offset == 0)
2013                     ost->vsync_method = VSYNC_VSCFR;
2014             }
2015 
2016             if (ost->vsync_method == VSYNC_CFR && copy_ts) {
2017                 ost->vsync_method = VSYNC_VSCFR;
2018             }
2019         }
2020         ost->is_cfr = (ost->vsync_method == VSYNC_CFR || ost->vsync_method == VSYNC_VSCFR);
2021 
2022         ost->avfilter = get_ost_filters(o, oc, ost);
2023         if (!ost->avfilter)
2024             exit_program(1);
2025 
2026         ost->last_frame = av_frame_alloc();
2027         if (!ost->last_frame)
2028             exit_program(1);
2029     }
2030 
2031     if (ost->stream_copy)
2032         check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_VIDEO);
2033 
2034     return ost;
2035 }
2036 
new_audio_stream(OptionsContext * o,AVFormatContext * oc,int source_index)2037 static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
2038 {
2039     int n;
2040     AVStream *st;
2041     OutputStream *ost;
2042     AVCodecContext *audio_enc;
2043 
2044     ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO, source_index);
2045     st  = ost->st;
2046 
2047     audio_enc = ost->enc_ctx;
2048     audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
2049 
2050     MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
2051     MATCH_PER_STREAM_OPT(filters,        str, ost->filters,        oc, st);
2052 
2053     if (!ost->stream_copy) {
2054         int channels = 0;
2055         char *layout = NULL;
2056         char *sample_fmt = NULL;
2057 
2058         MATCH_PER_STREAM_OPT(audio_channels, i, channels, oc, st);
2059         if (channels) {
2060             audio_enc->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
2061             audio_enc->ch_layout.nb_channels = channels;
2062         }
2063 
2064         MATCH_PER_STREAM_OPT(audio_ch_layouts, str, layout, oc, st);
2065         if (layout) {
2066             if (av_channel_layout_from_string(&audio_enc->ch_layout, layout) < 0) {
2067 #if FF_API_OLD_CHANNEL_LAYOUT
2068                 uint64_t mask;
2069                 AV_NOWARN_DEPRECATED({
2070                 mask = av_get_channel_layout(layout);
2071                 })
2072                 if (!mask) {
2073 #endif
2074                     av_log(NULL, AV_LOG_FATAL, "Unknown channel layout: %s\n", layout);
2075                     exit_program(1);
2076 #if FF_API_OLD_CHANNEL_LAYOUT
2077                 }
2078                 av_log(NULL, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n",
2079                        layout);
2080                 av_channel_layout_from_mask(&audio_enc->ch_layout, mask);
2081 #endif
2082             }
2083         }
2084 
2085         MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
2086         if (sample_fmt &&
2087             (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
2088             av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
2089             exit_program(1);
2090         }
2091 
2092         MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
2093 
2094         MATCH_PER_STREAM_OPT(apad, str, ost->apad, oc, st);
2095         ost->apad = av_strdup(ost->apad);
2096 
2097         ost->avfilter = get_ost_filters(o, oc, ost);
2098         if (!ost->avfilter)
2099             exit_program(1);
2100 
2101         /* check for channel mapping for this audio stream */
2102         for (n = 0; n < o->nb_audio_channel_maps; n++) {
2103             AudioChannelMap *map = &o->audio_channel_maps[n];
2104             if ((map->ofile_idx   == -1 || ost->file_index == map->ofile_idx) &&
2105                 (map->ostream_idx == -1 || ost->st->index  == map->ostream_idx)) {
2106                 InputStream *ist;
2107 
2108                 if (map->channel_idx == -1) {
2109                     ist = NULL;
2110                 } else if (ost->source_index < 0) {
2111                     av_log(NULL, AV_LOG_FATAL, "Cannot determine input stream for channel mapping %d.%d\n",
2112                            ost->file_index, ost->st->index);
2113                     continue;
2114                 } else {
2115                     ist = input_streams[ost->source_index];
2116                 }
2117 
2118                 if (!ist || (ist->file_index == map->file_idx && ist->st->index == map->stream_idx)) {
2119                     if (av_reallocp_array(&ost->audio_channels_map,
2120                                           ost->audio_channels_mapped + 1,
2121                                           sizeof(*ost->audio_channels_map)
2122                                           ) < 0 )
2123                         exit_program(1);
2124 
2125                     ost->audio_channels_map[ost->audio_channels_mapped++] = map->channel_idx;
2126                 }
2127             }
2128         }
2129     }
2130 
2131     if (ost->stream_copy)
2132         check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_AUDIO);
2133 
2134     return ost;
2135 }
2136 
new_data_stream(OptionsContext * o,AVFormatContext * oc,int source_index)2137 static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
2138 {
2139     OutputStream *ost;
2140 
2141     ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA, source_index);
2142     if (!ost->stream_copy) {
2143         av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
2144         exit_program(1);
2145     }
2146 
2147     return ost;
2148 }
2149 
new_unknown_stream(OptionsContext * o,AVFormatContext * oc,int source_index)2150 static OutputStream *new_unknown_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
2151 {
2152     OutputStream *ost;
2153 
2154     ost = new_output_stream(o, oc, AVMEDIA_TYPE_UNKNOWN, source_index);
2155     if (!ost->stream_copy) {
2156         av_log(NULL, AV_LOG_FATAL, "Unknown stream encoding not supported yet (only streamcopy)\n");
2157         exit_program(1);
2158     }
2159 
2160     return ost;
2161 }
2162 
new_attachment_stream(OptionsContext * o,AVFormatContext * oc,int source_index)2163 static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
2164 {
2165     OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT, source_index);
2166     ost->stream_copy = 1;
2167     ost->finished    = 1;
2168     return ost;
2169 }
2170 
new_subtitle_stream(OptionsContext * o,AVFormatContext * oc,int source_index)2171 static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
2172 {
2173     AVStream *st;
2174     OutputStream *ost;
2175     AVCodecContext *subtitle_enc;
2176 
2177     ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE, source_index);
2178     st  = ost->st;
2179     subtitle_enc = ost->enc_ctx;
2180 
2181     subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
2182 
2183     if (!ost->stream_copy) {
2184         char *frame_size = NULL;
2185 
2186         MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
2187         if (frame_size && av_parse_video_size(&subtitle_enc->width, &subtitle_enc->height, frame_size) < 0) {
2188             av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
2189             exit_program(1);
2190         }
2191     }
2192 
2193     return ost;
2194 }
2195 
2196 /* arg format is "output-stream-index:streamid-value". */
opt_streamid(void * optctx,const char * opt,const char * arg)2197 static int opt_streamid(void *optctx, const char *opt, const char *arg)
2198 {
2199     OptionsContext *o = optctx;
2200     int idx;
2201     char *p;
2202     char idx_str[16];
2203 
2204     av_strlcpy(idx_str, arg, sizeof(idx_str));
2205     p = strchr(idx_str, ':');
2206     if (!p) {
2207         av_log(NULL, AV_LOG_FATAL,
2208                "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
2209                arg, opt);
2210         exit_program(1);
2211     }
2212     *p++ = '\0';
2213     idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, MAX_STREAMS-1);
2214     o->streamid_map = grow_array(o->streamid_map, sizeof(*o->streamid_map), &o->nb_streamid_map, idx+1);
2215     o->streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
2216     return 0;
2217 }
2218 
copy_chapters(InputFile * ifile,OutputFile * ofile,AVFormatContext * os,int copy_metadata)2219 static int copy_chapters(InputFile *ifile, OutputFile *ofile, AVFormatContext *os,
2220                          int copy_metadata)
2221 {
2222     AVFormatContext *is = ifile->ctx;
2223     AVChapter **tmp;
2224     int i;
2225 
2226     tmp = av_realloc_f(os->chapters, is->nb_chapters + os->nb_chapters, sizeof(*os->chapters));
2227     if (!tmp)
2228         return AVERROR(ENOMEM);
2229     os->chapters = tmp;
2230 
2231     for (i = 0; i < is->nb_chapters; i++) {
2232         AVChapter *in_ch = is->chapters[i], *out_ch;
2233         int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
2234         int64_t ts_off   = av_rescale_q(start_time - ifile->ts_offset,
2235                                        AV_TIME_BASE_Q, in_ch->time_base);
2236         int64_t rt       = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
2237                            av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
2238 
2239 
2240         if (in_ch->end < ts_off)
2241             continue;
2242         if (rt != INT64_MAX && in_ch->start > rt + ts_off)
2243             break;
2244 
2245         out_ch = av_mallocz(sizeof(AVChapter));
2246         if (!out_ch)
2247             return AVERROR(ENOMEM);
2248 
2249         out_ch->id        = in_ch->id;
2250         out_ch->time_base = in_ch->time_base;
2251         out_ch->start     = FFMAX(0,  in_ch->start - ts_off);
2252         out_ch->end       = FFMIN(rt, in_ch->end   - ts_off);
2253 
2254         if (copy_metadata)
2255             av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
2256 
2257         os->chapters[os->nb_chapters++] = out_ch;
2258     }
2259     return 0;
2260 }
2261 
set_dispositions(OutputFile * of,AVFormatContext * ctx)2262 static int set_dispositions(OutputFile *of, AVFormatContext *ctx)
2263 {
2264     int nb_streams[AVMEDIA_TYPE_NB]   = { 0 };
2265     int have_default[AVMEDIA_TYPE_NB] = { 0 };
2266     int have_manual = 0;
2267 
2268     // first, copy the input dispositions
2269     for (int i = 0; i < ctx->nb_streams; i++) {
2270         OutputStream *ost = output_streams[of->ost_index + i];
2271 
2272         nb_streams[ost->st->codecpar->codec_type]++;
2273 
2274         have_manual |= !!ost->disposition;
2275 
2276         if (ost->source_index >= 0) {
2277             ost->st->disposition = input_streams[ost->source_index]->st->disposition;
2278 
2279             if (ost->st->disposition & AV_DISPOSITION_DEFAULT)
2280                 have_default[ost->st->codecpar->codec_type] = 1;
2281         }
2282     }
2283 
2284     if (have_manual) {
2285         // process manually set dispositions - they override the above copy
2286         for (int i = 0; i < ctx->nb_streams; i++) {
2287             OutputStream *ost = output_streams[of->ost_index + i];
2288             int ret;
2289 
2290             if (!ost->disposition)
2291                 continue;
2292 
2293 #if LIBAVFORMAT_VERSION_MAJOR >= 60
2294             ret = av_opt_set(ost->st, "disposition", ost->disposition, 0);
2295 #else
2296             {
2297                 const AVClass *class = av_stream_get_class();
2298                 const AVOption    *o = av_opt_find(&class, "disposition", NULL, 0, AV_OPT_SEARCH_FAKE_OBJ);
2299 
2300                 av_assert0(o);
2301                 ret = av_opt_eval_flags(&class, o, ost->disposition, &ost->st->disposition);
2302             }
2303 #endif
2304 
2305             if (ret < 0)
2306                 return ret;
2307         }
2308     } else {
2309         // For each media type with more than one stream, find a suitable stream to
2310         // mark as default, unless one is already marked default.
2311         // "Suitable" means the first of that type, skipping attached pictures.
2312         for (int i = 0; i < ctx->nb_streams; i++) {
2313             OutputStream *ost = output_streams[of->ost_index + i];
2314             enum AVMediaType type = ost->st->codecpar->codec_type;
2315 
2316             if (nb_streams[type] < 2 || have_default[type] ||
2317                 ost->st->disposition & AV_DISPOSITION_ATTACHED_PIC)
2318                 continue;
2319 
2320             ost->st->disposition |= AV_DISPOSITION_DEFAULT;
2321             have_default[type] = 1;
2322         }
2323     }
2324 
2325     return 0;
2326 }
2327 
init_output_filter(OutputFilter * ofilter,OptionsContext * o,AVFormatContext * oc)2328 static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
2329                                AVFormatContext *oc)
2330 {
2331     OutputStream *ost;
2332 
2333     switch (ofilter->type) {
2334     case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc, -1); break;
2335     case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc, -1); break;
2336     default:
2337         av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
2338                "currently.\n");
2339         exit_program(1);
2340     }
2341 
2342     ost->filter       = ofilter;
2343 
2344     ofilter->ost      = ost;
2345     ofilter->format   = -1;
2346 
2347     if (ost->stream_copy) {
2348         av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
2349                "which is fed from a complex filtergraph. Filtering and streamcopy "
2350                "cannot be used together.\n", ost->file_index, ost->index);
2351         exit_program(1);
2352     }
2353 
2354     if (ost->avfilter && (ost->filters || ost->filters_script)) {
2355         const char *opt = ost->filters ? "-vf/-af/-filter" : "-filter_script";
2356         av_log(NULL, AV_LOG_ERROR,
2357                "%s '%s' was specified through the %s option "
2358                "for output stream %d:%d, which is fed from a complex filtergraph.\n"
2359                "%s and -filter_complex cannot be used together for the same stream.\n",
2360                ost->filters ? "Filtergraph" : "Filtergraph script",
2361                ost->filters ? ost->filters : ost->filters_script,
2362                opt, ost->file_index, ost->index, opt);
2363         exit_program(1);
2364     }
2365 
2366     avfilter_inout_free(&ofilter->out_tmp);
2367 }
2368 
init_complex_filters(void)2369 static int init_complex_filters(void)
2370 {
2371     int i, ret = 0;
2372 
2373     for (i = 0; i < nb_filtergraphs; i++) {
2374         ret = init_complex_filtergraph(filtergraphs[i]);
2375         if (ret < 0)
2376             return ret;
2377     }
2378     return 0;
2379 }
2380 
set_channel_layout(OutputFilter * f,OutputStream * ost)2381 static void set_channel_layout(OutputFilter *f, OutputStream *ost)
2382 {
2383     int i, err;
2384 
2385     if (ost->enc_ctx->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
2386         /* Pass the layout through for all orders but UNSPEC */
2387         err = av_channel_layout_copy(&f->ch_layout, &ost->enc_ctx->ch_layout);
2388         if (err < 0)
2389             exit_program(1);
2390         return;
2391     }
2392 
2393     /* Requested layout is of order UNSPEC */
2394     if (!ost->enc->ch_layouts) {
2395         /* Use the default native layout for the requested amount of channels when the
2396            encoder doesn't have a list of supported layouts */
2397         av_channel_layout_default(&f->ch_layout, ost->enc_ctx->ch_layout.nb_channels);
2398         return;
2399     }
2400     /* Encoder has a list of supported layouts. Pick the first layout in it with the
2401        same amount of channels as the requested layout */
2402     for (i = 0; ost->enc->ch_layouts[i].nb_channels; i++) {
2403         if (ost->enc->ch_layouts[i].nb_channels == ost->enc_ctx->ch_layout.nb_channels)
2404             break;
2405     }
2406     if (ost->enc->ch_layouts[i].nb_channels) {
2407         /* Use it if one is found */
2408         err = av_channel_layout_copy(&f->ch_layout, &ost->enc->ch_layouts[i]);
2409         if (err < 0)
2410             exit_program(1);
2411         return;
2412     }
2413     /* If no layout for the amount of channels requested was found, use the default
2414        native layout for it. */
2415     av_channel_layout_default(&f->ch_layout, ost->enc_ctx->ch_layout.nb_channels);
2416 }
2417 
open_output_file(OptionsContext * o,const char * filename)2418 static int open_output_file(OptionsContext *o, const char *filename)
2419 {
2420     AVFormatContext *oc;
2421     int i, j, err;
2422     OutputFile *of;
2423     OutputStream *ost;
2424     InputStream  *ist;
2425     AVDictionary *unused_opts = NULL;
2426     const AVDictionaryEntry *e = NULL;
2427 
2428     if (o->stop_time != INT64_MAX && o->recording_time != INT64_MAX) {
2429         o->stop_time = INT64_MAX;
2430         av_log(NULL, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
2431     }
2432 
2433     if (o->stop_time != INT64_MAX && o->recording_time == INT64_MAX) {
2434         int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time;
2435         if (o->stop_time <= start_time) {
2436             av_log(NULL, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n");
2437             exit_program(1);
2438         } else {
2439             o->recording_time = o->stop_time - start_time;
2440         }
2441     }
2442 
2443     of = ALLOC_ARRAY_ELEM(output_files, nb_output_files);
2444 
2445     of->index          = nb_output_files - 1;
2446     of->ost_index      = nb_output_streams;
2447     of->recording_time = o->recording_time;
2448     of->start_time     = o->start_time;
2449     of->limit_filesize = o->limit_filesize;
2450     of->shortest       = o->shortest;
2451     av_dict_copy(&of->opts, o->g->format_opts, 0);
2452 
2453     if (!strcmp(filename, "-"))
2454         filename = "pipe:";
2455 
2456     err = avformat_alloc_output_context2(&oc, NULL, o->format, filename);
2457     if (!oc) {
2458         print_error(filename, err);
2459         exit_program(1);
2460     }
2461 
2462     of->ctx = oc;
2463     of->format = oc->oformat;
2464     if (o->recording_time != INT64_MAX)
2465         oc->duration = o->recording_time;
2466 
2467     oc->interrupt_callback = int_cb;
2468 
2469     if (o->bitexact) {
2470         oc->flags    |= AVFMT_FLAG_BITEXACT;
2471     }
2472 
2473     /* create streams for all unlabeled output pads */
2474     for (i = 0; i < nb_filtergraphs; i++) {
2475         FilterGraph *fg = filtergraphs[i];
2476         for (j = 0; j < fg->nb_outputs; j++) {
2477             OutputFilter *ofilter = fg->outputs[j];
2478 
2479             if (!ofilter->out_tmp || ofilter->out_tmp->name)
2480                 continue;
2481 
2482             switch (ofilter->type) {
2483             case AVMEDIA_TYPE_VIDEO:    o->video_disable    = 1; break;
2484             case AVMEDIA_TYPE_AUDIO:    o->audio_disable    = 1; break;
2485             case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
2486             }
2487             init_output_filter(ofilter, o, oc);
2488         }
2489     }
2490 
2491     if (!o->nb_stream_maps) {
2492         char *subtitle_codec_name = NULL;
2493         /* pick the "best" stream of each type */
2494 
2495         /* video: highest resolution */
2496         if (!o->video_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) {
2497             int best_score = 0, idx = -1;
2498             int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
2499             for (j = 0; j < nb_input_files; j++) {
2500                 InputFile *ifile = input_files[j];
2501                 int file_best_score = 0, file_best_idx = -1;
2502                 for (i = 0; i < ifile->nb_streams; i++) {
2503                     int score;
2504                     ist = input_streams[ifile->ist_index + i];
2505                     score = ist->st->codecpar->width * ist->st->codecpar->height
2506                                + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
2507                                + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
2508                     if (ist->user_set_discard == AVDISCARD_ALL)
2509                         continue;
2510                     if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
2511                         score = 1;
2512                     if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
2513                         score > file_best_score) {
2514                         if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
2515                             continue;
2516                         file_best_score = score;
2517                         file_best_idx = ifile->ist_index + i;
2518                     }
2519                 }
2520                 if (file_best_idx >= 0) {
2521                     if((qcr == MKTAG('A', 'P', 'I', 'C')) || !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
2522                         file_best_score -= 5000000*!!(input_streams[file_best_idx]->st->disposition & AV_DISPOSITION_DEFAULT);
2523                     if (file_best_score > best_score) {
2524                         best_score = file_best_score;
2525                         idx = file_best_idx;
2526                     }
2527                }
2528             }
2529             if (idx >= 0)
2530                 new_video_stream(o, oc, idx);
2531         }
2532 
2533         /* audio: most channels */
2534         if (!o->audio_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_AUDIO) != AV_CODEC_ID_NONE) {
2535             int best_score = 0, idx = -1;
2536             for (j = 0; j < nb_input_files; j++) {
2537                 InputFile *ifile = input_files[j];
2538                 int file_best_score = 0, file_best_idx = -1;
2539                 for (i = 0; i < ifile->nb_streams; i++) {
2540                     int score;
2541                     ist = input_streams[ifile->ist_index + i];
2542                     score = ist->st->codecpar->ch_layout.nb_channels
2543                             + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
2544                             + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
2545                     if (ist->user_set_discard == AVDISCARD_ALL)
2546                         continue;
2547                     if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2548                         score > file_best_score) {
2549                         file_best_score = score;
2550                         file_best_idx = ifile->ist_index + i;
2551                     }
2552                 }
2553                 if (file_best_idx >= 0) {
2554                     file_best_score -= 5000000*!!(input_streams[file_best_idx]->st->disposition & AV_DISPOSITION_DEFAULT);
2555                     if (file_best_score > best_score) {
2556                         best_score = file_best_score;
2557                         idx = file_best_idx;
2558                     }
2559                }
2560             }
2561             if (idx >= 0)
2562                 new_audio_stream(o, oc, idx);
2563         }
2564 
2565         /* subtitles: pick first */
2566         MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, oc, "s");
2567         if (!o->subtitle_disable && (avcodec_find_encoder(oc->oformat->subtitle_codec) || subtitle_codec_name)) {
2568             for (i = 0; i < nb_input_streams; i++)
2569                 if (input_streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
2570                     AVCodecDescriptor const *input_descriptor =
2571                         avcodec_descriptor_get(input_streams[i]->st->codecpar->codec_id);
2572                     AVCodecDescriptor const *output_descriptor = NULL;
2573                     AVCodec const *output_codec =
2574                         avcodec_find_encoder(oc->oformat->subtitle_codec);
2575                     int input_props = 0, output_props = 0;
2576                     if (input_streams[i]->user_set_discard == AVDISCARD_ALL)
2577                         continue;
2578                     if (output_codec)
2579                         output_descriptor = avcodec_descriptor_get(output_codec->id);
2580                     if (input_descriptor)
2581                         input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
2582                     if (output_descriptor)
2583                         output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
2584                     if (subtitle_codec_name ||
2585                         input_props & output_props ||
2586                         // Map dvb teletext which has neither property to any output subtitle encoder
2587                         input_descriptor && output_descriptor &&
2588                         (!input_descriptor->props ||
2589                          !output_descriptor->props)) {
2590                         new_subtitle_stream(o, oc, i);
2591                         break;
2592                     }
2593                 }
2594         }
2595         /* Data only if codec id match */
2596         if (!o->data_disable ) {
2597             enum AVCodecID codec_id = av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_DATA);
2598             for (i = 0; codec_id != AV_CODEC_ID_NONE && i < nb_input_streams; i++) {
2599                 if (input_streams[i]->user_set_discard == AVDISCARD_ALL)
2600                     continue;
2601                 if (input_streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_DATA
2602                     && input_streams[i]->st->codecpar->codec_id == codec_id )
2603                     new_data_stream(o, oc, i);
2604             }
2605         }
2606     } else {
2607         for (i = 0; i < o->nb_stream_maps; i++) {
2608             StreamMap *map = &o->stream_maps[i];
2609 
2610             if (map->disabled)
2611                 continue;
2612 
2613             if (map->linklabel) {
2614                 FilterGraph *fg;
2615                 OutputFilter *ofilter = NULL;
2616                 int j, k;
2617 
2618                 for (j = 0; j < nb_filtergraphs; j++) {
2619                     fg = filtergraphs[j];
2620                     for (k = 0; k < fg->nb_outputs; k++) {
2621                         AVFilterInOut *out = fg->outputs[k]->out_tmp;
2622                         if (out && !strcmp(out->name, map->linklabel)) {
2623                             ofilter = fg->outputs[k];
2624                             goto loop_end;
2625                         }
2626                     }
2627                 }
2628 loop_end:
2629                 if (!ofilter) {
2630                     av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist "
2631                            "in any defined filter graph, or was already used elsewhere.\n", map->linklabel);
2632                     exit_program(1);
2633                 }
2634                 init_output_filter(ofilter, o, oc);
2635             } else {
2636                 int src_idx = input_files[map->file_index]->ist_index + map->stream_index;
2637 
2638                 ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
2639                 if (ist->user_set_discard == AVDISCARD_ALL) {
2640                     av_log(NULL, AV_LOG_FATAL, "Stream #%d:%d is disabled and cannot be mapped.\n",
2641                            map->file_index, map->stream_index);
2642                     exit_program(1);
2643                 }
2644                 if(o->subtitle_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
2645                     continue;
2646                 if(o->   audio_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
2647                     continue;
2648                 if(o->   video_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2649                     continue;
2650                 if(o->    data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA)
2651                     continue;
2652 
2653                 ost = NULL;
2654                 switch (ist->st->codecpar->codec_type) {
2655                 case AVMEDIA_TYPE_VIDEO:      ost = new_video_stream     (o, oc, src_idx); break;
2656                 case AVMEDIA_TYPE_AUDIO:      ost = new_audio_stream     (o, oc, src_idx); break;
2657                 case AVMEDIA_TYPE_SUBTITLE:   ost = new_subtitle_stream  (o, oc, src_idx); break;
2658                 case AVMEDIA_TYPE_DATA:       ost = new_data_stream      (o, oc, src_idx); break;
2659                 case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc, src_idx); break;
2660                 case AVMEDIA_TYPE_UNKNOWN:
2661                     if (copy_unknown_streams) {
2662                         ost = new_unknown_stream   (o, oc, src_idx);
2663                         break;
2664                     }
2665                 default:
2666                     av_log(NULL, ignore_unknown_streams ? AV_LOG_WARNING : AV_LOG_FATAL,
2667                            "Cannot map stream #%d:%d - unsupported type.\n",
2668                            map->file_index, map->stream_index);
2669                     if (!ignore_unknown_streams) {
2670                         av_log(NULL, AV_LOG_FATAL,
2671                                "If you want unsupported types ignored instead "
2672                                "of failing, please use the -ignore_unknown option\n"
2673                                "If you want them copied, please use -copy_unknown\n");
2674                         exit_program(1);
2675                     }
2676                 }
2677                 if (ost)
2678                     ost->sync_ist = input_streams[  input_files[map->sync_file_index]->ist_index
2679                                                   + map->sync_stream_index];
2680             }
2681         }
2682     }
2683 
2684     /* handle attached files */
2685     for (i = 0; i < o->nb_attachments; i++) {
2686         AVIOContext *pb;
2687         uint8_t *attachment;
2688         const char *p;
2689         int64_t len;
2690 
2691         if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
2692             av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
2693                    o->attachments[i]);
2694             exit_program(1);
2695         }
2696         if ((len = avio_size(pb)) <= 0) {
2697             av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
2698                    o->attachments[i]);
2699             exit_program(1);
2700         }
2701         if (len > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE ||
2702             !(attachment = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE))) {
2703             av_log(NULL, AV_LOG_FATAL, "Attachment %s too large.\n",
2704                    o->attachments[i]);
2705             exit_program(1);
2706         }
2707         avio_read(pb, attachment, len);
2708         memset(attachment + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2709 
2710         ost = new_attachment_stream(o, oc, -1);
2711         ost->stream_copy               = 0;
2712         ost->attachment_filename       = o->attachments[i];
2713         ost->st->codecpar->extradata      = attachment;
2714         ost->st->codecpar->extradata_size = len;
2715 
2716         p = strrchr(o->attachments[i], '/');
2717         av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
2718         avio_closep(&pb);
2719     }
2720 
2721     if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
2722         av_dump_format(oc, nb_output_files - 1, oc->url, 1);
2723         av_log(NULL, AV_LOG_ERROR, "Output file #%d does not contain any stream\n", nb_output_files - 1);
2724         exit_program(1);
2725     }
2726 
2727     /* check if all codec options have been used */
2728     unused_opts = strip_specifiers(o->g->codec_opts);
2729     for (i = of->ost_index; i < nb_output_streams; i++) {
2730         e = NULL;
2731         while ((e = av_dict_get(output_streams[i]->encoder_opts, "", e,
2732                                 AV_DICT_IGNORE_SUFFIX)))
2733             av_dict_set(&unused_opts, e->key, NULL, 0);
2734     }
2735 
2736     e = NULL;
2737     while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
2738         const AVClass *class = avcodec_get_class();
2739         const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
2740                                              AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
2741         const AVClass *fclass = avformat_get_class();
2742         const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0,
2743                                               AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
2744         if (!option || foption)
2745             continue;
2746 
2747 
2748         if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) {
2749             av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
2750                    "output file #%d (%s) is not an encoding option.\n", e->key,
2751                    option->help ? option->help : "", nb_output_files - 1,
2752                    filename);
2753             exit_program(1);
2754         }
2755 
2756         // gop_timecode is injected by generic code but not always used
2757         if (!strcmp(e->key, "gop_timecode"))
2758             continue;
2759 
2760         av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
2761                "output file #%d (%s) has not been used for any stream. The most "
2762                "likely reason is either wrong type (e.g. a video option with "
2763                "no video streams) or that it is a private option of some encoder "
2764                "which was not actually used for any stream.\n", e->key,
2765                option->help ? option->help : "", nb_output_files - 1, filename);
2766     }
2767     av_dict_free(&unused_opts);
2768 
2769     /* set the decoding_needed flags and create simple filtergraphs */
2770     for (i = of->ost_index; i < nb_output_streams; i++) {
2771         OutputStream *ost = output_streams[i];
2772 
2773         if (ost->encoding_needed && ost->source_index >= 0) {
2774             InputStream *ist = input_streams[ost->source_index];
2775             ist->decoding_needed |= DECODING_FOR_OST;
2776             ist->processing_needed = 1;
2777 
2778             if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
2779                 ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
2780                 err = init_simple_filtergraph(ist, ost);
2781                 if (err < 0) {
2782                     av_log(NULL, AV_LOG_ERROR,
2783                            "Error initializing a simple filtergraph between streams "
2784                            "%d:%d->%d:%d\n", ist->file_index, ost->source_index,
2785                            nb_output_files - 1, ost->st->index);
2786                     exit_program(1);
2787                 }
2788             }
2789         } else if (ost->stream_copy && ost->source_index >= 0) {
2790             InputStream *ist = input_streams[ost->source_index];
2791             ist->processing_needed = 1;
2792         }
2793 
2794         /* set the filter output constraints */
2795         if (ost->filter) {
2796             OutputFilter *f = ost->filter;
2797             switch (ost->enc_ctx->codec_type) {
2798             case AVMEDIA_TYPE_VIDEO:
2799                 f->frame_rate = ost->frame_rate;
2800                 f->width      = ost->enc_ctx->width;
2801                 f->height     = ost->enc_ctx->height;
2802                 if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
2803                     f->format = ost->enc_ctx->pix_fmt;
2804                 } else {
2805                     f->formats = ost->enc->pix_fmts;
2806                 }
2807                 break;
2808             case AVMEDIA_TYPE_AUDIO:
2809                 if (ost->enc_ctx->sample_fmt != AV_SAMPLE_FMT_NONE) {
2810                     f->format = ost->enc_ctx->sample_fmt;
2811                 } else {
2812                     f->formats = ost->enc->sample_fmts;
2813                 }
2814                 if (ost->enc_ctx->sample_rate) {
2815                     f->sample_rate = ost->enc_ctx->sample_rate;
2816                 } else {
2817                     f->sample_rates = ost->enc->supported_samplerates;
2818                 }
2819                 if (ost->enc_ctx->ch_layout.nb_channels) {
2820                     set_channel_layout(f, ost);
2821                 } else if (ost->enc->ch_layouts) {
2822                     f->ch_layouts = ost->enc->ch_layouts;
2823                 }
2824                 break;
2825             }
2826         }
2827     }
2828 
2829     /* check filename in case of an image number is expected */
2830     if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
2831         if (!av_filename_number_test(oc->url)) {
2832             print_error(oc->url, AVERROR(EINVAL));
2833             exit_program(1);
2834         }
2835     }
2836 
2837     if (!(oc->oformat->flags & AVFMT_NOSTREAMS) && !input_stream_potentially_available) {
2838         av_log(NULL, AV_LOG_ERROR,
2839                "No input streams but output needs an input stream\n");
2840         exit_program(1);
2841     }
2842 
2843     if (!(oc->oformat->flags & AVFMT_NOFILE)) {
2844         /* test if it already exists to avoid losing precious files */
2845         assert_file_overwrite(filename);
2846 
2847         /* open the file */
2848         if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
2849                               &oc->interrupt_callback,
2850                               &of->opts)) < 0) {
2851             print_error(filename, err);
2852             exit_program(1);
2853         }
2854     } else if (strcmp(oc->oformat->name, "image2")==0 && !av_filename_number_test(filename))
2855         assert_file_overwrite(filename);
2856 
2857     if (o->mux_preload) {
2858         av_dict_set_int(&of->opts, "preload", o->mux_preload*AV_TIME_BASE, 0);
2859     }
2860     oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
2861 
2862     /* copy metadata */
2863     for (i = 0; i < o->nb_metadata_map; i++) {
2864         char *p;
2865         int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
2866 
2867         if (in_file_index >= nb_input_files) {
2868             av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index);
2869             exit_program(1);
2870         }
2871         copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc,
2872                       in_file_index >= 0 ?
2873                       input_files[in_file_index]->ctx : NULL, o);
2874     }
2875 
2876     /* copy chapters */
2877     if (o->chapters_input_file >= nb_input_files) {
2878         if (o->chapters_input_file == INT_MAX) {
2879             /* copy chapters from the first input file that has them*/
2880             o->chapters_input_file = -1;
2881             for (i = 0; i < nb_input_files; i++)
2882                 if (input_files[i]->ctx->nb_chapters) {
2883                     o->chapters_input_file = i;
2884                     break;
2885                 }
2886         } else {
2887             av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
2888                    o->chapters_input_file);
2889             exit_program(1);
2890         }
2891     }
2892     if (o->chapters_input_file >= 0)
2893         copy_chapters(input_files[o->chapters_input_file], of, oc,
2894                       !o->metadata_chapters_manual);
2895 
2896     /* copy global metadata by default */
2897     if (!o->metadata_global_manual && nb_input_files){
2898         av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
2899                      AV_DICT_DONT_OVERWRITE);
2900         if(o->recording_time != INT64_MAX)
2901             av_dict_set(&oc->metadata, "duration", NULL, 0);
2902         av_dict_set(&oc->metadata, "creation_time", NULL, 0);
2903         av_dict_set(&oc->metadata, "company_name", NULL, 0);
2904         av_dict_set(&oc->metadata, "product_name", NULL, 0);
2905         av_dict_set(&oc->metadata, "product_version", NULL, 0);
2906     }
2907     if (!o->metadata_streams_manual)
2908         for (i = of->ost_index; i < nb_output_streams; i++) {
2909             InputStream *ist;
2910             if (output_streams[i]->source_index < 0)         /* this is true e.g. for attached files */
2911                 continue;
2912             ist = input_streams[output_streams[i]->source_index];
2913             av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
2914             if (!output_streams[i]->stream_copy) {
2915                 av_dict_set(&output_streams[i]->st->metadata, "encoder", NULL, 0);
2916             }
2917         }
2918 
2919     /* process manually set programs */
2920     for (i = 0; i < o->nb_program; i++) {
2921         const char *p = o->program[i].u.str;
2922         int progid = i+1;
2923         AVProgram *program;
2924 
2925         while(*p) {
2926             const char *p2 = av_get_token(&p, ":");
2927             const char *to_dealloc = p2;
2928             char *key;
2929             if (!p2)
2930                 break;
2931 
2932             if(*p) p++;
2933 
2934             key = av_get_token(&p2, "=");
2935             if (!key || !*p2) {
2936                 av_freep(&to_dealloc);
2937                 av_freep(&key);
2938                 break;
2939             }
2940             p2++;
2941 
2942             if (!strcmp(key, "program_num"))
2943                 progid = strtol(p2, NULL, 0);
2944             av_freep(&to_dealloc);
2945             av_freep(&key);
2946         }
2947 
2948         program = av_new_program(oc, progid);
2949 
2950         p = o->program[i].u.str;
2951         while(*p) {
2952             const char *p2 = av_get_token(&p, ":");
2953             const char *to_dealloc = p2;
2954             char *key;
2955             if (!p2)
2956                 break;
2957             if(*p) p++;
2958 
2959             key = av_get_token(&p2, "=");
2960             if (!key) {
2961                 av_log(NULL, AV_LOG_FATAL,
2962                        "No '=' character in program string %s.\n",
2963                        p2);
2964                 exit_program(1);
2965             }
2966             if (!*p2)
2967                 exit_program(1);
2968             p2++;
2969 
2970             if (!strcmp(key, "title")) {
2971                 av_dict_set(&program->metadata, "title", p2, 0);
2972             } else if (!strcmp(key, "program_num")) {
2973             } else if (!strcmp(key, "st")) {
2974                 int st_num = strtol(p2, NULL, 0);
2975                 av_program_add_stream_index(oc, progid, st_num);
2976             } else {
2977                 av_log(NULL, AV_LOG_FATAL, "Unknown program key %s.\n", key);
2978                 exit_program(1);
2979             }
2980             av_freep(&to_dealloc);
2981             av_freep(&key);
2982         }
2983     }
2984 
2985     /* process manually set metadata */
2986     for (i = 0; i < o->nb_metadata; i++) {
2987         AVDictionary **m;
2988         char type, *val;
2989         const char *stream_spec;
2990         int index = 0, j, ret = 0;
2991 
2992         val = strchr(o->metadata[i].u.str, '=');
2993         if (!val) {
2994             av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
2995                    o->metadata[i].u.str);
2996             exit_program(1);
2997         }
2998         *val++ = 0;
2999 
3000         parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
3001         if (type == 's') {
3002             for (j = 0; j < oc->nb_streams; j++) {
3003                 ost = output_streams[nb_output_streams - oc->nb_streams + j];
3004                 if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
3005                     if (!strcmp(o->metadata[i].u.str, "rotate")) {
3006                         char *tail;
3007                         double theta = av_strtod(val, &tail);
3008                         if (!*tail) {
3009                             ost->rotate_overridden = 1;
3010                             ost->rotate_override_value = theta;
3011                         }
3012                     } else {
3013                         av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
3014                     }
3015                 } else if (ret < 0)
3016                     exit_program(1);
3017             }
3018         }
3019         else {
3020             switch (type) {
3021             case 'g':
3022                 m = &oc->metadata;
3023                 break;
3024             case 'c':
3025                 if (index < 0 || index >= oc->nb_chapters) {
3026                     av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
3027                     exit_program(1);
3028                 }
3029                 m = &oc->chapters[index]->metadata;
3030                 break;
3031             case 'p':
3032                 if (index < 0 || index >= oc->nb_programs) {
3033                     av_log(NULL, AV_LOG_FATAL, "Invalid program index %d in metadata specifier.\n", index);
3034                     exit_program(1);
3035                 }
3036                 m = &oc->programs[index]->metadata;
3037                 break;
3038             default:
3039                 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
3040                 exit_program(1);
3041             }
3042             av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
3043         }
3044     }
3045 
3046     err = set_dispositions(of, oc);
3047     if (err < 0) {
3048         av_log(NULL, AV_LOG_FATAL, "Error setting output stream dispositions\n");
3049         exit_program(1);
3050     }
3051 
3052     return 0;
3053 }
3054 
opt_target(void * optctx,const char * opt,const char * arg)3055 static int opt_target(void *optctx, const char *opt, const char *arg)
3056 {
3057     OptionsContext *o = optctx;
3058     enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
3059     static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" };
3060 
3061     if (!strncmp(arg, "pal-", 4)) {
3062         norm = PAL;
3063         arg += 4;
3064     } else if (!strncmp(arg, "ntsc-", 5)) {
3065         norm = NTSC;
3066         arg += 5;
3067     } else if (!strncmp(arg, "film-", 5)) {
3068         norm = FILM;
3069         arg += 5;
3070     } else {
3071         /* Try to determine PAL/NTSC by peeking in the input files */
3072         if (nb_input_files) {
3073             int i, j;
3074             for (j = 0; j < nb_input_files; j++) {
3075                 for (i = 0; i < input_files[j]->nb_streams; i++) {
3076                     AVStream *st = input_files[j]->ctx->streams[i];
3077                     int64_t fr;
3078                     if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
3079                         continue;
3080                     fr = st->time_base.den * 1000LL / st->time_base.num;
3081                     if (fr == 25000) {
3082                         norm = PAL;
3083                         break;
3084                     } else if ((fr == 29970) || (fr == 23976)) {
3085                         norm = NTSC;
3086                         break;
3087                     }
3088                 }
3089                 if (norm != UNKNOWN)
3090                     break;
3091             }
3092         }
3093         if (norm != UNKNOWN)
3094             av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
3095     }
3096 
3097     if (norm == UNKNOWN) {
3098         av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
3099         av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
3100         av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
3101         exit_program(1);
3102     }
3103 
3104     if (!strcmp(arg, "vcd")) {
3105         opt_video_codec(o, "c:v", "mpeg1video");
3106         opt_audio_codec(o, "c:a", "mp2");
3107         parse_option(o, "f", "vcd", options);
3108 
3109         parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
3110         parse_option(o, "r", frame_rates[norm], options);
3111         opt_default(NULL, "g", norm == PAL ? "15" : "18");
3112 
3113         opt_default(NULL, "b:v", "1150000");
3114         opt_default(NULL, "maxrate:v", "1150000");
3115         opt_default(NULL, "minrate:v", "1150000");
3116         opt_default(NULL, "bufsize:v", "327680"); // 40*1024*8;
3117 
3118         opt_default(NULL, "b:a", "224000");
3119         parse_option(o, "ar", "44100", options);
3120         parse_option(o, "ac", "2", options);
3121 
3122         opt_default(NULL, "packetsize", "2324");
3123         opt_default(NULL, "muxrate", "1411200"); // 2352 * 75 * 8;
3124 
3125         /* We have to offset the PTS, so that it is consistent with the SCR.
3126            SCR starts at 36000, but the first two packs contain only padding
3127            and the first pack from the other stream, respectively, may also have
3128            been written before.
3129            So the real data starts at SCR 36000+3*1200. */
3130         o->mux_preload = (36000 + 3 * 1200) / 90000.0; // 0.44
3131     } else if (!strcmp(arg, "svcd")) {
3132 
3133         opt_video_codec(o, "c:v", "mpeg2video");
3134         opt_audio_codec(o, "c:a", "mp2");
3135         parse_option(o, "f", "svcd", options);
3136 
3137         parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
3138         parse_option(o, "r", frame_rates[norm], options);
3139         parse_option(o, "pix_fmt", "yuv420p", options);
3140         opt_default(NULL, "g", norm == PAL ? "15" : "18");
3141 
3142         opt_default(NULL, "b:v", "2040000");
3143         opt_default(NULL, "maxrate:v", "2516000");
3144         opt_default(NULL, "minrate:v", "0"); // 1145000;
3145         opt_default(NULL, "bufsize:v", "1835008"); // 224*1024*8;
3146         opt_default(NULL, "scan_offset", "1");
3147 
3148         opt_default(NULL, "b:a", "224000");
3149         parse_option(o, "ar", "44100", options);
3150 
3151         opt_default(NULL, "packetsize", "2324");
3152 
3153     } else if (!strcmp(arg, "dvd")) {
3154 
3155         opt_video_codec(o, "c:v", "mpeg2video");
3156         opt_audio_codec(o, "c:a", "ac3");
3157         parse_option(o, "f", "dvd", options);
3158 
3159         parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
3160         parse_option(o, "r", frame_rates[norm], options);
3161         parse_option(o, "pix_fmt", "yuv420p", options);
3162         opt_default(NULL, "g", norm == PAL ? "15" : "18");
3163 
3164         opt_default(NULL, "b:v", "6000000");
3165         opt_default(NULL, "maxrate:v", "9000000");
3166         opt_default(NULL, "minrate:v", "0"); // 1500000;
3167         opt_default(NULL, "bufsize:v", "1835008"); // 224*1024*8;
3168 
3169         opt_default(NULL, "packetsize", "2048");  // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
3170         opt_default(NULL, "muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
3171 
3172         opt_default(NULL, "b:a", "448000");
3173         parse_option(o, "ar", "48000", options);
3174 
3175     } else if (!strncmp(arg, "dv", 2)) {
3176 
3177         parse_option(o, "f", "dv", options);
3178 
3179         parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
3180         parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
3181                           norm == PAL ? "yuv420p" : "yuv411p", options);
3182         parse_option(o, "r", frame_rates[norm], options);
3183 
3184         parse_option(o, "ar", "48000", options);
3185         parse_option(o, "ac", "2", options);
3186 
3187     } else {
3188         av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg);
3189         return AVERROR(EINVAL);
3190     }
3191 
3192     av_dict_copy(&o->g->codec_opts,  codec_opts, AV_DICT_DONT_OVERWRITE);
3193     av_dict_copy(&o->g->format_opts, format_opts, AV_DICT_DONT_OVERWRITE);
3194 
3195     return 0;
3196 }
3197 
opt_vstats_file(void * optctx,const char * opt,const char * arg)3198 static int opt_vstats_file(void *optctx, const char *opt, const char *arg)
3199 {
3200     av_free (vstats_filename);
3201     vstats_filename = av_strdup (arg);
3202     return 0;
3203 }
3204 
opt_vstats(void * optctx,const char * opt,const char * arg)3205 static int opt_vstats(void *optctx, const char *opt, const char *arg)
3206 {
3207     char filename[40];
3208     time_t today2 = time(NULL);
3209     struct tm *today = localtime(&today2);
3210 
3211     if (!today) { // maybe tomorrow
3212         av_log(NULL, AV_LOG_FATAL, "Unable to get current time: %s\n", strerror(errno));
3213         exit_program(1);
3214     }
3215 
3216     snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
3217              today->tm_sec);
3218     return opt_vstats_file(NULL, opt, filename);
3219 }
3220 
opt_video_frames(void * optctx,const char * opt,const char * arg)3221 static int opt_video_frames(void *optctx, const char *opt, const char *arg)
3222 {
3223     OptionsContext *o = optctx;
3224     return parse_option(o, "frames:v", arg, options);
3225 }
3226 
opt_audio_frames(void * optctx,const char * opt,const char * arg)3227 static int opt_audio_frames(void *optctx, const char *opt, const char *arg)
3228 {
3229     OptionsContext *o = optctx;
3230     return parse_option(o, "frames:a", arg, options);
3231 }
3232 
opt_data_frames(void * optctx,const char * opt,const char * arg)3233 static int opt_data_frames(void *optctx, const char *opt, const char *arg)
3234 {
3235     OptionsContext *o = optctx;
3236     return parse_option(o, "frames:d", arg, options);
3237 }
3238 
opt_default_new(OptionsContext * o,const char * opt,const char * arg)3239 static int opt_default_new(OptionsContext *o, const char *opt, const char *arg)
3240 {
3241     int ret;
3242     AVDictionary *cbak = codec_opts;
3243     AVDictionary *fbak = format_opts;
3244     codec_opts = NULL;
3245     format_opts = NULL;
3246 
3247     ret = opt_default(NULL, opt, arg);
3248 
3249     av_dict_copy(&o->g->codec_opts , codec_opts, 0);
3250     av_dict_copy(&o->g->format_opts, format_opts, 0);
3251     av_dict_free(&codec_opts);
3252     av_dict_free(&format_opts);
3253     codec_opts = cbak;
3254     format_opts = fbak;
3255 
3256     return ret;
3257 }
3258 
opt_preset(void * optctx,const char * opt,const char * arg)3259 static int opt_preset(void *optctx, const char *opt, const char *arg)
3260 {
3261     OptionsContext *o = optctx;
3262     FILE *f=NULL;
3263     char filename[1000], line[1000], tmp_line[1000];
3264     const char *codec_name = NULL;
3265 
3266     tmp_line[0] = *opt;
3267     tmp_line[1] = 0;
3268     MATCH_PER_TYPE_OPT(codec_names, str, codec_name, NULL, tmp_line);
3269 
3270     if (!(f = get_preset_file(filename, sizeof(filename), arg, *opt == 'f', codec_name))) {
3271         if(!strncmp(arg, "libx264-lossless", strlen("libx264-lossless"))){
3272             av_log(NULL, AV_LOG_FATAL, "Please use -preset <speed> -qp 0\n");
3273         }else
3274             av_log(NULL, AV_LOG_FATAL, "File for preset '%s' not found\n", arg);
3275         exit_program(1);
3276     }
3277 
3278     while (fgets(line, sizeof(line), f)) {
3279         char *key = tmp_line, *value, *endptr;
3280 
3281         if (strcspn(line, "#\n\r") == 0)
3282             continue;
3283         av_strlcpy(tmp_line, line, sizeof(tmp_line));
3284         if (!av_strtok(key,   "=",    &value) ||
3285             !av_strtok(value, "\r\n", &endptr)) {
3286             av_log(NULL, AV_LOG_FATAL, "%s: Invalid syntax: '%s'\n", filename, line);
3287             exit_program(1);
3288         }
3289         av_log(NULL, AV_LOG_DEBUG, "ffpreset[%s]: set '%s' = '%s'\n", filename, key, value);
3290 
3291         if      (!strcmp(key, "acodec")) opt_audio_codec   (o, key, value);
3292         else if (!strcmp(key, "vcodec")) opt_video_codec   (o, key, value);
3293         else if (!strcmp(key, "scodec")) opt_subtitle_codec(o, key, value);
3294         else if (!strcmp(key, "dcodec")) opt_data_codec    (o, key, value);
3295         else if (opt_default_new(o, key, value) < 0) {
3296             av_log(NULL, AV_LOG_FATAL, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n",
3297                    filename, line, key, value);
3298             exit_program(1);
3299         }
3300     }
3301 
3302     fclose(f);
3303 
3304     return 0;
3305 }
3306 
opt_old2new(void * optctx,const char * opt,const char * arg)3307 static int opt_old2new(void *optctx, const char *opt, const char *arg)
3308 {
3309     OptionsContext *o = optctx;
3310     int ret;
3311     char *s = av_asprintf("%s:%c", opt + 1, *opt);
3312     if (!s)
3313         return AVERROR(ENOMEM);
3314     ret = parse_option(o, s, arg, options);
3315     av_free(s);
3316     return ret;
3317 }
3318 
opt_bitrate(void * optctx,const char * opt,const char * arg)3319 static int opt_bitrate(void *optctx, const char *opt, const char *arg)
3320 {
3321     OptionsContext *o = optctx;
3322 
3323     if(!strcmp(opt, "ab")){
3324         av_dict_set(&o->g->codec_opts, "b:a", arg, 0);
3325         return 0;
3326     } else if(!strcmp(opt, "b")){
3327         av_log(NULL, AV_LOG_WARNING, "Please use -b:a or -b:v, -b is ambiguous\n");
3328         av_dict_set(&o->g->codec_opts, "b:v", arg, 0);
3329         return 0;
3330     }
3331     av_dict_set(&o->g->codec_opts, opt, arg, 0);
3332     return 0;
3333 }
3334 
opt_qscale(void * optctx,const char * opt,const char * arg)3335 static int opt_qscale(void *optctx, const char *opt, const char *arg)
3336 {
3337     OptionsContext *o = optctx;
3338     char *s;
3339     int ret;
3340     if(!strcmp(opt, "qscale")){
3341         av_log(NULL, AV_LOG_WARNING, "Please use -q:a or -q:v, -qscale is ambiguous\n");
3342         return parse_option(o, "q:v", arg, options);
3343     }
3344     s = av_asprintf("q%s", opt + 6);
3345     if (!s)
3346         return AVERROR(ENOMEM);
3347     ret = parse_option(o, s, arg, options);
3348     av_free(s);
3349     return ret;
3350 }
3351 
opt_profile(void * optctx,const char * opt,const char * arg)3352 static int opt_profile(void *optctx, const char *opt, const char *arg)
3353 {
3354     OptionsContext *o = optctx;
3355     if(!strcmp(opt, "profile")){
3356         av_log(NULL, AV_LOG_WARNING, "Please use -profile:a or -profile:v, -profile is ambiguous\n");
3357         av_dict_set(&o->g->codec_opts, "profile:v", arg, 0);
3358         return 0;
3359     }
3360     av_dict_set(&o->g->codec_opts, opt, arg, 0);
3361     return 0;
3362 }
3363 
opt_video_filters(void * optctx,const char * opt,const char * arg)3364 static int opt_video_filters(void *optctx, const char *opt, const char *arg)
3365 {
3366     OptionsContext *o = optctx;
3367     return parse_option(o, "filter:v", arg, options);
3368 }
3369 
opt_audio_filters(void * optctx,const char * opt,const char * arg)3370 static int opt_audio_filters(void *optctx, const char *opt, const char *arg)
3371 {
3372     OptionsContext *o = optctx;
3373     return parse_option(o, "filter:a", arg, options);
3374 }
3375 
opt_vsync(void * optctx,const char * opt,const char * arg)3376 static int opt_vsync(void *optctx, const char *opt, const char *arg)
3377 {
3378     av_log(NULL, AV_LOG_WARNING, "-vsync is deprecated. Use -fps_mode\n");
3379     parse_and_set_vsync(arg, &video_sync_method, -1, -1, 1);
3380     return 0;
3381 }
3382 
opt_timecode(void * optctx,const char * opt,const char * arg)3383 static int opt_timecode(void *optctx, const char *opt, const char *arg)
3384 {
3385     OptionsContext *o = optctx;
3386     int ret;
3387     char *tcr = av_asprintf("timecode=%s", arg);
3388     if (!tcr)
3389         return AVERROR(ENOMEM);
3390     ret = parse_option(o, "metadata:g", tcr, options);
3391     if (ret >= 0)
3392         ret = av_dict_set(&o->g->codec_opts, "gop_timecode", arg, 0);
3393     av_free(tcr);
3394     return ret;
3395 }
3396 
opt_audio_qscale(void * optctx,const char * opt,const char * arg)3397 static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
3398 {
3399     OptionsContext *o = optctx;
3400     return parse_option(o, "q:a", arg, options);
3401 }
3402 
opt_filter_complex(void * optctx,const char * opt,const char * arg)3403 static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
3404 {
3405     FilterGraph *fg = ALLOC_ARRAY_ELEM(filtergraphs, nb_filtergraphs);
3406 
3407     fg->index      = nb_filtergraphs - 1;
3408     fg->graph_desc = av_strdup(arg);
3409     if (!fg->graph_desc)
3410         return AVERROR(ENOMEM);
3411 
3412     input_stream_potentially_available = 1;
3413 
3414     return 0;
3415 }
3416 
opt_filter_complex_script(void * optctx,const char * opt,const char * arg)3417 static int opt_filter_complex_script(void *optctx, const char *opt, const char *arg)
3418 {
3419     FilterGraph *fg;
3420     char *graph_desc = read_file(arg);
3421     if (!graph_desc)
3422         return AVERROR(EINVAL);
3423 
3424     fg = ALLOC_ARRAY_ELEM(filtergraphs, nb_filtergraphs);
3425     fg->index      = nb_filtergraphs - 1;
3426     fg->graph_desc = graph_desc;
3427 
3428     input_stream_potentially_available = 1;
3429 
3430     return 0;
3431 }
3432 
show_help_default(const char * opt,const char * arg)3433 void show_help_default(const char *opt, const char *arg)
3434 {
3435     /* per-file options have at least one of those set */
3436     const int per_file = OPT_SPEC | OPT_OFFSET | OPT_PERFILE;
3437     int show_advanced = 0, show_avoptions = 0;
3438 
3439     if (opt && *opt) {
3440         if (!strcmp(opt, "long"))
3441             show_advanced = 1;
3442         else if (!strcmp(opt, "full"))
3443             show_advanced = show_avoptions = 1;
3444         else
3445             av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);
3446     }
3447 
3448     show_usage();
3449 
3450     printf("Getting help:\n"
3451            "    -h      -- print basic options\n"
3452            "    -h long -- print more options\n"
3453            "    -h full -- print all options (including all format and codec specific options, very long)\n"
3454            "    -h type=name -- print all options for the named decoder/encoder/demuxer/muxer/filter/bsf/protocol\n"
3455            "    See man %s for detailed description of the options.\n"
3456            "\n", program_name);
3457 
3458     show_help_options(options, "Print help / information / capabilities:",
3459                       OPT_EXIT, 0, 0);
3460 
3461     show_help_options(options, "Global options (affect whole program "
3462                       "instead of just one file):",
3463                       0, per_file | OPT_EXIT | OPT_EXPERT, 0);
3464     if (show_advanced)
3465         show_help_options(options, "Advanced global options:", OPT_EXPERT,
3466                           per_file | OPT_EXIT, 0);
3467 
3468     show_help_options(options, "Per-file main options:", 0,
3469                       OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE |
3470                       OPT_EXIT, per_file);
3471     if (show_advanced)
3472         show_help_options(options, "Advanced per-file options:",
3473                           OPT_EXPERT, OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE, per_file);
3474 
3475     show_help_options(options, "Video options:",
3476                       OPT_VIDEO, OPT_EXPERT | OPT_AUDIO, 0);
3477     if (show_advanced)
3478         show_help_options(options, "Advanced Video options:",
3479                           OPT_EXPERT | OPT_VIDEO, OPT_AUDIO, 0);
3480 
3481     show_help_options(options, "Audio options:",
3482                       OPT_AUDIO, OPT_EXPERT | OPT_VIDEO, 0);
3483     if (show_advanced)
3484         show_help_options(options, "Advanced Audio options:",
3485                           OPT_EXPERT | OPT_AUDIO, OPT_VIDEO, 0);
3486     show_help_options(options, "Subtitle options:",
3487                       OPT_SUBTITLE, 0, 0);
3488     printf("\n");
3489 
3490     if (show_avoptions) {
3491         int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
3492         show_help_children(avcodec_get_class(), flags);
3493         show_help_children(avformat_get_class(), flags);
3494 #if CONFIG_SWSCALE
3495         show_help_children(sws_get_class(), flags);
3496 #endif
3497 #if CONFIG_SWRESAMPLE
3498         show_help_children(swr_get_class(), AV_OPT_FLAG_AUDIO_PARAM);
3499 #endif
3500         show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM);
3501         show_help_children(av_bsf_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_BSF_PARAM);
3502     }
3503 }
3504 
show_usage(void)3505 void show_usage(void)
3506 {
3507     av_log(NULL, AV_LOG_INFO, "Hyper fast Audio and Video encoder\n");
3508     av_log(NULL, AV_LOG_INFO, "usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
3509     av_log(NULL, AV_LOG_INFO, "\n");
3510 }
3511 
3512 enum OptGroup {
3513     GROUP_OUTFILE,
3514     GROUP_INFILE,
3515 };
3516 
3517 static const OptionGroupDef groups[] = {
3518     [GROUP_OUTFILE] = { "output url",  NULL, OPT_OUTPUT },
3519     [GROUP_INFILE]  = { "input url",   "i",  OPT_INPUT },
3520 };
3521 
open_files(OptionGroupList * l,const char * inout,int (* open_file)(OptionsContext *,const char *))3522 static int open_files(OptionGroupList *l, const char *inout,
3523                       int (*open_file)(OptionsContext*, const char*))
3524 {
3525     int i, ret;
3526 
3527     for (i = 0; i < l->nb_groups; i++) {
3528         OptionGroup *g = &l->groups[i];
3529         OptionsContext o;
3530 
3531         init_options(&o);
3532         o.g = g;
3533 
3534         ret = parse_optgroup(&o, g);
3535         if (ret < 0) {
3536             av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
3537                    "%s.\n", inout, g->arg);
3538             uninit_options(&o);
3539             return ret;
3540         }
3541 
3542         av_log(NULL, AV_LOG_DEBUG, "Opening an %s file: %s.\n", inout, g->arg);
3543         ret = open_file(&o, g->arg);
3544         uninit_options(&o);
3545         if (ret < 0) {
3546             av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n",
3547                    inout, g->arg);
3548             return ret;
3549         }
3550         av_log(NULL, AV_LOG_DEBUG, "Successfully opened the file.\n");
3551     }
3552 
3553     return 0;
3554 }
3555 
ffmpeg_parse_options(int argc,char ** argv)3556 int ffmpeg_parse_options(int argc, char **argv)
3557 {
3558     OptionParseContext octx;
3559     uint8_t error[128];
3560     int ret;
3561 
3562     memset(&octx, 0, sizeof(octx));
3563 
3564     /* split the commandline into an internal representation */
3565     ret = split_commandline(&octx, argc, argv, options, groups,
3566                             FF_ARRAY_ELEMS(groups));
3567     if (ret < 0) {
3568         av_log(NULL, AV_LOG_FATAL, "Error splitting the argument list: ");
3569         goto fail;
3570     }
3571 
3572     /* apply global options */
3573     ret = parse_optgroup(NULL, &octx.global_opts);
3574     if (ret < 0) {
3575         av_log(NULL, AV_LOG_FATAL, "Error parsing global options: ");
3576         goto fail;
3577     }
3578 
3579     /* configure terminal and setup signal handlers */
3580     term_init();
3581 
3582     /* open input files */
3583     ret = open_files(&octx.groups[GROUP_INFILE], "input", open_input_file);
3584     if (ret < 0) {
3585         av_log(NULL, AV_LOG_FATAL, "Error opening input files: ");
3586         goto fail;
3587     }
3588 
3589     apply_sync_offsets();
3590 
3591     /* create the complex filtergraphs */
3592     ret = init_complex_filters();
3593     if (ret < 0) {
3594         av_log(NULL, AV_LOG_FATAL, "Error initializing complex filters.\n");
3595         goto fail;
3596     }
3597 
3598     /* open output files */
3599     ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);
3600     if (ret < 0) {
3601         av_log(NULL, AV_LOG_FATAL, "Error opening output files: ");
3602         goto fail;
3603     }
3604 
3605     check_filter_outputs();
3606 
3607 fail:
3608     uninit_parse_context(&octx);
3609     if (ret < 0) {
3610         av_strerror(ret, error, sizeof(error));
3611         av_log(NULL, AV_LOG_FATAL, "%s\n", error);
3612     }
3613     return ret;
3614 }
3615 
opt_progress(void * optctx,const char * opt,const char * arg)3616 static int opt_progress(void *optctx, const char *opt, const char *arg)
3617 {
3618     AVIOContext *avio = NULL;
3619     int ret;
3620 
3621     if (!strcmp(arg, "-"))
3622         arg = "pipe:";
3623     ret = avio_open2(&avio, arg, AVIO_FLAG_WRITE, &int_cb, NULL);
3624     if (ret < 0) {
3625         av_log(NULL, AV_LOG_ERROR, "Failed to open progress URL \"%s\": %s\n",
3626                arg, av_err2str(ret));
3627         return ret;
3628     }
3629     progress_avio = avio;
3630     return 0;
3631 }
3632 
opt_timelimit(void * optctx,const char * opt,const char * arg)3633 int opt_timelimit(void *optctx, const char *opt, const char *arg)
3634 {
3635 #if HAVE_SETRLIMIT
3636     int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
3637     struct rlimit rl = { lim, lim + 1 };
3638     if (setrlimit(RLIMIT_CPU, &rl))
3639         perror("setrlimit");
3640 #else
3641     av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
3642 #endif
3643     return 0;
3644 }
3645 
3646 #define OFFSET(x) offsetof(OptionsContext, x)
3647 const OptionDef options[] = {
3648     /* main options */
3649     CMDUTILS_COMMON_OPTIONS
3650     { "f",              HAS_ARG | OPT_STRING | OPT_OFFSET |
3651                         OPT_INPUT | OPT_OUTPUT,                      { .off       = OFFSET(format) },
3652         "force format", "fmt" },
3653     { "y",              OPT_BOOL,                                    {              &file_overwrite },
3654         "overwrite output files" },
3655     { "n",              OPT_BOOL,                                    {              &no_file_overwrite },
3656         "never overwrite output files" },
3657     { "ignore_unknown", OPT_BOOL,                                    {              &ignore_unknown_streams },
3658         "Ignore unknown stream types" },
3659     { "copy_unknown",   OPT_BOOL | OPT_EXPERT,                       {              &copy_unknown_streams },
3660         "Copy unknown stream types" },
3661     { "recast_media",   OPT_BOOL | OPT_EXPERT,                       {              &recast_media },
3662         "allow recasting stream type in order to force a decoder of different media type" },
3663     { "c",              HAS_ARG | OPT_STRING | OPT_SPEC |
3664                         OPT_INPUT | OPT_OUTPUT,                      { .off       = OFFSET(codec_names) },
3665         "codec name", "codec" },
3666     { "codec",          HAS_ARG | OPT_STRING | OPT_SPEC |
3667                         OPT_INPUT | OPT_OUTPUT,                      { .off       = OFFSET(codec_names) },
3668         "codec name", "codec" },
3669     { "pre",            HAS_ARG | OPT_STRING | OPT_SPEC |
3670                         OPT_OUTPUT,                                  { .off       = OFFSET(presets) },
3671         "preset name", "preset" },
3672     { "map",            HAS_ARG | OPT_EXPERT | OPT_PERFILE |
3673                         OPT_OUTPUT,                                  { .func_arg = opt_map },
3674         "set input stream mapping",
3675         "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },
3676     { "map_channel",    HAS_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_map_channel },
3677         "map an audio channel from one stream to another", "file.stream.channel[:syncfile.syncstream]" },
3678     { "map_metadata",   HAS_ARG | OPT_STRING | OPT_SPEC |
3679                         OPT_OUTPUT,                                  { .off       = OFFSET(metadata_map) },
3680         "set metadata information of outfile from infile",
3681         "outfile[,metadata]:infile[,metadata]" },
3682     { "map_chapters",   HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET |
3683                         OPT_OUTPUT,                                  { .off = OFFSET(chapters_input_file) },
3684         "set chapters mapping", "input_file_index" },
3685     { "t",              HAS_ARG | OPT_TIME | OPT_OFFSET |
3686                         OPT_INPUT | OPT_OUTPUT,                      { .off = OFFSET(recording_time) },
3687         "record or transcode \"duration\" seconds of audio/video",
3688         "duration" },
3689     { "to",             HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT,  { .off = OFFSET(stop_time) },
3690         "record or transcode stop time", "time_stop" },
3691     { "fs",             HAS_ARG | OPT_INT64 | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(limit_filesize) },
3692         "set the limit file size in bytes", "limit_size" },
3693     { "ss",             HAS_ARG | OPT_TIME | OPT_OFFSET |
3694                         OPT_INPUT | OPT_OUTPUT,                      { .off = OFFSET(start_time) },
3695         "set the start time offset", "time_off" },
3696     { "sseof",          HAS_ARG | OPT_TIME | OPT_OFFSET |
3697                         OPT_INPUT,                                   { .off = OFFSET(start_time_eof) },
3698         "set the start time offset relative to EOF", "time_off" },
3699     { "seek_timestamp", HAS_ARG | OPT_INT | OPT_OFFSET |
3700                         OPT_INPUT,                                   { .off = OFFSET(seek_timestamp) },
3701         "enable/disable seeking by timestamp with -ss" },
3702     { "accurate_seek",  OPT_BOOL | OPT_OFFSET | OPT_EXPERT |
3703                         OPT_INPUT,                                   { .off = OFFSET(accurate_seek) },
3704         "enable/disable accurate seeking with -ss" },
3705     { "isync",          HAS_ARG | OPT_INT | OPT_OFFSET |
3706                         OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(input_sync_ref) },
3707         "Indicate the input index for sync reference", "sync ref" },
3708     { "itsoffset",      HAS_ARG | OPT_TIME | OPT_OFFSET |
3709                         OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(input_ts_offset) },
3710         "set the input ts offset", "time_off" },
3711     { "itsscale",       HAS_ARG | OPT_DOUBLE | OPT_SPEC |
3712                         OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(ts_scale) },
3713         "set the input ts scale", "scale" },
3714     { "timestamp",      HAS_ARG | OPT_PERFILE | OPT_OUTPUT,          { .func_arg = opt_recording_timestamp },
3715         "set the recording timestamp ('now' to set the current time)", "time" },
3716     { "metadata",       HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(metadata) },
3717         "add metadata", "string=string" },
3718     { "program",        HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(program) },
3719         "add program with specified streams", "title=string:st=number..." },
3720     { "dframes",        HAS_ARG | OPT_PERFILE | OPT_EXPERT |
3721                         OPT_OUTPUT,                                  { .func_arg = opt_data_frames },
3722         "set the number of data frames to output", "number" },
3723     { "benchmark",      OPT_BOOL | OPT_EXPERT,                       { &do_benchmark },
3724         "add timings for benchmarking" },
3725     { "benchmark_all",  OPT_BOOL | OPT_EXPERT,                       { &do_benchmark_all },
3726       "add timings for each task" },
3727     { "progress",       HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_progress },
3728       "write program-readable progress information", "url" },
3729     { "stdin",          OPT_BOOL | OPT_EXPERT,                       { &stdin_interaction },
3730       "enable or disable interaction on standard input" },
3731     { "timelimit",      HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_timelimit },
3732         "set max runtime in seconds in CPU user time", "limit" },
3733     { "dump",           OPT_BOOL | OPT_EXPERT,                       { &do_pkt_dump },
3734         "dump each input packet" },
3735     { "hex",            OPT_BOOL | OPT_EXPERT,                       { &do_hex_dump },
3736         "when dumping packets, also dump the payload" },
3737     { "re",             OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
3738                         OPT_INPUT,                                   { .off = OFFSET(rate_emu) },
3739         "read input at native frame rate; equivalent to -readrate 1", "" },
3740     { "readrate",       HAS_ARG | OPT_FLOAT | OPT_OFFSET |
3741                         OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(readrate) },
3742         "read input at specified rate", "speed" },
3743     { "target",         HAS_ARG | OPT_PERFILE | OPT_OUTPUT,          { .func_arg = opt_target },
3744         "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\" or \"dv50\" "
3745         "with optional prefixes \"pal-\", \"ntsc-\" or \"film-\")", "type" },
3746     { "vsync",          HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_vsync },
3747         "set video sync method globally; deprecated, use -fps_mode", "" },
3748     { "frame_drop_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,      { &frame_drop_threshold },
3749         "frame drop threshold", "" },
3750     { "async",          HAS_ARG | OPT_INT | OPT_EXPERT,              { &audio_sync_method },
3751         "audio sync method", "" },
3752     { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,          { &audio_drift_threshold },
3753         "audio drift threshold", "threshold" },
3754     { "copyts",         OPT_BOOL | OPT_EXPERT,                       { &copy_ts },
3755         "copy timestamps" },
3756     { "start_at_zero",  OPT_BOOL | OPT_EXPERT,                       { &start_at_zero },
3757         "shift input timestamps to start at 0 when using copyts" },
3758     { "copytb",         HAS_ARG | OPT_INT | OPT_EXPERT,              { &copy_tb },
3759         "copy input stream time base when stream copying", "mode" },
3760     { "shortest",       OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
3761                         OPT_OUTPUT,                                  { .off = OFFSET(shortest) },
3762         "finish encoding within shortest input" },
3763     { "bitexact",       OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
3764                         OPT_OUTPUT | OPT_INPUT,                      { .off = OFFSET(bitexact) },
3765         "bitexact mode" },
3766     { "apad",           OPT_STRING | HAS_ARG | OPT_SPEC |
3767                         OPT_OUTPUT,                                  { .off = OFFSET(apad) },
3768         "audio pad", "" },
3769     { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_delta_threshold },
3770         "timestamp discontinuity delta threshold", "threshold" },
3771     { "dts_error_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_error_threshold },
3772         "timestamp error delta threshold", "threshold" },
3773     { "xerror",         OPT_BOOL | OPT_EXPERT,                       { &exit_on_error },
3774         "exit on error", "error" },
3775     { "abort_on",       HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_abort_on },
3776         "abort on the specified condition flags", "flags" },
3777     { "copyinkf",       OPT_BOOL | OPT_EXPERT | OPT_SPEC |
3778                         OPT_OUTPUT,                                  { .off = OFFSET(copy_initial_nonkeyframes) },
3779         "copy initial non-keyframes" },
3780     { "copypriorss",    OPT_INT | HAS_ARG | OPT_EXPERT | OPT_SPEC | OPT_OUTPUT,   { .off = OFFSET(copy_prior_start) },
3781         "copy or discard frames before start time" },
3782     { "frames",         OPT_INT64 | HAS_ARG | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(max_frames) },
3783         "set the number of frames to output", "number" },
3784     { "tag",            OPT_STRING | HAS_ARG | OPT_SPEC |
3785                         OPT_EXPERT | OPT_OUTPUT | OPT_INPUT,         { .off = OFFSET(codec_tags) },
3786         "force codec tag/fourcc", "fourcc/tag" },
3787     { "q",              HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
3788                         OPT_SPEC | OPT_OUTPUT,                       { .off = OFFSET(qscale) },
3789         "use fixed quality scale (VBR)", "q" },
3790     { "qscale",         HAS_ARG | OPT_EXPERT | OPT_PERFILE |
3791                         OPT_OUTPUT,                                  { .func_arg = opt_qscale },
3792         "use fixed quality scale (VBR)", "q" },
3793     { "profile",        HAS_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_profile },
3794         "set profile", "profile" },
3795     { "filter",         HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filters) },
3796         "set stream filtergraph", "filter_graph" },
3797     { "filter_threads", HAS_ARG,                                     { .func_arg = opt_filter_threads },
3798         "number of non-complex filter threads" },
3799     { "filter_script",  HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filter_scripts) },
3800         "read stream filtergraph description from a file", "filename" },
3801     { "reinit_filter",  HAS_ARG | OPT_INT | OPT_SPEC | OPT_INPUT,    { .off = OFFSET(reinit_filters) },
3802         "reinit filtergraph on input parameter changes", "" },
3803     { "filter_complex", HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_filter_complex },
3804         "create a complex filtergraph", "graph_description" },
3805     { "filter_complex_threads", HAS_ARG | OPT_INT,                   { &filter_complex_nbthreads },
3806         "number of threads for -filter_complex" },
3807     { "lavfi",          HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_filter_complex },
3808         "create a complex filtergraph", "graph_description" },
3809     { "filter_complex_script", HAS_ARG | OPT_EXPERT,                 { .func_arg = opt_filter_complex_script },
3810         "read complex filtergraph description from a file", "filename" },
3811     { "auto_conversion_filters", OPT_BOOL | OPT_EXPERT,              { &auto_conversion_filters },
3812         "enable automatic conversion filters globally" },
3813     { "stats",          OPT_BOOL,                                    { &print_stats },
3814         "print progress report during encoding", },
3815     { "stats_period",    HAS_ARG | OPT_EXPERT,                       { .func_arg = opt_stats_period },
3816         "set the period at which ffmpeg updates stats and -progress output", "time" },
3817     { "attach",         HAS_ARG | OPT_PERFILE | OPT_EXPERT |
3818                         OPT_OUTPUT,                                  { .func_arg = opt_attach },
3819         "add an attachment to the output file", "filename" },
3820     { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC |
3821                          OPT_EXPERT | OPT_INPUT,                     { .off = OFFSET(dump_attachment) },
3822         "extract an attachment into a file", "filename" },
3823     { "stream_loop", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_INPUT |
3824                         OPT_OFFSET,                                  { .off = OFFSET(loop) }, "set number of times input stream shall be looped", "loop count" },
3825     { "debug_ts",       OPT_BOOL | OPT_EXPERT,                       { &debug_ts },
3826         "print timestamp debugging info" },
3827     { "max_error_rate",  HAS_ARG | OPT_FLOAT,                        { &max_error_rate },
3828         "ratio of decoding errors (0.0: no errors, 1.0: 100% errors) above which ffmpeg returns an error instead of success.", "maximum error rate" },
3829     { "discard",        OPT_STRING | HAS_ARG | OPT_SPEC |
3830                         OPT_INPUT,                                   { .off = OFFSET(discard) },
3831         "discard", "" },
3832     { "disposition",    OPT_STRING | HAS_ARG | OPT_SPEC |
3833                         OPT_OUTPUT,                                  { .off = OFFSET(disposition) },
3834         "disposition", "" },
3835     { "thread_queue_size", HAS_ARG | OPT_INT | OPT_OFFSET | OPT_EXPERT | OPT_INPUT,
3836                                                                      { .off = OFFSET(thread_queue_size) },
3837         "set the maximum number of queued packets from the demuxer" },
3838     { "find_stream_info", OPT_BOOL | OPT_PERFILE | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
3839         "read and decode the streams to fill missing information with heuristics" },
3840     { "bits_per_raw_sample", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_SPEC | OPT_OUTPUT,
3841         { .off = OFFSET(bits_per_raw_sample) },
3842         "set the number of bits per raw sample", "number" },
3843 
3844     /* video options */
3845     { "vframes",      OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_video_frames },
3846         "set the number of video frames to output", "number" },
3847     { "r",            OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC |
3848                       OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(frame_rates) },
3849         "set frame rate (Hz value, fraction or abbreviation)", "rate" },
3850     { "fpsmax",       OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC |
3851                       OPT_OUTPUT,                                                { .off = OFFSET(max_frame_rates) },
3852         "set max frame rate (Hz value, fraction or abbreviation)", "rate" },
3853     { "s",            OPT_VIDEO | HAS_ARG | OPT_SUBTITLE | OPT_STRING | OPT_SPEC |
3854                       OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(frame_sizes) },
3855         "set frame size (WxH or abbreviation)", "size" },
3856     { "aspect",       OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC |
3857                       OPT_OUTPUT,                                                { .off = OFFSET(frame_aspect_ratios) },
3858         "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
3859     { "pix_fmt",      OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
3860                       OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(frame_pix_fmts) },
3861         "set pixel format", "format" },
3862     { "vn",           OPT_VIDEO | OPT_BOOL  | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT,{ .off = OFFSET(video_disable) },
3863         "disable video" },
3864     { "rc_override",  OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
3865                       OPT_OUTPUT,                                                { .off = OFFSET(rc_overrides) },
3866         "rate control override for specific intervals", "override" },
3867     { "vcodec",       OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_INPUT |
3868                       OPT_OUTPUT,                                                { .func_arg = opt_video_codec },
3869         "force video codec ('copy' to copy stream)", "codec" },
3870     { "timecode",     OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT,            { .func_arg = opt_timecode },
3871         "set initial TimeCode value.", "hh:mm:ss[:;.]ff" },
3872     { "pass",         OPT_VIDEO | HAS_ARG | OPT_SPEC | OPT_INT | OPT_OUTPUT,     { .off = OFFSET(pass) },
3873         "select the pass number (1 to 3)", "n" },
3874     { "passlogfile",  OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC |
3875                       OPT_OUTPUT,                                                { .off = OFFSET(passlogfiles) },
3876         "select two pass log file name prefix", "prefix" },
3877     { "psnr",         OPT_VIDEO | OPT_BOOL | OPT_EXPERT,                         { &do_psnr },
3878         "calculate PSNR of compressed frames" },
3879     { "vstats",       OPT_VIDEO | OPT_EXPERT ,                                   { .func_arg = opt_vstats },
3880         "dump video coding statistics to file" },
3881     { "vstats_file",  OPT_VIDEO | HAS_ARG | OPT_EXPERT ,                         { .func_arg = opt_vstats_file },
3882         "dump video coding statistics to file", "file" },
3883     { "vstats_version",  OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT ,            { &vstats_version },
3884         "Version of the vstats format to use."},
3885     { "vf",           OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_video_filters },
3886         "set video filters", "filter_graph" },
3887     { "intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
3888                       OPT_OUTPUT,                                                { .off = OFFSET(intra_matrices) },
3889         "specify intra matrix coeffs", "matrix" },
3890     { "inter_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
3891                       OPT_OUTPUT,                                                { .off = OFFSET(inter_matrices) },
3892         "specify inter matrix coeffs", "matrix" },
3893     { "chroma_intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
3894                       OPT_OUTPUT,                                                { .off = OFFSET(chroma_intra_matrices) },
3895         "specify intra matrix coeffs", "matrix" },
3896     { "top",          OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_INT| OPT_SPEC |
3897                       OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(top_field_first) },
3898         "top=1/bottom=0/auto=-1 field first", "" },
3899     { "vtag",         OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_PERFILE |
3900                       OPT_INPUT | OPT_OUTPUT,                                    { .func_arg = opt_old2new },
3901         "force video tag/fourcc", "fourcc/tag" },
3902     { "qphist",       OPT_VIDEO | OPT_BOOL | OPT_EXPERT ,                        { &qp_hist },
3903         "show QP histogram" },
3904     { "fps_mode",     OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT |
3905                       OPT_SPEC | OPT_OUTPUT,                                     { .off = OFFSET(fps_mode) },
3906         "set framerate mode for matching video streams; overrides vsync" },
3907     { "force_fps",    OPT_VIDEO | OPT_BOOL | OPT_EXPERT  | OPT_SPEC |
3908                       OPT_OUTPUT,                                                { .off = OFFSET(force_fps) },
3909         "force the selected framerate, disable the best supported framerate selection" },
3910     { "streamid",     OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
3911                       OPT_OUTPUT,                                                { .func_arg = opt_streamid },
3912         "set the value of an outfile streamid", "streamIndex:value" },
3913     { "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
3914                           OPT_SPEC | OPT_OUTPUT,                                 { .off = OFFSET(forced_key_frames) },
3915         "force key frames at specified timestamps", "timestamps" },
3916     { "ab",           OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT,            { .func_arg = opt_bitrate },
3917         "audio bitrate (please use -b:a)", "bitrate" },
3918     { "b",            OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT,            { .func_arg = opt_bitrate },
3919         "video bitrate (please use -b:v)", "bitrate" },
3920     { "hwaccel",          OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
3921                           OPT_SPEC | OPT_INPUT,                                  { .off = OFFSET(hwaccels) },
3922         "use HW accelerated decoding", "hwaccel name" },
3923     { "hwaccel_device",   OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
3924                           OPT_SPEC | OPT_INPUT,                                  { .off = OFFSET(hwaccel_devices) },
3925         "select a device for HW acceleration", "devicename" },
3926     { "hwaccel_output_format", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
3927                           OPT_SPEC | OPT_INPUT,                                  { .off = OFFSET(hwaccel_output_formats) },
3928         "select output format used with HW accelerated decoding", "format" },
3929     { "hwaccels",         OPT_EXIT,                                              { .func_arg = show_hwaccels },
3930         "show available HW acceleration methods" },
3931     { "autorotate",       HAS_ARG | OPT_BOOL | OPT_SPEC |
3932                           OPT_EXPERT | OPT_INPUT,                                { .off = OFFSET(autorotate) },
3933         "automatically insert correct rotate filters" },
3934     { "autoscale",        HAS_ARG | OPT_BOOL | OPT_SPEC |
3935                           OPT_EXPERT | OPT_OUTPUT,                               { .off = OFFSET(autoscale) },
3936         "automatically insert a scale filter at the end of the filter graph" },
3937 
3938     /* audio options */
3939     { "aframes",        OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_audio_frames },
3940         "set the number of audio frames to output", "number" },
3941     { "aq",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_audio_qscale },
3942         "set audio quality (codec-specific)", "quality", },
3943     { "ar",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC |
3944                         OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(audio_sample_rate) },
3945         "set audio sampling rate (in Hz)", "rate" },
3946     { "ac",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC |
3947                         OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(audio_channels) },
3948         "set number of audio channels", "channels" },
3949     { "an",             OPT_AUDIO | OPT_BOOL | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT,{ .off = OFFSET(audio_disable) },
3950         "disable audio" },
3951     { "acodec",         OPT_AUDIO | HAS_ARG  | OPT_PERFILE |
3952                         OPT_INPUT | OPT_OUTPUT,                                    { .func_arg = opt_audio_codec },
3953         "force audio codec ('copy' to copy stream)", "codec" },
3954     { "atag",           OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE |
3955                         OPT_OUTPUT,                                                { .func_arg = opt_old2new },
3956         "force audio tag/fourcc", "fourcc/tag" },
3957     { "vol",            OPT_AUDIO | HAS_ARG  | OPT_INT,                            { &audio_volume },
3958         "change audio volume (256=normal)" , "volume" },
3959     { "sample_fmt",     OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_SPEC |
3960                         OPT_STRING | OPT_INPUT | OPT_OUTPUT,                       { .off = OFFSET(sample_fmts) },
3961         "set sample format", "format" },
3962     { "channel_layout", OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_SPEC |
3963                         OPT_STRING | OPT_INPUT | OPT_OUTPUT,                       { .off = OFFSET(audio_ch_layouts) },
3964         "set channel layout", "layout" },
3965     { "ch_layout",      OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_SPEC |
3966                         OPT_STRING | OPT_INPUT | OPT_OUTPUT,                       { .off = OFFSET(audio_ch_layouts) },
3967         "set channel layout", "layout" },
3968     { "af",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_audio_filters },
3969         "set audio filters", "filter_graph" },
3970     { "guess_layout_max", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC | OPT_EXPERT | OPT_INPUT, { .off = OFFSET(guess_layout_max) },
3971       "set the maximum number of channels to try to guess the channel layout" },
3972 
3973     /* subtitle options */
3974     { "sn",     OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(subtitle_disable) },
3975         "disable subtitle" },
3976     { "scodec", OPT_SUBTITLE | HAS_ARG  | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_subtitle_codec },
3977         "force subtitle codec ('copy' to copy stream)", "codec" },
3978     { "stag",   OPT_SUBTITLE | HAS_ARG  | OPT_EXPERT  | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_old2new }
3979         , "force subtitle tag/fourcc", "fourcc/tag" },
3980     { "fix_sub_duration", OPT_BOOL | OPT_EXPERT | OPT_SUBTITLE | OPT_SPEC | OPT_INPUT, { .off = OFFSET(fix_sub_duration) },
3981         "fix subtitles duration" },
3982     { "canvas_size", OPT_SUBTITLE | HAS_ARG | OPT_STRING | OPT_SPEC | OPT_INPUT, { .off = OFFSET(canvas_sizes) },
3983         "set canvas size (WxH or abbreviation)", "size" },
3984 
3985     /* muxer options */
3986     { "muxdelay",   OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_max_delay) },
3987         "set the maximum demux-decode delay", "seconds" },
3988     { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_preload) },
3989         "set the initial demux-decode delay", "seconds" },
3990     { "sdp_file", HAS_ARG | OPT_EXPERT | OPT_OUTPUT, { .func_arg = opt_sdp_file },
3991         "specify a file in which to print sdp information", "file" },
3992 
3993     { "time_base", HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(time_bases) },
3994         "set the desired time base hint for output stream (1:24, 1:48000 or 0.04166, 2.0833e-5)", "ratio" },
3995     { "enc_time_base", HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(enc_time_bases) },
3996         "set the desired time base for the encoder (1:24, 1:48000 or 0.04166, 2.0833e-5). "
3997         "two special values are defined - "
3998         "0 = use frame rate (video) or sample rate (audio),"
3999         "-1 = match source time base", "ratio" },
4000 
4001     { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(bitstream_filters) },
4002         "A comma-separated list of bitstream filters", "bitstream_filters" },
4003     { "absf", HAS_ARG | OPT_AUDIO | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_old2new },
4004         "deprecated", "audio bitstream_filters" },
4005     { "vbsf", OPT_VIDEO | HAS_ARG | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_old2new },
4006         "deprecated", "video bitstream_filters" },
4007 
4008     { "apre", HAS_ARG | OPT_AUDIO | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT,    { .func_arg = opt_preset },
4009         "set the audio options to the indicated preset", "preset" },
4010     { "vpre", OPT_VIDEO | HAS_ARG | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT,    { .func_arg = opt_preset },
4011         "set the video options to the indicated preset", "preset" },
4012     { "spre", HAS_ARG | OPT_SUBTITLE | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_preset },
4013         "set the subtitle options to the indicated preset", "preset" },
4014     { "fpre", HAS_ARG | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT,                { .func_arg = opt_preset },
4015         "set options from indicated preset file", "filename" },
4016 
4017     { "max_muxing_queue_size", HAS_ARG | OPT_INT | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(max_muxing_queue_size) },
4018         "maximum number of packets that can be buffered while waiting for all streams to initialize", "packets" },
4019     { "muxing_queue_data_threshold", HAS_ARG | OPT_INT | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(muxing_queue_data_threshold) },
4020         "set the threshold after which max_muxing_queue_size is taken into account", "bytes" },
4021 
4022     /* data codec support */
4023     { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_data_codec },
4024         "force data codec ('copy' to copy stream)", "codec" },
4025     { "dn", OPT_BOOL | OPT_VIDEO | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(data_disable) },
4026         "disable data" },
4027 
4028 #if CONFIG_VAAPI
4029     { "vaapi_device", HAS_ARG | OPT_EXPERT, { .func_arg = opt_vaapi_device },
4030         "set VAAPI hardware device (DRM path or X11 display name)", "device" },
4031 #endif
4032 
4033 #if CONFIG_QSV
4034     { "qsv_device", HAS_ARG | OPT_EXPERT, { .func_arg = opt_qsv_device },
4035         "set QSV hardware device (DirectX adapter index, DRM path or X11 display name)", "device"},
4036 #endif
4037 
4038     { "init_hw_device", HAS_ARG | OPT_EXPERT, { .func_arg = opt_init_hw_device },
4039         "initialise hardware device", "args" },
4040     { "filter_hw_device", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_hw_device },
4041         "set hardware device used when filtering", "device" },
4042 
4043     { NULL, },
4044 };
4045