| Line | Branch | Exec | Source |
|---|---|---|---|
| 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 "ffmpeg_sched.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/mathematics.h" | ||
| 46 | #include "libavutil/mem.h" | ||
| 47 | #include "libavutil/opt.h" | ||
| 48 | #include "libavutil/parseutils.h" | ||
| 49 | #include "libavutil/stereo3d.h" | ||
| 50 | #include "graph/graphprint.h" | ||
| 51 | |||
| 52 | HWDevice *filter_hw_device; | ||
| 53 | |||
| 54 | char *vstats_filename; | ||
| 55 | |||
| 56 | float dts_delta_threshold = 10; | ||
| 57 | float dts_error_threshold = 3600*30; | ||
| 58 | |||
| 59 | #if FFMPEG_OPT_VSYNC | ||
| 60 | enum VideoSyncMethod video_sync_method = VSYNC_AUTO; | ||
| 61 | #endif | ||
| 62 | float frame_drop_threshold = 0; | ||
| 63 | int do_benchmark = 0; | ||
| 64 | int do_benchmark_all = 0; | ||
| 65 | int do_hex_dump = 0; | ||
| 66 | int do_pkt_dump = 0; | ||
| 67 | int copy_ts = 0; | ||
| 68 | int start_at_zero = 0; | ||
| 69 | int copy_tb = -1; | ||
| 70 | int debug_ts = 0; | ||
| 71 | int exit_on_error = 0; | ||
| 72 | int abort_on_flags = 0; | ||
| 73 | int print_stats = -1; | ||
| 74 | int stdin_interaction = 1; | ||
| 75 | float max_error_rate = 2.0/3; | ||
| 76 | char *filter_nbthreads; | ||
| 77 | int filter_complex_nbthreads = 0; | ||
| 78 | int filter_buffered_frames = 0; | ||
| 79 | int vstats_version = 2; | ||
| 80 | int print_graphs = 0; | ||
| 81 | char *print_graphs_file = NULL; | ||
| 82 | char *print_graphs_format = NULL; | ||
| 83 | int auto_conversion_filters = 1; | ||
| 84 | int64_t stats_period = 500000; | ||
| 85 | |||
| 86 | |||
| 87 | static int file_overwrite = 0; | ||
| 88 | static int no_file_overwrite = 0; | ||
| 89 | int ignore_unknown_streams = 0; | ||
| 90 | int copy_unknown_streams = 0; | ||
| 91 | int recast_media = 0; | ||
| 92 | |||
| 93 | // this struct is passed as the optctx argument | ||
| 94 | // to func_arg() for global options | ||
| 95 | typedef struct GlobalOptionsContext { | ||
| 96 | Scheduler *sch; | ||
| 97 | |||
| 98 | char **filtergraphs; | ||
| 99 | int nb_filtergraphs; | ||
| 100 | } GlobalOptionsContext; | ||
| 101 | |||
| 102 | 16097 | static void uninit_options(OptionsContext *o) | |
| 103 | { | ||
| 104 | /* all OPT_SPEC and OPT_TYPE_STRING can be freed in generic way */ | ||
| 105 |
2/2✓ Branch 0 taken 3171109 times.
✓ Branch 1 taken 16097 times.
|
3187206 | for (const OptionDef *po = options; po->name; po++) { |
| 106 | void *dst; | ||
| 107 | |||
| 108 |
2/2✓ Branch 0 taken 1674088 times.
✓ Branch 1 taken 1497021 times.
|
3171109 | if (!(po->flags & OPT_FLAG_OFFSET)) |
| 109 | 1674088 | continue; | |
| 110 | |||
| 111 | 1497021 | dst = (uint8_t*)o + po->u.off; | |
| 112 |
2/2✓ Branch 0 taken 1062402 times.
✓ Branch 1 taken 434619 times.
|
1497021 | if (po->flags & OPT_FLAG_SPEC) { |
| 113 | 1062402 | SpecifierOptList *so = dst; | |
| 114 |
2/2✓ Branch 0 taken 34320 times.
✓ Branch 1 taken 1062402 times.
|
1096722 | for (int i = 0; i < so->nb_opt; i++) { |
| 115 | 34320 | av_freep(&so->opt[i].specifier); | |
| 116 |
2/2✓ Branch 0 taken 34068 times.
✓ Branch 1 taken 252 times.
|
34320 | if (po->flags & OPT_FLAG_PERSTREAM) |
| 117 | 34068 | stream_specifier_uninit(&so->opt[i].stream_spec); | |
| 118 |
2/2✓ Branch 0 taken 28228 times.
✓ Branch 1 taken 6092 times.
|
34320 | if (po->type == OPT_TYPE_STRING) |
| 119 | 28228 | av_freep(&so->opt[i].u.str); | |
| 120 | } | ||
| 121 | 1062402 | av_freep(&so->opt); | |
| 122 | 1062402 | so->nb_opt = 0; | |
| 123 |
2/2✓ Branch 0 taken 16097 times.
✓ Branch 1 taken 418522 times.
|
434619 | } else if (po->type == OPT_TYPE_STRING) |
| 124 | 16097 | av_freep(dst); | |
| 125 | } | ||
| 126 | |||
| 127 |
2/2✓ Branch 0 taken 457 times.
✓ Branch 1 taken 16097 times.
|
16554 | for (int i = 0; i < o->nb_stream_maps; i++) |
| 128 | 457 | av_freep(&o->stream_maps[i].linklabel); | |
| 129 | 16097 | av_freep(&o->stream_maps); | |
| 130 | |||
| 131 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 16097 times.
|
16098 | for (int i = 0; i < o->nb_attachments; i++) |
| 132 | 1 | av_freep(&o->attachments[i]); | |
| 133 | 16097 | av_freep(&o->attachments); | |
| 134 | |||
| 135 | 16097 | av_dict_free(&o->streamid); | |
| 136 | 16097 | } | |
| 137 | |||
| 138 | 16097 | static void init_options(OptionsContext *o) | |
| 139 | { | ||
| 140 | 16097 | memset(o, 0, sizeof(*o)); | |
| 141 | |||
| 142 | 16097 | o->stop_time = INT64_MAX; | |
| 143 | 16097 | o->mux_max_delay = 0.7; | |
| 144 | 16097 | o->start_time = AV_NOPTS_VALUE; | |
| 145 | 16097 | o->start_time_eof = AV_NOPTS_VALUE; | |
| 146 | 16097 | o->recording_time = INT64_MAX; | |
| 147 | 16097 | o->limit_filesize = INT64_MAX; | |
| 148 | 16097 | o->chapters_input_file = INT_MAX; | |
| 149 | 16097 | o->accurate_seek = 1; | |
| 150 | 16097 | o->thread_queue_size = 0; | |
| 151 | 16097 | o->input_sync_ref = -1; | |
| 152 | 16097 | o->find_stream_info = 1; | |
| 153 | 16097 | o->shortest_buf_duration = 10.f; | |
| 154 | 16097 | } | |
| 155 | |||
| 156 | ✗ | static int show_hwaccels(void *optctx, const char *opt, const char *arg) | |
| 157 | { | ||
| 158 | ✗ | enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE; | |
| 159 | |||
| 160 | ✗ | printf("Hardware acceleration methods:\n"); | |
| 161 | ✗ | while ((type = av_hwdevice_iterate_types(type)) != | |
| 162 | AV_HWDEVICE_TYPE_NONE) | ||
| 163 | ✗ | printf("%s\n", av_hwdevice_get_type_name(type)); | |
| 164 | ✗ | printf("\n"); | |
| 165 | ✗ | return 0; | |
| 166 | } | ||
| 167 | |||
| 168 | 38412 | const char *opt_match_per_type_str(const SpecifierOptList *sol, | |
| 169 | char mediatype) | ||
| 170 | { | ||
| 171 |
3/4✓ Branch 0 taken 17762 times.
✓ Branch 1 taken 20650 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17762 times.
|
38412 | av_assert0(!sol->nb_opt || sol->type == OPT_TYPE_STRING); |
| 172 | |||
| 173 |
2/2✓ Branch 0 taken 17866 times.
✓ Branch 1 taken 35085 times.
|
52951 | for (int i = 0; i < sol->nb_opt; i++) { |
| 174 | 17866 | const char *spec = sol->opt[i].specifier; | |
| 175 |
3/4✓ Branch 0 taken 3327 times.
✓ Branch 1 taken 14539 times.
✓ Branch 2 taken 3327 times.
✗ Branch 3 not taken.
|
17866 | if (spec[0] == mediatype && !spec[1]) |
| 176 | 3327 | return sol->opt[i].u.str; | |
| 177 | } | ||
| 178 | 35085 | return NULL; | |
| 179 | } | ||
| 180 | |||
| 181 | 435270 | static unsigned opt_match_per_stream(void *logctx, enum OptionType type, | |
| 182 | const SpecifierOptList *sol, | ||
| 183 | AVFormatContext *fc, AVStream *st) | ||
| 184 | { | ||
| 185 | 435270 | int matches = 0, match_idx = -1; | |
| 186 | |||
| 187 |
3/4✓ Branch 0 taken 402383 times.
✓ Branch 1 taken 32887 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 402383 times.
|
435270 | av_assert0((type == sol->type) || !sol->nb_opt); |
| 188 | |||
| 189 |
2/2✓ Branch 0 taken 35715 times.
✓ Branch 1 taken 435270 times.
|
470985 | for (int i = 0; i < sol->nb_opt; i++) { |
| 190 | 35715 | const StreamSpecifier *ss = &sol->opt[i].stream_spec; | |
| 191 | |||
| 192 |
2/2✓ Branch 1 taken 35246 times.
✓ Branch 2 taken 469 times.
|
35715 | if (stream_specifier_match(ss, fc, st, logctx)) { |
| 193 | 35246 | match_idx = i; | |
| 194 | 35246 | matches++; | |
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 |
3/4✓ Branch 0 taken 2516 times.
✓ Branch 1 taken 432754 times.
✓ Branch 2 taken 2516 times.
✗ Branch 3 not taken.
|
435270 | if (matches > 1 && sol->opt_canon) { |
| 199 | 2516 | const SpecifierOpt *so = &sol->opt[match_idx]; | |
| 200 |
3/4✓ Branch 0 taken 2516 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2514 times.
✓ Branch 3 taken 2 times.
|
2516 | const char *spec = so->specifier && so->specifier[0] ? so->specifier : ""; |
| 201 | |||
| 202 | 2516 | char namestr[128] = ""; | |
| 203 | char optval_buf[32]; | ||
| 204 | 2516 | const char *optval = optval_buf; | |
| 205 | |||
| 206 | 2516 | snprintf(namestr, sizeof(namestr), "-%s", sol->opt_canon->name); | |
| 207 |
1/2✓ Branch 0 taken 2516 times.
✗ Branch 1 not taken.
|
2516 | if (sol->opt_canon->flags & OPT_HAS_ALT) { |
| 208 | 2516 | const char * const *names_alt = sol->opt_canon->u1.names_alt; | |
| 209 |
2/2✓ Branch 0 taken 7672 times.
✓ Branch 1 taken 2516 times.
|
10188 | for (int i = 0; names_alt[i]; i++) |
| 210 | 7672 | av_strlcatf(namestr, sizeof(namestr), "/-%s", names_alt[i]); | |
| 211 | } | ||
| 212 | |||
| 213 |
3/6✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2452 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
2516 | switch (sol->type) { |
| 214 | 63 | case OPT_TYPE_STRING: optval = so->u.str; break; | |
| 215 | ✗ | case OPT_TYPE_INT: snprintf(optval_buf, sizeof(optval_buf), "%d", so->u.i); break; | |
| 216 | 2452 | case OPT_TYPE_INT64: snprintf(optval_buf, sizeof(optval_buf), "%"PRId64, so->u.i64); break; | |
| 217 | ✗ | case OPT_TYPE_FLOAT: snprintf(optval_buf, sizeof(optval_buf), "%f", so->u.f); break; | |
| 218 | 1 | case OPT_TYPE_DOUBLE: snprintf(optval_buf, sizeof(optval_buf), "%f", so->u.dbl); break; | |
| 219 | ✗ | default: av_assert0(0); | |
| 220 | } | ||
| 221 | |||
| 222 | 2516 | av_log(logctx, AV_LOG_WARNING, "Multiple %s options specified for " | |
| 223 | "stream %d, only the last option '-%s%s%s %s' will be used.\n", | ||
| 224 |
2/2✓ Branch 0 taken 2514 times.
✓ Branch 1 taken 2 times.
|
5032 | namestr, st->index, sol->opt_canon->name, spec[0] ? ":" : "", |
| 225 | spec, optval); | ||
| 226 | } | ||
| 227 | |||
| 228 | 435270 | return match_idx + 1; | |
| 229 | } | ||
| 230 | |||
| 231 | #define OPT_MATCH_PER_STREAM(name, type, opt_type, m) \ | ||
| 232 | void opt_match_per_stream_ ## name(void *logctx, const SpecifierOptList *sol, \ | ||
| 233 | AVFormatContext *fc, AVStream *st, type *out) \ | ||
| 234 | { \ | ||
| 235 | unsigned ret = opt_match_per_stream(logctx, opt_type, sol, fc, st); \ | ||
| 236 | if (ret > 0) \ | ||
| 237 | *out = sol->opt[ret - 1].u.m; \ | ||
| 238 | } | ||
| 239 | |||
| 240 |
2/2✓ Branch 1 taken 29178 times.
✓ Branch 2 taken 242323 times.
|
271501 | OPT_MATCH_PER_STREAM(str, const char *, OPT_TYPE_STRING, str); |
| 241 |
2/2✓ Branch 1 taken 54 times.
✓ Branch 2 taken 131228 times.
|
131282 | OPT_MATCH_PER_STREAM(int, int, OPT_TYPE_INT, i); |
| 242 |
2/2✓ Branch 1 taken 3230 times.
✓ Branch 2 taken 5855 times.
|
9085 | OPT_MATCH_PER_STREAM(int64, int64_t, OPT_TYPE_INT64, i64); |
| 243 |
2/2✓ Branch 1 taken 268 times.
✓ Branch 2 taken 23134 times.
|
23402 | OPT_MATCH_PER_STREAM(dbl, double, OPT_TYPE_DOUBLE, dbl); |
| 244 | |||
| 245 | 12 | static unsigned opt_match_per_stream_group(void *logctx, enum OptionType type, | |
| 246 | const SpecifierOptList *sol, | ||
| 247 | AVFormatContext *fc, AVStreamGroup *stg) | ||
| 248 | { | ||
| 249 | 12 | int matches = 0, match_idx = -1; | |
| 250 | |||
| 251 |
2/4✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
|
12 | av_assert0((type == sol->type) || !sol->nb_opt); |
| 252 | |||
| 253 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | for (int i = 0; i < sol->nb_opt; i++) { |
| 254 | ✗ | const StreamSpecifier *ss = &sol->opt[i].stream_spec; | |
| 255 | |||
| 256 | ✗ | if (stream_group_specifier_match(ss, fc, stg, logctx)) { | |
| 257 | ✗ | match_idx = i; | |
| 258 | ✗ | matches++; | |
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
12 | if (matches > 1 && sol->opt_canon) { |
| 263 | ✗ | const SpecifierOpt *so = &sol->opt[match_idx]; | |
| 264 | ✗ | const char *spec = so->specifier && so->specifier[0] ? so->specifier : ""; | |
| 265 | |||
| 266 | ✗ | char namestr[128] = ""; | |
| 267 | char optval_buf[32]; | ||
| 268 | ✗ | const char *optval = optval_buf; | |
| 269 | |||
| 270 | ✗ | snprintf(namestr, sizeof(namestr), "-%s", sol->opt_canon->name); | |
| 271 | ✗ | if (sol->opt_canon->flags & OPT_HAS_ALT) { | |
| 272 | ✗ | const char * const *names_alt = sol->opt_canon->u1.names_alt; | |
| 273 | ✗ | for (int i = 0; names_alt[i]; i++) | |
| 274 | ✗ | av_strlcatf(namestr, sizeof(namestr), "/-%s", names_alt[i]); | |
| 275 | } | ||
| 276 | |||
| 277 | ✗ | switch (sol->type) { | |
| 278 | ✗ | case OPT_TYPE_STRING: optval = so->u.str; break; | |
| 279 | ✗ | case OPT_TYPE_INT: snprintf(optval_buf, sizeof(optval_buf), "%d", so->u.i); break; | |
| 280 | ✗ | case OPT_TYPE_INT64: snprintf(optval_buf, sizeof(optval_buf), "%"PRId64, so->u.i64); break; | |
| 281 | ✗ | case OPT_TYPE_FLOAT: snprintf(optval_buf, sizeof(optval_buf), "%f", so->u.f); break; | |
| 282 | ✗ | case OPT_TYPE_DOUBLE: snprintf(optval_buf, sizeof(optval_buf), "%f", so->u.dbl); break; | |
| 283 | ✗ | default: av_assert0(0); | |
| 284 | } | ||
| 285 | |||
| 286 | ✗ | av_log(logctx, AV_LOG_WARNING, "Multiple %s options specified for " | |
| 287 | "stream group %d, only the last option '-%s%s%s %s' will be used.\n", | ||
| 288 | ✗ | namestr, stg->index, sol->opt_canon->name, spec[0] ? ":" : "", | |
| 289 | spec, optval); | ||
| 290 | } | ||
| 291 | |||
| 292 | 12 | return match_idx + 1; | |
| 293 | } | ||
| 294 | |||
| 295 | #define OPT_MATCH_PER_STREAM_GROUP(name, type, opt_type, m) \ | ||
| 296 | void opt_match_per_stream_group_ ## name(void *logctx, const SpecifierOptList *sol, \ | ||
| 297 | AVFormatContext *fc, AVStreamGroup *stg, type *out) \ | ||
| 298 | { \ | ||
| 299 | unsigned ret = opt_match_per_stream_group(logctx, opt_type, sol, fc, stg); \ | ||
| 300 | if (ret > 0) \ | ||
| 301 | *out = sol->opt[ret - 1].u.m; \ | ||
| 302 | } | ||
| 303 | |||
| 304 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
|
6 | OPT_MATCH_PER_STREAM_GROUP(str, const char *, OPT_TYPE_STRING, str); |
| 305 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
|
6 | OPT_MATCH_PER_STREAM_GROUP(int, int, OPT_TYPE_INT, i); |
| 306 | ✗ | OPT_MATCH_PER_STREAM_GROUP(int64, int64_t, OPT_TYPE_INT64, i64); | |
| 307 | ✗ | OPT_MATCH_PER_STREAM_GROUP(dbl, double, OPT_TYPE_DOUBLE, dbl); | |
| 308 | |||
| 309 | 374 | int view_specifier_parse(const char **pspec, ViewSpecifier *vs) | |
| 310 | { | ||
| 311 | 374 | const char *spec = *pspec; | |
| 312 | char *endptr; | ||
| 313 | |||
| 314 | 374 | vs->type = VIEW_SPECIFIER_TYPE_NONE; | |
| 315 | |||
| 316 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 365 times.
|
374 | if (!strncmp(spec, "view:", 5)) { |
| 317 | 9 | spec += 5; | |
| 318 | |||
| 319 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8 times.
|
9 | if (!strncmp(spec, "all", 3)) { |
| 320 | 1 | spec += 3; | |
| 321 | 1 | vs->type = VIEW_SPECIFIER_TYPE_ALL; | |
| 322 | } else { | ||
| 323 | 8 | vs->type = VIEW_SPECIFIER_TYPE_ID; | |
| 324 | 8 | vs->val = strtoul(spec, &endptr, 0); | |
| 325 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (endptr == spec) { |
| 326 | ✗ | av_log(NULL, AV_LOG_ERROR, "Invalid view ID: %s\n", spec); | |
| 327 | ✗ | return AVERROR(EINVAL); | |
| 328 | } | ||
| 329 | 8 | spec = endptr; | |
| 330 | } | ||
| 331 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 363 times.
|
365 | } else if (!strncmp(spec, "vidx:", 5)) { |
| 332 | 2 | spec += 5; | |
| 333 | 2 | vs->type = VIEW_SPECIFIER_TYPE_IDX; | |
| 334 | 2 | vs->val = strtoul(spec, &endptr, 0); | |
| 335 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (endptr == spec) { |
| 336 | ✗ | av_log(NULL, AV_LOG_ERROR, "Invalid view index: %s\n", spec); | |
| 337 | ✗ | return AVERROR(EINVAL); | |
| 338 | } | ||
| 339 | 2 | spec = endptr; | |
| 340 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 361 times.
|
363 | } else if (!strncmp(spec, "vpos:", 5)) { |
| 341 | 2 | spec += 5; | |
| 342 | 2 | vs->type = VIEW_SPECIFIER_TYPE_POS; | |
| 343 | |||
| 344 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | if (!strncmp(spec, "left", 4) && !cmdutils_isalnum(spec[4])) { |
| 345 | 1 | spec += 4; | |
| 346 | 1 | vs->val = AV_STEREO3D_VIEW_LEFT; | |
| 347 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | } else if (!strncmp(spec, "right", 5) && !cmdutils_isalnum(spec[5])) { |
| 348 | 1 | spec += 5; | |
| 349 | 1 | vs->val = AV_STEREO3D_VIEW_RIGHT; | |
| 350 | } else { | ||
| 351 | ✗ | av_log(NULL, AV_LOG_ERROR, "Invalid view position: %s\n", spec); | |
| 352 | ✗ | return AVERROR(EINVAL); | |
| 353 | } | ||
| 354 | } else | ||
| 355 | 361 | return 0; | |
| 356 | |||
| 357 | 13 | *pspec = spec; | |
| 358 | |||
| 359 | 13 | return 0; | |
| 360 | } | ||
| 361 | |||
| 362 | 533 | int parse_and_set_vsync(const char *arg, enum VideoSyncMethod *vsync_var, int file_idx, int st_idx, int is_global) | |
| 363 | { | ||
| 364 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 527 times.
|
533 | if (!av_strcasecmp(arg, "cfr")) *vsync_var = VSYNC_CFR; |
| 365 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 526 times.
|
527 | else if (!av_strcasecmp(arg, "vfr")) *vsync_var = VSYNC_VFR; |
| 366 |
1/2✓ Branch 1 taken 526 times.
✗ Branch 2 not taken.
|
526 | else if (!av_strcasecmp(arg, "passthrough")) *vsync_var = VSYNC_PASSTHROUGH; |
| 367 | #if FFMPEG_OPT_VSYNC_DROP | ||
| 368 | ✗ | else if (!av_strcasecmp(arg, "drop")) { | |
| 369 | ✗ | av_log(NULL, AV_LOG_WARNING, "-vsync/fps_mode drop is deprecated\n"); | |
| 370 | ✗ | *vsync_var = VSYNC_DROP; | |
| 371 | } | ||
| 372 | #endif | ||
| 373 | ✗ | else if (!is_global && !av_strcasecmp(arg, "auto")) *vsync_var = VSYNC_AUTO; | |
| 374 | ✗ | else if (!is_global) { | |
| 375 | ✗ | av_log(NULL, AV_LOG_FATAL, "Invalid value %s specified for fps_mode of #%d:%d.\n", arg, file_idx, st_idx); | |
| 376 | ✗ | return AVERROR(EINVAL); | |
| 377 | } | ||
| 378 | |||
| 379 | #if FFMPEG_OPT_VSYNC | ||
| 380 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 533 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
533 | if (is_global && *vsync_var == VSYNC_AUTO) { |
| 381 | int ret; | ||
| 382 | double num; | ||
| 383 | |||
| 384 | ✗ | ret = parse_number("vsync", arg, OPT_TYPE_INT, VSYNC_AUTO, VSYNC_VFR, &num); | |
| 385 | ✗ | if (ret < 0) | |
| 386 | ✗ | return ret; | |
| 387 | |||
| 388 | ✗ | video_sync_method = num; | |
| 389 | ✗ | av_log(NULL, AV_LOG_WARNING, "Passing a number to -vsync is deprecated," | |
| 390 | " use a string argument as described in the manual.\n"); | ||
| 391 | } | ||
| 392 | #endif | ||
| 393 | |||
| 394 | 533 | return 0; | |
| 395 | } | ||
| 396 | |||
| 397 | /* Correct input file start times based on enabled streams */ | ||
| 398 | 8591 | static void correct_input_start_times(void) | |
| 399 | { | ||
| 400 |
2/2✓ Branch 0 taken 7501 times.
✓ Branch 1 taken 8591 times.
|
16092 | for (int i = 0; i < nb_input_files; i++) { |
| 401 | 7501 | InputFile *ifile = input_files[i]; | |
| 402 | 7501 | AVFormatContext *is = ifile->ctx; | |
| 403 | 7501 | int64_t new_start_time = INT64_MAX, diff, abs_start_seek; | |
| 404 | |||
| 405 | 7501 | ifile->start_time_effective = is->start_time; | |
| 406 | |||
| 407 |
2/2✓ Branch 0 taken 5753 times.
✓ Branch 1 taken 1748 times.
|
7501 | if (is->start_time == AV_NOPTS_VALUE || |
| 408 |
2/2✓ Branch 0 taken 5645 times.
✓ Branch 1 taken 108 times.
|
5753 | !(is->iformat->flags & AVFMT_TS_DISCONT)) |
| 409 | 7393 | continue; | |
| 410 | |||
| 411 |
2/2✓ Branch 0 taken 167 times.
✓ Branch 1 taken 108 times.
|
275 | for (int j = 0; j < is->nb_streams; j++) { |
| 412 | 167 | AVStream *st = is->streams[j]; | |
| 413 |
3/4✓ Branch 0 taken 123 times.
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 123 times.
|
167 | if(st->discard == AVDISCARD_ALL || st->start_time == AV_NOPTS_VALUE) |
| 414 | 44 | continue; | |
| 415 |
2/2✓ Branch 0 taken 120 times.
✓ Branch 1 taken 3 times.
|
123 | new_start_time = FFMIN(new_start_time, av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q)); |
| 416 | } | ||
| 417 | |||
| 418 | 108 | diff = new_start_time - is->start_time; | |
| 419 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 104 times.
|
108 | if (diff) { |
| 420 | 4 | av_log(NULL, AV_LOG_VERBOSE, "Correcting start time of Input #%d by %"PRId64" us.\n", i, diff); | |
| 421 | 4 | ifile->start_time_effective = new_start_time; | |
| 422 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
4 | if (copy_ts && start_at_zero) |
| 423 | ✗ | ifile->ts_offset = -new_start_time; | |
| 424 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | else if (!copy_ts) { |
| 425 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | abs_start_seek = is->start_time + ((ifile->start_time != AV_NOPTS_VALUE) ? ifile->start_time : 0); |
| 426 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | ifile->ts_offset = abs_start_seek > new_start_time ? -abs_start_seek : -new_start_time; |
| 427 | ✗ | } else if (copy_ts) | |
| 428 | ✗ | ifile->ts_offset = 0; | |
| 429 | |||
| 430 | 4 | ifile->ts_offset += ifile->input_ts_offset; | |
| 431 | } | ||
| 432 | } | ||
| 433 | 8591 | } | |
| 434 | |||
| 435 | 8591 | static int apply_sync_offsets(void) | |
| 436 | { | ||
| 437 |
2/2✓ Branch 0 taken 7501 times.
✓ Branch 1 taken 8591 times.
|
16092 | for (int i = 0; i < nb_input_files; i++) { |
| 438 | 7501 | InputFile *ref, *self = input_files[i]; | |
| 439 | int64_t adjustment; | ||
| 440 | int64_t self_start_time, ref_start_time, self_seek_start, ref_seek_start; | ||
| 441 | 7501 | int start_times_set = 1; | |
| 442 | |||
| 443 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 7501 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
7501 | if (self->input_sync_ref == -1 || self->input_sync_ref == i) continue; |
| 444 | ✗ | if (self->input_sync_ref >= nb_input_files || self->input_sync_ref < -1) { | |
| 445 | ✗ | av_log(NULL, AV_LOG_FATAL, "-isync for input %d references non-existent input %d.\n", i, self->input_sync_ref); | |
| 446 | ✗ | return AVERROR(EINVAL); | |
| 447 | } | ||
| 448 | |||
| 449 | ✗ | if (copy_ts && !start_at_zero) { | |
| 450 | ✗ | av_log(NULL, AV_LOG_FATAL, "Use of -isync requires that start_at_zero be set if copyts is set.\n"); | |
| 451 | ✗ | return AVERROR(EINVAL); | |
| 452 | } | ||
| 453 | |||
| 454 | ✗ | ref = input_files[self->input_sync_ref]; | |
| 455 | ✗ | if (ref->input_sync_ref != -1 && ref->input_sync_ref != self->input_sync_ref) { | |
| 456 | ✗ | av_log(NULL, AV_LOG_ERROR, "-isync for input %d references a resynced input %d. Sync not set.\n", i, self->input_sync_ref); | |
| 457 | ✗ | continue; | |
| 458 | } | ||
| 459 | |||
| 460 | ✗ | if (self->ctx->start_time_realtime != AV_NOPTS_VALUE && ref->ctx->start_time_realtime != AV_NOPTS_VALUE) { | |
| 461 | ✗ | self_start_time = self->ctx->start_time_realtime; | |
| 462 | ✗ | ref_start_time = ref->ctx->start_time_realtime; | |
| 463 | ✗ | } else if (self->start_time_effective != AV_NOPTS_VALUE && ref->start_time_effective != AV_NOPTS_VALUE) { | |
| 464 | ✗ | self_start_time = self->start_time_effective; | |
| 465 | ✗ | ref_start_time = ref->start_time_effective; | |
| 466 | } else { | ||
| 467 | ✗ | start_times_set = 0; | |
| 468 | } | ||
| 469 | |||
| 470 | ✗ | if (start_times_set) { | |
| 471 | ✗ | self_seek_start = self->start_time == AV_NOPTS_VALUE ? 0 : self->start_time; | |
| 472 | ✗ | ref_seek_start = ref->start_time == AV_NOPTS_VALUE ? 0 : ref->start_time; | |
| 473 | |||
| 474 | ✗ | adjustment = (self_start_time - ref_start_time) + !copy_ts*(self_seek_start - ref_seek_start) + ref->input_ts_offset; | |
| 475 | |||
| 476 | ✗ | self->ts_offset += adjustment; | |
| 477 | |||
| 478 | ✗ | 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); | |
| 479 | } else { | ||
| 480 | ✗ | 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); | |
| 481 | } | ||
| 482 | } | ||
| 483 | |||
| 484 | 8591 | return 0; | |
| 485 | } | ||
| 486 | |||
| 487 | 1449 | static int opt_filter_threads(void *optctx, const char *opt, const char *arg) | |
| 488 | { | ||
| 489 | 1449 | av_free(filter_nbthreads); | |
| 490 | 1449 | filter_nbthreads = av_strdup(arg); | |
| 491 | 1449 | return 0; | |
| 492 | } | ||
| 493 | |||
| 494 | ✗ | static int opt_abort_on(void *optctx, const char *opt, const char *arg) | |
| 495 | { | ||
| 496 | static const AVOption opts[] = { | ||
| 497 | { "abort_on" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, (double)INT64_MAX, .unit = "flags" }, | ||
| 498 | { "empty_output" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT }, .unit = "flags" }, | ||
| 499 | { "empty_output_stream", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM }, .unit = "flags" }, | ||
| 500 | { NULL }, | ||
| 501 | }; | ||
| 502 | static const AVClass class = { | ||
| 503 | .class_name = "", | ||
| 504 | .item_name = av_default_item_name, | ||
| 505 | .option = opts, | ||
| 506 | .version = LIBAVUTIL_VERSION_INT, | ||
| 507 | }; | ||
| 508 | ✗ | const AVClass *pclass = &class; | |
| 509 | |||
| 510 | ✗ | return av_opt_eval_flags(&pclass, &opts[0], arg, &abort_on_flags); | |
| 511 | } | ||
| 512 | |||
| 513 | ✗ | static int opt_stats_period(void *optctx, const char *opt, const char *arg) | |
| 514 | { | ||
| 515 | int64_t user_stats_period; | ||
| 516 | ✗ | int ret = av_parse_time(&user_stats_period, arg, 1); | |
| 517 | ✗ | if (ret < 0) | |
| 518 | ✗ | return ret; | |
| 519 | |||
| 520 | ✗ | if (user_stats_period <= 0) { | |
| 521 | ✗ | av_log(NULL, AV_LOG_ERROR, "stats_period %s must be positive.\n", arg); | |
| 522 | ✗ | return AVERROR(EINVAL); | |
| 523 | } | ||
| 524 | |||
| 525 | ✗ | stats_period = user_stats_period; | |
| 526 | ✗ | av_log(NULL, AV_LOG_INFO, "ffmpeg stats and -progress period set to %s.\n", arg); | |
| 527 | |||
| 528 | ✗ | return 0; | |
| 529 | } | ||
| 530 | |||
| 531 | 18 | static int opt_audio_codec(void *optctx, const char *opt, const char *arg) | |
| 532 | { | ||
| 533 | 18 | OptionsContext *o = optctx; | |
| 534 | 18 | return parse_option(o, "codec:a", arg, options); | |
| 535 | } | ||
| 536 | |||
| 537 | 5820 | static int opt_video_codec(void *optctx, const char *opt, const char *arg) | |
| 538 | { | ||
| 539 | 5820 | OptionsContext *o = optctx; | |
| 540 | 5820 | return parse_option(o, "codec:v", arg, options); | |
| 541 | } | ||
| 542 | |||
| 543 | 2 | static int opt_subtitle_codec(void *optctx, const char *opt, const char *arg) | |
| 544 | { | ||
| 545 | 2 | OptionsContext *o = optctx; | |
| 546 | 2 | return parse_option(o, "codec:s", arg, options); | |
| 547 | } | ||
| 548 | |||
| 549 | ✗ | static int opt_data_codec(void *optctx, const char *opt, const char *arg) | |
| 550 | { | ||
| 551 | ✗ | OptionsContext *o = optctx; | |
| 552 | ✗ | return parse_option(o, "codec:d", arg, options); | |
| 553 | } | ||
| 554 | |||
| 555 | 303 | static int opt_map(void *optctx, const char *opt, const char *arg) | |
| 556 | { | ||
| 557 | 303 | OptionsContext *o = optctx; | |
| 558 | 303 | StreamMap *m = NULL; | |
| 559 | StreamSpecifier ss; | ||
| 560 | 303 | int i, negative = 0, file_idx, disabled = 0; | |
| 561 | 303 | int ret, allow_unused = 0; | |
| 562 | |||
| 563 | 303 | memset(&ss, 0, sizeof(ss)); | |
| 564 | |||
| 565 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 303 times.
|
303 | if (*arg == '-') { |
| 566 | ✗ | negative = 1; | |
| 567 | ✗ | arg++; | |
| 568 | } | ||
| 569 | |||
| 570 |
2/2✓ Branch 0 taken 77 times.
✓ Branch 1 taken 226 times.
|
303 | if (arg[0] == '[') { |
| 571 | ViewSpecifier vs; | ||
| 572 | /* this mapping refers to lavfi output */ | ||
| 573 | 77 | const char *c = arg + 1; | |
| 574 | char *endptr; | ||
| 575 | |||
| 576 | 77 | ret = GROW_ARRAY(o->stream_maps, o->nb_stream_maps); | |
| 577 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 77 times.
|
77 | if (ret < 0) |
| 578 | ✗ | goto fail; | |
| 579 | |||
| 580 | 77 | m = &o->stream_maps[o->nb_stream_maps - 1]; | |
| 581 | 77 | m->linklabel = av_get_token(&c, "]"); | |
| 582 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 77 times.
|
77 | if (!m->linklabel) { |
| 583 | ✗ | av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", arg); | |
| 584 | ✗ | ret = AVERROR(EINVAL); | |
| 585 | ✗ | goto fail; | |
| 586 | } | ||
| 587 | |||
| 588 | 77 | arg++; | |
| 589 | |||
| 590 | 77 | m->group_index = -1; | |
| 591 | 77 | file_idx = strtol(arg, &endptr, 0); | |
| 592 |
3/4✓ Branch 0 taken 73 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 73 times.
|
77 | if (file_idx >= nb_input_files || file_idx < 0) |
| 593 | 76 | goto end; | |
| 594 | |||
| 595 | 73 | arg = endptr; | |
| 596 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 72 times.
|
73 | ret = stream_specifier_parse(&ss, *arg == ':' ? arg + 1 : arg, 1, NULL); |
| 597 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
|
73 | if (ret < 0) |
| 598 | ✗ | goto end; | |
| 599 | |||
| 600 |
1/2✓ Branch 0 taken 73 times.
✗ Branch 1 not taken.
|
73 | arg = ss.remainder ? ss.remainder : ""; |
| 601 | 73 | ret = view_specifier_parse(&arg, &vs); | |
| 602 |
4/6✓ Branch 0 taken 73 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 72 times.
✓ Branch 5 taken 1 times.
|
73 | if (ret < 0 || (*arg && strcmp(arg, "]"))) |
| 603 | 72 | goto end; | |
| 604 | |||
| 605 | 1 | m->file_index = file_idx; | |
| 606 | 1 | m->stream_index = ss.idx; | |
| 607 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | m->group_index = ss.stream_list == STREAM_LIST_GROUP_IDX ? ss.list_id : -1; |
| 608 | } else { | ||
| 609 | ViewSpecifier vs; | ||
| 610 | char *endptr; | ||
| 611 | |||
| 612 | 226 | file_idx = strtol(arg, &endptr, 0); | |
| 613 |
2/4✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 226 times.
|
226 | if (file_idx >= nb_input_files || file_idx < 0) { |
| 614 | ✗ | av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx); | |
| 615 | ✗ | ret = AVERROR(EINVAL); | |
| 616 | ✗ | goto fail; | |
| 617 | } | ||
| 618 | 226 | arg = endptr; | |
| 619 | |||
| 620 |
2/2✓ Branch 0 taken 104 times.
✓ Branch 1 taken 122 times.
|
226 | ret = stream_specifier_parse(&ss, *arg == ':' ? arg + 1 : arg, 1, NULL); |
| 621 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 226 times.
|
226 | if (ret < 0) { |
| 622 | ✗ | av_log(NULL, AV_LOG_ERROR, "Invalid stream specifier: %s\n", arg); | |
| 623 | ✗ | goto fail; | |
| 624 | } | ||
| 625 | |||
| 626 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 213 times.
|
226 | arg = ss.remainder ? ss.remainder : ""; |
| 627 | |||
| 628 | 226 | ret = view_specifier_parse(&arg, &vs); | |
| 629 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 226 times.
|
226 | if (ret < 0) |
| 630 | ✗ | goto fail; | |
| 631 | |||
| 632 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 226 times.
|
226 | if (*arg) { |
| 633 | ✗ | if (!strcmp(arg, "?")) | |
| 634 | ✗ | allow_unused = 1; | |
| 635 | else { | ||
| 636 | ✗ | av_log(NULL, AV_LOG_ERROR, | |
| 637 | "Trailing garbage after stream specifier: %s\n", arg); | ||
| 638 | ✗ | ret = AVERROR(EINVAL); | |
| 639 | ✗ | goto fail; | |
| 640 | } | ||
| 641 | } | ||
| 642 | |||
| 643 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 226 times.
|
226 | if (negative) |
| 644 | /* disable some already defined maps */ | ||
| 645 | ✗ | for (i = 0; i < o->nb_stream_maps; i++) { | |
| 646 | ✗ | m = &o->stream_maps[i]; | |
| 647 | ✗ | if (file_idx == m->file_index && | |
| 648 | ✗ | stream_specifier_match(&ss, | |
| 649 | ✗ | input_files[m->file_index]->ctx, | |
| 650 | ✗ | input_files[m->file_index]->ctx->streams[m->stream_index], | |
| 651 | NULL)) | ||
| 652 | ✗ | m->disabled = 1; | |
| 653 | } | ||
| 654 | else | ||
| 655 |
2/2✓ Branch 0 taken 526 times.
✓ Branch 1 taken 226 times.
|
752 | for (i = 0; i < input_files[file_idx]->nb_streams; i++) { |
| 656 |
2/2✓ Branch 0 taken 146 times.
✓ Branch 1 taken 380 times.
|
526 | if (!stream_specifier_match(&ss, |
| 657 | 526 | input_files[file_idx]->ctx, | |
| 658 | 526 | input_files[file_idx]->ctx->streams[i], | |
| 659 | NULL)) | ||
| 660 | 146 | continue; | |
| 661 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 380 times.
|
380 | if (input_files[file_idx]->streams[i]->user_set_discard == AVDISCARD_ALL) { |
| 662 | ✗ | disabled = 1; | |
| 663 | ✗ | continue; | |
| 664 | } | ||
| 665 | 380 | ret = GROW_ARRAY(o->stream_maps, o->nb_stream_maps); | |
| 666 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 380 times.
|
380 | if (ret < 0) |
| 667 | ✗ | goto fail; | |
| 668 | |||
| 669 | 380 | m = &o->stream_maps[o->nb_stream_maps - 1]; | |
| 670 | |||
| 671 | 380 | m->file_index = file_idx; | |
| 672 | 380 | m->stream_index = i; | |
| 673 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 373 times.
|
380 | m->group_index = ss.stream_list == STREAM_LIST_GROUP_IDX ? ss.list_id : -1; |
| 674 | 380 | m->vs = vs; | |
| 675 | } | ||
| 676 | } | ||
| 677 | |||
| 678 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 227 times.
|
227 | if (!m) { |
| 679 | ✗ | if (allow_unused) { | |
| 680 | ✗ | av_log(NULL, AV_LOG_VERBOSE, "Stream map '%s' matches no streams; ignoring.\n", arg); | |
| 681 | ✗ | } else if (disabled) { | |
| 682 | ✗ | av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches disabled streams.\n" | |
| 683 | "To ignore this, add a trailing '?' to the map.\n", arg); | ||
| 684 | ✗ | ret = AVERROR(EINVAL); | |
| 685 | ✗ | goto fail; | |
| 686 | } else { | ||
| 687 | ✗ | av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n" | |
| 688 | "To ignore this, add a trailing '?' to the map.\n", arg); | ||
| 689 | ✗ | ret = AVERROR(EINVAL); | |
| 690 | ✗ | goto fail; | |
| 691 | } | ||
| 692 | } | ||
| 693 | 227 | end: | |
| 694 | 303 | ret = 0; | |
| 695 | 303 | fail: | |
| 696 | 303 | stream_specifier_uninit(&ss); | |
| 697 | 303 | return ret; | |
| 698 | } | ||
| 699 | |||
| 700 | 1 | static int opt_attach(void *optctx, const char *opt, const char *arg) | |
| 701 | { | ||
| 702 | 1 | OptionsContext *o = optctx; | |
| 703 | 1 | int ret = GROW_ARRAY(o->attachments, o->nb_attachments); | |
| 704 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (ret < 0) |
| 705 | ✗ | return ret; | |
| 706 | |||
| 707 | 1 | o->attachments[o->nb_attachments - 1] = av_strdup(arg); | |
| 708 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!o->attachments[o->nb_attachments - 1]) |
| 709 | ✗ | return AVERROR(ENOMEM); | |
| 710 | |||
| 711 | 1 | return 0; | |
| 712 | } | ||
| 713 | |||
| 714 | ✗ | static int opt_sdp_file(void *optctx, const char *opt, const char *arg) | |
| 715 | { | ||
| 716 | ✗ | GlobalOptionsContext *go = optctx; | |
| 717 | ✗ | return sch_sdp_filename(go->sch, arg); | |
| 718 | } | ||
| 719 | |||
| 720 | #if CONFIG_VAAPI | ||
| 721 | ✗ | static int opt_vaapi_device(void *optctx, const char *opt, const char *arg) | |
| 722 | { | ||
| 723 | ✗ | const char *prefix = "vaapi:"; | |
| 724 | char *tmp; | ||
| 725 | int err; | ||
| 726 | ✗ | tmp = av_asprintf("%s%s", prefix, arg); | |
| 727 | ✗ | if (!tmp) | |
| 728 | ✗ | return AVERROR(ENOMEM); | |
| 729 | ✗ | err = hw_device_init_from_string(tmp, NULL); | |
| 730 | ✗ | av_free(tmp); | |
| 731 | ✗ | return err; | |
| 732 | } | ||
| 733 | #endif | ||
| 734 | |||
| 735 | #if CONFIG_QSV | ||
| 736 | static int opt_qsv_device(void *optctx, const char *opt, const char *arg) | ||
| 737 | { | ||
| 738 | const char *prefix = "qsv=__qsv_device:hw_any,child_device="; | ||
| 739 | int err; | ||
| 740 | char *tmp = av_asprintf("%s%s", prefix, arg); | ||
| 741 | |||
| 742 | if (!tmp) | ||
| 743 | return AVERROR(ENOMEM); | ||
| 744 | |||
| 745 | err = hw_device_init_from_string(tmp, NULL); | ||
| 746 | av_free(tmp); | ||
| 747 | |||
| 748 | return err; | ||
| 749 | } | ||
| 750 | #endif | ||
| 751 | |||
| 752 | ✗ | static int opt_init_hw_device(void *optctx, const char *opt, const char *arg) | |
| 753 | { | ||
| 754 | ✗ | if (!strcmp(arg, "list")) { | |
| 755 | ✗ | enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE; | |
| 756 | ✗ | printf("Supported hardware device types:\n"); | |
| 757 | ✗ | while ((type = av_hwdevice_iterate_types(type)) != | |
| 758 | AV_HWDEVICE_TYPE_NONE) | ||
| 759 | ✗ | printf("%s\n", av_hwdevice_get_type_name(type)); | |
| 760 | ✗ | printf("\n"); | |
| 761 | ✗ | return AVERROR_EXIT; | |
| 762 | } else { | ||
| 763 | ✗ | return hw_device_init_from_string(arg, NULL); | |
| 764 | } | ||
| 765 | } | ||
| 766 | |||
| 767 | ✗ | static int opt_filter_hw_device(void *optctx, const char *opt, const char *arg) | |
| 768 | { | ||
| 769 | ✗ | if (filter_hw_device) { | |
| 770 | ✗ | av_log(NULL, AV_LOG_ERROR, "Only one filter device can be used.\n"); | |
| 771 | ✗ | return AVERROR(EINVAL); | |
| 772 | } | ||
| 773 | ✗ | filter_hw_device = hw_device_get_by_name(arg); | |
| 774 | ✗ | if (!filter_hw_device) { | |
| 775 | ✗ | av_log(NULL, AV_LOG_ERROR, "Invalid filter device %s.\n", arg); | |
| 776 | ✗ | return AVERROR(EINVAL); | |
| 777 | } | ||
| 778 | ✗ | return 0; | |
| 779 | } | ||
| 780 | |||
| 781 | ✗ | static int opt_recording_timestamp(void *optctx, const char *opt, const char *arg) | |
| 782 | { | ||
| 783 | ✗ | OptionsContext *o = optctx; | |
| 784 | char buf[128]; | ||
| 785 | int64_t recording_timestamp; | ||
| 786 | int ret; | ||
| 787 | struct tm time; | ||
| 788 | |||
| 789 | ✗ | ret = av_parse_time(&recording_timestamp, arg, 0); | |
| 790 | ✗ | if (ret < 0) | |
| 791 | ✗ | return ret; | |
| 792 | |||
| 793 | ✗ | recording_timestamp /= 1e6; | |
| 794 | ✗ | time = *gmtime((time_t*)&recording_timestamp); | |
| 795 | ✗ | if (!strftime(buf, sizeof(buf), "creation_time=%Y-%m-%dT%H:%M:%S%z", &time)) | |
| 796 | ✗ | return -1; | |
| 797 | ✗ | parse_option(o, "metadata", buf, options); | |
| 798 | |||
| 799 | ✗ | av_log(NULL, AV_LOG_WARNING, "%s is deprecated, set the 'creation_time' metadata " | |
| 800 | "tag instead.\n", opt); | ||
| 801 | ✗ | return 0; | |
| 802 | } | ||
| 803 | |||
| 804 | 14166 | int find_codec(void *logctx, const char *name, | |
| 805 | enum AVMediaType type, int encoder, const AVCodec **pcodec) | ||
| 806 | { | ||
| 807 | const AVCodecDescriptor *desc; | ||
| 808 |
2/2✓ Branch 0 taken 4201 times.
✓ Branch 1 taken 9965 times.
|
14166 | const char *codec_string = encoder ? "encoder" : "decoder"; |
| 809 | const AVCodec *codec; | ||
| 810 | |||
| 811 | 14166 | codec = encoder ? | |
| 812 |
2/2✓ Branch 0 taken 4201 times.
✓ Branch 1 taken 9965 times.
|
14166 | avcodec_find_encoder_by_name(name) : |
| 813 | 9965 | avcodec_find_decoder_by_name(name); | |
| 814 | |||
| 815 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14165 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
14166 | if (!codec && (desc = avcodec_descriptor_get_by_name(name))) { |
| 816 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | codec = encoder ? avcodec_find_encoder(desc->id) : |
| 817 | ✗ | avcodec_find_decoder(desc->id); | |
| 818 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (codec) |
| 819 | 1 | av_log(logctx, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n", | |
| 820 | 1 | codec_string, codec->name, desc->name); | |
| 821 | } | ||
| 822 | |||
| 823 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14166 times.
|
14166 | if (!codec) { |
| 824 | ✗ | av_log(logctx, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name); | |
| 825 | ✗ | return encoder ? AVERROR_ENCODER_NOT_FOUND : | |
| 826 | AVERROR_DECODER_NOT_FOUND; | ||
| 827 | } | ||
| 828 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 14166 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
14166 | if (codec->type != type && !recast_media) { |
| 829 | ✗ | av_log(logctx, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name); | |
| 830 | ✗ | return AVERROR(EINVAL); | |
| 831 | } | ||
| 832 | |||
| 833 | 14166 | *pcodec = codec; | |
| 834 | 14166 | return 0;; | |
| 835 | } | ||
| 836 | |||
| 837 | 8506 | int assert_file_overwrite(const char *filename) | |
| 838 | { | ||
| 839 | 8506 | const char *proto_name = avio_find_protocol_name(filename); | |
| 840 | |||
| 841 |
3/4✓ Branch 0 taken 3025 times.
✓ Branch 1 taken 5481 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3025 times.
|
8506 | if (file_overwrite && no_file_overwrite) { |
| 842 | ✗ | fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n"); | |
| 843 | ✗ | return AVERROR(EINVAL); | |
| 844 | } | ||
| 845 | |||
| 846 |
2/2✓ Branch 0 taken 5481 times.
✓ Branch 1 taken 3025 times.
|
8506 | if (!file_overwrite) { |
| 847 |
2/6✓ Branch 0 taken 5481 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5481 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
5481 | if (proto_name && !strcmp(proto_name, "file") && avio_check(filename, 0) == 0) { |
| 848 | ✗ | if (stdin_interaction && !no_file_overwrite) { | |
| 849 | ✗ | fprintf(stderr,"File '%s' already exists. Overwrite? [y/N] ", filename); | |
| 850 | ✗ | fflush(stderr); | |
| 851 | ✗ | term_exit(); | |
| 852 | ✗ | signal(SIGINT, SIG_DFL); | |
| 853 | ✗ | if (!read_yesno()) { | |
| 854 | ✗ | av_log(NULL, AV_LOG_FATAL, "Not overwriting - exiting\n"); | |
| 855 | ✗ | return AVERROR_EXIT; | |
| 856 | } | ||
| 857 | ✗ | term_init(); | |
| 858 | } | ||
| 859 | else { | ||
| 860 | ✗ | av_log(NULL, AV_LOG_FATAL, "File '%s' already exists. Exiting.\n", filename); | |
| 861 | ✗ | return AVERROR_EXIT; | |
| 862 | } | ||
| 863 | } | ||
| 864 | } | ||
| 865 | |||
| 866 |
3/4✓ Branch 0 taken 8506 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2881 times.
✓ Branch 3 taken 5625 times.
|
8506 | if (proto_name && !strcmp(proto_name, "file")) { |
| 867 |
2/2✓ Branch 0 taken 1827 times.
✓ Branch 1 taken 2881 times.
|
4708 | for (int i = 0; i < nb_input_files; i++) { |
| 868 | 1827 | InputFile *file = input_files[i]; | |
| 869 |
2/2✓ Branch 0 taken 99 times.
✓ Branch 1 taken 1728 times.
|
1827 | if (file->ctx->iformat->flags & AVFMT_NOFILE) |
| 870 | 99 | continue; | |
| 871 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1728 times.
|
1728 | if (!strcmp(filename, file->ctx->url)) { |
| 872 | ✗ | av_log(NULL, AV_LOG_FATAL, "Output %s same as Input #%d - exiting\n", filename, i); | |
| 873 | ✗ | av_log(NULL, AV_LOG_WARNING, "FFmpeg cannot edit existing files in-place.\n"); | |
| 874 | ✗ | return AVERROR(EINVAL); | |
| 875 | } | ||
| 876 | } | ||
| 877 | } | ||
| 878 | |||
| 879 | 8506 | return 0; | |
| 880 | } | ||
| 881 | |||
| 882 | /* arg format is "output-stream-index:streamid-value". */ | ||
| 883 | 59 | static int opt_streamid(void *optctx, const char *opt, const char *arg) | |
| 884 | { | ||
| 885 | 59 | OptionsContext *o = optctx; | |
| 886 | char *p; | ||
| 887 | char idx_str[16]; | ||
| 888 | |||
| 889 | 59 | av_strlcpy(idx_str, arg, sizeof(idx_str)); | |
| 890 | 59 | p = strchr(idx_str, ':'); | |
| 891 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
|
59 | if (!p) { |
| 892 | ✗ | av_log(NULL, AV_LOG_FATAL, | |
| 893 | "Invalid value '%s' for option '%s', required syntax is 'index:value'\n", | ||
| 894 | arg, opt); | ||
| 895 | ✗ | return AVERROR(EINVAL); | |
| 896 | } | ||
| 897 | 59 | *p++ = '\0'; | |
| 898 | |||
| 899 | 59 | return av_dict_set(&o->streamid, idx_str, p, 0); | |
| 900 | } | ||
| 901 | |||
| 902 | ✗ | static int opt_target(void *optctx, const char *opt, const char *arg) | |
| 903 | { | ||
| 904 | ✗ | OptionsContext *o = optctx; | |
| 905 | ✗ | enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN; | |
| 906 | static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" }; | ||
| 907 | |||
| 908 | ✗ | if (!strncmp(arg, "pal-", 4)) { | |
| 909 | ✗ | norm = PAL; | |
| 910 | ✗ | arg += 4; | |
| 911 | ✗ | } else if (!strncmp(arg, "ntsc-", 5)) { | |
| 912 | ✗ | norm = NTSC; | |
| 913 | ✗ | arg += 5; | |
| 914 | ✗ | } else if (!strncmp(arg, "film-", 5)) { | |
| 915 | ✗ | norm = FILM; | |
| 916 | ✗ | arg += 5; | |
| 917 | } else { | ||
| 918 | /* Try to determine PAL/NTSC by peeking in the input files */ | ||
| 919 | ✗ | if (nb_input_files) { | |
| 920 | int i, j; | ||
| 921 | ✗ | for (j = 0; j < nb_input_files; j++) { | |
| 922 | ✗ | for (i = 0; i < input_files[j]->nb_streams; i++) { | |
| 923 | ✗ | AVStream *st = input_files[j]->ctx->streams[i]; | |
| 924 | int64_t fr; | ||
| 925 | ✗ | if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) | |
| 926 | ✗ | continue; | |
| 927 | ✗ | fr = st->time_base.den * 1000LL / st->time_base.num; | |
| 928 | ✗ | if (fr == 25000) { | |
| 929 | ✗ | norm = PAL; | |
| 930 | ✗ | break; | |
| 931 | ✗ | } else if ((fr == 29970) || (fr == 23976)) { | |
| 932 | ✗ | norm = NTSC; | |
| 933 | ✗ | break; | |
| 934 | } | ||
| 935 | } | ||
| 936 | ✗ | if (norm != UNKNOWN) | |
| 937 | ✗ | break; | |
| 938 | } | ||
| 939 | } | ||
| 940 | ✗ | if (norm != UNKNOWN) | |
| 941 | ✗ | av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC"); | |
| 942 | } | ||
| 943 | |||
| 944 | ✗ | if (norm == UNKNOWN) { | |
| 945 | ✗ | av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n"); | |
| 946 | ✗ | av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n"); | |
| 947 | ✗ | av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n"); | |
| 948 | ✗ | return AVERROR(EINVAL); | |
| 949 | } | ||
| 950 | |||
| 951 | ✗ | if (!strcmp(arg, "vcd")) { | |
| 952 | ✗ | opt_video_codec(o, "c:v", "mpeg1video"); | |
| 953 | ✗ | opt_audio_codec(o, "c:a", "mp2"); | |
| 954 | ✗ | parse_option(o, "f", "vcd", options); | |
| 955 | |||
| 956 | ✗ | parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options); | |
| 957 | ✗ | parse_option(o, "r", frame_rates[norm], options); | |
| 958 | ✗ | opt_default(NULL, "g", norm == PAL ? "15" : "18"); | |
| 959 | |||
| 960 | ✗ | opt_default(NULL, "b:v", "1150000"); | |
| 961 | ✗ | opt_default(NULL, "maxrate:v", "1150000"); | |
| 962 | ✗ | opt_default(NULL, "minrate:v", "1150000"); | |
| 963 | ✗ | opt_default(NULL, "bufsize:v", "327680"); // 40*1024*8; | |
| 964 | |||
| 965 | ✗ | opt_default(NULL, "b:a", "224000"); | |
| 966 | ✗ | parse_option(o, "ar", "44100", options); | |
| 967 | ✗ | parse_option(o, "ac", "2", options); | |
| 968 | |||
| 969 | ✗ | opt_default(NULL, "packetsize", "2324"); | |
| 970 | ✗ | opt_default(NULL, "muxrate", "1411200"); // 2352 * 75 * 8; | |
| 971 | |||
| 972 | /* We have to offset the PTS, so that it is consistent with the SCR. | ||
| 973 | SCR starts at 36000, but the first two packs contain only padding | ||
| 974 | and the first pack from the other stream, respectively, may also have | ||
| 975 | been written before. | ||
| 976 | So the real data starts at SCR 36000+3*1200. */ | ||
| 977 | ✗ | o->mux_preload = (36000 + 3 * 1200) / 90000.0; // 0.44 | |
| 978 | ✗ | } else if (!strcmp(arg, "svcd")) { | |
| 979 | |||
| 980 | ✗ | opt_video_codec(o, "c:v", "mpeg2video"); | |
| 981 | ✗ | opt_audio_codec(o, "c:a", "mp2"); | |
| 982 | ✗ | parse_option(o, "f", "svcd", options); | |
| 983 | |||
| 984 | ✗ | parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options); | |
| 985 | ✗ | parse_option(o, "r", frame_rates[norm], options); | |
| 986 | ✗ | parse_option(o, "pix_fmt", "yuv420p", options); | |
| 987 | ✗ | opt_default(NULL, "g", norm == PAL ? "15" : "18"); | |
| 988 | |||
| 989 | ✗ | opt_default(NULL, "b:v", "2040000"); | |
| 990 | ✗ | opt_default(NULL, "maxrate:v", "2516000"); | |
| 991 | ✗ | opt_default(NULL, "minrate:v", "0"); // 1145000; | |
| 992 | ✗ | opt_default(NULL, "bufsize:v", "1835008"); // 224*1024*8; | |
| 993 | ✗ | opt_default(NULL, "scan_offset", "1"); | |
| 994 | |||
| 995 | ✗ | opt_default(NULL, "b:a", "224000"); | |
| 996 | ✗ | parse_option(o, "ar", "44100", options); | |
| 997 | |||
| 998 | ✗ | opt_default(NULL, "packetsize", "2324"); | |
| 999 | |||
| 1000 | ✗ | } else if (!strcmp(arg, "dvd")) { | |
| 1001 | |||
| 1002 | ✗ | opt_video_codec(o, "c:v", "mpeg2video"); | |
| 1003 | ✗ | opt_audio_codec(o, "c:a", "ac3"); | |
| 1004 | ✗ | parse_option(o, "f", "dvd", options); | |
| 1005 | |||
| 1006 | ✗ | parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options); | |
| 1007 | ✗ | parse_option(o, "r", frame_rates[norm], options); | |
| 1008 | ✗ | parse_option(o, "pix_fmt", "yuv420p", options); | |
| 1009 | ✗ | opt_default(NULL, "g", norm == PAL ? "15" : "18"); | |
| 1010 | |||
| 1011 | ✗ | opt_default(NULL, "b:v", "6000000"); | |
| 1012 | ✗ | opt_default(NULL, "maxrate:v", "9000000"); | |
| 1013 | ✗ | opt_default(NULL, "minrate:v", "0"); // 1500000; | |
| 1014 | ✗ | opt_default(NULL, "bufsize:v", "1835008"); // 224*1024*8; | |
| 1015 | |||
| 1016 | ✗ | opt_default(NULL, "packetsize", "2048"); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack. | |
| 1017 | ✗ | opt_default(NULL, "muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8 | |
| 1018 | |||
| 1019 | ✗ | opt_default(NULL, "b:a", "448000"); | |
| 1020 | ✗ | parse_option(o, "ar", "48000", options); | |
| 1021 | |||
| 1022 | ✗ | } else if (!strncmp(arg, "dv", 2)) { | |
| 1023 | |||
| 1024 | ✗ | parse_option(o, "f", "dv", options); | |
| 1025 | |||
| 1026 | ✗ | parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options); | |
| 1027 | ✗ | parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" : | |
| 1028 | ✗ | norm == PAL ? "yuv420p" : "yuv411p", options); | |
| 1029 | ✗ | parse_option(o, "r", frame_rates[norm], options); | |
| 1030 | |||
| 1031 | ✗ | parse_option(o, "ar", "48000", options); | |
| 1032 | ✗ | parse_option(o, "ac", "2", options); | |
| 1033 | |||
| 1034 | } else { | ||
| 1035 | ✗ | av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg); | |
| 1036 | ✗ | return AVERROR(EINVAL); | |
| 1037 | } | ||
| 1038 | |||
| 1039 | ✗ | av_dict_copy(&o->g->codec_opts, codec_opts, AV_DICT_DONT_OVERWRITE); | |
| 1040 | ✗ | av_dict_copy(&o->g->format_opts, format_opts, AV_DICT_DONT_OVERWRITE); | |
| 1041 | |||
| 1042 | ✗ | return 0; | |
| 1043 | } | ||
| 1044 | |||
| 1045 | ✗ | static int opt_vstats_file(void *optctx, const char *opt, const char *arg) | |
| 1046 | { | ||
| 1047 | ✗ | av_free (vstats_filename); | |
| 1048 | ✗ | vstats_filename = av_strdup (arg); | |
| 1049 | ✗ | return 0; | |
| 1050 | } | ||
| 1051 | |||
| 1052 | ✗ | static int opt_vstats(void *optctx, const char *opt, const char *arg) | |
| 1053 | { | ||
| 1054 | char filename[40]; | ||
| 1055 | ✗ | time_t today2 = time(NULL); | |
| 1056 | ✗ | struct tm *today = localtime(&today2); | |
| 1057 | |||
| 1058 | ✗ | if (!today) { // maybe tomorrow | |
| 1059 | ✗ | av_log(NULL, AV_LOG_FATAL, "Unable to get current time: %s\n", strerror(errno)); | |
| 1060 | ✗ | return AVERROR(errno); | |
| 1061 | } | ||
| 1062 | |||
| 1063 | ✗ | snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min, | |
| 1064 | today->tm_sec); | ||
| 1065 | ✗ | return opt_vstats_file(NULL, opt, filename); | |
| 1066 | } | ||
| 1067 | |||
| 1068 | ✗ | static int opt_video_frames(void *optctx, const char *opt, const char *arg) | |
| 1069 | { | ||
| 1070 | ✗ | OptionsContext *o = optctx; | |
| 1071 | ✗ | return parse_option(o, "frames:v", arg, options); | |
| 1072 | } | ||
| 1073 | |||
| 1074 | ✗ | static int opt_audio_frames(void *optctx, const char *opt, const char *arg) | |
| 1075 | { | ||
| 1076 | ✗ | OptionsContext *o = optctx; | |
| 1077 | ✗ | return parse_option(o, "frames:a", arg, options); | |
| 1078 | } | ||
| 1079 | |||
| 1080 | ✗ | static int opt_data_frames(void *optctx, const char *opt, const char *arg) | |
| 1081 | { | ||
| 1082 | ✗ | OptionsContext *o = optctx; | |
| 1083 | ✗ | return parse_option(o, "frames:d", arg, options); | |
| 1084 | } | ||
| 1085 | |||
| 1086 | ✗ | static int opt_default_new(OptionsContext *o, const char *opt, const char *arg) | |
| 1087 | { | ||
| 1088 | int ret; | ||
| 1089 | ✗ | AVDictionary *cbak = codec_opts; | |
| 1090 | ✗ | AVDictionary *fbak = format_opts; | |
| 1091 | ✗ | codec_opts = NULL; | |
| 1092 | ✗ | format_opts = NULL; | |
| 1093 | |||
| 1094 | ✗ | ret = opt_default(NULL, opt, arg); | |
| 1095 | |||
| 1096 | ✗ | av_dict_copy(&o->g->codec_opts , codec_opts, 0); | |
| 1097 | ✗ | av_dict_copy(&o->g->format_opts, format_opts, 0); | |
| 1098 | ✗ | av_dict_free(&codec_opts); | |
| 1099 | ✗ | av_dict_free(&format_opts); | |
| 1100 | ✗ | codec_opts = cbak; | |
| 1101 | ✗ | format_opts = fbak; | |
| 1102 | |||
| 1103 | ✗ | return ret; | |
| 1104 | } | ||
| 1105 | |||
| 1106 | ✗ | static int opt_preset(void *optctx, const char *opt, const char *arg) | |
| 1107 | { | ||
| 1108 | ✗ | OptionsContext *o = optctx; | |
| 1109 | ✗ | FILE *f=NULL; | |
| 1110 | char filename[1000], line[1000], tmp_line[1000]; | ||
| 1111 | ✗ | const char *codec_name = NULL; | |
| 1112 | ✗ | int ret = 0; | |
| 1113 | |||
| 1114 | ✗ | codec_name = opt_match_per_type_str(&o->codec_names, *opt); | |
| 1115 | |||
| 1116 | ✗ | if (!(f = get_preset_file(filename, sizeof(filename), arg, *opt == 'f', codec_name))) { | |
| 1117 | ✗ | if(!strncmp(arg, "libx264-lossless", strlen("libx264-lossless"))){ | |
| 1118 | ✗ | av_log(NULL, AV_LOG_FATAL, "Please use -preset <speed> -qp 0\n"); | |
| 1119 | }else | ||
| 1120 | ✗ | av_log(NULL, AV_LOG_FATAL, "File for preset '%s' not found\n", arg); | |
| 1121 | ✗ | return AVERROR(ENOENT); | |
| 1122 | } | ||
| 1123 | |||
| 1124 | ✗ | while (fgets(line, sizeof(line), f)) { | |
| 1125 | ✗ | char *key = tmp_line, *value, *endptr; | |
| 1126 | |||
| 1127 | ✗ | if (strcspn(line, "#\n\r") == 0) | |
| 1128 | ✗ | continue; | |
| 1129 | ✗ | av_strlcpy(tmp_line, line, sizeof(tmp_line)); | |
| 1130 | ✗ | if (!av_strtok(key, "=", &value) || | |
| 1131 | ✗ | !av_strtok(value, "\r\n", &endptr)) { | |
| 1132 | ✗ | av_log(NULL, AV_LOG_FATAL, "%s: Invalid syntax: '%s'\n", filename, line); | |
| 1133 | ✗ | ret = AVERROR(EINVAL); | |
| 1134 | ✗ | goto fail; | |
| 1135 | } | ||
| 1136 | ✗ | av_log(NULL, AV_LOG_DEBUG, "ffpreset[%s]: set '%s' = '%s'\n", filename, key, value); | |
| 1137 | |||
| 1138 | ✗ | if (!strcmp(key, "acodec")) opt_audio_codec (o, key, value); | |
| 1139 | ✗ | else if (!strcmp(key, "vcodec")) opt_video_codec (o, key, value); | |
| 1140 | ✗ | else if (!strcmp(key, "scodec")) opt_subtitle_codec(o, key, value); | |
| 1141 | ✗ | else if (!strcmp(key, "dcodec")) opt_data_codec (o, key, value); | |
| 1142 | ✗ | else if ((parse_option(o, key, value, options) < 0) && | |
| 1143 | ✗ | (opt_default_new(o, key, value) < 0)) { | |
| 1144 | ✗ | av_log(NULL, AV_LOG_FATAL, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", | |
| 1145 | filename, line, key, value); | ||
| 1146 | ✗ | ret = AVERROR(EINVAL); | |
| 1147 | ✗ | goto fail; | |
| 1148 | } | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | ✗ | fail: | |
| 1152 | ✗ | fclose(f); | |
| 1153 | |||
| 1154 | ✗ | return ret; | |
| 1155 | } | ||
| 1156 | |||
| 1157 | ✗ | static int opt_old2new(void *optctx, const char *opt, const char *arg) | |
| 1158 | { | ||
| 1159 | ✗ | OptionsContext *o = optctx; | |
| 1160 | int ret; | ||
| 1161 | ✗ | char *s = av_asprintf("%s:%c", opt + 1, *opt); | |
| 1162 | ✗ | if (!s) | |
| 1163 | ✗ | return AVERROR(ENOMEM); | |
| 1164 | ✗ | ret = parse_option(o, s, arg, options); | |
| 1165 | ✗ | av_free(s); | |
| 1166 | ✗ | return ret; | |
| 1167 | } | ||
| 1168 | |||
| 1169 | 169 | static int opt_bitrate(void *optctx, const char *opt, const char *arg) | |
| 1170 | { | ||
| 1171 | 169 | OptionsContext *o = optctx; | |
| 1172 | |||
| 1173 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 167 times.
|
169 | if(!strcmp(opt, "ab")){ |
| 1174 | 2 | av_dict_set(&o->g->codec_opts, "b:a", arg, 0); | |
| 1175 | 2 | return 0; | |
| 1176 |
2/2✓ Branch 0 taken 43 times.
✓ Branch 1 taken 124 times.
|
167 | } else if(!strcmp(opt, "b")){ |
| 1177 | 43 | av_log(NULL, AV_LOG_WARNING, "Please use -b:a or -b:v, -b is ambiguous\n"); | |
| 1178 | 43 | av_dict_set(&o->g->codec_opts, "b:v", arg, 0); | |
| 1179 | 43 | return 0; | |
| 1180 | } | ||
| 1181 | 124 | av_dict_set(&o->g->codec_opts, opt, arg, 0); | |
| 1182 | 124 | return 0; | |
| 1183 | } | ||
| 1184 | |||
| 1185 | 289 | static int opt_qscale(void *optctx, const char *opt, const char *arg) | |
| 1186 | { | ||
| 1187 | 289 | OptionsContext *o = optctx; | |
| 1188 | char *s; | ||
| 1189 | int ret; | ||
| 1190 |
2/2✓ Branch 0 taken 247 times.
✓ Branch 1 taken 42 times.
|
289 | if(!strcmp(opt, "qscale")){ |
| 1191 | 247 | av_log(NULL, AV_LOG_WARNING, "Please use -q:a or -q:v, -qscale is ambiguous\n"); | |
| 1192 | 247 | return parse_option(o, "q:v", arg, options); | |
| 1193 | } | ||
| 1194 | 42 | s = av_asprintf("q%s", opt + 6); | |
| 1195 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
|
42 | if (!s) |
| 1196 | ✗ | return AVERROR(ENOMEM); | |
| 1197 | 42 | ret = parse_option(o, s, arg, options); | |
| 1198 | 42 | av_free(s); | |
| 1199 | 42 | return ret; | |
| 1200 | } | ||
| 1201 | |||
| 1202 | 44 | static int opt_profile(void *optctx, const char *opt, const char *arg) | |
| 1203 | { | ||
| 1204 | 44 | OptionsContext *o = optctx; | |
| 1205 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 40 times.
|
44 | if(!strcmp(opt, "profile")){ |
| 1206 | 4 | av_log(NULL, AV_LOG_WARNING, "Please use -profile:a or -profile:v, -profile is ambiguous\n"); | |
| 1207 | 4 | av_dict_set(&o->g->codec_opts, "profile:v", arg, 0); | |
| 1208 | 4 | return 0; | |
| 1209 | } | ||
| 1210 | 40 | av_dict_set(&o->g->codec_opts, opt, arg, 0); | |
| 1211 | 40 | return 0; | |
| 1212 | } | ||
| 1213 | |||
| 1214 | 3460 | static int opt_video_filters(void *optctx, const char *opt, const char *arg) | |
| 1215 | { | ||
| 1216 | 3460 | OptionsContext *o = optctx; | |
| 1217 | 3460 | return parse_option(o, "filter:v", arg, options); | |
| 1218 | } | ||
| 1219 | |||
| 1220 | 577 | static int opt_audio_filters(void *optctx, const char *opt, const char *arg) | |
| 1221 | { | ||
| 1222 | 577 | OptionsContext *o = optctx; | |
| 1223 | 577 | return parse_option(o, "filter:a", arg, options); | |
| 1224 | } | ||
| 1225 | |||
| 1226 | #if FFMPEG_OPT_VSYNC | ||
| 1227 | ✗ | static int opt_vsync(void *optctx, const char *opt, const char *arg) | |
| 1228 | { | ||
| 1229 | ✗ | av_log(NULL, AV_LOG_WARNING, "-vsync is deprecated. Use -fps_mode\n"); | |
| 1230 | ✗ | return parse_and_set_vsync(arg, &video_sync_method, -1, -1, 1); | |
| 1231 | } | ||
| 1232 | #endif | ||
| 1233 | |||
| 1234 | 15 | static int opt_timecode(void *optctx, const char *opt, const char *arg) | |
| 1235 | { | ||
| 1236 | 15 | OptionsContext *o = optctx; | |
| 1237 | int ret; | ||
| 1238 | 15 | char *tcr = av_asprintf("timecode=%s", arg); | |
| 1239 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
15 | if (!tcr) |
| 1240 | ✗ | return AVERROR(ENOMEM); | |
| 1241 | 15 | ret = parse_option(o, "metadata:g", tcr, options); | |
| 1242 |
1/2✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
|
15 | if (ret >= 0) |
| 1243 | 15 | ret = av_dict_set(&o->g->codec_opts, "gop_timecode", arg, 0); | |
| 1244 | 15 | av_free(tcr); | |
| 1245 | 15 | return ret; | |
| 1246 | } | ||
| 1247 | |||
| 1248 | ✗ | static int opt_audio_qscale(void *optctx, const char *opt, const char *arg) | |
| 1249 | { | ||
| 1250 | ✗ | OptionsContext *o = optctx; | |
| 1251 | ✗ | return parse_option(o, "q:a", arg, options); | |
| 1252 | } | ||
| 1253 | |||
| 1254 | 1250 | static int opt_filter_complex(void *optctx, const char *opt, const char *arg) | |
| 1255 | { | ||
| 1256 | 1250 | GlobalOptionsContext *go = optctx; | |
| 1257 | char *graph_desc; | ||
| 1258 | int ret; | ||
| 1259 | |||
| 1260 | 1250 | graph_desc = av_strdup(arg); | |
| 1261 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1250 times.
|
1250 | if (!graph_desc) |
| 1262 | ✗ | return AVERROR(ENOMEM); | |
| 1263 | |||
| 1264 | 1250 | ret = GROW_ARRAY(go->filtergraphs, go->nb_filtergraphs); | |
| 1265 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1250 times.
|
1250 | if (ret < 0) { |
| 1266 | ✗ | av_freep(&graph_desc); | |
| 1267 | ✗ | return ret; | |
| 1268 | } | ||
| 1269 | 1250 | go->filtergraphs[go->nb_filtergraphs - 1] = graph_desc; | |
| 1270 | |||
| 1271 | 1250 | return 0; | |
| 1272 | } | ||
| 1273 | |||
| 1274 | #if FFMPEG_OPT_FILTER_SCRIPT | ||
| 1275 | ✗ | static int opt_filter_complex_script(void *optctx, const char *opt, const char *arg) | |
| 1276 | { | ||
| 1277 | ✗ | GlobalOptionsContext *go = optctx; | |
| 1278 | char *graph_desc; | ||
| 1279 | int ret; | ||
| 1280 | |||
| 1281 | ✗ | graph_desc = read_file_to_string(arg); | |
| 1282 | ✗ | if (!graph_desc) | |
| 1283 | ✗ | return AVERROR(EINVAL); | |
| 1284 | |||
| 1285 | ✗ | av_log(NULL, AV_LOG_WARNING, "-%s is deprecated, use -/filter_complex %s instead\n", | |
| 1286 | opt, arg); | ||
| 1287 | |||
| 1288 | ✗ | ret = GROW_ARRAY(go->filtergraphs, go->nb_filtergraphs); | |
| 1289 | ✗ | if (ret < 0) { | |
| 1290 | ✗ | av_freep(&graph_desc); | |
| 1291 | ✗ | return ret; | |
| 1292 | } | ||
| 1293 | ✗ | go->filtergraphs[go->nb_filtergraphs - 1] = graph_desc; | |
| 1294 | |||
| 1295 | ✗ | return 0; | |
| 1296 | } | ||
| 1297 | #endif | ||
| 1298 | |||
| 1299 | ✗ | void show_help_default(const char *opt, const char *arg) | |
| 1300 | { | ||
| 1301 | ✗ | int show_advanced = 0, show_avoptions = 0; | |
| 1302 | |||
| 1303 | ✗ | if (opt && *opt) { | |
| 1304 | ✗ | if (!strcmp(opt, "long")) | |
| 1305 | ✗ | show_advanced = 1; | |
| 1306 | ✗ | else if (!strcmp(opt, "full")) | |
| 1307 | ✗ | show_advanced = show_avoptions = 1; | |
| 1308 | else | ||
| 1309 | ✗ | av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt); | |
| 1310 | } | ||
| 1311 | |||
| 1312 | ✗ | show_usage(); | |
| 1313 | |||
| 1314 | ✗ | printf("Getting help:\n" | |
| 1315 | " -h -- print basic options\n" | ||
| 1316 | " -h long -- print more options\n" | ||
| 1317 | " -h full -- print all options (including all format and codec specific options, very long)\n" | ||
| 1318 | " -h type=name -- print all options for the named decoder/encoder/demuxer/muxer/filter/bsf/protocol\n" | ||
| 1319 | " See man %s for detailed description of the options.\n" | ||
| 1320 | "\n" | ||
| 1321 | "Per-stream options can be followed by :<stream_spec> to apply that option to specific streams only. " | ||
| 1322 | "<stream_spec> can be a stream index, or v/a/s for video/audio/subtitle (see manual for full syntax).\n" | ||
| 1323 | "\n", program_name); | ||
| 1324 | |||
| 1325 | ✗ | show_help_options(options, "Print help / information / capabilities:", | |
| 1326 | OPT_EXIT, OPT_EXPERT); | ||
| 1327 | ✗ | if (show_advanced) | |
| 1328 | ✗ | show_help_options(options, "Advanced information / capabilities:", | |
| 1329 | OPT_EXIT | OPT_EXPERT, 0); | ||
| 1330 | |||
| 1331 | ✗ | show_help_options(options, "Global options (affect whole program " | |
| 1332 | "instead of just one file):", | ||
| 1333 | 0, OPT_PERFILE | OPT_EXIT | OPT_EXPERT); | ||
| 1334 | ✗ | if (show_advanced) | |
| 1335 | ✗ | show_help_options(options, "Advanced global options:", OPT_EXPERT, | |
| 1336 | OPT_PERFILE | OPT_EXIT); | ||
| 1337 | |||
| 1338 | ✗ | show_help_options(options, "Per-file options (input and output):", | |
| 1339 | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT, | ||
| 1340 | OPT_EXIT | OPT_FLAG_PERSTREAM | OPT_EXPERT | | ||
| 1341 | OPT_VIDEO | OPT_AUDIO | OPT_SUBTITLE | OPT_DATA); | ||
| 1342 | ✗ | if (show_advanced) | |
| 1343 | ✗ | show_help_options(options, "Advanced per-file options (input and output):", | |
| 1344 | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT | OPT_EXPERT, | ||
| 1345 | OPT_EXIT | OPT_FLAG_PERSTREAM | | ||
| 1346 | OPT_VIDEO | OPT_AUDIO | OPT_SUBTITLE | OPT_DATA); | ||
| 1347 | |||
| 1348 | ✗ | show_help_options(options, "Per-file options (input-only):", | |
| 1349 | OPT_PERFILE | OPT_INPUT, | ||
| 1350 | OPT_EXIT | OPT_FLAG_PERSTREAM | OPT_OUTPUT | OPT_EXPERT | | ||
| 1351 | OPT_VIDEO | OPT_AUDIO | OPT_SUBTITLE | OPT_DATA); | ||
| 1352 | ✗ | if (show_advanced) | |
| 1353 | ✗ | show_help_options(options, "Advanced per-file options (input-only):", | |
| 1354 | OPT_PERFILE | OPT_INPUT | OPT_EXPERT, | ||
| 1355 | OPT_EXIT | OPT_FLAG_PERSTREAM | OPT_OUTPUT | | ||
| 1356 | OPT_VIDEO | OPT_AUDIO | OPT_SUBTITLE | OPT_DATA); | ||
| 1357 | |||
| 1358 | ✗ | show_help_options(options, "Per-file options (output-only):", | |
| 1359 | OPT_PERFILE | OPT_OUTPUT, | ||
| 1360 | OPT_EXIT | OPT_FLAG_PERSTREAM | OPT_INPUT | OPT_EXPERT | | ||
| 1361 | OPT_VIDEO | OPT_AUDIO | OPT_SUBTITLE | OPT_DATA); | ||
| 1362 | ✗ | if (show_advanced) | |
| 1363 | ✗ | show_help_options(options, "Advanced per-file options (output-only):", | |
| 1364 | OPT_PERFILE | OPT_OUTPUT | OPT_EXPERT, | ||
| 1365 | OPT_EXIT | OPT_FLAG_PERSTREAM | OPT_INPUT | | ||
| 1366 | OPT_VIDEO | OPT_AUDIO | OPT_SUBTITLE | OPT_DATA); | ||
| 1367 | |||
| 1368 | ✗ | show_help_options(options, "Per-stream options:", | |
| 1369 | OPT_FLAG_PERSTREAM, | ||
| 1370 | OPT_EXIT | OPT_EXPERT | | ||
| 1371 | OPT_VIDEO | OPT_AUDIO | OPT_SUBTITLE | OPT_DATA); | ||
| 1372 | ✗ | if (show_advanced) | |
| 1373 | ✗ | show_help_options(options, "Advanced per-stream options:", | |
| 1374 | OPT_FLAG_PERSTREAM | OPT_EXPERT, | ||
| 1375 | OPT_EXIT | | ||
| 1376 | OPT_VIDEO | OPT_AUDIO | OPT_SUBTITLE | OPT_DATA); | ||
| 1377 | |||
| 1378 | ✗ | show_help_options(options, "Video options:", | |
| 1379 | OPT_VIDEO, OPT_EXPERT | OPT_AUDIO | OPT_SUBTITLE | OPT_DATA); | ||
| 1380 | ✗ | if (show_advanced) | |
| 1381 | ✗ | show_help_options(options, "Advanced Video options:", | |
| 1382 | OPT_EXPERT | OPT_VIDEO, OPT_AUDIO | OPT_SUBTITLE | OPT_DATA); | ||
| 1383 | |||
| 1384 | ✗ | show_help_options(options, "Audio options:", | |
| 1385 | OPT_AUDIO, OPT_EXPERT | OPT_VIDEO | OPT_SUBTITLE | OPT_DATA); | ||
| 1386 | ✗ | if (show_advanced) | |
| 1387 | ✗ | show_help_options(options, "Advanced Audio options:", | |
| 1388 | OPT_EXPERT | OPT_AUDIO, OPT_VIDEO | OPT_SUBTITLE | OPT_DATA); | ||
| 1389 | |||
| 1390 | ✗ | show_help_options(options, "Subtitle options:", | |
| 1391 | OPT_SUBTITLE, OPT_EXPERT | OPT_VIDEO | OPT_AUDIO | OPT_DATA); | ||
| 1392 | ✗ | if (show_advanced) | |
| 1393 | ✗ | show_help_options(options, "Advanced Subtitle options:", | |
| 1394 | OPT_EXPERT | OPT_SUBTITLE, OPT_VIDEO | OPT_AUDIO | OPT_DATA); | ||
| 1395 | |||
| 1396 | ✗ | if (show_advanced) | |
| 1397 | ✗ | show_help_options(options, "Data stream options:", | |
| 1398 | OPT_DATA, OPT_VIDEO | OPT_AUDIO | OPT_SUBTITLE); | ||
| 1399 | ✗ | printf("\n"); | |
| 1400 | |||
| 1401 | ✗ | if (show_avoptions) { | |
| 1402 | ✗ | int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM; | |
| 1403 | ✗ | show_help_children(avcodec_get_class(), flags); | |
| 1404 | ✗ | show_help_children(avformat_get_class(), flags); | |
| 1405 | #if CONFIG_SWSCALE | ||
| 1406 | ✗ | show_help_children(sws_get_class(), flags); | |
| 1407 | #endif | ||
| 1408 | #if CONFIG_SWRESAMPLE | ||
| 1409 | ✗ | show_help_children(swr_get_class(), AV_OPT_FLAG_AUDIO_PARAM); | |
| 1410 | #endif | ||
| 1411 | ✗ | show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM); | |
| 1412 | ✗ | show_help_children(av_bsf_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_BSF_PARAM); | |
| 1413 | } | ||
| 1414 | ✗ | } | |
| 1415 | |||
| 1416 | ✗ | void show_usage(void) | |
| 1417 | { | ||
| 1418 | ✗ | av_log(NULL, AV_LOG_INFO, "Universal media converter\n"); | |
| 1419 | ✗ | av_log(NULL, AV_LOG_INFO, "usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name); | |
| 1420 | ✗ | av_log(NULL, AV_LOG_INFO, "\n"); | |
| 1421 | ✗ | } | |
| 1422 | |||
| 1423 | enum OptGroup { | ||
| 1424 | GROUP_OUTFILE, | ||
| 1425 | GROUP_INFILE, | ||
| 1426 | GROUP_DECODER, | ||
| 1427 | }; | ||
| 1428 | |||
| 1429 | static const OptionGroupDef groups[] = { | ||
| 1430 | [GROUP_OUTFILE] = { "output url", NULL, OPT_OUTPUT }, | ||
| 1431 | [GROUP_INFILE] = { "input url", "i", OPT_INPUT }, | ||
| 1432 | [GROUP_DECODER] = { "loopback decoder", "dec", OPT_DECODER }, | ||
| 1433 | }; | ||
| 1434 | |||
| 1435 | 25773 | static int open_files(OptionGroupList *l, const char *inout, Scheduler *sch, | |
| 1436 | int (*open_file)(const OptionsContext*, const char*, | ||
| 1437 | Scheduler*)) | ||
| 1438 | { | ||
| 1439 | int i, ret; | ||
| 1440 | |||
| 1441 |
2/2✓ Branch 0 taken 16097 times.
✓ Branch 1 taken 25773 times.
|
41870 | for (i = 0; i < l->nb_groups; i++) { |
| 1442 | 16097 | OptionGroup *g = &l->groups[i]; | |
| 1443 | OptionsContext o; | ||
| 1444 | |||
| 1445 | 16097 | init_options(&o); | |
| 1446 | 16097 | o.g = g; | |
| 1447 | |||
| 1448 | 16097 | ret = parse_optgroup(&o, g, options); | |
| 1449 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16097 times.
|
16097 | if (ret < 0) { |
| 1450 | ✗ | av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file " | |
| 1451 | "%s.\n", inout, g->arg); | ||
| 1452 | ✗ | uninit_options(&o); | |
| 1453 | ✗ | return ret; | |
| 1454 | } | ||
| 1455 | |||
| 1456 | 16097 | av_log(NULL, AV_LOG_DEBUG, "Opening an %s file: %s.\n", inout, g->arg); | |
| 1457 | 16097 | ret = open_file(&o, g->arg, sch); | |
| 1458 | 16097 | uninit_options(&o); | |
| 1459 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16097 times.
|
16097 | if (ret < 0) { |
| 1460 | ✗ | av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n", | |
| 1461 | inout, g->arg); | ||
| 1462 | ✗ | return ret; | |
| 1463 | } | ||
| 1464 | 16097 | av_log(NULL, AV_LOG_DEBUG, "Successfully opened the file.\n"); | |
| 1465 | } | ||
| 1466 | |||
| 1467 | 25773 | return 0; | |
| 1468 | } | ||
| 1469 | |||
| 1470 | 8592 | int ffmpeg_parse_options(int argc, char **argv, Scheduler *sch) | |
| 1471 | { | ||
| 1472 | 8592 | GlobalOptionsContext go = { .sch = sch }; | |
| 1473 | OptionParseContext octx; | ||
| 1474 | 8592 | const char *errmsg = NULL; | |
| 1475 | int ret; | ||
| 1476 | |||
| 1477 | 8592 | memset(&octx, 0, sizeof(octx)); | |
| 1478 | |||
| 1479 | /* split the commandline into an internal representation */ | ||
| 1480 | 8592 | ret = split_commandline(&octx, argc, argv, options, groups, | |
| 1481 | FF_ARRAY_ELEMS(groups)); | ||
| 1482 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8592 times.
|
8592 | if (ret < 0) { |
| 1483 | ✗ | errmsg = "splitting the argument list"; | |
| 1484 | ✗ | goto fail; | |
| 1485 | } | ||
| 1486 | |||
| 1487 | /* apply global options */ | ||
| 1488 | 8592 | ret = parse_optgroup(&go, &octx.global_opts, options); | |
| 1489 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8591 times.
|
8592 | if (ret < 0) { |
| 1490 | 1 | errmsg = "parsing global options"; | |
| 1491 | 1 | goto fail; | |
| 1492 | } | ||
| 1493 | |||
| 1494 | /* configure terminal and setup signal handlers */ | ||
| 1495 | 8591 | term_init(); | |
| 1496 | |||
| 1497 | /* create complex filtergraphs */ | ||
| 1498 |
2/2✓ Branch 0 taken 1250 times.
✓ Branch 1 taken 8591 times.
|
9841 | for (int i = 0; i < go.nb_filtergraphs; i++) { |
| 1499 | 1250 | ret = fg_create(NULL, go.filtergraphs[i], sch, NULL); | |
| 1500 | 1250 | go.filtergraphs[i] = NULL; | |
| 1501 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1250 times.
|
1250 | if (ret < 0) |
| 1502 | ✗ | goto fail; | |
| 1503 | } | ||
| 1504 | |||
| 1505 | /* open input files */ | ||
| 1506 | 8591 | ret = open_files(&octx.groups[GROUP_INFILE], "input", sch, ifile_open); | |
| 1507 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8591 times.
|
8591 | if (ret < 0) { |
| 1508 | ✗ | errmsg = "opening input files"; | |
| 1509 | ✗ | goto fail; | |
| 1510 | } | ||
| 1511 | |||
| 1512 | /* open output files */ | ||
| 1513 | 8591 | ret = open_files(&octx.groups[GROUP_OUTFILE], "output", sch, of_open); | |
| 1514 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8591 times.
|
8591 | if (ret < 0) { |
| 1515 | ✗ | errmsg = "opening output files"; | |
| 1516 | ✗ | goto fail; | |
| 1517 | } | ||
| 1518 | |||
| 1519 | /* create loopback decoders */ | ||
| 1520 | 8591 | ret = open_files(&octx.groups[GROUP_DECODER], "decoder", sch, dec_create); | |
| 1521 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8591 times.
|
8591 | if (ret < 0) { |
| 1522 | ✗ | errmsg = "creating loopback decoders"; | |
| 1523 | ✗ | goto fail; | |
| 1524 | } | ||
| 1525 | |||
| 1526 | // bind unbound filtegraph inputs/outputs and check consistency | ||
| 1527 | 8591 | ret = fg_finalise_bindings(); | |
| 1528 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8591 times.
|
8591 | if (ret < 0) { |
| 1529 | ✗ | errmsg = "binding filtergraph inputs/outputs"; | |
| 1530 | ✗ | goto fail; | |
| 1531 | } | ||
| 1532 | |||
| 1533 | 8591 | correct_input_start_times(); | |
| 1534 | |||
| 1535 | 8591 | ret = apply_sync_offsets(); | |
| 1536 |
1/2✓ Branch 0 taken 8591 times.
✗ Branch 1 not taken.
|
8591 | if (ret < 0) |
| 1537 | ✗ | goto fail; | |
| 1538 | |||
| 1539 | 8591 | fail: | |
| 1540 |
2/2✓ Branch 0 taken 1250 times.
✓ Branch 1 taken 8592 times.
|
9842 | for (int i = 0; i < go.nb_filtergraphs; i++) |
| 1541 | 1250 | av_freep(&go.filtergraphs[i]); | |
| 1542 | 8592 | av_freep(&go.filtergraphs); | |
| 1543 | |||
| 1544 | 8592 | uninit_parse_context(&octx); | |
| 1545 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8591 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
8592 | if (ret < 0 && ret != AVERROR_EXIT) { |
| 1546 | ✗ | av_log(NULL, AV_LOG_FATAL, "Error %s: %s\n", | |
| 1547 | ✗ | errmsg ? errmsg : "", av_err2str(ret)); | |
| 1548 | } | ||
| 1549 | 8592 | return ret; | |
| 1550 | } | ||
| 1551 | |||
| 1552 | ✗ | static int opt_progress(void *optctx, const char *opt, const char *arg) | |
| 1553 | { | ||
| 1554 | ✗ | AVIOContext *avio = NULL; | |
| 1555 | int ret; | ||
| 1556 | |||
| 1557 | ✗ | if (!strcmp(arg, "-")) | |
| 1558 | ✗ | arg = "pipe:"; | |
| 1559 | ✗ | ret = avio_open2(&avio, arg, AVIO_FLAG_WRITE, &int_cb, NULL); | |
| 1560 | ✗ | if (ret < 0) { | |
| 1561 | ✗ | av_log(NULL, AV_LOG_ERROR, "Failed to open progress URL \"%s\": %s\n", | |
| 1562 | ✗ | arg, av_err2str(ret)); | |
| 1563 | ✗ | return ret; | |
| 1564 | } | ||
| 1565 | ✗ | progress_avio = avio; | |
| 1566 | ✗ | return 0; | |
| 1567 | } | ||
| 1568 | |||
| 1569 | ✗ | int opt_timelimit(void *optctx, const char *opt, const char *arg) | |
| 1570 | { | ||
| 1571 | #if HAVE_SETRLIMIT | ||
| 1572 | int ret; | ||
| 1573 | double lim; | ||
| 1574 | struct rlimit rl; | ||
| 1575 | |||
| 1576 | ✗ | ret = parse_number(opt, arg, OPT_TYPE_INT64, 0, INT_MAX, &lim); | |
| 1577 | ✗ | if (ret < 0) | |
| 1578 | ✗ | return ret; | |
| 1579 | |||
| 1580 | ✗ | rl = (struct rlimit){ lim, lim + 1 }; | |
| 1581 | ✗ | if (setrlimit(RLIMIT_CPU, &rl)) | |
| 1582 | ✗ | perror("setrlimit"); | |
| 1583 | #else | ||
| 1584 | av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt); | ||
| 1585 | #endif | ||
| 1586 | ✗ | return 0; | |
| 1587 | } | ||
| 1588 | |||
| 1589 | #if FFMPEG_OPT_QPHIST | ||
| 1590 | ✗ | static int opt_qphist(void *optctx, const char *opt, const char *arg) | |
| 1591 | { | ||
| 1592 | ✗ | av_log(NULL, AV_LOG_WARNING, "Option -%s is deprecated and has no effect\n", opt); | |
| 1593 | ✗ | return 0; | |
| 1594 | } | ||
| 1595 | #endif | ||
| 1596 | |||
| 1597 | #if FFMPEG_OPT_ADRIFT_THRESHOLD | ||
| 1598 | ✗ | static int opt_adrift_threshold(void *optctx, const char *opt, const char *arg) | |
| 1599 | { | ||
| 1600 | ✗ | av_log(NULL, AV_LOG_WARNING, "Option -%s is deprecated and has no effect\n", opt); | |
| 1601 | ✗ | return 0; | |
| 1602 | } | ||
| 1603 | #endif | ||
| 1604 | |||
| 1605 | static const char *const alt_channel_layout[] = { "ch_layout", NULL}; | ||
| 1606 | static const char *const alt_codec[] = { "c", "acodec", "vcodec", "scodec", "dcodec", NULL }; | ||
| 1607 | static const char *const alt_filter[] = { "af", "vf", NULL }; | ||
| 1608 | static const char *const alt_frames[] = { "aframes", "vframes", "dframes", NULL }; | ||
| 1609 | static const char *const alt_pre[] = { "apre", "vpre", "spre", NULL}; | ||
| 1610 | static const char *const alt_qscale[] = { "q", NULL}; | ||
| 1611 | static const char *const alt_tag[] = { "atag", "vtag", "stag", NULL }; | ||
| 1612 | |||
| 1613 | #define OFFSET(x) offsetof(OptionsContext, x) | ||
| 1614 | const OptionDef options[] = { | ||
| 1615 | /* main options */ | ||
| 1616 | CMDUTILS_COMMON_OPTIONS | ||
| 1617 | { "f", OPT_TYPE_STRING, OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, | ||
| 1618 | { .off = OFFSET(format) }, | ||
| 1619 | "force container format (auto-detected otherwise)", "fmt" }, | ||
| 1620 | { "y", OPT_TYPE_BOOL, 0, | ||
| 1621 | { &file_overwrite }, | ||
| 1622 | "overwrite output files" }, | ||
| 1623 | { "n", OPT_TYPE_BOOL, 0, | ||
| 1624 | { &no_file_overwrite }, | ||
| 1625 | "never overwrite output files" }, | ||
| 1626 | { "ignore_unknown", OPT_TYPE_BOOL, OPT_EXPERT, | ||
| 1627 | { &ignore_unknown_streams }, | ||
| 1628 | "Ignore unknown stream types" }, | ||
| 1629 | { "copy_unknown", OPT_TYPE_BOOL, OPT_EXPERT, | ||
| 1630 | { ©_unknown_streams }, | ||
| 1631 | "Copy unknown stream types" }, | ||
| 1632 | { "recast_media", OPT_TYPE_BOOL, OPT_EXPERT, | ||
| 1633 | { &recast_media }, | ||
| 1634 | "allow recasting stream type in order to force a decoder of different media type" }, | ||
| 1635 | { "c", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_INPUT | OPT_OUTPUT | OPT_DECODER | OPT_HAS_CANON, | ||
| 1636 | { .off = OFFSET(codec_names) }, | ||
| 1637 | "select encoder/decoder ('copy' to copy stream without reencoding)", "codec", | ||
| 1638 | .u1.name_canon = "codec", }, | ||
| 1639 | { "codec", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_INPUT | OPT_OUTPUT | OPT_DECODER | OPT_EXPERT | OPT_HAS_ALT, | ||
| 1640 | { .off = OFFSET(codec_names) }, | ||
| 1641 | "alias for -c (select encoder/decoder)", "codec", | ||
| 1642 | .u1.names_alt = alt_codec, }, | ||
| 1643 | { "pre", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_OUTPUT | OPT_EXPERT | OPT_HAS_ALT, | ||
| 1644 | { .off = OFFSET(presets) }, | ||
| 1645 | "preset name", "preset", | ||
| 1646 | .u1.names_alt = alt_pre, }, | ||
| 1647 | { "map", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT, | ||
| 1648 | { .func_arg = opt_map }, | ||
| 1649 | "set input stream mapping", | ||
| 1650 | "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" }, | ||
| 1651 | { "map_metadata", OPT_TYPE_STRING, OPT_SPEC | OPT_OUTPUT | OPT_EXPERT, | ||
| 1652 | { .off = OFFSET(metadata_map) }, | ||
| 1653 | "set metadata information of outfile from infile", | ||
| 1654 | "outfile[,metadata]:infile[,metadata]" }, | ||
| 1655 | { "map_chapters", OPT_TYPE_INT, OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, | ||
| 1656 | { .off = OFFSET(chapters_input_file) }, | ||
| 1657 | "set chapters mapping", "input_file_index" }, | ||
| 1658 | { "t", OPT_TYPE_TIME, OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, | ||
| 1659 | { .off = OFFSET(recording_time) }, | ||
| 1660 | "stop transcoding after specified duration", | ||
| 1661 | "duration" }, | ||
| 1662 | { "to", OPT_TYPE_TIME, OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, | ||
| 1663 | { .off = OFFSET(stop_time) }, | ||
| 1664 | "stop transcoding after specified time is reached", | ||
| 1665 | "time_stop" }, | ||
| 1666 | { "fs", OPT_TYPE_INT64, OPT_OFFSET | OPT_OUTPUT | OPT_EXPERT, | ||
| 1667 | { .off = OFFSET(limit_filesize) }, | ||
| 1668 | "set the limit file size in bytes", "limit_size" }, | ||
| 1669 | { "ss", OPT_TYPE_TIME, OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, | ||
| 1670 | { .off = OFFSET(start_time) }, | ||
| 1671 | "start transcoding at specified time", "time_off" }, | ||
| 1672 | { "sseof", OPT_TYPE_TIME, OPT_OFFSET | OPT_INPUT | OPT_EXPERT, | ||
| 1673 | { .off = OFFSET(start_time_eof) }, | ||
| 1674 | "set the start time offset relative to EOF", "time_off" }, | ||
| 1675 | { "seek_timestamp", OPT_TYPE_INT, OPT_OFFSET | OPT_INPUT | OPT_EXPERT, | ||
| 1676 | { .off = OFFSET(seek_timestamp) }, | ||
| 1677 | "enable/disable seeking by timestamp with -ss" }, | ||
| 1678 | { "accurate_seek", OPT_TYPE_BOOL, OPT_OFFSET | OPT_EXPERT | OPT_INPUT, | ||
| 1679 | { .off = OFFSET(accurate_seek) }, | ||
| 1680 | "enable/disable accurate seeking with -ss" }, | ||
| 1681 | { "isync", OPT_TYPE_INT, OPT_OFFSET | OPT_EXPERT | OPT_INPUT, | ||
| 1682 | { .off = OFFSET(input_sync_ref) }, | ||
| 1683 | "Indicate the input index for sync reference", "sync ref" }, | ||
| 1684 | { "itsoffset", OPT_TYPE_TIME, OPT_OFFSET | OPT_EXPERT | OPT_INPUT, | ||
| 1685 | { .off = OFFSET(input_ts_offset) }, | ||
| 1686 | "set the input ts offset", "time_off" }, | ||
| 1687 | { "itsscale", OPT_TYPE_DOUBLE, OPT_PERSTREAM | OPT_EXPERT | OPT_INPUT, | ||
| 1688 | { .off = OFFSET(ts_scale) }, | ||
| 1689 | "set the input ts scale", "scale" }, | ||
| 1690 | { "timestamp", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_PERFILE | OPT_EXPERT | OPT_OUTPUT, | ||
| 1691 | { .func_arg = opt_recording_timestamp }, | ||
| 1692 | "set the recording timestamp ('now' to set the current time)", "time" }, | ||
| 1693 | { "metadata", OPT_TYPE_STRING, OPT_SPEC | OPT_OUTPUT, | ||
| 1694 | { .off = OFFSET(metadata) }, | ||
| 1695 | "add metadata", "key=value" }, | ||
| 1696 | { "program", OPT_TYPE_STRING, OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, | ||
| 1697 | { .off = OFFSET(program) }, | ||
| 1698 | "add program with specified streams", "title=string:st=number..." }, | ||
| 1699 | { "stream_group", OPT_TYPE_STRING, OPT_SPEC | OPT_OUTPUT | OPT_EXPERT, | ||
| 1700 | { .off = OFFSET(stream_groups) }, | ||
| 1701 | "add stream group with specified streams and group type-specific arguments", "id=number:st=number..." }, | ||
| 1702 | { "dframes", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_PERFILE | OPT_EXPERT | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 1703 | { .func_arg = opt_data_frames }, | ||
| 1704 | "set the number of data frames to output", "number", | ||
| 1705 | .u1.name_canon = "frames" }, | ||
| 1706 | { "benchmark", OPT_TYPE_BOOL, OPT_EXPERT, | ||
| 1707 | { &do_benchmark }, | ||
| 1708 | "add timings for benchmarking" }, | ||
| 1709 | { "benchmark_all", OPT_TYPE_BOOL, OPT_EXPERT, | ||
| 1710 | { &do_benchmark_all }, | ||
| 1711 | "add timings for each task" }, | ||
| 1712 | { "progress", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 1713 | { .func_arg = opt_progress }, | ||
| 1714 | "write program-readable progress information", "url" }, | ||
| 1715 | { "stdin", OPT_TYPE_BOOL, OPT_EXPERT, | ||
| 1716 | { &stdin_interaction }, | ||
| 1717 | "enable or disable interaction on standard input" }, | ||
| 1718 | { "timelimit", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 1719 | { .func_arg = opt_timelimit }, | ||
| 1720 | "set max runtime in seconds in CPU user time", "limit" }, | ||
| 1721 | { "dump", OPT_TYPE_BOOL, OPT_EXPERT, | ||
| 1722 | { &do_pkt_dump }, | ||
| 1723 | "dump each input packet" }, | ||
| 1724 | { "hex", OPT_TYPE_BOOL, OPT_EXPERT, | ||
| 1725 | { &do_hex_dump }, | ||
| 1726 | "when dumping packets, also dump the payload" }, | ||
| 1727 | { "re", OPT_TYPE_BOOL, OPT_EXPERT | OPT_OFFSET | OPT_INPUT, | ||
| 1728 | { .off = OFFSET(rate_emu) }, | ||
| 1729 | "read input at native frame rate; equivalent to -readrate 1", "" }, | ||
| 1730 | { "readrate", OPT_TYPE_FLOAT, OPT_OFFSET | OPT_EXPERT | OPT_INPUT, | ||
| 1731 | { .off = OFFSET(readrate) }, | ||
| 1732 | "read input at specified rate", "speed" }, | ||
| 1733 | { "readrate_initial_burst", OPT_TYPE_DOUBLE, OPT_OFFSET | OPT_EXPERT | OPT_INPUT, | ||
| 1734 | { .off = OFFSET(readrate_initial_burst) }, | ||
| 1735 | "The initial amount of input to burst read before imposing any readrate", "seconds" }, | ||
| 1736 | { "readrate_catchup", OPT_TYPE_FLOAT, OPT_OFFSET | OPT_EXPERT | OPT_INPUT, | ||
| 1737 | { .off = OFFSET(readrate_catchup) }, | ||
| 1738 | "Temporary readrate used to catch up if an input lags behind the specified readrate", "speed" }, | ||
| 1739 | { "target", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_PERFILE | OPT_EXPERT | OPT_OUTPUT, | ||
| 1740 | { .func_arg = opt_target }, | ||
| 1741 | "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\" or \"dv50\" " | ||
| 1742 | "with optional prefixes \"pal-\", \"ntsc-\" or \"film-\")", "type" }, | ||
| 1743 | { "frame_drop_threshold", OPT_TYPE_FLOAT, OPT_EXPERT, | ||
| 1744 | { &frame_drop_threshold }, | ||
| 1745 | "frame drop threshold", "" }, | ||
| 1746 | { "copyts", OPT_TYPE_BOOL, OPT_EXPERT, | ||
| 1747 | { ©_ts }, | ||
| 1748 | "copy timestamps" }, | ||
| 1749 | { "start_at_zero", OPT_TYPE_BOOL, OPT_EXPERT, | ||
| 1750 | { &start_at_zero }, | ||
| 1751 | "shift input timestamps to start at 0 when using copyts" }, | ||
| 1752 | { "copytb", OPT_TYPE_INT, OPT_EXPERT, | ||
| 1753 | { ©_tb }, | ||
| 1754 | "copy input stream time base when stream copying", "mode" }, | ||
| 1755 | { "shortest", OPT_TYPE_BOOL, OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, | ||
| 1756 | { .off = OFFSET(shortest) }, | ||
| 1757 | "finish encoding within shortest input" }, | ||
| 1758 | { "shortest_buf_duration", OPT_TYPE_FLOAT, OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, | ||
| 1759 | { .off = OFFSET(shortest_buf_duration) }, | ||
| 1760 | "maximum buffering duration (in seconds) for the -shortest option" }, | ||
| 1761 | { "bitexact", OPT_TYPE_BOOL, OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT | OPT_INPUT, | ||
| 1762 | { .off = OFFSET(bitexact) }, | ||
| 1763 | "bitexact mode" }, | ||
| 1764 | { "dts_delta_threshold", OPT_TYPE_FLOAT, OPT_EXPERT, | ||
| 1765 | { &dts_delta_threshold }, | ||
| 1766 | "timestamp discontinuity delta threshold", "threshold" }, | ||
| 1767 | { "dts_error_threshold", OPT_TYPE_FLOAT, OPT_EXPERT, | ||
| 1768 | { &dts_error_threshold }, | ||
| 1769 | "timestamp error delta threshold", "threshold" }, | ||
| 1770 | { "xerror", OPT_TYPE_BOOL, OPT_EXPERT, | ||
| 1771 | { &exit_on_error }, | ||
| 1772 | "exit on error", "error" }, | ||
| 1773 | { "abort_on", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 1774 | { .func_arg = opt_abort_on }, | ||
| 1775 | "abort on the specified condition flags", "flags" }, | ||
| 1776 | { "copyinkf", OPT_TYPE_BOOL, OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 1777 | { .off = OFFSET(copy_initial_nonkeyframes) }, | ||
| 1778 | "copy initial non-keyframes" }, | ||
| 1779 | { "copypriorss", OPT_TYPE_INT, OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 1780 | { .off = OFFSET(copy_prior_start) }, | ||
| 1781 | "copy or discard frames before start time" }, | ||
| 1782 | { "frames", OPT_TYPE_INT64, OPT_PERSTREAM | OPT_OUTPUT | OPT_EXPERT | OPT_HAS_ALT, | ||
| 1783 | { .off = OFFSET(max_frames) }, | ||
| 1784 | "set the number of frames to output", "number", | ||
| 1785 | .u1.names_alt = alt_frames, }, | ||
| 1786 | { "tag", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT | OPT_INPUT | OPT_HAS_ALT, | ||
| 1787 | { .off = OFFSET(codec_tags) }, | ||
| 1788 | "force codec tag/fourcc", "fourcc/tag", | ||
| 1789 | .u1.names_alt = alt_tag, }, | ||
| 1790 | { "q", OPT_TYPE_DOUBLE, OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 1791 | { .off = OFFSET(qscale) }, | ||
| 1792 | "use fixed quality scale (VBR)", "q", | ||
| 1793 | .u1.name_canon = "qscale", }, | ||
| 1794 | { "qscale", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT | OPT_HAS_ALT, | ||
| 1795 | { .func_arg = opt_qscale }, | ||
| 1796 | "use fixed quality scale (VBR)", "q", | ||
| 1797 | .u1.names_alt = alt_qscale, }, | ||
| 1798 | { "profile", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT, | ||
| 1799 | { .func_arg = opt_profile }, | ||
| 1800 | "set profile", "profile" }, | ||
| 1801 | { "filter", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_OUTPUT | OPT_HAS_ALT, | ||
| 1802 | { .off = OFFSET(filters) }, | ||
| 1803 | "apply specified filters to audio/video", "filter_graph", | ||
| 1804 | .u1.names_alt = alt_filter, }, | ||
| 1805 | { "filter_threads", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 1806 | { .func_arg = opt_filter_threads }, | ||
| 1807 | "number of non-complex filter threads" }, | ||
| 1808 | { "filter_buffered_frames", OPT_TYPE_INT, OPT_EXPERT, | ||
| 1809 | { &filter_buffered_frames }, | ||
| 1810 | "maximum number of buffered frames in a filter graph" }, | ||
| 1811 | #if FFMPEG_OPT_FILTER_SCRIPT | ||
| 1812 | { "filter_script", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT, | ||
| 1813 | { .off = OFFSET(filter_scripts) }, | ||
| 1814 | "deprecated, use -/filter", "filename" }, | ||
| 1815 | #endif | ||
| 1816 | { "reinit_filter", OPT_TYPE_INT, OPT_PERSTREAM | OPT_INPUT | OPT_EXPERT, | ||
| 1817 | { .off = OFFSET(reinit_filters) }, | ||
| 1818 | "reinit filtergraph on input parameter changes", "" }, | ||
| 1819 | { "drop_changed", OPT_TYPE_INT, OPT_PERSTREAM | OPT_INPUT | OPT_EXPERT, | ||
| 1820 | { .off = OFFSET(drop_changed) }, | ||
| 1821 | "drop frame instead of reiniting filtergraph on input parameter changes", "" }, | ||
| 1822 | { "filter_complex", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 1823 | { .func_arg = opt_filter_complex }, | ||
| 1824 | "create a complex filtergraph", "graph_description" }, | ||
| 1825 | { "filter_complex_threads", OPT_TYPE_INT, OPT_EXPERT, | ||
| 1826 | { &filter_complex_nbthreads }, | ||
| 1827 | "number of threads for -filter_complex" }, | ||
| 1828 | { "lavfi", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 1829 | { .func_arg = opt_filter_complex }, | ||
| 1830 | "create a complex filtergraph", "graph_description" }, | ||
| 1831 | #if FFMPEG_OPT_FILTER_SCRIPT | ||
| 1832 | { "filter_complex_script", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 1833 | { .func_arg = opt_filter_complex_script }, | ||
| 1834 | "deprecated, use -/filter_complex instead", "filename" }, | ||
| 1835 | #endif | ||
| 1836 | { "print_graphs", OPT_TYPE_BOOL, 0, | ||
| 1837 | { &print_graphs }, | ||
| 1838 | "print execution graph data to stderr" }, | ||
| 1839 | { "print_graphs_file", OPT_TYPE_STRING, 0, | ||
| 1840 | { &print_graphs_file }, | ||
| 1841 | "write execution graph data to the specified file", "filename" }, | ||
| 1842 | { "print_graphs_format", OPT_TYPE_STRING, 0, | ||
| 1843 | { &print_graphs_format }, | ||
| 1844 | "set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml, mermaid, mermaidhtml)", "format" }, | ||
| 1845 | { "auto_conversion_filters", OPT_TYPE_BOOL, OPT_EXPERT, | ||
| 1846 | { &auto_conversion_filters }, | ||
| 1847 | "enable automatic conversion filters globally" }, | ||
| 1848 | { "stats", OPT_TYPE_BOOL, 0, | ||
| 1849 | { &print_stats }, | ||
| 1850 | "print progress report during encoding", }, | ||
| 1851 | { "stats_period", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 1852 | { .func_arg = opt_stats_period }, | ||
| 1853 | "set the period at which ffmpeg updates stats and -progress output", "time" }, | ||
| 1854 | { "attach", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_PERFILE | OPT_EXPERT | OPT_OUTPUT, | ||
| 1855 | { .func_arg = opt_attach }, | ||
| 1856 | "add an attachment to the output file", "filename" }, | ||
| 1857 | { "dump_attachment", OPT_TYPE_STRING, OPT_SPEC | OPT_EXPERT | OPT_INPUT, | ||
| 1858 | { .off = OFFSET(dump_attachment) }, | ||
| 1859 | "extract an attachment into a file", "filename" }, | ||
| 1860 | { "stream_loop", OPT_TYPE_INT, OPT_EXPERT | OPT_INPUT | OPT_OFFSET, | ||
| 1861 | { .off = OFFSET(loop) }, "set number of times input stream shall be looped", "loop count" }, | ||
| 1862 | { "debug_ts", OPT_TYPE_BOOL, OPT_EXPERT, | ||
| 1863 | { &debug_ts }, | ||
| 1864 | "print timestamp debugging info" }, | ||
| 1865 | { "max_error_rate", OPT_TYPE_FLOAT, OPT_EXPERT, | ||
| 1866 | { &max_error_rate }, | ||
| 1867 | "ratio of decoding errors (0.0: no errors, 1.0: 100% errors) above which ffmpeg returns an error instead of success.", "maximum error rate" }, | ||
| 1868 | { "discard", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_INPUT | OPT_EXPERT, | ||
| 1869 | { .off = OFFSET(discard) }, | ||
| 1870 | "discard", "" }, | ||
| 1871 | { "disposition", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_OUTPUT | OPT_EXPERT, | ||
| 1872 | { .off = OFFSET(disposition) }, | ||
| 1873 | "disposition", "" }, | ||
| 1874 | { "thread_queue_size", OPT_TYPE_INT, OPT_OFFSET | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT, | ||
| 1875 | { .off = OFFSET(thread_queue_size) }, | ||
| 1876 | "set the maximum number of queued packets from the demuxer" }, | ||
| 1877 | { "find_stream_info", OPT_TYPE_BOOL, OPT_INPUT | OPT_EXPERT | OPT_OFFSET, | ||
| 1878 | { .off = OFFSET(find_stream_info) }, | ||
| 1879 | "read and decode the streams to fill missing information with heuristics" }, | ||
| 1880 | { "bits_per_raw_sample", OPT_TYPE_INT, OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 1881 | { .off = OFFSET(bits_per_raw_sample) }, | ||
| 1882 | "set the number of bits per raw sample", "number" }, | ||
| 1883 | |||
| 1884 | { "stats_enc_pre", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT, | ||
| 1885 | { .off = OFFSET(enc_stats_pre) }, | ||
| 1886 | "write encoding stats before encoding" }, | ||
| 1887 | { "stats_enc_post", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT, | ||
| 1888 | { .off = OFFSET(enc_stats_post) }, | ||
| 1889 | "write encoding stats after encoding" }, | ||
| 1890 | { "stats_mux_pre", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT, | ||
| 1891 | { .off = OFFSET(mux_stats) }, | ||
| 1892 | "write packets stats before muxing" }, | ||
| 1893 | { "stats_enc_pre_fmt", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT, | ||
| 1894 | { .off = OFFSET(enc_stats_pre_fmt) }, | ||
| 1895 | "format of the stats written with -stats_enc_pre" }, | ||
| 1896 | { "stats_enc_post_fmt", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT, | ||
| 1897 | { .off = OFFSET(enc_stats_post_fmt) }, | ||
| 1898 | "format of the stats written with -stats_enc_post" }, | ||
| 1899 | { "stats_mux_pre_fmt", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT, | ||
| 1900 | { .off = OFFSET(mux_stats_fmt) }, | ||
| 1901 | "format of the stats written with -stats_mux_pre" }, | ||
| 1902 | |||
| 1903 | /* video options */ | ||
| 1904 | { "vframes", OPT_TYPE_FUNC, OPT_VIDEO | OPT_FUNC_ARG | OPT_PERFILE | OPT_OUTPUT | OPT_EXPERT | OPT_HAS_CANON, | ||
| 1905 | { .func_arg = opt_video_frames }, | ||
| 1906 | "set the number of video frames to output", "number", | ||
| 1907 | .u1.name_canon = "frames", }, | ||
| 1908 | { "r", OPT_TYPE_STRING, OPT_VIDEO | OPT_PERSTREAM | OPT_INPUT | OPT_OUTPUT, | ||
| 1909 | { .off = OFFSET(frame_rates) }, | ||
| 1910 | "override input framerate/convert to given output framerate (Hz value, fraction or abbreviation)", "rate" }, | ||
| 1911 | { "fpsmax", OPT_TYPE_STRING, OPT_VIDEO | OPT_PERSTREAM | OPT_OUTPUT | OPT_EXPERT, | ||
| 1912 | { .off = OFFSET(max_frame_rates) }, | ||
| 1913 | "set max frame rate (Hz value, fraction or abbreviation)", "rate" }, | ||
| 1914 | { "s", OPT_TYPE_STRING, OPT_VIDEO | OPT_SUBTITLE | OPT_PERSTREAM | OPT_INPUT | OPT_OUTPUT, | ||
| 1915 | { .off = OFFSET(frame_sizes) }, | ||
| 1916 | "set frame size (WxH or abbreviation)", "size" }, | ||
| 1917 | { "aspect", OPT_TYPE_STRING, OPT_VIDEO | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 1918 | { .off = OFFSET(frame_aspect_ratios) }, | ||
| 1919 | "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" }, | ||
| 1920 | { "pix_fmt", OPT_TYPE_STRING, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_INPUT | OPT_OUTPUT, | ||
| 1921 | { .off = OFFSET(frame_pix_fmts) }, | ||
| 1922 | "set pixel format", "format" }, | ||
| 1923 | { "display_rotation", OPT_TYPE_DOUBLE, OPT_VIDEO | OPT_PERSTREAM | OPT_INPUT | OPT_EXPERT, | ||
| 1924 | { .off = OFFSET(display_rotations) }, | ||
| 1925 | "set pure counter-clockwise rotation in degrees for stream(s)", | ||
| 1926 | "angle" }, | ||
| 1927 | { "display_hflip", OPT_TYPE_BOOL, OPT_VIDEO | OPT_PERSTREAM | OPT_INPUT | OPT_EXPERT, | ||
| 1928 | { .off = OFFSET(display_hflips) }, | ||
| 1929 | "set display horizontal flip for stream(s) " | ||
| 1930 | "(overrides any display rotation if it is not set)"}, | ||
| 1931 | { "display_vflip", OPT_TYPE_BOOL, OPT_VIDEO | OPT_PERSTREAM | OPT_INPUT | OPT_EXPERT, | ||
| 1932 | { .off = OFFSET(display_vflips) }, | ||
| 1933 | "set display vertical flip for stream(s) " | ||
| 1934 | "(overrides any display rotation if it is not set)"}, | ||
| 1935 | { "vn", OPT_TYPE_BOOL, OPT_VIDEO | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, | ||
| 1936 | { .off = OFFSET(video_disable) }, | ||
| 1937 | "disable video" }, | ||
| 1938 | { "rc_override", OPT_TYPE_STRING, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 1939 | { .off = OFFSET(rc_overrides) }, | ||
| 1940 | "rate control override for specific intervals", "override" }, | ||
| 1941 | { "vcodec", OPT_TYPE_FUNC, OPT_VIDEO | OPT_FUNC_ARG | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 1942 | { .func_arg = opt_video_codec }, | ||
| 1943 | "alias for -c:v (select encoder/decoder for video streams)", "codec", | ||
| 1944 | .u1.name_canon = "codec", }, | ||
| 1945 | { "timecode", OPT_TYPE_FUNC, OPT_VIDEO | OPT_FUNC_ARG | OPT_PERFILE | OPT_OUTPUT | OPT_EXPERT, | ||
| 1946 | { .func_arg = opt_timecode }, | ||
| 1947 | "set initial TimeCode value.", "hh:mm:ss[:;.]ff" }, | ||
| 1948 | { "pass", OPT_TYPE_INT, OPT_VIDEO | OPT_PERSTREAM | OPT_OUTPUT | OPT_EXPERT, | ||
| 1949 | { .off = OFFSET(pass) }, | ||
| 1950 | "select the pass number (1 to 3)", "n" }, | ||
| 1951 | { "passlogfile", OPT_TYPE_STRING, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 1952 | { .off = OFFSET(passlogfiles) }, | ||
| 1953 | "select two pass log file name prefix", "prefix" }, | ||
| 1954 | { "vstats", OPT_TYPE_FUNC, OPT_VIDEO | OPT_EXPERT, | ||
| 1955 | { .func_arg = opt_vstats }, | ||
| 1956 | "dump video coding statistics to file" }, | ||
| 1957 | { "vstats_file", OPT_TYPE_FUNC, OPT_VIDEO | OPT_FUNC_ARG | OPT_EXPERT, | ||
| 1958 | { .func_arg = opt_vstats_file }, | ||
| 1959 | "dump video coding statistics to file", "file" }, | ||
| 1960 | { "vstats_version", OPT_TYPE_INT, OPT_VIDEO | OPT_EXPERT, | ||
| 1961 | { &vstats_version }, | ||
| 1962 | "Version of the vstats format to use."}, | ||
| 1963 | { "vf", OPT_TYPE_FUNC, OPT_VIDEO | OPT_FUNC_ARG | OPT_PERFILE | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 1964 | { .func_arg = opt_video_filters }, | ||
| 1965 | "alias for -filter:v (apply filters to video streams)", "filter_graph", | ||
| 1966 | .u1.name_canon = "filter", }, | ||
| 1967 | { "intra_matrix", OPT_TYPE_STRING, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 1968 | { .off = OFFSET(intra_matrices) }, | ||
| 1969 | "specify intra matrix coeffs", "matrix" }, | ||
| 1970 | { "inter_matrix", OPT_TYPE_STRING, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 1971 | { .off = OFFSET(inter_matrices) }, | ||
| 1972 | "specify inter matrix coeffs", "matrix" }, | ||
| 1973 | { "chroma_intra_matrix", OPT_TYPE_STRING, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 1974 | { .off = OFFSET(chroma_intra_matrices) }, | ||
| 1975 | "specify intra matrix coeffs", "matrix" }, | ||
| 1976 | { "vtag", OPT_TYPE_FUNC, OPT_VIDEO | OPT_FUNC_ARG | OPT_EXPERT | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 1977 | { .func_arg = opt_old2new }, | ||
| 1978 | "force video tag/fourcc", "fourcc/tag", | ||
| 1979 | .u1.name_canon = "tag", }, | ||
| 1980 | { "fps_mode", OPT_TYPE_STRING, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 1981 | { .off = OFFSET(fps_mode) }, | ||
| 1982 | "set framerate mode for matching video streams; overrides vsync" }, | ||
| 1983 | { "force_fps", OPT_TYPE_BOOL, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 1984 | { .off = OFFSET(force_fps) }, | ||
| 1985 | "force the selected framerate, disable the best supported framerate selection" }, | ||
| 1986 | { "streamid", OPT_TYPE_FUNC, OPT_VIDEO | OPT_FUNC_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT, | ||
| 1987 | { .func_arg = opt_streamid }, | ||
| 1988 | "set the value of an outfile streamid", "streamIndex:value" }, | ||
| 1989 | { "force_key_frames", OPT_TYPE_STRING, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 1990 | { .off = OFFSET(forced_key_frames) }, | ||
| 1991 | "force key frames at specified timestamps", "timestamps" }, | ||
| 1992 | { "b", OPT_TYPE_FUNC, OPT_VIDEO | OPT_FUNC_ARG | OPT_PERFILE | OPT_OUTPUT, | ||
| 1993 | { .func_arg = opt_bitrate }, | ||
| 1994 | "video bitrate (please use -b:v)", "bitrate" }, | ||
| 1995 | { "hwaccel", OPT_TYPE_STRING, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_INPUT, | ||
| 1996 | { .off = OFFSET(hwaccels) }, | ||
| 1997 | "use HW accelerated decoding", "hwaccel name" }, | ||
| 1998 | { "hwaccel_device", OPT_TYPE_STRING, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_INPUT, | ||
| 1999 | { .off = OFFSET(hwaccel_devices) }, | ||
| 2000 | "select a device for HW acceleration", "devicename" }, | ||
| 2001 | { "hwaccel_output_format", OPT_TYPE_STRING, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_INPUT, | ||
| 2002 | { .off = OFFSET(hwaccel_output_formats) }, | ||
| 2003 | "select output format used with HW accelerated decoding", "format" }, | ||
| 2004 | { "hwaccels", OPT_TYPE_FUNC, OPT_EXIT | OPT_EXPERT, | ||
| 2005 | { .func_arg = show_hwaccels }, | ||
| 2006 | "show available HW acceleration methods" }, | ||
| 2007 | { "autorotate", OPT_TYPE_BOOL, OPT_VIDEO | OPT_PERSTREAM | OPT_EXPERT | OPT_INPUT, | ||
| 2008 | { .off = OFFSET(autorotate) }, | ||
| 2009 | "automatically insert correct rotate filters" }, | ||
| 2010 | { "autoscale", OPT_TYPE_BOOL, OPT_VIDEO | OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT, | ||
| 2011 | { .off = OFFSET(autoscale) }, | ||
| 2012 | "automatically insert a scale filter at the end of the filter graph" }, | ||
| 2013 | { "apply_cropping", OPT_TYPE_STRING, OPT_VIDEO | OPT_PERSTREAM | OPT_EXPERT | OPT_INPUT, | ||
| 2014 | { .off = OFFSET(apply_cropping) }, | ||
| 2015 | "select the cropping to apply" }, | ||
| 2016 | { "fix_sub_duration_heartbeat", OPT_TYPE_BOOL, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 2017 | { .off = OFFSET(fix_sub_duration_heartbeat) }, | ||
| 2018 | "set this video output stream to be a heartbeat stream for " | ||
| 2019 | "fix_sub_duration, according to which subtitles should be split at " | ||
| 2020 | "random access points" }, | ||
| 2021 | |||
| 2022 | /* audio options */ | ||
| 2023 | { "aframes", OPT_TYPE_FUNC, OPT_AUDIO | OPT_FUNC_ARG | OPT_PERFILE | OPT_OUTPUT | OPT_EXPERT | OPT_HAS_CANON, | ||
| 2024 | { .func_arg = opt_audio_frames }, | ||
| 2025 | "set the number of audio frames to output", "number", | ||
| 2026 | .u1.name_canon = "frames", }, | ||
| 2027 | { "aq", OPT_TYPE_FUNC, OPT_AUDIO | OPT_FUNC_ARG | OPT_PERFILE | OPT_OUTPUT, | ||
| 2028 | { .func_arg = opt_audio_qscale }, | ||
| 2029 | "set audio quality (codec-specific)", "quality", }, | ||
| 2030 | { "ar", OPT_TYPE_INT, OPT_AUDIO | OPT_PERSTREAM | OPT_INPUT | OPT_OUTPUT, | ||
| 2031 | { .off = OFFSET(audio_sample_rate) }, | ||
| 2032 | "set audio sampling rate (in Hz)", "rate" }, | ||
| 2033 | { "ac", OPT_TYPE_INT, OPT_AUDIO | OPT_PERSTREAM | OPT_INPUT | OPT_OUTPUT, | ||
| 2034 | { .off = OFFSET(audio_channels) }, | ||
| 2035 | "set number of audio channels", "channels" }, | ||
| 2036 | { "an", OPT_TYPE_BOOL, OPT_AUDIO | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, | ||
| 2037 | { .off = OFFSET(audio_disable) }, | ||
| 2038 | "disable audio" }, | ||
| 2039 | { "acodec", OPT_TYPE_FUNC, OPT_AUDIO | OPT_FUNC_ARG | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 2040 | { .func_arg = opt_audio_codec }, | ||
| 2041 | "alias for -c:a (select encoder/decoder for audio streams)", "codec", | ||
| 2042 | .u1.name_canon = "codec", }, | ||
| 2043 | { "ab", OPT_TYPE_FUNC, OPT_AUDIO | OPT_FUNC_ARG | OPT_PERFILE | OPT_OUTPUT, | ||
| 2044 | { .func_arg = opt_bitrate }, | ||
| 2045 | "alias for -b:a (select bitrate for audio streams)", "bitrate" }, | ||
| 2046 | { "apad", OPT_TYPE_STRING, OPT_AUDIO | OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT, | ||
| 2047 | { .off = OFFSET(apad) }, | ||
| 2048 | "audio pad", "" }, | ||
| 2049 | { "atag", OPT_TYPE_FUNC, OPT_AUDIO | OPT_FUNC_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 2050 | { .func_arg = opt_old2new }, | ||
| 2051 | "force audio tag/fourcc", "fourcc/tag", | ||
| 2052 | .u1.name_canon = "tag", }, | ||
| 2053 | { "sample_fmt", OPT_TYPE_STRING, OPT_AUDIO | OPT_EXPERT | OPT_PERSTREAM | OPT_INPUT | OPT_OUTPUT, | ||
| 2054 | { .off = OFFSET(sample_fmts) }, | ||
| 2055 | "set sample format", "format" }, | ||
| 2056 | { "channel_layout", OPT_TYPE_STRING, OPT_AUDIO | OPT_EXPERT | OPT_PERSTREAM | OPT_INPUT | OPT_OUTPUT | OPT_HAS_ALT, | ||
| 2057 | { .off = OFFSET(audio_ch_layouts) }, | ||
| 2058 | "set channel layout", "layout", | ||
| 2059 | .u1.names_alt = alt_channel_layout, }, | ||
| 2060 | { "ch_layout", OPT_TYPE_STRING, OPT_AUDIO | OPT_EXPERT | OPT_PERSTREAM | OPT_INPUT | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 2061 | { .off = OFFSET(audio_ch_layouts) }, | ||
| 2062 | "set channel layout", "layout", | ||
| 2063 | .u1.name_canon = "channel_layout", }, | ||
| 2064 | { "af", OPT_TYPE_FUNC, OPT_AUDIO | OPT_FUNC_ARG | OPT_PERFILE | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 2065 | { .func_arg = opt_audio_filters }, | ||
| 2066 | "alias for -filter:a (apply filters to audio streams)", "filter_graph", | ||
| 2067 | .u1.name_canon = "filter", }, | ||
| 2068 | { "guess_layout_max", OPT_TYPE_INT, OPT_AUDIO | OPT_PERSTREAM | OPT_EXPERT | OPT_INPUT, | ||
| 2069 | { .off = OFFSET(guess_layout_max) }, | ||
| 2070 | "set the maximum number of channels to try to guess the channel layout" }, | ||
| 2071 | |||
| 2072 | /* subtitle options */ | ||
| 2073 | { "sn", OPT_TYPE_BOOL, OPT_SUBTITLE | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, | ||
| 2074 | { .off = OFFSET(subtitle_disable) }, | ||
| 2075 | "disable subtitle" }, | ||
| 2076 | { "scodec", OPT_TYPE_FUNC, OPT_SUBTITLE | OPT_FUNC_ARG | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 2077 | { .func_arg = opt_subtitle_codec }, | ||
| 2078 | "alias for -c:s (select encoder/decoder for subtitle streams)", "codec", | ||
| 2079 | .u1.name_canon = "codec", }, | ||
| 2080 | { "stag", OPT_TYPE_FUNC, OPT_SUBTITLE | OPT_FUNC_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 2081 | { .func_arg = opt_old2new } | ||
| 2082 | , "force subtitle tag/fourcc", "fourcc/tag", | ||
| 2083 | .u1.name_canon = "tag" }, | ||
| 2084 | { "fix_sub_duration", OPT_TYPE_BOOL, OPT_EXPERT | OPT_SUBTITLE | OPT_PERSTREAM | OPT_INPUT, | ||
| 2085 | { .off = OFFSET(fix_sub_duration) }, | ||
| 2086 | "fix subtitles duration" }, | ||
| 2087 | { "canvas_size", OPT_TYPE_STRING, OPT_SUBTITLE | OPT_PERSTREAM | OPT_INPUT | OPT_EXPERT, | ||
| 2088 | { .off = OFFSET(canvas_sizes) }, | ||
| 2089 | "set canvas size (WxH or abbreviation)", "size" }, | ||
| 2090 | |||
| 2091 | /* muxer options */ | ||
| 2092 | { "muxdelay", OPT_TYPE_FLOAT, OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, | ||
| 2093 | { .off = OFFSET(mux_max_delay) }, | ||
| 2094 | "set the maximum demux-decode delay", "seconds" }, | ||
| 2095 | { "muxpreload", OPT_TYPE_FLOAT, OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, | ||
| 2096 | { .off = OFFSET(mux_preload) }, | ||
| 2097 | "set the initial demux-decode delay", "seconds" }, | ||
| 2098 | { "sdp_file", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT | OPT_OUTPUT, | ||
| 2099 | { .func_arg = opt_sdp_file }, | ||
| 2100 | "specify a file in which to print sdp information", "file" }, | ||
| 2101 | |||
| 2102 | { "time_base", OPT_TYPE_STRING, OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 2103 | { .off = OFFSET(time_bases) }, | ||
| 2104 | "set the desired time base hint for output stream (1:24, 1:48000 or 0.04166, 2.0833e-5)", "ratio" }, | ||
| 2105 | { "enc_time_base", OPT_TYPE_STRING, OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT, | ||
| 2106 | { .off = OFFSET(enc_time_bases) }, | ||
| 2107 | "set the desired time base for the encoder (1:24, 1:48000 or 0.04166, 2.0833e-5). " | ||
| 2108 | "two special values are defined - " | ||
| 2109 | "0 = use frame rate (video) or sample rate (audio)," | ||
| 2110 | "-1 = match source time base", "ratio" }, | ||
| 2111 | |||
| 2112 | { "bsf", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT | OPT_INPUT, | ||
| 2113 | { .off = OFFSET(bitstream_filters) }, | ||
| 2114 | "A comma-separated list of bitstream filters", "bitstream_filters", }, | ||
| 2115 | |||
| 2116 | { "apre", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_AUDIO | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 2117 | { .func_arg = opt_preset }, | ||
| 2118 | "set the audio options to the indicated preset", "preset", | ||
| 2119 | .u1.name_canon = "pre", }, | ||
| 2120 | { "vpre", OPT_TYPE_FUNC, OPT_VIDEO | OPT_FUNC_ARG | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 2121 | { .func_arg = opt_preset }, | ||
| 2122 | "set the video options to the indicated preset", "preset", | ||
| 2123 | .u1.name_canon = "pre", }, | ||
| 2124 | { "spre", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_SUBTITLE | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 2125 | { .func_arg = opt_preset }, | ||
| 2126 | "set the subtitle options to the indicated preset", "preset", | ||
| 2127 | .u1.name_canon = "pre", }, | ||
| 2128 | { "fpre", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 2129 | { .func_arg = opt_preset }, | ||
| 2130 | "set options from indicated preset file", "filename", | ||
| 2131 | .u1.name_canon = "pre", }, | ||
| 2132 | |||
| 2133 | { "max_muxing_queue_size", OPT_TYPE_INT, OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT, | ||
| 2134 | { .off = OFFSET(max_muxing_queue_size) }, | ||
| 2135 | "maximum number of packets that can be buffered while waiting for all streams to initialize", "packets" }, | ||
| 2136 | { "muxing_queue_data_threshold", OPT_TYPE_INT, OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT, | ||
| 2137 | { .off = OFFSET(muxing_queue_data_threshold) }, | ||
| 2138 | "set the threshold after which max_muxing_queue_size is taken into account", "bytes" }, | ||
| 2139 | |||
| 2140 | /* data codec support */ | ||
| 2141 | { "dcodec", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT | OPT_HAS_CANON, | ||
| 2142 | { .func_arg = opt_data_codec }, | ||
| 2143 | "alias for -c:d (select encoder/decoder for data streams)", "codec", | ||
| 2144 | .u1.name_canon = "codec", }, | ||
| 2145 | { "dn", OPT_TYPE_BOOL, OPT_DATA | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, | ||
| 2146 | { .off = OFFSET(data_disable) }, "disable data" }, | ||
| 2147 | |||
| 2148 | #if CONFIG_VAAPI | ||
| 2149 | { "vaapi_device", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 2150 | { .func_arg = opt_vaapi_device }, | ||
| 2151 | "set VAAPI hardware device (DirectX adapter index, DRM path or X11 display name)", "device" }, | ||
| 2152 | #endif | ||
| 2153 | |||
| 2154 | #if CONFIG_QSV | ||
| 2155 | { "qsv_device", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 2156 | { .func_arg = opt_qsv_device }, | ||
| 2157 | "set QSV hardware device (DirectX adapter index, DRM path or X11 display name)", "device"}, | ||
| 2158 | #endif | ||
| 2159 | |||
| 2160 | { "init_hw_device", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 2161 | { .func_arg = opt_init_hw_device }, | ||
| 2162 | "initialise hardware device", "args" }, | ||
| 2163 | { "filter_hw_device", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 2164 | { .func_arg = opt_filter_hw_device }, | ||
| 2165 | "set hardware device used when filtering", "device" }, | ||
| 2166 | |||
| 2167 | // deprecated options | ||
| 2168 | #if FFMPEG_OPT_ADRIFT_THRESHOLD | ||
| 2169 | { "adrift_threshold", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 2170 | { .func_arg = opt_adrift_threshold }, | ||
| 2171 | "deprecated, does nothing", "threshold" }, | ||
| 2172 | #endif | ||
| 2173 | #if FFMPEG_OPT_TOP | ||
| 2174 | { "top", OPT_TYPE_INT, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_INPUT | OPT_OUTPUT, | ||
| 2175 | { .off = OFFSET(top_field_first) }, | ||
| 2176 | "deprecated, use the setfield video filter", "" }, | ||
| 2177 | #endif | ||
| 2178 | #if FFMPEG_OPT_QPHIST | ||
| 2179 | { "qphist", OPT_TYPE_FUNC, OPT_VIDEO | OPT_EXPERT, | ||
| 2180 | { .func_arg = opt_qphist }, | ||
| 2181 | "deprecated, does nothing" }, | ||
| 2182 | #endif | ||
| 2183 | #if FFMPEG_OPT_VSYNC | ||
| 2184 | { "vsync", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, | ||
| 2185 | { .func_arg = opt_vsync }, | ||
| 2186 | "set video sync method globally; deprecated, use -fps_mode", "" }, | ||
| 2187 | #endif | ||
| 2188 | |||
| 2189 | { NULL, }, | ||
| 2190 | }; | ||
| 2191 |