mov: Fix empty edit detection.
[ffmpeg.git] / cmdutils.c
index f25f61d..943a77c 100644 (file)
@@ -38,6 +38,7 @@
 #include "libavutil/parseutils.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/eval.h"
+#include "libavutil/dict.h"
 #include "libavutil/opt.h"
 #include "cmdutils.h"
 #include "version.h"
@@ -54,6 +55,7 @@ static int opt_name_count;
 AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
 AVFormatContext *avformat_opts;
 struct SwsContext *sws_opts;
+AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts;
 
 static const int this_year = 2011;
 
@@ -76,7 +78,8 @@ void uninit_opts(void)
     av_freep(&avformat_opts->key);
     av_freep(&avformat_opts);
 #if CONFIG_SWSCALE
-    av_freep(&sws_opts);
+    sws_freeContext(sws_opts);
+    sws_opts = NULL;
 #endif
     for (i = 0; i < opt_name_count; i++) {
         //opt_values are only stored for codec-specific options in which case
@@ -88,6 +91,11 @@ void uninit_opts(void)
     }
     av_freep(&opt_names);
     av_freep(&opt_values);
+    opt_name_count = 0;
+    av_dict_free(&format_opts);
+    av_dict_free(&video_opts);
+    av_dict_free(&audio_opts);
+    av_dict_free(&sub_opts);
 }
 
 void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
@@ -106,6 +114,8 @@ double parse_number_or_die(const char *context, const char *numstr, int type, do
         error= "The value for %s was %s which is not within %f - %f\n";
     else if(type == OPT_INT64 && (int64_t)d != d)
         error= "Expected int64 for %s but found %s\n";
+    else if (type == OPT_INT && (int)d != d)
+        error= "Expected int for %s but found %s\n";
     else
         return d;
     fprintf(stderr, error, context, numstr, min, max);
@@ -156,6 +166,7 @@ static const OptionDef* find_option(const OptionDef *po, const char *name){
 }
 
 #if defined(_WIN32) && !defined(__MINGW32CE__)
+#include <windows.h>
 /* Will be leaked on exit */
 static char** win32_argv_utf8 = NULL;
 static int win32_argc = 0;
@@ -272,13 +283,11 @@ unknown_opt:
                 *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
             } else if (po->flags & OPT_FLOAT) {
                 *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
-            } else if (po->flags & OPT_FUNC2) {
-                if (po->u.func2_arg(opt, arg) < 0) {
+            } else if (po->u.func_arg) {
+                if (po->u.func_arg(opt, arg) < 0) {
                     fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt);
                     exit(1);
                 }
-            } else {
-                po->u.func_arg(arg);
             }
             if(po->flags & OPT_EXIT)
                 exit(0);
@@ -289,6 +298,43 @@ unknown_opt:
     }
 }
 
+#define FLAGS (o->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
+#define SET_PREFIXED_OPTS(ch, flag, output) \
+    if (opt[0] == ch && avcodec_opts[0] && (o = av_opt_find(avcodec_opts[0], opt+1, NULL, flag, 0)))\
+        av_dict_set(&output, opt+1, arg, FLAGS);
+static int opt_default2(const char *opt, const char *arg)
+{
+    const AVOption *o;
+    if ((o = av_opt_find(avcodec_opts[0], opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) {
+        if (o->flags & AV_OPT_FLAG_VIDEO_PARAM)
+            av_dict_set(&video_opts, opt, arg, FLAGS);
+        if (o->flags & AV_OPT_FLAG_AUDIO_PARAM)
+            av_dict_set(&audio_opts, opt, arg, FLAGS);
+        if (o->flags & AV_OPT_FLAG_SUBTITLE_PARAM)
+            av_dict_set(&sub_opts, opt, arg, FLAGS);
+    } else if ((o = av_opt_find(avformat_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN)))
+        av_dict_set(&format_opts, opt, arg, FLAGS);
+    else if ((o = av_opt_find(sws_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) {
+        // XXX we only support sws_flags, not arbitrary sws options
+        int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
+        if (ret < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
+            return ret;
+        }
+    }
+
+    if (!o) {
+        SET_PREFIXED_OPTS('v', AV_OPT_FLAG_VIDEO_PARAM,    video_opts)
+        SET_PREFIXED_OPTS('a', AV_OPT_FLAG_AUDIO_PARAM,    audio_opts)
+        SET_PREFIXED_OPTS('s', AV_OPT_FLAG_SUBTITLE_PARAM, sub_opts)
+    }
+
+    if (o)
+        return 0;
+    fprintf(stderr, "Unrecognized option '%s'\n", opt);
+    return AVERROR_OPTION_NOT_FOUND;
+}
+
 int opt_default(const char *opt, const char *arg){
     int type;
     int ret= 0;
@@ -296,7 +342,7 @@ int opt_default(const char *opt, const char *arg){
     int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
 
     for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){
-        const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]);
+        const AVOption *o2 = av_opt_find(avcodec_opts[0], opt, NULL, opt_types[type], 0);
         if(o2)
             ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
     }
@@ -320,23 +366,22 @@ int opt_default(const char *opt, const char *arg){
         AVCodec *p = NULL;
         AVOutputFormat *oformat = NULL;
         while ((p=av_codec_next(p))){
-            AVClass *c= p->priv_class;
-            if(c && av_find_opt(&c, opt, NULL, 0, 0))
+            const AVClass *c = p->priv_class;
+            if(c && av_opt_find(&c, opt, NULL, 0, 0))
                 break;
         }
         if (!p) {
             while ((oformat = av_oformat_next(oformat))) {
                 const AVClass *c = oformat->priv_class;
-                if (c && av_find_opt(&c, opt, NULL, 0, 0))
+                if (c && av_opt_find(&c, opt, NULL, 0, 0))
                     break;
             }
         }
-        if(!p && !oformat){
-            fprintf(stderr, "Unrecognized option '%s'\n", opt);
-            exit(1);
-        }
     }
 
+    if ((ret = opt_default2(opt, arg)) < 0)
+        return ret;
+
 //    av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL));
 
     //FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this
@@ -569,16 +614,6 @@ void show_license(void)
     );
 }
 
-void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts)
-{
-    int i;
-    char fmt_str[128];
-    for (i=-1; i < nb_fmts; i++) {
-        get_fmt_string (fmt_str, sizeof(fmt_str), i);
-        fprintf(stdout, "%s\n", fmt_str);
-    }
-}
-
 void show_formats(void)
 {
     AVInputFormat *ifmt=NULL;
@@ -921,6 +956,8 @@ int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
     memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
     frame->interlaced_frame = picref->video->interlaced;
     frame->top_field_first  = picref->video->top_field_first;
+    frame->key_frame        = picref->video->key_frame;
+    frame->pict_type        = picref->video->pict_type;
 
     return 1;
 }