Browse code

Merge remote-tracking branch 'qatar/master'

* 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>

Michael Niedermayer authored on 2011/09/05 09:04:27
Showing 14 changed files
... ...
@@ -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