* qatar/master:
lavc: fix type for thread_type option
avconv: move format to options context
avconv: move limit_filesize to options context
avconv: move start_time, recording_time and input_ts_offset to options context
avconv: add a context for options.
cmdutils: allow storing per-stream/chapter/.... options in a generic way
cmdutils: split per-option code out of parse_options().
cmdutils: add support for caller-provided option context.
cmdutils: declare only one pointer type in OptionDef
cmdutils: move grow_array() from avconv to cmdutils.
cmdutils: move exit_program() declaration to cmdutils from avconv
http: Consider the stream as seekable if the reply contains Accept-Ranges: bytes
nutenc: add namespace to the api facing functions
Conflicts:
avconv.c
cmdutils.c
cmdutils.h
ffmpeg.c
ffplay.c
ffprobe.c
ffserver.c
libavformat/http.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
| ... | ... |
@@ -110,12 +110,8 @@ typedef struct MetadataMap {
|
| 110 | 110 |
static const OptionDef options[]; |
| 111 | 111 |
|
| 112 | 112 |
#define MAX_STREAMS 1024 /* arbitrary sanity check value */ |
| 113 |
-static const char *last_asked_format = NULL; |
|
| 114 | 113 |
static AVDictionary *ts_scale; |
| 115 | 114 |
|
| 116 |
-static StreamMap *stream_maps = NULL; |
|
| 117 |
-static int nb_stream_maps; |
|
| 118 |
- |
|
| 119 | 115 |
static AVDictionary *codec_names; |
| 120 | 116 |
|
| 121 | 117 |
/* first item specifies output metadata, second is input */ |
| ... | ... |
@@ -175,9 +171,6 @@ static unsigned int data_codec_tag = 0; |
| 175 | 175 |
static float mux_preload= 0.5; |
| 176 | 176 |
static float mux_max_delay= 0.7; |
| 177 | 177 |
|
| 178 |
-static int64_t recording_time = INT64_MAX; |
|
| 179 |
-static int64_t start_time = 0; |
|
| 180 |
-static int64_t input_ts_offset = 0; |
|
| 181 | 178 |
static int file_overwrite = 0; |
| 182 | 179 |
static AVDictionary *metadata; |
| 183 | 180 |
static int do_benchmark = 0; |
| ... | ... |
@@ -212,7 +205,6 @@ static int64_t extra_size = 0; |
| 212 | 212 |
static int nb_frames_dup = 0; |
| 213 | 213 |
static int nb_frames_drop = 0; |
| 214 | 214 |
static int input_sync; |
| 215 |
-static uint64_t limit_filesize = UINT64_MAX; |
|
| 216 | 215 |
static int force_fps = 0; |
| 217 | 216 |
static char *forced_key_frames = NULL; |
| 218 | 217 |
|
| ... | ... |
@@ -337,6 +329,56 @@ static int nb_output_streams = 0; |
| 337 | 337 |
static OutputFile *output_files = NULL; |
| 338 | 338 |
static int nb_output_files = 0; |
| 339 | 339 |
|
| 340 |
+typedef struct OptionsContext {
|
|
| 341 |
+ /* input/output options */ |
|
| 342 |
+ int64_t start_time; |
|
| 343 |
+ const char *format; |
|
| 344 |
+ |
|
| 345 |
+ /* input options */ |
|
| 346 |
+ int64_t input_ts_offset; |
|
| 347 |
+ |
|
| 348 |
+ /* output options */ |
|
| 349 |
+ StreamMap *stream_maps; |
|
| 350 |
+ int nb_stream_maps; |
|
| 351 |
+ |
|
| 352 |
+ int64_t recording_time; |
|
| 353 |
+ uint64_t limit_filesize; |
|
| 354 |
+} OptionsContext; |
|
| 355 |
+ |
|
| 356 |
+static void reset_options(OptionsContext *o) |
|
| 357 |
+{
|
|
| 358 |
+ const OptionDef *po = options; |
|
| 359 |
+ |
|
| 360 |
+ /* all OPT_SPEC and OPT_STRING can be freed in generic way */ |
|
| 361 |
+ while (po->name) {
|
|
| 362 |
+ void *dst = (uint8_t*)o + po->u.off; |
|
| 363 |
+ |
|
| 364 |
+ if (po->flags & OPT_SPEC) {
|
|
| 365 |
+ SpecifierOpt **so = dst; |
|
| 366 |
+ int i, *count = (int*)(so + 1); |
|
| 367 |
+ for (i = 0; i < *count; i++) {
|
|
| 368 |
+ av_freep(&(*so)[i].specifier); |
|
| 369 |
+ if (po->flags & OPT_STRING) |
|
| 370 |
+ av_freep(&(*so)[i].u.str); |
|
| 371 |
+ } |
|
| 372 |
+ av_freep(so); |
|
| 373 |
+ *count = 0; |
|
| 374 |
+ } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING) |
|
| 375 |
+ av_freep(dst); |
|
| 376 |
+ po++; |
|
| 377 |
+ } |
|
| 378 |
+ |
|
| 379 |
+ av_freep(&o->stream_maps); |
|
| 380 |
+ |
|
| 381 |
+ memset(o, 0, sizeof(*o)); |
|
| 382 |
+ |
|
| 383 |
+ o->recording_time = INT64_MAX; |
|
| 384 |
+ o->limit_filesize = UINT64_MAX; |
|
| 385 |
+ |
|
| 386 |
+ uninit_opts(); |
|
| 387 |
+ init_opts(); |
|
| 388 |
+} |
|
| 389 |
+ |
|
| 340 | 390 |
#if CONFIG_AVFILTER |
| 341 | 391 |
|
| 342 | 392 |
static int configure_video_filters(InputStream *ist, OutputStream *ost) |
| ... | ... |
@@ -510,7 +552,7 @@ static int decode_interrupt_cb(void) |
| 510 | 510 |
return q_pressed > 1; |
| 511 | 511 |
} |
| 512 | 512 |
|
| 513 |
-static int exit_program(int ret) |
|
| 513 |
+void exit_program(int ret) |
|
| 514 | 514 |
{
|
| 515 | 515 |
int i; |
| 516 | 516 |
|
| ... | ... |
@@ -560,7 +602,6 @@ static int exit_program(int ret) |
| 560 | 560 |
} |
| 561 | 561 |
|
| 562 | 562 |
exit(ret); /* not all OS-es handle main() return value */ |
| 563 |
- return ret; |
|
| 564 | 563 |
} |
| 565 | 564 |
|
| 566 | 565 |
static void assert_avoptions(AVDictionary *m) |
| ... | ... |
@@ -589,26 +630,6 @@ static void assert_codec_experimental(AVCodecContext *c, int encoder) |
| 589 | 589 |
} |
| 590 | 590 |
} |
| 591 | 591 |
|
| 592 |
-/* similar to ff_dynarray_add() and av_fast_realloc() */ |
|
| 593 |
-static void *grow_array(void *array, int elem_size, int *size, int new_size) |
|
| 594 |
-{
|
|
| 595 |
- if (new_size >= INT_MAX / elem_size) {
|
|
| 596 |
- fprintf(stderr, "Array too big.\n"); |
|
| 597 |
- exit_program(1); |
|
| 598 |
- } |
|
| 599 |
- if (*size < new_size) {
|
|
| 600 |
- uint8_t *tmp = av_realloc(array, new_size*elem_size); |
|
| 601 |
- if (!tmp) {
|
|
| 602 |
- fprintf(stderr, "Could not alloc buffer.\n"); |
|
| 603 |
- exit_program(1); |
|
| 604 |
- } |
|
| 605 |
- memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size); |
|
| 606 |
- *size = new_size; |
|
| 607 |
- return tmp; |
|
| 608 |
- } |
|
| 609 |
- return array; |
|
| 610 |
-} |
|
| 611 |
- |
|
| 612 | 592 |
static void choose_sample_fmt(AVStream *st, AVCodec *codec) |
| 613 | 593 |
{
|
| 614 | 594 |
if(codec && codec->sample_fmts){
|
| ... | ... |
@@ -2552,12 +2573,6 @@ static int transcode(OutputFile *output_files, |
| 2552 | 2552 |
return ret; |
| 2553 | 2553 |
} |
| 2554 | 2554 |
|
| 2555 |
-static int opt_format(const char *opt, const char *arg) |
|
| 2556 |
-{
|
|
| 2557 |
- last_asked_format = arg; |
|
| 2558 |
- return 0; |
|
| 2559 |
-} |
|
| 2560 |
- |
|
| 2561 | 2555 |
static int opt_video_rc_override_string(const char *opt, const char *arg) |
| 2562 | 2556 |
{
|
| 2563 | 2557 |
video_rc_override_string = arg; |
| ... | ... |
@@ -2738,7 +2753,7 @@ static int opt_codec_tag(const char *opt, const char *arg) |
| 2738 | 2738 |
return 0; |
| 2739 | 2739 |
} |
| 2740 | 2740 |
|
| 2741 |
-static int opt_map(const char *opt, const char *arg) |
|
| 2741 |
+static int opt_map(OptionsContext *o, const char *opt, const char *arg) |
|
| 2742 | 2742 |
{
|
| 2743 | 2743 |
StreamMap *m = NULL; |
| 2744 | 2744 |
int i, negative = 0, file_idx; |
| ... | ... |
@@ -2783,8 +2798,8 @@ static int opt_map(const char *opt, const char *arg) |
| 2783 | 2783 |
} |
| 2784 | 2784 |
if (negative) |
| 2785 | 2785 |
/* disable some already defined maps */ |
| 2786 |
- for (i = 0; i < nb_stream_maps; i++) {
|
|
| 2787 |
- m = &stream_maps[i]; |
|
| 2786 |
+ for (i = 0; i < o->nb_stream_maps; i++) {
|
|
| 2787 |
+ m = &o->stream_maps[i]; |
|
| 2788 | 2788 |
if (check_stream_specifier(input_files[m->file_index].ctx, |
| 2789 | 2789 |
input_files[m->file_index].ctx->streams[m->stream_index], |
| 2790 | 2790 |
*p == ':' ? p + 1 : p) > 0) |
| ... | ... |
@@ -2795,8 +2810,9 @@ static int opt_map(const char *opt, const char *arg) |
| 2795 | 2795 |
if (check_stream_specifier(input_files[file_idx].ctx, input_files[file_idx].ctx->streams[i], |
| 2796 | 2796 |
*p == ':' ? p + 1 : p) <= 0) |
| 2797 | 2797 |
continue; |
| 2798 |
- stream_maps = grow_array(stream_maps, sizeof(*stream_maps), &nb_stream_maps, nb_stream_maps + 1); |
|
| 2799 |
- m = &stream_maps[nb_stream_maps - 1]; |
|
| 2798 |
+ o->stream_maps = grow_array(o->stream_maps, sizeof(*o->stream_maps), |
|
| 2799 |
+ &o->nb_stream_maps, o->nb_stream_maps + 1); |
|
| 2800 |
+ m = &o->stream_maps[o->nb_stream_maps - 1]; |
|
| 2800 | 2801 |
|
| 2801 | 2802 |
m->file_index = file_idx; |
| 2802 | 2803 |
m->stream_index = i; |
| ... | ... |
@@ -2873,24 +2889,6 @@ static int opt_input_ts_scale(const char *opt, const char *arg) |
| 2873 | 2873 |
return av_dict_set(&ts_scale, opt, arg, 0); |
| 2874 | 2874 |
} |
| 2875 | 2875 |
|
| 2876 |
-static int opt_recording_time(const char *opt, const char *arg) |
|
| 2877 |
-{
|
|
| 2878 |
- recording_time = parse_time_or_die(opt, arg, 1); |
|
| 2879 |
- return 0; |
|
| 2880 |
-} |
|
| 2881 |
- |
|
| 2882 |
-static int opt_start_time(const char *opt, const char *arg) |
|
| 2883 |
-{
|
|
| 2884 |
- start_time = parse_time_or_die(opt, arg, 1); |
|
| 2885 |
- return 0; |
|
| 2886 |
-} |
|
| 2887 |
- |
|
| 2888 |
-static int opt_input_ts_offset(const char *opt, const char *arg) |
|
| 2889 |
-{
|
|
| 2890 |
- input_ts_offset = parse_time_or_die(opt, arg, 1); |
|
| 2891 |
- return 0; |
|
| 2892 |
-} |
|
| 2893 |
- |
|
| 2894 | 2876 |
static enum CodecID find_codec_or_die(const char *name, enum AVMediaType type, int encoder) |
| 2895 | 2877 |
{
|
| 2896 | 2878 |
const char *codec_string = encoder ? "encoder" : "decoder"; |
| ... | ... |
@@ -3029,7 +3027,7 @@ static void add_input_streams(AVFormatContext *ic) |
| 3029 | 3029 |
} |
| 3030 | 3030 |
} |
| 3031 | 3031 |
|
| 3032 |
-static int opt_input_file(const char *opt, const char *filename) |
|
| 3032 |
+static int opt_input_file(OptionsContext *o, const char *opt, const char *filename) |
|
| 3033 | 3033 |
{
|
| 3034 | 3034 |
AVFormatContext *ic; |
| 3035 | 3035 |
AVInputFormat *file_iformat = NULL; |
| ... | ... |
@@ -3039,12 +3037,11 @@ static int opt_input_file(const char *opt, const char *filename) |
| 3039 | 3039 |
AVDictionary **opts; |
| 3040 | 3040 |
int orig_nb_streams; // number of streams before avformat_find_stream_info |
| 3041 | 3041 |
|
| 3042 |
- if (last_asked_format) {
|
|
| 3043 |
- if (!(file_iformat = av_find_input_format(last_asked_format))) {
|
|
| 3044 |
- fprintf(stderr, "Unknown input format: '%s'\n", last_asked_format); |
|
| 3042 |
+ if (o->format) {
|
|
| 3043 |
+ if (!(file_iformat = av_find_input_format(o->format))) {
|
|
| 3044 |
+ fprintf(stderr, "Unknown input format: '%s'\n", o->format); |
|
| 3045 | 3045 |
exit_program(1); |
| 3046 | 3046 |
} |
| 3047 |
- last_asked_format = NULL; |
|
| 3048 | 3047 |
} |
| 3049 | 3048 |
|
| 3050 | 3049 |
if (!strcmp(filename, "-")) |
| ... | ... |
@@ -3129,20 +3126,18 @@ static int opt_input_file(const char *opt, const char *filename) |
| 3129 | 3129 |
exit_program(1); |
| 3130 | 3130 |
} |
| 3131 | 3131 |
|
| 3132 |
- timestamp = start_time; |
|
| 3132 |
+ timestamp = o->start_time; |
|
| 3133 | 3133 |
/* add the stream start time */ |
| 3134 | 3134 |
if (ic->start_time != AV_NOPTS_VALUE) |
| 3135 | 3135 |
timestamp += ic->start_time; |
| 3136 | 3136 |
|
| 3137 | 3137 |
/* if seeking requested, we execute it */ |
| 3138 |
- if (start_time != 0) {
|
|
| 3138 |
+ if (o->start_time != 0) {
|
|
| 3139 | 3139 |
ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD); |
| 3140 | 3140 |
if (ret < 0) {
|
| 3141 | 3141 |
fprintf(stderr, "%s: could not seek to position %0.3f\n", |
| 3142 | 3142 |
filename, (double)timestamp / AV_TIME_BASE); |
| 3143 | 3143 |
} |
| 3144 |
- /* reset seek info */ |
|
| 3145 |
- start_time = 0; |
|
| 3146 | 3144 |
} |
| 3147 | 3145 |
|
| 3148 | 3146 |
/* update the current parameters so that they match the one of the input stream */ |
| ... | ... |
@@ -3155,7 +3150,7 @@ static int opt_input_file(const char *opt, const char *filename) |
| 3155 | 3155 |
input_files = grow_array(input_files, sizeof(*input_files), &nb_input_files, nb_input_files + 1); |
| 3156 | 3156 |
input_files[nb_input_files - 1].ctx = ic; |
| 3157 | 3157 |
input_files[nb_input_files - 1].ist_index = nb_input_streams - ic->nb_streams; |
| 3158 |
- input_files[nb_input_files - 1].ts_offset = input_ts_offset - (copy_ts ? 0 : timestamp); |
|
| 3158 |
+ input_files[nb_input_files - 1].ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp); |
|
| 3159 | 3159 |
input_files[nb_input_files - 1].nb_streams = ic->nb_streams; |
| 3160 | 3160 |
|
| 3161 | 3161 |
top_field_first = -1; |
| ... | ... |
@@ -3167,14 +3162,13 @@ static int opt_input_file(const char *opt, const char *filename) |
| 3167 | 3167 |
audio_channels = 0; |
| 3168 | 3168 |
audio_sample_fmt = AV_SAMPLE_FMT_NONE; |
| 3169 | 3169 |
av_dict_free(&ts_scale); |
| 3170 |
- input_ts_offset = 0; |
|
| 3171 | 3170 |
|
| 3172 | 3171 |
for (i = 0; i < orig_nb_streams; i++) |
| 3173 | 3172 |
av_dict_free(&opts[i]); |
| 3174 | 3173 |
av_freep(&opts); |
| 3175 | 3174 |
av_dict_free(&codec_names); |
| 3176 |
- uninit_opts(); |
|
| 3177 |
- init_opts(); |
|
| 3175 |
+ |
|
| 3176 |
+ reset_options(o); |
|
| 3178 | 3177 |
return 0; |
| 3179 | 3178 |
} |
| 3180 | 3179 |
|
| ... | ... |
@@ -3465,18 +3459,18 @@ static int opt_streamid(const char *opt, const char *arg) |
| 3465 | 3465 |
return 0; |
| 3466 | 3466 |
} |
| 3467 | 3467 |
|
| 3468 |
-static int copy_chapters(int infile, int outfile) |
|
| 3468 |
+static int copy_chapters(InputFile *ifile, OutputFile *ofile) |
|
| 3469 | 3469 |
{
|
| 3470 |
- AVFormatContext *is = input_files[infile].ctx; |
|
| 3471 |
- AVFormatContext *os = output_files[outfile].ctx; |
|
| 3470 |
+ AVFormatContext *is = ifile->ctx; |
|
| 3471 |
+ AVFormatContext *os = ofile->ctx; |
|
| 3472 | 3472 |
int i; |
| 3473 | 3473 |
|
| 3474 | 3474 |
for (i = 0; i < is->nb_chapters; i++) {
|
| 3475 | 3475 |
AVChapter *in_ch = is->chapters[i], *out_ch; |
| 3476 |
- int64_t ts_off = av_rescale_q(start_time - input_files[infile].ts_offset, |
|
| 3476 |
+ int64_t ts_off = av_rescale_q(ofile->start_time - ifile->ts_offset, |
|
| 3477 | 3477 |
AV_TIME_BASE_Q, in_ch->time_base); |
| 3478 |
- int64_t rt = (recording_time == INT64_MAX) ? INT64_MAX : |
|
| 3479 |
- av_rescale_q(recording_time, AV_TIME_BASE_Q, in_ch->time_base); |
|
| 3478 |
+ int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX : |
|
| 3479 |
+ av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base); |
|
| 3480 | 3480 |
|
| 3481 | 3481 |
|
| 3482 | 3482 |
if (in_ch->end < ts_off) |
| ... | ... |
@@ -3539,8 +3533,9 @@ static int read_ffserver_streams(AVFormatContext *s, const char *filename) |
| 3539 | 3539 |
return 0; |
| 3540 | 3540 |
} |
| 3541 | 3541 |
|
| 3542 |
-static int opt_output_file(const char *opt, const char *filename) |
|
| 3542 |
+static void opt_output_file(void *optctx, const char *filename) |
|
| 3543 | 3543 |
{
|
| 3544 |
+ OptionsContext *o = optctx; |
|
| 3544 | 3545 |
AVFormatContext *oc; |
| 3545 | 3546 |
int i, err; |
| 3546 | 3547 |
AVOutputFormat *file_oformat; |
| ... | ... |
@@ -3550,8 +3545,7 @@ static int opt_output_file(const char *opt, const char *filename) |
| 3550 | 3550 |
if (!strcmp(filename, "-")) |
| 3551 | 3551 |
filename = "pipe:"; |
| 3552 | 3552 |
|
| 3553 |
- err = avformat_alloc_output_context2(&oc, NULL, last_asked_format, filename); |
|
| 3554 |
- last_asked_format = NULL; |
|
| 3553 |
+ err = avformat_alloc_output_context2(&oc, NULL, o->format, filename); |
|
| 3555 | 3554 |
if (!oc) {
|
| 3556 | 3555 |
print_error(filename, err); |
| 3557 | 3556 |
exit_program(1); |
| ... | ... |
@@ -3568,7 +3562,7 @@ static int opt_output_file(const char *opt, const char *filename) |
| 3568 | 3568 |
print_error(filename, err); |
| 3569 | 3569 |
exit_program(1); |
| 3570 | 3570 |
} |
| 3571 |
- } else if (!nb_stream_maps) {
|
|
| 3571 |
+ } else if (!o->nb_stream_maps) {
|
|
| 3572 | 3572 |
/* pick the "best" stream of each type */ |
| 3573 | 3573 |
#define NEW_STREAM(type, index)\ |
| 3574 | 3574 |
if (index >= 0) {\
|
| ... | ... |
@@ -3616,8 +3610,8 @@ static int opt_output_file(const char *opt, const char *filename) |
| 3616 | 3616 |
} |
| 3617 | 3617 |
/* do something with data? */ |
| 3618 | 3618 |
} else {
|
| 3619 |
- for (i = 0; i < nb_stream_maps; i++) {
|
|
| 3620 |
- StreamMap *map = &stream_maps[i]; |
|
| 3619 |
+ for (i = 0; i < o->nb_stream_maps; i++) {
|
|
| 3620 |
+ StreamMap *map = &o->stream_maps[i]; |
|
| 3621 | 3621 |
|
| 3622 | 3622 |
if (map->disabled) |
| 3623 | 3623 |
continue; |
| ... | ... |
@@ -3648,9 +3642,9 @@ static int opt_output_file(const char *opt, const char *filename) |
| 3648 | 3648 |
output_files = grow_array(output_files, sizeof(*output_files), &nb_output_files, nb_output_files + 1); |
| 3649 | 3649 |
output_files[nb_output_files - 1].ctx = oc; |
| 3650 | 3650 |
output_files[nb_output_files - 1].ost_index = nb_output_streams - oc->nb_streams; |
| 3651 |
- output_files[nb_output_files - 1].recording_time = recording_time; |
|
| 3652 |
- output_files[nb_output_files - 1].start_time = start_time; |
|
| 3653 |
- output_files[nb_output_files - 1].limit_filesize = limit_filesize; |
|
| 3651 |
+ output_files[nb_output_files - 1].recording_time = o->recording_time; |
|
| 3652 |
+ output_files[nb_output_files - 1].start_time = o->start_time; |
|
| 3653 |
+ output_files[nb_output_files - 1].limit_filesize = o->limit_filesize; |
|
| 3654 | 3654 |
av_dict_copy(&output_files[nb_output_files - 1].opts, format_opts, 0); |
| 3655 | 3655 |
|
| 3656 | 3656 |
/* check filename in case of an image number is expected */ |
| ... | ... |
@@ -3710,7 +3704,7 @@ static int opt_output_file(const char *opt, const char *filename) |
| 3710 | 3710 |
} |
| 3711 | 3711 |
} |
| 3712 | 3712 |
if (chapters_input_file >= 0) |
| 3713 |
- copy_chapters(chapters_input_file, nb_output_files - 1); |
|
| 3713 |
+ copy_chapters(&input_files[chapters_input_file], &output_files[nb_output_files - 1]); |
|
| 3714 | 3714 |
|
| 3715 | 3715 |
/* copy metadata */ |
| 3716 | 3716 |
for (i = 0; i < nb_meta_data_maps; i++) {
|
| ... | ... |
@@ -3775,26 +3769,19 @@ static int opt_output_file(const char *opt, const char *filename) |
| 3775 | 3775 |
audio_channels = 0; |
| 3776 | 3776 |
audio_sample_fmt = AV_SAMPLE_FMT_NONE; |
| 3777 | 3777 |
chapters_input_file = INT_MAX; |
| 3778 |
- recording_time = INT64_MAX; |
|
| 3779 |
- start_time = 0; |
|
| 3780 |
- limit_filesize = UINT64_MAX; |
|
| 3781 | 3778 |
|
| 3782 | 3779 |
av_freep(&meta_data_maps); |
| 3783 | 3780 |
nb_meta_data_maps = 0; |
| 3784 | 3781 |
metadata_global_autocopy = 1; |
| 3785 | 3782 |
metadata_streams_autocopy = 1; |
| 3786 | 3783 |
metadata_chapters_autocopy = 1; |
| 3787 |
- av_freep(&stream_maps); |
|
| 3788 |
- nb_stream_maps = 0; |
|
| 3789 | 3784 |
av_freep(&streamid_map); |
| 3790 | 3785 |
nb_streamid_map = 0; |
| 3791 | 3786 |
|
| 3792 | 3787 |
av_dict_free(&codec_names); |
| 3793 | 3788 |
|
| 3794 | 3789 |
av_freep(&forced_key_frames); |
| 3795 |
- uninit_opts(); |
|
| 3796 |
- init_opts(); |
|
| 3797 |
- return 0; |
|
| 3790 |
+ reset_options(o); |
|
| 3798 | 3791 |
} |
| 3799 | 3792 |
|
| 3800 | 3793 |
/* same option as mencoder */ |
| ... | ... |
@@ -3949,7 +3936,7 @@ static int opt_help(const char *opt, const char *arg) |
| 3949 | 3949 |
return 0; |
| 3950 | 3950 |
} |
| 3951 | 3951 |
|
| 3952 |
-static int opt_target(const char *opt, const char *arg) |
|
| 3952 |
+static int opt_target(OptionsContext *o, const char *opt, const char *arg) |
|
| 3953 | 3953 |
{
|
| 3954 | 3954 |
enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
|
| 3955 | 3955 |
static const char *const frame_rates[] = {"25", "30000/1001", "24000/1001"};
|
| ... | ... |
@@ -4008,7 +3995,7 @@ static int opt_target(const char *opt, const char *arg) |
| 4008 | 4008 |
if(!strcmp(arg, "vcd")) {
|
| 4009 | 4009 |
opt_codec("c:v", "mpeg1video");
|
| 4010 | 4010 |
opt_codec("c:a", "mp2");
|
| 4011 |
- opt_format("f", "vcd");
|
|
| 4011 |
+ parse_option(o, "f", "vcd", options); |
|
| 4012 | 4012 |
|
| 4013 | 4013 |
opt_frame_size("s", norm == PAL ? "352x288" : "352x240");
|
| 4014 | 4014 |
opt_frame_rate("r", frame_rates[norm]);
|
| ... | ... |
@@ -4036,7 +4023,7 @@ static int opt_target(const char *opt, const char *arg) |
| 4036 | 4036 |
|
| 4037 | 4037 |
opt_codec("c:v", "mpeg2video");
|
| 4038 | 4038 |
opt_codec("c:a", "mp2");
|
| 4039 |
- opt_format("f", "svcd");
|
|
| 4039 |
+ parse_option(o, "f", "svcd", options); |
|
| 4040 | 4040 |
|
| 4041 | 4041 |
opt_frame_size("s", norm == PAL ? "480x576" : "480x480");
|
| 4042 | 4042 |
opt_frame_rate("r", frame_rates[norm]);
|
| ... | ... |
@@ -4059,7 +4046,7 @@ static int opt_target(const char *opt, const char *arg) |
| 4059 | 4059 |
|
| 4060 | 4060 |
opt_codec("c:v", "mpeg2video");
|
| 4061 | 4061 |
opt_codec("c:a", "ac3");
|
| 4062 |
- opt_format("f", "dvd");
|
|
| 4062 |
+ parse_option(o, "f", "dvd", options); |
|
| 4063 | 4063 |
|
| 4064 | 4064 |
opt_frame_size("vcodec", norm == PAL ? "720x576" : "720x480");
|
| 4065 | 4065 |
opt_frame_rate("r", frame_rates[norm]);
|
| ... | ... |
@@ -4079,7 +4066,7 @@ static int opt_target(const char *opt, const char *arg) |
| 4079 | 4079 |
|
| 4080 | 4080 |
} else if(!strncmp(arg, "dv", 2)) {
|
| 4081 | 4081 |
|
| 4082 |
- opt_format("f", "dv");
|
|
| 4082 |
+ parse_option(o, "f", "dv", options); |
|
| 4083 | 4083 |
|
| 4084 | 4084 |
opt_frame_size("s", norm == PAL ? "720x576" : "720x480");
|
| 4085 | 4085 |
opt_frame_pix_fmt("pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
|
| ... | ... |
@@ -4149,22 +4136,23 @@ static int opt_passlogfile(const char *opt, const char *arg) |
| 4149 | 4149 |
#endif |
| 4150 | 4150 |
} |
| 4151 | 4151 |
|
| 4152 |
+#define OFFSET(x) offsetof(OptionsContext, x) |
|
| 4152 | 4153 |
static const OptionDef options[] = {
|
| 4153 | 4154 |
/* main options */ |
| 4154 | 4155 |
#include "cmdutils_common_opts.h" |
| 4155 |
- { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
|
|
| 4156 |
- { "i", HAS_ARG, {(void*)opt_input_file}, "input file name", "filename" },
|
|
| 4156 |
+ { "f", HAS_ARG | OPT_STRING | OPT_OFFSET, {.off = OFFSET(format)}, "force format", "fmt" },
|
|
| 4157 |
+ { "i", HAS_ARG | OPT_FUNC2, {(void*)opt_input_file}, "input file name", "filename" },
|
|
| 4157 | 4158 |
{ "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
|
| 4158 | 4159 |
{ "c", HAS_ARG, {(void*)opt_codec}, "codec name", "codec" },
|
| 4159 | 4160 |
{ "codec", HAS_ARG, {(void*)opt_codec}, "codec name", "codec" },
|
| 4160 |
- { "map", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" },
|
|
| 4161 |
+ { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" },
|
|
| 4161 | 4162 |
{ "map_metadata", HAS_ARG | OPT_EXPERT, {(void*)opt_map_metadata}, "set metadata information of outfile from infile",
|
| 4162 | 4163 |
"outfile[,metadata]:infile[,metadata]" }, |
| 4163 | 4164 |
{ "map_chapters", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&chapters_input_file}, "set chapters mapping", "input_file_index" },
|
| 4164 |
- { "t", HAS_ARG, {(void*)opt_recording_time}, "record or transcode \"duration\" seconds of audio/video", "duration" },
|
|
| 4165 |
- { "fs", HAS_ARG | OPT_INT64, {(void*)&limit_filesize}, "set the limit file size in bytes", "limit_size" }, //
|
|
| 4166 |
- { "ss", HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" },
|
|
| 4167 |
- { "itsoffset", HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" },
|
|
| 4165 |
+ { "t", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(recording_time)}, "record or transcode \"duration\" seconds of audio/video", "duration" },
|
|
| 4166 |
+ { "fs", HAS_ARG | OPT_INT64 | OPT_OFFSET, {.off = OFFSET(limit_filesize)}, "set the limit file size in bytes", "limit_size" }, //
|
|
| 4167 |
+ { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(start_time)}, "set the start time offset", "time_off" },
|
|
| 4168 |
+ { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(input_ts_offset)}, "set the input ts offset", "time_off" },
|
|
| 4168 | 4169 |
{ "itsscale", HAS_ARG, {(void*)opt_input_ts_scale}, "set the input ts scale", "scale" },
|
| 4169 | 4170 |
{ "metadata", HAS_ARG, {(void*)opt_metadata}, "add metadata", "string=string" },
|
| 4170 | 4171 |
{ "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[AVMEDIA_TYPE_DATA]}, "set the number of data frames to record", "number" },
|
| ... | ... |
@@ -4177,7 +4165,7 @@ static const OptionDef options[] = {
|
| 4177 | 4177 |
"when dumping packets, also dump the payload" }, |
| 4178 | 4178 |
{ "re", OPT_BOOL | OPT_EXPERT, {(void*)&rate_emu}, "read input at native frame rate", "" },
|
| 4179 | 4179 |
{ "v", HAS_ARG, {(void*)opt_verbose}, "set the verbosity level", "number" },
|
| 4180 |
- { "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
|
|
| 4180 |
+ { "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
|
|
| 4181 | 4181 |
{ "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" },
|
| 4182 | 4182 |
{ "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" },
|
| 4183 | 4183 |
{ "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" },
|
| ... | ... |
@@ -4263,8 +4251,11 @@ static const OptionDef options[] = {
|
| 4263 | 4263 |
|
| 4264 | 4264 |
int main(int argc, char **argv) |
| 4265 | 4265 |
{
|
| 4266 |
+ OptionsContext o = { 0 };
|
|
| 4266 | 4267 |
int64_t ti; |
| 4267 | 4268 |
|
| 4269 |
+ reset_options(&o); |
|
| 4270 |
+ |
|
| 4268 | 4271 |
av_log_set_flags(AV_LOG_SKIP_REPEATED); |
| 4269 | 4272 |
|
| 4270 | 4273 |
if(argc>1 && !strcmp(argv[1], "-d")){
|
| ... | ... |
@@ -4289,13 +4280,11 @@ int main(int argc, char **argv) |
| 4289 | 4289 |
avio_set_interrupt_cb(decode_interrupt_cb); |
| 4290 | 4290 |
#endif |
| 4291 | 4291 |
|
| 4292 |
- init_opts(); |
|
| 4293 |
- |
|
| 4294 | 4292 |
if(verbose>=0) |
| 4295 | 4293 |
show_banner(); |
| 4296 | 4294 |
|
| 4297 | 4295 |
/* parse options */ |
| 4298 |
- parse_options(argc, argv, options, opt_output_file); |
|
| 4296 |
+ parse_options(&o, argc, argv, options, opt_output_file); |
|
| 4299 | 4297 |
|
| 4300 | 4298 |
if(nb_output_files <= 0 && nb_input_files == 0) {
|
| 4301 | 4299 |
show_usage(); |
| ... | ... |
@@ -4323,5 +4312,6 @@ int main(int argc, char **argv) |
| 4323 | 4323 |
printf("bench: utime=%0.3fs maxrss=%ikB\n", ti / 1000000.0, maxrss);
|
| 4324 | 4324 |
} |
| 4325 | 4325 |
|
| 4326 |
- return exit_program(0); |
|
| 4326 |
+ exit_program(0); |
|
| 4327 |
+ return 0; |
|
| 4327 | 4328 |
} |
| ... | ... |
@@ -92,7 +92,8 @@ double parse_number_or_die(const char *context, const char *numstr, int type, do |
| 92 | 92 |
else |
| 93 | 93 |
return d; |
| 94 | 94 |
fprintf(stderr, error, context, numstr, min, max); |
| 95 |
- exit(1); |
|
| 95 |
+ exit_program(1); |
|
| 96 |
+ return 0; |
|
| 96 | 97 |
} |
| 97 | 98 |
|
| 98 | 99 |
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration) |
| ... | ... |
@@ -101,7 +102,7 @@ int64_t parse_time_or_die(const char *context, const char *timestr, int is_durat |
| 101 | 101 |
if (av_parse_time(&us, timestr, is_duration) < 0) {
|
| 102 | 102 |
fprintf(stderr, "Invalid %s specification for %s: %s\n", |
| 103 | 103 |
is_duration ? "duration" : "date", context, timestr); |
| 104 |
- exit(1); |
|
| 104 |
+ exit_program(1); |
|
| 105 | 105 |
} |
| 106 | 106 |
return us; |
| 107 | 107 |
} |
| ... | ... |
@@ -202,12 +203,80 @@ static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr) |
| 202 | 202 |
} |
| 203 | 203 |
#endif /* WIN32 && !__MINGW32CE__ */ |
| 204 | 204 |
|
| 205 |
-void parse_options(int argc, char **argv, const OptionDef *options, |
|
| 206 |
- int (* parse_arg_function)(const char *opt, const char *arg)) |
|
| 205 |
+ |
|
| 206 |
+int parse_option(void *optctx, const char *opt, const char *arg, const OptionDef *options) |
|
| 207 | 207 |
{
|
| 208 |
- const char *opt, *arg; |
|
| 209 |
- int optindex, handleoptions=1; |
|
| 210 | 208 |
const OptionDef *po; |
| 209 |
+ int bool_val = 1; |
|
| 210 |
+ int *dstcount; |
|
| 211 |
+ void *dst; |
|
| 212 |
+ |
|
| 213 |
+ po = find_option(options, opt); |
|
| 214 |
+ if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
|
|
| 215 |
+ /* handle 'no' bool option */ |
|
| 216 |
+ po = find_option(options, opt + 2); |
|
| 217 |
+ if (!(po->name && (po->flags & OPT_BOOL))) |
|
| 218 |
+ goto unknown_opt; |
|
| 219 |
+ bool_val = 0; |
|
| 220 |
+ } |
|
| 221 |
+ if (!po->name) |
|
| 222 |
+ po = find_option(options, "default"); |
|
| 223 |
+ if (!po->name) {
|
|
| 224 |
+unknown_opt: |
|
| 225 |
+ av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt); |
|
| 226 |
+ return AVERROR(EINVAL); |
|
| 227 |
+ } |
|
| 228 |
+ if (po->flags & HAS_ARG && !arg) {
|
|
| 229 |
+ av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'\n", opt); |
|
| 230 |
+ return AVERROR(EINVAL); |
|
| 231 |
+ } |
|
| 232 |
+ |
|
| 233 |
+ /* new-style options contain an offset into optctx, old-style address of |
|
| 234 |
+ * a global var*/ |
|
| 235 |
+ dst = po->flags & (OPT_OFFSET|OPT_SPEC) ? (uint8_t*)optctx + po->u.off : po->u.dst_ptr; |
|
| 236 |
+ |
|
| 237 |
+ if (po->flags & OPT_SPEC) {
|
|
| 238 |
+ SpecifierOpt **so = dst; |
|
| 239 |
+ char *p = strchr(opt, ':'); |
|
| 240 |
+ |
|
| 241 |
+ dstcount = (int*)(so + 1); |
|
| 242 |
+ *so = grow_array(*so, sizeof(**so), dstcount, *dstcount + 1); |
|
| 243 |
+ (*so)[*dstcount - 1].specifier = av_strdup(p ? p + 1 : ""); |
|
| 244 |
+ dst = &(*so)[*dstcount - 1].u; |
|
| 245 |
+ } |
|
| 246 |
+ |
|
| 247 |
+ if (po->flags & OPT_STRING) {
|
|
| 248 |
+ char *str; |
|
| 249 |
+ str = av_strdup(arg); |
|
| 250 |
+ *(char**)dst = str; |
|
| 251 |
+ } else if (po->flags & OPT_BOOL) {
|
|
| 252 |
+ *(int*)dst = bool_val; |
|
| 253 |
+ } else if (po->flags & OPT_INT) {
|
|
| 254 |
+ *(int*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX); |
|
| 255 |
+ } else if (po->flags & OPT_INT64) {
|
|
| 256 |
+ *(int64_t*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX); |
|
| 257 |
+ } else if (po->flags & OPT_TIME) {
|
|
| 258 |
+ *(int64_t*)dst = parse_time_or_die(opt, arg, 1); |
|
| 259 |
+ } else if (po->flags & OPT_FLOAT) {
|
|
| 260 |
+ *(float*)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY); |
|
| 261 |
+ } else if (po->u.func_arg) {
|
|
| 262 |
+ int ret = po->flags & OPT_FUNC2 ? po->u.func2_arg(optctx, opt, arg) : |
|
| 263 |
+ po->u.func_arg(opt, arg); |
|
| 264 |
+ if (ret < 0) {
|
|
| 265 |
+ av_log(NULL, AV_LOG_ERROR, "Failed to set value '%s' for option '%s'\n", arg, opt); |
|
| 266 |
+ return ret; |
|
| 267 |
+ } |
|
| 268 |
+ } |
|
| 269 |
+ if (po->flags & OPT_EXIT) |
|
| 270 |
+ exit_program(0); |
|
| 271 |
+ return !!(po->flags & HAS_ARG); |
|
| 272 |
+} |
|
| 273 |
+ |
|
| 274 |
+void parse_options(void *optctx, int argc, char **argv, const OptionDef *options, |
|
| 275 |
+ void (* parse_arg_function)(void *, const char*)) |
|
| 276 |
+{
|
|
| 277 |
+ const char *opt; |
|
| 278 |
+ int optindex, handleoptions = 1, ret; |
|
| 211 | 279 |
|
| 212 | 280 |
/* perform system-dependent conversions for arguments list */ |
| 213 | 281 |
prepare_app_arguments(&argc, &argv); |
| ... | ... |
@@ -218,60 +287,18 @@ void parse_options(int argc, char **argv, const OptionDef *options, |
| 218 | 218 |
opt = argv[optindex++]; |
| 219 | 219 |
|
| 220 | 220 |
if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
|
| 221 |
- int bool_val = 1; |
|
| 222 | 221 |
if (opt[1] == '-' && opt[2] == '\0') {
|
| 223 | 222 |
handleoptions = 0; |
| 224 | 223 |
continue; |
| 225 | 224 |
} |
| 226 | 225 |
opt++; |
| 227 |
- po= find_option(options, opt); |
|
| 228 |
- if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
|
|
| 229 |
- /* handle 'no' bool option */ |
|
| 230 |
- po = find_option(options, opt + 2); |
|
| 231 |
- if (!(po->name && (po->flags & OPT_BOOL))) |
|
| 232 |
- goto unknown_opt; |
|
| 233 |
- bool_val = 0; |
|
| 234 |
- } |
|
| 235 |
- if (!po->name) |
|
| 236 |
- po= find_option(options, "default"); |
|
| 237 |
- if (!po->name) {
|
|
| 238 |
-unknown_opt: |
|
| 239 |
- fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt); |
|
| 240 |
- exit(1); |
|
| 241 |
- } |
|
| 242 |
- arg = NULL; |
|
| 243 |
- if (po->flags & HAS_ARG) {
|
|
| 244 |
- arg = argv[optindex++]; |
|
| 245 |
- if (!arg) {
|
|
| 246 |
- fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt); |
|
| 247 |
- exit(1); |
|
| 248 |
- } |
|
| 249 |
- } |
|
| 250 |
- if (po->flags & OPT_STRING) {
|
|
| 251 |
- char *str; |
|
| 252 |
- str = av_strdup(arg); |
|
| 253 |
- *po->u.str_arg = str; |
|
| 254 |
- } else if (po->flags & OPT_BOOL) {
|
|
| 255 |
- *po->u.int_arg = bool_val; |
|
| 256 |
- } else if (po->flags & OPT_INT) {
|
|
| 257 |
- *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX); |
|
| 258 |
- } else if (po->flags & OPT_INT64) {
|
|
| 259 |
- *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX); |
|
| 260 |
- } else if (po->flags & OPT_FLOAT) {
|
|
| 261 |
- *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY); |
|
| 262 |
- } else if (po->u.func_arg) {
|
|
| 263 |
- if (po->u.func_arg(opt, arg) < 0) {
|
|
| 264 |
- fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg ? arg : "[null]", opt); |
|
| 265 |
- exit(1); |
|
| 266 |
- } |
|
| 267 |
- } |
|
| 268 |
- if(po->flags & OPT_EXIT) |
|
| 269 |
- exit(0); |
|
| 226 |
+ |
|
| 227 |
+ if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0) |
|
| 228 |
+ exit_program(1); |
|
| 229 |
+ optindex += ret; |
|
| 270 | 230 |
} else {
|
| 271 |
- if (parse_arg_function) {
|
|
| 272 |
- if (parse_arg_function(NULL, opt) < 0) |
|
| 273 |
- exit(1); |
|
| 274 |
- } |
|
| 231 |
+ if (parse_arg_function) |
|
| 232 |
+ parse_arg_function(optctx, opt); |
|
| 275 | 233 |
} |
| 276 | 234 |
} |
| 277 | 235 |
} |
| ... | ... |
@@ -338,7 +365,7 @@ int opt_loglevel(const char *opt, const char *arg) |
| 338 | 338 |
"Possible levels are numbers or:\n", arg); |
| 339 | 339 |
for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) |
| 340 | 340 |
fprintf(stderr, "\"%s\"\n", log_levels[i].name); |
| 341 |
- exit(1); |
|
| 341 |
+ exit_program(1); |
|
| 342 | 342 |
} |
| 343 | 343 |
av_log_set_level(level); |
| 344 | 344 |
return 0; |
| ... | ... |
@@ -872,3 +899,21 @@ AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *cod |
| 872 | 872 |
return opts; |
| 873 | 873 |
} |
| 874 | 874 |
|
| 875 |
+void *grow_array(void *array, int elem_size, int *size, int new_size) |
|
| 876 |
+{
|
|
| 877 |
+ if (new_size >= INT_MAX / elem_size) {
|
|
| 878 |
+ av_log(NULL, AV_LOG_ERROR, "Array too big.\n"); |
|
| 879 |
+ exit_program(1); |
|
| 880 |
+ } |
|
| 881 |
+ if (*size < new_size) {
|
|
| 882 |
+ uint8_t *tmp = av_realloc(array, new_size*elem_size); |
|
| 883 |
+ if (!tmp) {
|
|
| 884 |
+ av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n"); |
|
| 885 |
+ exit_program(1); |
|
| 886 |
+ } |
|
| 887 |
+ memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size); |
|
| 888 |
+ *size = new_size; |
|
| 889 |
+ return tmp; |
|
| 890 |
+ } |
|
| 891 |
+ return array; |
|
| 892 |
+} |
| ... | ... |
@@ -112,6 +112,16 @@ double parse_number_or_die(const char *context, const char *numstr, int type, do |
| 112 | 112 |
*/ |
| 113 | 113 |
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration); |
| 114 | 114 |
|
| 115 |
+typedef struct SpecifierOpt {
|
|
| 116 |
+ char *specifier; /**< stream/chapter/program/... specifier */ |
|
| 117 |
+ union {
|
|
| 118 |
+ uint8_t *str; |
|
| 119 |
+ int i; |
|
| 120 |
+ int64_t i64; |
|
| 121 |
+ float f; |
|
| 122 |
+ } u; |
|
| 123 |
+} SpecifierOpt; |
|
| 124 |
+ |
|
| 115 | 125 |
typedef struct {
|
| 116 | 126 |
const char *name; |
| 117 | 127 |
int flags; |
| ... | ... |
@@ -128,12 +138,17 @@ typedef struct {
|
| 128 | 128 |
#define OPT_INT64 0x0400 |
| 129 | 129 |
#define OPT_EXIT 0x0800 |
| 130 | 130 |
#define OPT_DATA 0x1000 |
| 131 |
+#define OPT_FUNC2 0x2000 |
|
| 132 |
+#define OPT_OFFSET 0x4000 /* option is specified as an offset in a passed optctx */ |
|
| 133 |
+#define OPT_SPEC 0x8000 /* option is to be stored in an array of SpecifierOpt. |
|
| 134 |
+ Implies OPT_OFFSET. Next element after the offset is |
|
| 135 |
+ an int containing element count in the array. */ |
|
| 136 |
+#define OPT_TIME 0x10000 |
|
| 131 | 137 |
union {
|
| 132 |
- int *int_arg; |
|
| 133 |
- char **str_arg; |
|
| 134 |
- float *float_arg; |
|
| 138 |
+ void *dst_ptr; |
|
| 135 | 139 |
int (*func_arg)(const char *, const char *); |
| 136 |
- int64_t *int64_arg; |
|
| 140 |
+ int (*func2_arg)(void *, const char *, const char *); |
|
| 141 |
+ size_t off; |
|
| 137 | 142 |
} u; |
| 138 | 143 |
const char *help; |
| 139 | 144 |
const char *argname; |
| ... | ... |
@@ -143,14 +158,23 @@ void show_help_options(const OptionDef *options, const char *msg, int mask, int |
| 143 | 143 |
|
| 144 | 144 |
/** |
| 145 | 145 |
* Parse the command line arguments. |
| 146 |
+ * |
|
| 147 |
+ * @param optctx an opaque options context |
|
| 146 | 148 |
* @param options Array with the definitions required to interpret every |
| 147 | 149 |
* option of the form: -option_name [argument] |
| 148 | 150 |
* @param parse_arg_function Name of the function called to process every |
| 149 | 151 |
* argument without a leading option name flag. NULL if such arguments do |
| 150 | 152 |
* not have to be processed. |
| 151 | 153 |
*/ |
| 152 |
-void parse_options(int argc, char **argv, const OptionDef *options, |
|
| 153 |
- int (* parse_arg_function)(const char *opt, const char *arg)); |
|
| 154 |
+void parse_options(void *optctx, int argc, char **argv, const OptionDef *options, |
|
| 155 |
+ void (* parse_arg_function)(void *optctx, const char*)); |
|
| 156 |
+ |
|
| 157 |
+/** |
|
| 158 |
+ * Parse one given option. |
|
| 159 |
+ * |
|
| 160 |
+ * @return on success 1 if arg was consumed, 0 otherwise; negative number on error |
|
| 161 |
+ */ |
|
| 162 |
+int parse_option(void *optctx, const char *opt, const char *arg, const OptionDef *options); |
|
| 154 | 163 |
|
| 155 | 164 |
/** |
| 156 | 165 |
* Check if the given stream matches a stream specifier. |
| ... | ... |
@@ -301,4 +325,20 @@ int read_file(const char *filename, char **bufptr, size_t *size); |
| 301 | 301 |
FILE *get_preset_file(char *filename, size_t filename_size, |
| 302 | 302 |
const char *preset_name, int is_path, const char *codec_name); |
| 303 | 303 |
|
| 304 |
-#endif /* FFMPEG_CMDUTILS_H */ |
|
| 304 |
+/** |
|
| 305 |
+ * Do all the necessary cleanup and abort. |
|
| 306 |
+ * This function is implemented in the avtools, not cmdutils. |
|
| 307 |
+ */ |
|
| 308 |
+void exit_program(int ret); |
|
| 309 |
+ |
|
| 310 |
+/** |
|
| 311 |
+ * Realloc array to hold new_size elements of elem_size. |
|
| 312 |
+ * Calls exit_program() on failure. |
|
| 313 |
+ * |
|
| 314 |
+ * @param elem_size size in bytes of each element |
|
| 315 |
+ * @param size new element count will be written here |
|
| 316 |
+ * @return reallocated array |
|
| 317 |
+ */ |
|
| 318 |
+void *grow_array(void *array, int elem_size, int *size, int new_size); |
|
| 319 |
+ |
|
| 320 |
+#endif /* LIBAV_CMDUTILS_H */ |
| ... | ... |
@@ -110,12 +110,8 @@ typedef struct MetadataMap {
|
| 110 | 110 |
static const OptionDef options[]; |
| 111 | 111 |
|
| 112 | 112 |
#define MAX_STREAMS 1024 /* arbitrary sanity check value */ |
| 113 |
-static const char *last_asked_format = NULL; |
|
| 114 | 113 |
static AVDictionary *ts_scale; |
| 115 | 114 |
|
| 116 |
-static StreamMap *stream_maps = NULL; |
|
| 117 |
-static int nb_stream_maps; |
|
| 118 |
- |
|
| 119 | 115 |
static AVDictionary *codec_names; |
| 120 | 116 |
|
| 121 | 117 |
/* first item specifies output metadata, second is input */ |
| ... | ... |
@@ -182,9 +178,6 @@ static unsigned int data_codec_tag = 0; |
| 182 | 182 |
static float mux_preload= 0.5; |
| 183 | 183 |
static float mux_max_delay= 0.7; |
| 184 | 184 |
|
| 185 |
-static int64_t recording_time = INT64_MAX; |
|
| 186 |
-static int64_t start_time = 0; |
|
| 187 |
-static int64_t input_ts_offset = 0; |
|
| 188 | 185 |
static int file_overwrite = 0; |
| 189 | 186 |
static AVDictionary *metadata; |
| 190 | 187 |
static int do_benchmark = 0; |
| ... | ... |
@@ -220,7 +213,6 @@ static int64_t extra_size = 0; |
| 220 | 220 |
static int nb_frames_dup = 0; |
| 221 | 221 |
static int nb_frames_drop = 0; |
| 222 | 222 |
static int input_sync; |
| 223 |
-static uint64_t limit_filesize = UINT64_MAX; |
|
| 224 | 223 |
static int force_fps = 0; |
| 225 | 224 |
static char *forced_key_frames = NULL; |
| 226 | 225 |
|
| ... | ... |
@@ -348,6 +340,56 @@ static int nb_output_streams = 0; |
| 348 | 348 |
static OutputFile *output_files = NULL; |
| 349 | 349 |
static int nb_output_files = 0; |
| 350 | 350 |
|
| 351 |
+typedef struct OptionsContext {
|
|
| 352 |
+ /* input/output options */ |
|
| 353 |
+ int64_t start_time; |
|
| 354 |
+ const char *format; |
|
| 355 |
+ |
|
| 356 |
+ /* input options */ |
|
| 357 |
+ int64_t input_ts_offset; |
|
| 358 |
+ |
|
| 359 |
+ /* output options */ |
|
| 360 |
+ StreamMap *stream_maps; |
|
| 361 |
+ int nb_stream_maps; |
|
| 362 |
+ |
|
| 363 |
+ int64_t recording_time; |
|
| 364 |
+ uint64_t limit_filesize; |
|
| 365 |
+} OptionsContext; |
|
| 366 |
+ |
|
| 367 |
+static void reset_options(OptionsContext *o) |
|
| 368 |
+{
|
|
| 369 |
+ const OptionDef *po = options; |
|
| 370 |
+ |
|
| 371 |
+ /* all OPT_SPEC and OPT_STRING can be freed in generic way */ |
|
| 372 |
+ while (po->name) {
|
|
| 373 |
+ void *dst = (uint8_t*)o + po->u.off; |
|
| 374 |
+ |
|
| 375 |
+ if (po->flags & OPT_SPEC) {
|
|
| 376 |
+ SpecifierOpt **so = dst; |
|
| 377 |
+ int i, *count = (int*)(so + 1); |
|
| 378 |
+ for (i = 0; i < *count; i++) {
|
|
| 379 |
+ av_freep(&(*so)[i].specifier); |
|
| 380 |
+ if (po->flags & OPT_STRING) |
|
| 381 |
+ av_freep(&(*so)[i].u.str); |
|
| 382 |
+ } |
|
| 383 |
+ av_freep(so); |
|
| 384 |
+ *count = 0; |
|
| 385 |
+ } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING) |
|
| 386 |
+ av_freep(dst); |
|
| 387 |
+ po++; |
|
| 388 |
+ } |
|
| 389 |
+ |
|
| 390 |
+ av_freep(&o->stream_maps); |
|
| 391 |
+ |
|
| 392 |
+ memset(o, 0, sizeof(*o)); |
|
| 393 |
+ |
|
| 394 |
+ o->recording_time = INT64_MAX; |
|
| 395 |
+ o->limit_filesize = UINT64_MAX; |
|
| 396 |
+ |
|
| 397 |
+ uninit_opts(); |
|
| 398 |
+ init_opts(); |
|
| 399 |
+} |
|
| 400 |
+ |
|
| 351 | 401 |
#if CONFIG_AVFILTER |
| 352 | 402 |
|
| 353 | 403 |
static int configure_video_filters(InputStream *ist, OutputStream *ost) |
| ... | ... |
@@ -547,7 +589,7 @@ static int decode_interrupt_cb(void) |
| 547 | 547 |
return q_pressed > 1; |
| 548 | 548 |
} |
| 549 | 549 |
|
| 550 |
-static int exit_program(int ret) |
|
| 550 |
+void exit_program(int ret) |
|
| 551 | 551 |
{
|
| 552 | 552 |
int i; |
| 553 | 553 |
|
| ... | ... |
@@ -599,7 +641,6 @@ static int exit_program(int ret) |
| 599 | 599 |
} |
| 600 | 600 |
|
| 601 | 601 |
exit(ret); /* not all OS-es handle main() return value */ |
| 602 |
- return ret; |
|
| 603 | 602 |
} |
| 604 | 603 |
|
| 605 | 604 |
static void assert_avoptions(AVDictionary *m) |
| ... | ... |
@@ -628,26 +669,6 @@ static void assert_codec_experimental(AVCodecContext *c, int encoder) |
| 628 | 628 |
} |
| 629 | 629 |
} |
| 630 | 630 |
|
| 631 |
-/* similar to ff_dynarray_add() and av_fast_realloc() */ |
|
| 632 |
-static void *grow_array(void *array, int elem_size, int *size, int new_size) |
|
| 633 |
-{
|
|
| 634 |
- if (new_size >= INT_MAX / elem_size) {
|
|
| 635 |
- fprintf(stderr, "Array too big.\n"); |
|
| 636 |
- exit_program(1); |
|
| 637 |
- } |
|
| 638 |
- if (*size < new_size) {
|
|
| 639 |
- uint8_t *tmp = av_realloc(array, new_size*elem_size); |
|
| 640 |
- if (!tmp) {
|
|
| 641 |
- fprintf(stderr, "Could not alloc buffer.\n"); |
|
| 642 |
- exit_program(1); |
|
| 643 |
- } |
|
| 644 |
- memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size); |
|
| 645 |
- *size = new_size; |
|
| 646 |
- return tmp; |
|
| 647 |
- } |
|
| 648 |
- return array; |
|
| 649 |
-} |
|
| 650 |
- |
|
| 651 | 631 |
static void choose_sample_fmt(AVStream *st, AVCodec *codec) |
| 652 | 632 |
{
|
| 653 | 633 |
if(codec && codec->sample_fmts){
|
| ... | ... |
@@ -1715,8 +1736,9 @@ static int output_packet(InputStream *ist, int ist_index, |
| 1715 | 1715 |
|
| 1716 | 1716 |
#if CONFIG_AVFILTER |
| 1717 | 1717 |
if(ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) |
| 1718 |
- if (start_time == 0 || ist->pts >= start_time) {
|
|
| 1719 |
- for(i=0;i<nb_ostreams;i++) {
|
|
| 1718 |
+ for(i=0;i<nb_ostreams;i++) {
|
|
| 1719 |
+ OutputFile *of = &output_files[ost_table[i].file_index]; |
|
| 1720 |
+ if (of->start_time == 0 || ist->pts >= of->start_time) {
|
|
| 1720 | 1721 |
ost = &ost_table[i]; |
| 1721 | 1722 |
if (ost->input_video_filter && ost->source_index == ist_index) {
|
| 1722 | 1723 |
if (!picture.sample_aspect_ratio.num) |
| ... | ... |
@@ -2614,12 +2636,6 @@ static int transcode(OutputFile *output_files, |
| 2614 | 2614 |
return ret; |
| 2615 | 2615 |
} |
| 2616 | 2616 |
|
| 2617 |
-static int opt_format(const char *opt, const char *arg) |
|
| 2618 |
-{
|
|
| 2619 |
- last_asked_format = arg; |
|
| 2620 |
- return 0; |
|
| 2621 |
-} |
|
| 2622 |
- |
|
| 2623 | 2617 |
static int opt_video_rc_override_string(const char *opt, const char *arg) |
| 2624 | 2618 |
{
|
| 2625 | 2619 |
video_rc_override_string = arg; |
| ... | ... |
@@ -2839,7 +2855,7 @@ static int opt_codec_tag(const char *opt, const char *arg) |
| 2839 | 2839 |
return 0; |
| 2840 | 2840 |
} |
| 2841 | 2841 |
|
| 2842 |
-static int opt_map(const char *opt, const char *arg) |
|
| 2842 |
+static int opt_map(OptionsContext *o, const char *opt, const char *arg) |
|
| 2843 | 2843 |
{
|
| 2844 | 2844 |
StreamMap *m = NULL; |
| 2845 | 2845 |
int i, negative = 0, file_idx; |
| ... | ... |
@@ -2884,8 +2900,8 @@ static int opt_map(const char *opt, const char *arg) |
| 2884 | 2884 |
} |
| 2885 | 2885 |
if (negative) |
| 2886 | 2886 |
/* disable some already defined maps */ |
| 2887 |
- for (i = 0; i < nb_stream_maps; i++) {
|
|
| 2888 |
- m = &stream_maps[i]; |
|
| 2887 |
+ for (i = 0; i < o->nb_stream_maps; i++) {
|
|
| 2888 |
+ m = &o->stream_maps[i]; |
|
| 2889 | 2889 |
if (check_stream_specifier(input_files[m->file_index].ctx, |
| 2890 | 2890 |
input_files[m->file_index].ctx->streams[m->stream_index], |
| 2891 | 2891 |
*p == ':' ? p + 1 : p) > 0) |
| ... | ... |
@@ -2896,8 +2912,9 @@ static int opt_map(const char *opt, const char *arg) |
| 2896 | 2896 |
if (check_stream_specifier(input_files[file_idx].ctx, input_files[file_idx].ctx->streams[i], |
| 2897 | 2897 |
*p == ':' ? p + 1 : p) <= 0) |
| 2898 | 2898 |
continue; |
| 2899 |
- stream_maps = grow_array(stream_maps, sizeof(*stream_maps), &nb_stream_maps, nb_stream_maps + 1); |
|
| 2900 |
- m = &stream_maps[nb_stream_maps - 1]; |
|
| 2899 |
+ o->stream_maps = grow_array(o->stream_maps, sizeof(*o->stream_maps), |
|
| 2900 |
+ &o->nb_stream_maps, o->nb_stream_maps + 1); |
|
| 2901 |
+ m = &o->stream_maps[o->nb_stream_maps - 1]; |
|
| 2901 | 2902 |
|
| 2902 | 2903 |
m->file_index = file_idx; |
| 2903 | 2904 |
m->stream_index = i; |
| ... | ... |
@@ -2981,18 +2998,6 @@ static int opt_input_ts_scale(const char *opt, const char *arg) |
| 2981 | 2981 |
return av_dict_set(&ts_scale, opt, arg, 0); |
| 2982 | 2982 |
} |
| 2983 | 2983 |
|
| 2984 |
-static int opt_recording_time(const char *opt, const char *arg) |
|
| 2985 |
-{
|
|
| 2986 |
- recording_time = parse_time_or_die(opt, arg, 1); |
|
| 2987 |
- return 0; |
|
| 2988 |
-} |
|
| 2989 |
- |
|
| 2990 |
-static int opt_start_time(const char *opt, const char *arg) |
|
| 2991 |
-{
|
|
| 2992 |
- start_time = parse_time_or_die(opt, arg, 1); |
|
| 2993 |
- return 0; |
|
| 2994 |
-} |
|
| 2995 |
- |
|
| 2996 | 2984 |
static int opt_recording_timestamp(const char *opt, const char *arg) |
| 2997 | 2985 |
{
|
| 2998 | 2986 |
char buf[128]; |
| ... | ... |
@@ -3006,12 +3011,6 @@ static int opt_recording_timestamp(const char *opt, const char *arg) |
| 3006 | 3006 |
return 0; |
| 3007 | 3007 |
} |
| 3008 | 3008 |
|
| 3009 |
-static int opt_input_ts_offset(const char *opt, const char *arg) |
|
| 3010 |
-{
|
|
| 3011 |
- input_ts_offset = parse_time_or_die(opt, arg, 1); |
|
| 3012 |
- return 0; |
|
| 3013 |
-} |
|
| 3014 |
- |
|
| 3015 | 3009 |
static enum CodecID find_codec_or_die(const char *name, enum AVMediaType type, int encoder) |
| 3016 | 3010 |
{
|
| 3017 | 3011 |
const char *codec_string = encoder ? "encoder" : "decoder"; |
| ... | ... |
@@ -3152,7 +3151,7 @@ static void add_input_streams(AVFormatContext *ic) |
| 3152 | 3152 |
} |
| 3153 | 3153 |
} |
| 3154 | 3154 |
|
| 3155 |
-static int opt_input_file(const char *opt, const char *filename) |
|
| 3155 |
+static int opt_input_file(OptionsContext *o, const char *opt, const char *filename) |
|
| 3156 | 3156 |
{
|
| 3157 | 3157 |
AVFormatContext *ic; |
| 3158 | 3158 |
AVInputFormat *file_iformat = NULL; |
| ... | ... |
@@ -3162,12 +3161,11 @@ static int opt_input_file(const char *opt, const char *filename) |
| 3162 | 3162 |
AVDictionary **opts; |
| 3163 | 3163 |
int orig_nb_streams; // number of streams before avformat_find_stream_info |
| 3164 | 3164 |
|
| 3165 |
- if (last_asked_format) {
|
|
| 3166 |
- if (!(file_iformat = av_find_input_format(last_asked_format))) {
|
|
| 3167 |
- fprintf(stderr, "Unknown input format: '%s'\n", last_asked_format); |
|
| 3165 |
+ if (o->format) {
|
|
| 3166 |
+ if (!(file_iformat = av_find_input_format(o->format))) {
|
|
| 3167 |
+ fprintf(stderr, "Unknown input format: '%s'\n", o->format); |
|
| 3168 | 3168 |
exit_program(1); |
| 3169 | 3169 |
} |
| 3170 |
- last_asked_format = NULL; |
|
| 3171 | 3170 |
} |
| 3172 | 3171 |
|
| 3173 | 3172 |
if (!strcmp(filename, "-")) |
| ... | ... |
@@ -3257,20 +3255,18 @@ static int opt_input_file(const char *opt, const char *filename) |
| 3257 | 3257 |
exit_program(1); |
| 3258 | 3258 |
} |
| 3259 | 3259 |
|
| 3260 |
- timestamp = start_time; |
|
| 3260 |
+ timestamp = o->start_time; |
|
| 3261 | 3261 |
/* add the stream start time */ |
| 3262 | 3262 |
if (ic->start_time != AV_NOPTS_VALUE) |
| 3263 | 3263 |
timestamp += ic->start_time; |
| 3264 | 3264 |
|
| 3265 | 3265 |
/* if seeking requested, we execute it */ |
| 3266 |
- if (start_time != 0) {
|
|
| 3266 |
+ if (o->start_time != 0) {
|
|
| 3267 | 3267 |
ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD); |
| 3268 | 3268 |
if (ret < 0) {
|
| 3269 | 3269 |
fprintf(stderr, "%s: could not seek to position %0.3f\n", |
| 3270 | 3270 |
filename, (double)timestamp / AV_TIME_BASE); |
| 3271 | 3271 |
} |
| 3272 |
- /* reset seek info */ |
|
| 3273 |
- start_time = 0; |
|
| 3274 | 3272 |
} |
| 3275 | 3273 |
|
| 3276 | 3274 |
/* update the current parameters so that they match the one of the input stream */ |
| ... | ... |
@@ -3283,7 +3279,7 @@ static int opt_input_file(const char *opt, const char *filename) |
| 3283 | 3283 |
input_files = grow_array(input_files, sizeof(*input_files), &nb_input_files, nb_input_files + 1); |
| 3284 | 3284 |
input_files[nb_input_files - 1].ctx = ic; |
| 3285 | 3285 |
input_files[nb_input_files - 1].ist_index = nb_input_streams - ic->nb_streams; |
| 3286 |
- input_files[nb_input_files - 1].ts_offset = input_ts_offset - (copy_ts ? 0 : timestamp); |
|
| 3286 |
+ input_files[nb_input_files - 1].ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp); |
|
| 3287 | 3287 |
input_files[nb_input_files - 1].nb_streams = ic->nb_streams; |
| 3288 | 3288 |
|
| 3289 | 3289 |
top_field_first = -1; |
| ... | ... |
@@ -3295,14 +3291,13 @@ static int opt_input_file(const char *opt, const char *filename) |
| 3295 | 3295 |
audio_channels = 0; |
| 3296 | 3296 |
audio_sample_fmt = AV_SAMPLE_FMT_NONE; |
| 3297 | 3297 |
av_dict_free(&ts_scale); |
| 3298 |
- input_ts_offset = 0; |
|
| 3299 | 3298 |
|
| 3300 | 3299 |
for (i = 0; i < orig_nb_streams; i++) |
| 3301 | 3300 |
av_dict_free(&opts[i]); |
| 3302 | 3301 |
av_freep(&opts); |
| 3303 | 3302 |
av_dict_free(&codec_names); |
| 3304 |
- uninit_opts(); |
|
| 3305 |
- init_opts(); |
|
| 3303 |
+ |
|
| 3304 |
+ reset_options(o); |
|
| 3306 | 3305 |
return 0; |
| 3307 | 3306 |
} |
| 3308 | 3307 |
|
| ... | ... |
@@ -3633,18 +3628,18 @@ static int read_ffserver_streams(AVFormatContext *s, const char *filename) |
| 3633 | 3633 |
} |
| 3634 | 3634 |
|
| 3635 | 3635 |
|
| 3636 |
-static int copy_chapters(int infile, int outfile) |
|
| 3636 |
+static int copy_chapters(InputFile *ifile, OutputFile *ofile) |
|
| 3637 | 3637 |
{
|
| 3638 |
- AVFormatContext *is = input_files[infile].ctx; |
|
| 3639 |
- AVFormatContext *os = output_files[outfile].ctx; |
|
| 3638 |
+ AVFormatContext *is = ifile->ctx; |
|
| 3639 |
+ AVFormatContext *os = ofile->ctx; |
|
| 3640 | 3640 |
int i; |
| 3641 | 3641 |
|
| 3642 | 3642 |
for (i = 0; i < is->nb_chapters; i++) {
|
| 3643 | 3643 |
AVChapter *in_ch = is->chapters[i], *out_ch; |
| 3644 |
- int64_t ts_off = av_rescale_q(start_time - input_files[infile].ts_offset, |
|
| 3644 |
+ int64_t ts_off = av_rescale_q(ofile->start_time - ifile->ts_offset, |
|
| 3645 | 3645 |
AV_TIME_BASE_Q, in_ch->time_base); |
| 3646 |
- int64_t rt = (recording_time == INT64_MAX) ? INT64_MAX : |
|
| 3647 |
- av_rescale_q(recording_time, AV_TIME_BASE_Q, in_ch->time_base); |
|
| 3646 |
+ int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX : |
|
| 3647 |
+ av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base); |
|
| 3648 | 3648 |
|
| 3649 | 3649 |
|
| 3650 | 3650 |
if (in_ch->end < ts_off) |
| ... | ... |
@@ -3673,8 +3668,9 @@ static int copy_chapters(int infile, int outfile) |
| 3673 | 3673 |
return 0; |
| 3674 | 3674 |
} |
| 3675 | 3675 |
|
| 3676 |
-static int opt_output_file(const char *opt, const char *filename) |
|
| 3676 |
+static void opt_output_file(void *optctx, const char *filename) |
|
| 3677 | 3677 |
{
|
| 3678 |
+ OptionsContext *o = optctx; |
|
| 3678 | 3679 |
AVFormatContext *oc; |
| 3679 | 3680 |
int i, err; |
| 3680 | 3681 |
AVOutputFormat *file_oformat; |
| ... | ... |
@@ -3684,8 +3680,7 @@ static int opt_output_file(const char *opt, const char *filename) |
| 3684 | 3684 |
if (!strcmp(filename, "-")) |
| 3685 | 3685 |
filename = "pipe:"; |
| 3686 | 3686 |
|
| 3687 |
- err = avformat_alloc_output_context2(&oc, NULL, last_asked_format, filename); |
|
| 3688 |
- last_asked_format = NULL; |
|
| 3687 |
+ err = avformat_alloc_output_context2(&oc, NULL, o->format, filename); |
|
| 3689 | 3688 |
if (!oc) {
|
| 3690 | 3689 |
print_error(filename, err); |
| 3691 | 3690 |
exit_program(1); |
| ... | ... |
@@ -3701,7 +3696,7 @@ static int opt_output_file(const char *opt, const char *filename) |
| 3701 | 3701 |
print_error(filename, err); |
| 3702 | 3702 |
exit_program(1); |
| 3703 | 3703 |
} |
| 3704 |
- } else if (!nb_stream_maps) {
|
|
| 3704 |
+ } else if (!o->nb_stream_maps) {
|
|
| 3705 | 3705 |
/* pick the "best" stream of each type */ |
| 3706 | 3706 |
#define NEW_STREAM(type, index)\ |
| 3707 | 3707 |
if (index >= 0) {\
|
| ... | ... |
@@ -3749,8 +3744,8 @@ static int opt_output_file(const char *opt, const char *filename) |
| 3749 | 3749 |
} |
| 3750 | 3750 |
/* do something with data? */ |
| 3751 | 3751 |
} else {
|
| 3752 |
- for (i = 0; i < nb_stream_maps; i++) {
|
|
| 3753 |
- StreamMap *map = &stream_maps[i]; |
|
| 3752 |
+ for (i = 0; i < o->nb_stream_maps; i++) {
|
|
| 3753 |
+ StreamMap *map = &o->stream_maps[i]; |
|
| 3754 | 3754 |
|
| 3755 | 3755 |
if (map->disabled) |
| 3756 | 3756 |
continue; |
| ... | ... |
@@ -3781,9 +3776,9 @@ static int opt_output_file(const char *opt, const char *filename) |
| 3781 | 3781 |
output_files = grow_array(output_files, sizeof(*output_files), &nb_output_files, nb_output_files + 1); |
| 3782 | 3782 |
output_files[nb_output_files - 1].ctx = oc; |
| 3783 | 3783 |
output_files[nb_output_files - 1].ost_index = nb_output_streams - oc->nb_streams; |
| 3784 |
- output_files[nb_output_files - 1].recording_time = recording_time; |
|
| 3785 |
- output_files[nb_output_files - 1].start_time = start_time; |
|
| 3786 |
- output_files[nb_output_files - 1].limit_filesize = limit_filesize; |
|
| 3784 |
+ output_files[nb_output_files - 1].recording_time = o->recording_time; |
|
| 3785 |
+ output_files[nb_output_files - 1].start_time = o->start_time; |
|
| 3786 |
+ output_files[nb_output_files - 1].limit_filesize = o->limit_filesize; |
|
| 3787 | 3787 |
av_dict_copy(&output_files[nb_output_files - 1].opts, format_opts, 0); |
| 3788 | 3788 |
|
| 3789 | 3789 |
/* check filename in case of an image number is expected */ |
| ... | ... |
@@ -3848,7 +3843,7 @@ static int opt_output_file(const char *opt, const char *filename) |
| 3848 | 3848 |
} |
| 3849 | 3849 |
} |
| 3850 | 3850 |
if (chapters_input_file >= 0) |
| 3851 |
- copy_chapters(chapters_input_file, nb_output_files - 1); |
|
| 3851 |
+ copy_chapters(&input_files[chapters_input_file], &output_files[nb_output_files - 1]); |
|
| 3852 | 3852 |
|
| 3853 | 3853 |
/* copy metadata */ |
| 3854 | 3854 |
for (i = 0; i < nb_meta_data_maps; i++) {
|
| ... | ... |
@@ -3913,26 +3908,19 @@ static int opt_output_file(const char *opt, const char *filename) |
| 3913 | 3913 |
audio_channels = 0; |
| 3914 | 3914 |
audio_sample_fmt = AV_SAMPLE_FMT_NONE; |
| 3915 | 3915 |
chapters_input_file = INT_MAX; |
| 3916 |
- recording_time = INT64_MAX; |
|
| 3917 |
- start_time = 0; |
|
| 3918 |
- limit_filesize = UINT64_MAX; |
|
| 3919 | 3916 |
|
| 3920 | 3917 |
av_freep(&meta_data_maps); |
| 3921 | 3918 |
nb_meta_data_maps = 0; |
| 3922 | 3919 |
metadata_global_autocopy = 1; |
| 3923 | 3920 |
metadata_streams_autocopy = 1; |
| 3924 | 3921 |
metadata_chapters_autocopy = 1; |
| 3925 |
- av_freep(&stream_maps); |
|
| 3926 |
- nb_stream_maps = 0; |
|
| 3927 | 3922 |
av_freep(&streamid_map); |
| 3928 | 3923 |
nb_streamid_map = 0; |
| 3929 | 3924 |
|
| 3930 | 3925 |
av_dict_free(&codec_names); |
| 3931 | 3926 |
|
| 3932 | 3927 |
av_freep(&forced_key_frames); |
| 3933 |
- uninit_opts(); |
|
| 3934 |
- init_opts(); |
|
| 3935 |
- return 0; |
|
| 3928 |
+ reset_options(o); |
|
| 3936 | 3929 |
} |
| 3937 | 3930 |
|
| 3938 | 3931 |
/* same option as mencoder */ |
| ... | ... |
@@ -4087,7 +4075,7 @@ static int opt_help(const char *opt, const char *arg) |
| 4087 | 4087 |
return 0; |
| 4088 | 4088 |
} |
| 4089 | 4089 |
|
| 4090 |
-static int opt_target(const char *opt, const char *arg) |
|
| 4090 |
+static int opt_target(OptionsContext *o, const char *opt, const char *arg) |
|
| 4091 | 4091 |
{
|
| 4092 | 4092 |
enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
|
| 4093 | 4093 |
static const char *const frame_rates[] = {"25", "30000/1001", "24000/1001"};
|
| ... | ... |
@@ -4146,7 +4134,7 @@ static int opt_target(const char *opt, const char *arg) |
| 4146 | 4146 |
if(!strcmp(arg, "vcd")) {
|
| 4147 | 4147 |
opt_codec("c:v", "mpeg1video");
|
| 4148 | 4148 |
opt_codec("c:a", "mp2");
|
| 4149 |
- opt_format("f", "vcd");
|
|
| 4149 |
+ parse_option(o, "f", "vcd", options); |
|
| 4150 | 4150 |
|
| 4151 | 4151 |
opt_frame_size("s", norm == PAL ? "352x288" : "352x240");
|
| 4152 | 4152 |
opt_frame_rate("r", frame_rates[norm]);
|
| ... | ... |
@@ -4174,7 +4162,7 @@ static int opt_target(const char *opt, const char *arg) |
| 4174 | 4174 |
|
| 4175 | 4175 |
opt_codec("c:v", "mpeg2video");
|
| 4176 | 4176 |
opt_codec("c:a", "mp2");
|
| 4177 |
- opt_format("f", "svcd");
|
|
| 4177 |
+ parse_option(o, "f", "svcd", options); |
|
| 4178 | 4178 |
|
| 4179 | 4179 |
opt_frame_size("s", norm == PAL ? "480x576" : "480x480");
|
| 4180 | 4180 |
opt_frame_rate("r", frame_rates[norm]);
|
| ... | ... |
@@ -4197,7 +4185,7 @@ static int opt_target(const char *opt, const char *arg) |
| 4197 | 4197 |
|
| 4198 | 4198 |
opt_codec("c:v", "mpeg2video");
|
| 4199 | 4199 |
opt_codec("c:a", "ac3");
|
| 4200 |
- opt_format("f", "dvd");
|
|
| 4200 |
+ parse_option(o, "f", "dvd", options); |
|
| 4201 | 4201 |
|
| 4202 | 4202 |
opt_frame_size("vcodec", norm == PAL ? "720x576" : "720x480");
|
| 4203 | 4203 |
opt_frame_rate("r", frame_rates[norm]);
|
| ... | ... |
@@ -4217,7 +4205,7 @@ static int opt_target(const char *opt, const char *arg) |
| 4217 | 4217 |
|
| 4218 | 4218 |
} else if(!strncmp(arg, "dv", 2)) {
|
| 4219 | 4219 |
|
| 4220 |
- opt_format("f", "dv");
|
|
| 4220 |
+ parse_option(o, "f", "dv", options); |
|
| 4221 | 4221 |
|
| 4222 | 4222 |
opt_frame_size("s", norm == PAL ? "720x576" : "720x480");
|
| 4223 | 4223 |
opt_frame_pix_fmt("pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
|
| ... | ... |
@@ -4328,24 +4316,25 @@ static int opt_passlogfile(const char *opt, const char *arg) |
| 4328 | 4328 |
#endif |
| 4329 | 4329 |
} |
| 4330 | 4330 |
|
| 4331 |
+#define OFFSET(x) offsetof(OptionsContext, x) |
|
| 4331 | 4332 |
static const OptionDef options[] = {
|
| 4332 | 4333 |
/* main options */ |
| 4333 | 4334 |
#include "cmdutils_common_opts.h" |
| 4334 |
- { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
|
|
| 4335 |
- { "i", HAS_ARG, {(void*)opt_input_file}, "input file name", "filename" },
|
|
| 4335 |
+ { "f", HAS_ARG | OPT_STRING | OPT_OFFSET, {.off = OFFSET(format)}, "force format", "fmt" },
|
|
| 4336 |
+ { "i", HAS_ARG | OPT_FUNC2, {(void*)opt_input_file}, "input file name", "filename" },
|
|
| 4336 | 4337 |
{ "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
|
| 4337 | 4338 |
{ "c", HAS_ARG, {(void*)opt_codec}, "codec name", "codec" },
|
| 4338 | 4339 |
{ "codec", HAS_ARG, {(void*)opt_codec}, "codec name", "codec" },
|
| 4339 |
- { "map", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" },
|
|
| 4340 |
+ { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" },
|
|
| 4340 | 4341 |
{ "map_meta_data", HAS_ARG | OPT_EXPERT, {(void*)opt_map_meta_data}, "DEPRECATED set meta data information of outfile from infile",
|
| 4341 | 4342 |
"outfile[,metadata]:infile[,metadata]" }, |
| 4342 | 4343 |
{ "map_metadata", HAS_ARG | OPT_EXPERT, {(void*)opt_map_metadata}, "set metadata information of outfile from infile",
|
| 4343 | 4344 |
"outfile[,metadata]:infile[,metadata]" }, |
| 4344 | 4345 |
{ "map_chapters", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&chapters_input_file}, "set chapters mapping", "input_file_index" },
|
| 4345 |
- { "t", HAS_ARG, {(void*)opt_recording_time}, "record or transcode \"duration\" seconds of audio/video", "duration" },
|
|
| 4346 |
- { "fs", HAS_ARG | OPT_INT64, {(void*)&limit_filesize}, "set the limit file size in bytes", "limit_size" }, //
|
|
| 4347 |
- { "ss", HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" },
|
|
| 4348 |
- { "itsoffset", HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" },
|
|
| 4346 |
+ { "t", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(recording_time)}, "record or transcode \"duration\" seconds of audio/video", "duration" },
|
|
| 4347 |
+ { "fs", HAS_ARG | OPT_INT64 | OPT_OFFSET, {.off = OFFSET(limit_filesize)}, "set the limit file size in bytes", "limit_size" }, //
|
|
| 4348 |
+ { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(start_time)}, "set the start time offset", "time_off" },
|
|
| 4349 |
+ { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(input_ts_offset)}, "set the input ts offset", "time_off" },
|
|
| 4349 | 4350 |
{ "itsscale", HAS_ARG, {(void*)opt_input_ts_scale}, "set the input ts scale", "scale" },
|
| 4350 | 4351 |
{ "timestamp", HAS_ARG, {(void*)opt_recording_timestamp}, "set the recording timestamp ('now' to set the current time)", "time" },
|
| 4351 | 4352 |
{ "metadata", HAS_ARG, {(void*)opt_metadata}, "add metadata", "string=string" },
|
| ... | ... |
@@ -4361,7 +4350,7 @@ static const OptionDef options[] = {
|
| 4361 | 4361 |
{ "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "deprecated, use -loop" },
|
| 4362 | 4362 |
{ "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "deprecated, use -loop", "" },
|
| 4363 | 4363 |
{ "v", HAS_ARG, {(void*)opt_verbose}, "set the verbosity level", "number" },
|
| 4364 |
- { "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
|
|
| 4364 |
+ { "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
|
|
| 4365 | 4365 |
{ "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
|
| 4366 | 4366 |
{ "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" },
|
| 4367 | 4367 |
{ "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" },
|
| ... | ... |
@@ -4464,8 +4453,11 @@ static const OptionDef options[] = {
|
| 4464 | 4464 |
|
| 4465 | 4465 |
int main(int argc, char **argv) |
| 4466 | 4466 |
{
|
| 4467 |
+ OptionsContext o = { 0 };
|
|
| 4467 | 4468 |
int64_t ti; |
| 4468 | 4469 |
|
| 4470 |
+ reset_options(&o); |
|
| 4471 |
+ |
|
| 4469 | 4472 |
av_log_set_flags(AV_LOG_SKIP_REPEATED); |
| 4470 | 4473 |
|
| 4471 | 4474 |
if(argc>1 && !strcmp(argv[1], "-d")){
|
| ... | ... |
@@ -4490,13 +4482,11 @@ int main(int argc, char **argv) |
| 4490 | 4490 |
avio_set_interrupt_cb(decode_interrupt_cb); |
| 4491 | 4491 |
#endif |
| 4492 | 4492 |
|
| 4493 |
- init_opts(); |
|
| 4494 |
- |
|
| 4495 | 4493 |
if(verbose>=0) |
| 4496 | 4494 |
show_banner(); |
| 4497 | 4495 |
|
| 4498 | 4496 |
/* parse options */ |
| 4499 |
- parse_options(argc, argv, options, opt_output_file); |
|
| 4497 |
+ parse_options(&o, argc, argv, options, opt_output_file); |
|
| 4500 | 4498 |
|
| 4501 | 4499 |
if(nb_output_files <= 0 && nb_input_files == 0) {
|
| 4502 | 4500 |
show_usage(); |
| ... | ... |
@@ -4524,5 +4514,6 @@ int main(int argc, char **argv) |
| 4524 | 4524 |
printf("bench: utime=%0.3fs maxrss=%ikB\n", ti / 1000000.0, maxrss);
|
| 4525 | 4525 |
} |
| 4526 | 4526 |
|
| 4527 |
- return exit_program(0); |
|
| 4527 |
+ exit_program(0); |
|
| 4528 |
+ return 0; |
|
| 4528 | 4529 |
} |
| ... | ... |
@@ -277,6 +277,11 @@ static AVPacket flush_pkt; |
| 277 | 277 |
|
| 278 | 278 |
static SDL_Surface *screen; |
| 279 | 279 |
|
| 280 |
+void exit_program(int ret) |
|
| 281 |
+{
|
|
| 282 |
+ exit(ret); |
|
| 283 |
+} |
|
| 284 |
+ |
|
| 280 | 285 |
static int packet_queue_put(PacketQueue *q, AVPacket *pkt) |
| 281 | 286 |
{
|
| 282 | 287 |
AVPacketList *pkt1; |
| ... | ... |
@@ -2891,19 +2896,20 @@ static int opt_show_mode(const char *opt, const char *arg) |
| 2891 | 2891 |
return 0; |
| 2892 | 2892 |
} |
| 2893 | 2893 |
|
| 2894 |
-static int opt_input_file(const char *opt, const char *filename) |
|
| 2894 |
+static void opt_input_file(void *optctx, const char *filename) |
|
| 2895 | 2895 |
{
|
| 2896 | 2896 |
if (input_filename) {
|
| 2897 | 2897 |
fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n", |
| 2898 | 2898 |
filename, input_filename); |
| 2899 |
- exit(1); |
|
| 2899 |
+ exit_program(1); |
|
| 2900 | 2900 |
} |
| 2901 | 2901 |
if (!strcmp(filename, "-")) |
| 2902 | 2902 |
filename = "pipe:"; |
| 2903 | 2903 |
input_filename = filename; |
| 2904 |
- return 0; |
|
| 2905 | 2904 |
} |
| 2906 | 2905 |
|
| 2906 |
+static int dummy; |
|
| 2907 |
+ |
|
| 2907 | 2908 |
static const OptionDef options[] = {
|
| 2908 | 2909 |
#include "cmdutils_common_opts.h" |
| 2909 | 2910 |
{ "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
|
| ... | ... |
@@ -2947,7 +2953,7 @@ static const OptionDef options[] = {
|
| 2947 | 2947 |
{ "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, {(void*)&rdftspeed}, "rdft speed", "msecs" },
|
| 2948 | 2948 |
{ "showmode", HAS_ARG, {(void*)opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
|
| 2949 | 2949 |
{ "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
|
| 2950 |
- { "i", HAS_ARG, {(void *)opt_input_file}, "read specified file", "input_file"},
|
|
| 2950 |
+ { "i", OPT_BOOL, {(void *)&dummy}, "read specified file", "input_file"},
|
|
| 2951 | 2951 |
{ NULL, },
|
| 2952 | 2952 |
}; |
| 2953 | 2953 |
|
| ... | ... |
@@ -3038,7 +3044,7 @@ int main(int argc, char **argv) |
| 3038 | 3038 |
|
| 3039 | 3039 |
show_banner(); |
| 3040 | 3040 |
|
| 3041 |
- parse_options(argc, argv, options, opt_input_file); |
|
| 3041 |
+ parse_options(NULL, argc, argv, options, opt_input_file); |
|
| 3042 | 3042 |
|
| 3043 | 3043 |
if (!input_filename) {
|
| 3044 | 3044 |
show_usage(); |
| ... | ... |
@@ -58,6 +58,11 @@ static const char *unit_hertz_str = "Hz" ; |
| 58 | 58 |
static const char *unit_byte_str = "byte" ; |
| 59 | 59 |
static const char *unit_bit_per_second_str = "bit/s"; |
| 60 | 60 |
|
| 61 |
+void exit_program(int ret) |
|
| 62 |
+{
|
|
| 63 |
+ exit(ret); |
|
| 64 |
+} |
|
| 65 |
+ |
|
| 61 | 66 |
static char *value_string(char *buf, int buf_size, double val, const char *unit) |
| 62 | 67 |
{
|
| 63 | 68 |
if (unit == unit_second_str && use_value_sexagesimal_format) {
|
| ... | ... |
@@ -455,7 +460,7 @@ static int opt_format(const char *opt, const char *arg) |
| 455 | 455 |
return 0; |
| 456 | 456 |
} |
| 457 | 457 |
|
| 458 |
-static int opt_input_file(const char *opt, const char *arg) |
|
| 458 |
+static void opt_input_file(void *optctx, const char *arg) |
|
| 459 | 459 |
{
|
| 460 | 460 |
if (input_filename) {
|
| 461 | 461 |
fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n", |
| ... | ... |
@@ -465,7 +470,6 @@ static int opt_input_file(const char *opt, const char *arg) |
| 465 | 465 |
if (!strcmp(arg, "-")) |
| 466 | 466 |
arg = "pipe:"; |
| 467 | 467 |
input_filename = arg; |
| 468 |
- return 0; |
|
| 469 | 468 |
} |
| 470 | 469 |
|
| 471 | 470 |
static int opt_help(const char *opt, const char *arg) |
| ... | ... |
@@ -519,7 +523,7 @@ int main(int argc, char **argv) |
| 519 | 519 |
#endif |
| 520 | 520 |
|
| 521 | 521 |
show_banner(); |
| 522 |
- parse_options(argc, argv, options, opt_input_file); |
|
| 522 |
+ parse_options(NULL, argc, argv, options, opt_input_file); |
|
| 523 | 523 |
|
| 524 | 524 |
if (!input_filename) {
|
| 525 | 525 |
show_usage(); |
| ... | ... |
@@ -321,6 +321,11 @@ static AVLFG random_state; |
| 321 | 321 |
static FILE *logfile = NULL; |
| 322 | 322 |
|
| 323 | 323 |
/* FIXME: make ffserver work with IPv6 */ |
| 324 |
+void exit_program(int ret) |
|
| 325 |
+{
|
|
| 326 |
+ exit(ret); |
|
| 327 |
+} |
|
| 328 |
+ |
|
| 324 | 329 |
/* resolve host with also IP address parsing */ |
| 325 | 330 |
static int resolve_host(struct in_addr *sin_addr, const char *hostname) |
| 326 | 331 |
{
|
| ... | ... |
@@ -4672,7 +4677,7 @@ int main(int argc, char **argv) |
| 4672 | 4672 |
my_program_dir = getcwd(0, 0); |
| 4673 | 4673 |
ffserver_daemon = 1; |
| 4674 | 4674 |
|
| 4675 |
- parse_options(argc, argv, options, NULL); |
|
| 4675 |
+ parse_options(NULL, argc, argv, options, NULL); |
|
| 4676 | 4676 |
|
| 4677 | 4677 |
unsetenv("http_proxy"); /* Kill the http_proxy */
|
| 4678 | 4678 |
|
| ... | ... |
@@ -483,7 +483,7 @@ static const AVOption options[]={
|
| 483 | 483 |
{"lpc_passes", "deprecated, use flac-specific options", OFFSET(lpc_passes), FF_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
|
| 484 | 484 |
#endif |
| 485 | 485 |
{"slices", "number of slices, used in parallelized decoding", OFFSET(slices), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, V|E},
|
| 486 |
-{"thread_type", "select multithreading type", OFFSET(thread_type), FF_OPT_TYPE_INT, {.dbl = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|E|D, "thread_type"},
|
|
| 486 |
+{"thread_type", "select multithreading type", OFFSET(thread_type), FF_OPT_TYPE_FLAGS, {.dbl = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|E|D, "thread_type"},
|
|
| 487 | 487 |
{"slice", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
|
| 488 | 488 |
{"frame", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
|
| 489 | 489 |
{"audio_service_type", "audio service type", OFFSET(audio_service_type), FF_OPT_TYPE_INT, {.dbl = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"},
|
| ... | ... |
@@ -265,7 +265,7 @@ static int process_line(URLContext *h, char *line, int line_count, |
| 265 | 265 |
s->filesize = atoll(slash+1); |
| 266 | 266 |
} |
| 267 | 267 |
h->is_streamed = 0; /* we _can_ in fact seek */ |
| 268 |
- } else if (!strcasecmp (tag, "Accept-Ranges") && !strncmp (p, "bytes", 5)) {
|
|
| 268 |
+ } else if (!strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5)) {
|
|
| 269 | 269 |
h->is_streamed = 0; |
| 270 | 270 |
} else if (!strcasecmp (tag, "Transfer-Encoding") && !strncasecmp(p, "chunked", 7)) {
|
| 271 | 271 |
s->filesize = -1; |
| ... | ... |
@@ -580,7 +580,7 @@ static int write_headers(AVFormatContext *avctx, AVIOContext *bc){
|
| 580 | 580 |
return 0; |
| 581 | 581 |
} |
| 582 | 582 |
|
| 583 |
-static int write_header(AVFormatContext *s){
|
|
| 583 |
+static int nut_write_header(AVFormatContext *s){
|
|
| 584 | 584 |
NUTContext *nut = s->priv_data; |
| 585 | 585 |
AVIOContext *bc = s->pb; |
| 586 | 586 |
int i, j, ret; |
| ... | ... |
@@ -692,7 +692,7 @@ static int find_best_header_idx(NUTContext *nut, AVPacket *pkt){
|
| 692 | 692 |
return best_i; |
| 693 | 693 |
} |
| 694 | 694 |
|
| 695 |
-static int write_packet(AVFormatContext *s, AVPacket *pkt){
|
|
| 695 |
+static int nut_write_packet(AVFormatContext *s, AVPacket *pkt){
|
|
| 696 | 696 |
NUTContext *nut = s->priv_data; |
| 697 | 697 |
StreamContext *nus= &nut->stream[pkt->stream_index]; |
| 698 | 698 |
AVIOContext *bc = s->pb, *dyn_bc; |
| ... | ... |
@@ -846,7 +846,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt){
|
| 846 | 846 |
return 0; |
| 847 | 847 |
} |
| 848 | 848 |
|
| 849 |
-static int write_trailer(AVFormatContext *s){
|
|
| 849 |
+static int nut_write_trailer(AVFormatContext *s){
|
|
| 850 | 850 |
NUTContext *nut= s->priv_data; |
| 851 | 851 |
AVIOContext *bc= s->pb; |
| 852 | 852 |
|
| ... | ... |
@@ -875,9 +875,9 @@ AVOutputFormat ff_nut_muxer = {
|
| 875 | 875 |
.audio_codec = CODEC_ID_MP2, |
| 876 | 876 |
#endif |
| 877 | 877 |
.video_codec = CODEC_ID_MPEG4, |
| 878 |
- .write_header = write_header, |
|
| 879 |
- .write_packet = write_packet, |
|
| 880 |
- .write_trailer = write_trailer, |
|
| 878 |
+ .write_header = nut_write_header, |
|
| 879 |
+ .write_packet = nut_write_packet, |
|
| 880 |
+ .write_trailer = nut_write_trailer, |
|
| 881 | 881 |
.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, |
| 882 | 882 |
.codec_tag = (const AVCodecTag * const []){ ff_codec_bmp_tags, ff_nut_video_tags, ff_codec_wav_tags, ff_nut_subtitle_tags, 0 },
|
| 883 | 883 |
}; |
| ... | ... |
@@ -35,7 +35,7 @@ fate-bink-demux-video: CMD = framecrc -i $(SAMPLES)/bink/hol2br.bik |
| 35 | 35 |
FATE_TESTS += fate-caf |
| 36 | 36 |
fate-caf: CMD = crc -i $(SAMPLES)/caf/caf-pcm16.caf |
| 37 | 37 |
FATE_TESTS += fate-cdgraphics |
| 38 |
-fate-cdgraphics: CMD = framecrc -t 1 -i $(SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgb24 |
|
| 38 |
+fate-cdgraphics: CMD = framecrc -i $(SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgb24 -t 1 |
|
| 39 | 39 |
FATE_TESTS += fate-cljr |
| 40 | 40 |
fate-cljr: CMD = framecrc -i $(SAMPLES)/cljr/testcljr-partial.avi |
| 41 | 41 |
FATE_TESTS += fate-corepng |
| ... | ... |
@@ -129,7 +129,7 @@ fate-id-cin-video: CMD = framecrc -i $(SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rg |
| 129 | 129 |
FATE_TESTS += fate-idroq-video-dpcm |
| 130 | 130 |
fate-idroq-video-dpcm: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq |
| 131 | 131 |
FATE_TESTS += fate-idroq-video-encode |
| 132 |
-fate-idroq-video-encode: CMD = md5 -t 0.2 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f RoQ |
|
| 132 |
+fate-idroq-video-encode: CMD = md5 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f RoQ -t 0.2 |
|
| 133 | 133 |
FATE_TESTS += fate-iff-byterun1 |
| 134 | 134 |
fate-iff-byterun1: CMD = framecrc -i $(SAMPLES)/iff/ASH.LBM -pix_fmt rgb24 |
| 135 | 135 |
FATE_TESTS += fate-iff-fibonacci |
| ... | ... |
@@ -4,32 +4,32 @@ fate-mp3-float-conf-compl: CMP = stddev |
| 4 | 4 |
fate-mp3-float-conf-compl: REF = $(SAMPLES)/mp3-conformance/compl.pcm |
| 5 | 5 |
|
| 6 | 6 |
FATE_MP3 += fate-mp3-float-conf-he_32khz |
| 7 |
-fate-mp3-float-conf-he_32khz: CMD = pcm -acodec mp3float -fs 343296 -i $(SAMPLES)/mp3-conformance/he_32khz.bit |
|
| 7 |
+fate-mp3-float-conf-he_32khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_32khz.bit -fs 343296 |
|
| 8 | 8 |
fate-mp3-float-conf-he_32khz: CMP = stddev |
| 9 | 9 |
fate-mp3-float-conf-he_32khz: REF = $(SAMPLES)/mp3-conformance/he_32khz.pcm |
| 10 | 10 |
|
| 11 | 11 |
FATE_MP3 += fate-mp3-float-conf-he_44khz |
| 12 |
-fate-mp3-float-conf-he_44khz: CMD = pcm -acodec mp3float -fs 942336 -i $(SAMPLES)/mp3-conformance/he_44khz.bit |
|
| 12 |
+fate-mp3-float-conf-he_44khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_44khz.bit -fs 942336 |
|
| 13 | 13 |
fate-mp3-float-conf-he_44khz: CMP = stddev |
| 14 | 14 |
fate-mp3-float-conf-he_44khz: REF = $(SAMPLES)/mp3-conformance/he_44khz.pcm |
| 15 | 15 |
|
| 16 | 16 |
FATE_MP3 += fate-mp3-float-conf-he_48khz |
| 17 |
-fate-mp3-float-conf-he_48khz: CMD = pcm -acodec mp3float -fs 343296 -i $(SAMPLES)/mp3-conformance/he_48khz.bit |
|
| 17 |
+fate-mp3-float-conf-he_48khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_48khz.bit -fs 343296 |
|
| 18 | 18 |
fate-mp3-float-conf-he_48khz: CMP = stddev |
| 19 | 19 |
fate-mp3-float-conf-he_48khz: REF = $(SAMPLES)/mp3-conformance/he_48khz.pcm |
| 20 | 20 |
|
| 21 | 21 |
FATE_MP3 += fate-mp3-float-conf-hecommon |
| 22 |
-fate-mp3-float-conf-hecommon: CMD = pcm -acodec mp3float -fs 133632 -i $(SAMPLES)/mp3-conformance/hecommon.bit |
|
| 22 |
+fate-mp3-float-conf-hecommon: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/hecommon.bit -fs 133632 |
|
| 23 | 23 |
fate-mp3-float-conf-hecommon: CMP = stddev |
| 24 | 24 |
fate-mp3-float-conf-hecommon: REF = $(SAMPLES)/mp3-conformance/hecommon.pcm |
| 25 | 25 |
|
| 26 | 26 |
FATE_MP3 += fate-mp3-float-conf-si |
| 27 |
-fate-mp3-float-conf-si: CMD = pcm -acodec mp3float -fs 269568 -i $(SAMPLES)/mp3-conformance/si.bit |
|
| 27 |
+fate-mp3-float-conf-si: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/si.bit -fs 269568 |
|
| 28 | 28 |
fate-mp3-float-conf-si: CMP = stddev |
| 29 | 29 |
fate-mp3-float-conf-si: REF = $(SAMPLES)/mp3-conformance/si.pcm |
| 30 | 30 |
|
| 31 | 31 |
FATE_MP3 += fate-mp3-float-conf-si_block |
| 32 |
-fate-mp3-float-conf-si_block: CMD = pcm -acodec mp3float -fs 145152 -i $(SAMPLES)/mp3-conformance/si_block.bit |
|
| 32 |
+fate-mp3-float-conf-si_block: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/si_block.bit -fs 145152 |
|
| 33 | 33 |
fate-mp3-float-conf-si_block: CMP = stddev |
| 34 | 34 |
fate-mp3-float-conf-si_block: REF = $(SAMPLES)/mp3-conformance/si_block.pcm |
| 35 | 35 |
|
| ... | ... |
@@ -125,7 +125,7 @@ fate-atrac3-3: CMP = oneoff |
| 125 | 125 |
fate-atrac3-3: REF = $(SAMPLES)/atrac3/mc_sich_at3_132_small.pcm |
| 126 | 126 |
|
| 127 | 127 |
FATE_TESTS += fate-gsm |
| 128 |
-fate-gsm: CMD = framecrc -t 10 -i $(SAMPLES)/gsm/sample-gsm-8000.mov |
|
| 128 |
+fate-gsm: CMD = framecrc -i $(SAMPLES)/gsm/sample-gsm-8000.mov -t 10 |
|
| 129 | 129 |
|
| 130 | 130 |
FATE_TESTS += fate-gsm-ms |
| 131 | 131 |
fate-gsm-ms: CMD = framecrc -i $(SAMPLES)/gsm/ciao.wav |
| ... | ... |
@@ -227,8 +227,8 @@ conversions="yuv420p yuv422p yuv444p yuyv422 yuv410p yuv411p yuvj420p \ |
| 227 | 227 |
monob yuv440p yuvj440p" |
| 228 | 228 |
for pix_fmt in $conversions ; do |
| 229 | 229 |
file=${outfile}${pix_fmt}.yuv
|
| 230 |
- run_avconv $DEC_OPTS -r 1 -t 1 -f image2 -vcodec pgmyuv -i $raw_src \ |
|
| 231 |
- $ENC_OPTS -f rawvideo -s 352x288 -pix_fmt $pix_fmt $target_path/$raw_dst |
|
| 230 |
+ run_avconv $DEC_OPTS -r 1 -f image2 -vcodec pgmyuv -i $raw_src \ |
|
| 231 |
+ $ENC_OPTS -f rawvideo -t 1 -s 352x288 -pix_fmt $pix_fmt $target_path/$raw_dst |
|
| 232 | 232 |
do_avconv $file $DEC_OPTS -f rawvideo -s 352x288 -pix_fmt $pix_fmt -i $target_path/$raw_dst \ |
| 233 | 233 |
$ENC_OPTS -f rawvideo -s 352x288 -pix_fmt yuv444p |
| 234 | 234 |
done |