]> git.sesse.net Git - ffmpeg/blobdiff - avconv_opt.c
qsvdec: make ff_qsv_decode_init() static
[ffmpeg] / avconv_opt.c
index 7adf05197848be41019a0c4b7bd01898badadb46..3b841356ccc3dc8e0392a51bca1c2b3ae4f1d1b6 100644 (file)
@@ -41,6 +41,8 @@
 #include "libavutil/pixdesc.h"
 #include "libavutil/pixfmt.h"
 
+#define DEFAULT_PASS_LOGFILENAME_PREFIX "av2pass"
+
 #define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
 {\
     int i, ret;\
@@ -175,6 +177,18 @@ static double parse_frame_aspect_ratio(const char *arg)
     return ar;
 }
 
+static int show_hwaccels(void *optctx, const char *opt, const char *arg)
+{
+    int i;
+
+    printf("Supported hardware acceleration:\n");
+    for (i = 0; i < FF_ARRAY_ELEMS(hwaccels) - 1; i++) {
+        printf("%s\n", hwaccels[i].name);
+    }
+    printf("\n");
+    return 0;
+}
+
 static int opt_audio_codec(void *optctx, const char *opt, const char *arg)
 {
     OptionsContext *o = optctx;
@@ -982,12 +996,12 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
 
     MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
     if (qscale >= 0) {
-        ost->enc_ctx->flags |= CODEC_FLAG_QSCALE;
+        ost->enc_ctx->flags |= AV_CODEC_FLAG_QSCALE;
         ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale;
     }
 
     if (oc->oformat->flags & AVFMT_GLOBALHEADER)
-        ost->enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
+        ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
 
     av_opt_get_int(o->g->sws_opts, "sws_flags", 0, &ost->sws_flags);
 
@@ -1163,9 +1177,9 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
         MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
         if (do_pass) {
             if (do_pass == 1) {
-                video_enc->flags |= CODEC_FLAG_PASS1;
+                video_enc->flags |= AV_CODEC_FLAG_PASS1;
             } else {
-                video_enc->flags |= CODEC_FLAG_PASS2;
+                video_enc->flags |= AV_CODEC_FLAG_PASS2;
             }
         }
 
@@ -1174,6 +1188,38 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
             !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
             exit_program(1);
 
+        if (do_pass) {
+            char logfilename[1024];
+            FILE *f;
+
+            snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
+                     ost->logfile_prefix ? ost->logfile_prefix :
+                                           DEFAULT_PASS_LOGFILENAME_PREFIX,
+                     i);
+            if (!strcmp(ost->enc->name, "libx264")) {
+                av_dict_set(&ost->encoder_opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
+            } else {
+                if (video_enc->flags & AV_CODEC_FLAG_PASS1) {
+                    f = fopen(logfilename, "wb");
+                    if (!f) {
+                        av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n",
+                               logfilename, strerror(errno));
+                        exit_program(1);
+                    }
+                    ost->logfile = f;
+                } else {
+                    char  *logbuffer = read_file(logfilename);
+
+                    if (!logbuffer) {
+                        av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
+                               logfilename);
+                        exit_program(1);
+                    }
+                    video_enc->stats_in = logbuffer;
+                }
+            }
+        }
+
         MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
         if (ost->forced_keyframes)
             ost->forced_keyframes = av_strdup(ost->forced_keyframes);
@@ -1333,8 +1379,7 @@ static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
 {
     OutputStream *ost;
 
-    switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
-                                  ofilter->out_tmp->pad_idx)) {
+    switch (ofilter->type) {
     case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
     case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
     default:
@@ -1355,13 +1400,21 @@ static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
         exit_program(1);
     }
 
-    if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
-        av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
-        exit_program(1);
-    }
     avfilter_inout_free(&ofilter->out_tmp);
 }
 
+static int init_complex_filters(void)
+{
+    int i, ret = 0;
+
+    for (i = 0; i < nb_filtergraphs; i++) {
+        ret = init_complex_filtergraph(filtergraphs[i]);
+        if (ret < 0)
+            return ret;
+    }
+    return 0;
+}
+
 static int configure_complex_filters(void)
 {
     int i, ret = 0;
@@ -1384,11 +1437,6 @@ static int open_output_file(OptionsContext *o, const char *filename)
     AVDictionary *unused_opts = NULL;
     AVDictionaryEntry *e = NULL;
 
-    if (configure_complex_filters() < 0) {
-        av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n");
-        exit_program(1);
-    }
-
     GROW_ARRAY(output_files, nb_output_files);
     of = av_mallocz(sizeof(*of));
     if (!of)
@@ -1442,8 +1490,7 @@ static int open_output_file(OptionsContext *o, const char *filename)
             if (!ofilter->out_tmp || ofilter->out_tmp->name)
                 continue;
 
-            switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
-                                          ofilter->out_tmp->pad_idx)) {
+            switch (ofilter->type) {
             case AVMEDIA_TYPE_VIDEO:    o->video_disable    = 1; break;
             case AVMEDIA_TYPE_AUDIO:    o->audio_disable    = 1; break;
             case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
@@ -1588,6 +1635,12 @@ loop_end:
         avio_close(pb);
     }
 
+    if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
+        av_dump_format(oc, nb_output_files - 1, oc->filename, 1);
+        av_log(NULL, AV_LOG_ERROR, "Output file #%d does not contain any stream\n", nb_output_files - 1);
+        exit_program(1);
+    }
+
     /* check if all codec options have been used */
     unused_opts = strip_specifiers(o->g->codec_opts);
     for (i = of->ost_index; i < nb_output_streams; i++) {
@@ -2047,6 +2100,63 @@ static int opt_filter_complex_script(void *optctx, const char *opt, const char *
     return 0;
 }
 
+/* Search a class from a codec, format, or filter, named 'opt', in order
+ * to extract its private options. If the class type is specified, only
+ * the associated options are printed, otherwise all the ones matching
+ * the input name are shown. */
+static int show_help_specific(const char *opt)
+{
+    AVCodec *codec = NULL;
+    AVFilter *filter = NULL;
+    AVInputFormat *iformat = NULL;
+    AVOutputFormat *oformat = NULL;
+    int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM |
+                AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM;
+
+    char *kind = av_get_token(&opt, ":");
+    if (!kind)
+        return 0;
+    if (*opt)
+        opt = &opt[1]; // skip ':'
+
+    show_usage();
+
+    if (!strcmp(kind, "decoder") &&
+        (codec = avcodec_find_decoder_by_name(opt)) && codec->priv_class)
+        show_help_children(codec->priv_class, flags);
+    else if (!strcmp(kind, "encoder") &&
+             (codec = avcodec_find_encoder_by_name(opt)) && codec->priv_class)
+        show_help_children(codec->priv_class, flags);
+    else if (!strcmp(kind, "demuxer") &&
+             (iformat = av_find_input_format(opt)) && iformat->priv_class)
+        show_help_children(iformat->priv_class, flags);
+    else if (!strcmp(kind, "muxer") &&
+             (oformat = av_guess_format(opt, NULL, NULL)) && oformat->priv_class)
+        show_help_children(oformat->priv_class, flags);
+    else if (!strcmp(kind, "filter") &&
+             (filter = avfilter_get_by_name(opt)) && filter->priv_class)
+        show_help_children(filter->priv_class, flags);
+    else if (!opt)
+        av_log(NULL, AV_LOG_ERROR,
+               "Unknown class '%s', only 'decoder', 'encoder', 'demuxer', "
+               "'muxer', or 'filter' are valid specifiers.\n", kind);
+    else {
+        if ((codec = avcodec_find_decoder_by_name(kind)) && codec->priv_class)
+            show_help_children(codec->priv_class, flags);
+        if ((codec = avcodec_find_encoder_by_name(kind)) && codec->priv_class)
+            show_help_children(codec->priv_class, flags);
+        if ((iformat = av_find_input_format(kind)) && iformat->priv_class)
+            show_help_children(iformat->priv_class, flags);
+        if ((oformat = av_guess_format(kind, NULL, NULL)) && oformat->priv_class)
+            show_help_children(oformat->priv_class, flags);
+        if ((filter = avfilter_get_by_name(kind)) && filter->priv_class)
+            show_help_children(filter->priv_class, flags);
+    }
+    av_freep(&kind);
+
+    return codec || iformat || oformat || filter;
+}
+
 void show_help_default(const char *opt, const char *arg)
 {
     /* per-file options have at least one of those set */
@@ -2058,6 +2168,8 @@ void show_help_default(const char *opt, const char *arg)
             show_advanced = 1;
         else if (!strcmp(opt, "full"))
             show_advanced = show_avoptions = 1;
+        else if (show_help_specific(opt))
+            return;
         else
             av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);
     }
@@ -2068,6 +2180,7 @@ void show_help_default(const char *opt, const char *arg)
            "    -h      -- print basic options\n"
            "    -h long -- print more options\n"
            "    -h full -- print all options (including all format and codec specific options, very long)\n"
+           "    -h [type:]name -- print private options from a codec, format or filter named 'name' (set 'type' to print options from a single class)\n"
            "    See man %s for detailed description of the options.\n"
            "\n", program_name);
 
@@ -2192,6 +2305,13 @@ int avconv_parse_options(int argc, char **argv)
         goto fail;
     }
 
+    /* create the complex filtergraphs */
+    ret = init_complex_filters();
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_FATAL, "Error initializing complex filters.\n");
+        goto fail;
+    }
+
     /* open output files */
     ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);
     if (ret < 0) {
@@ -2199,6 +2319,13 @@ int avconv_parse_options(int argc, char **argv)
         goto fail;
     }
 
+    /* configure the complex filtergraphs */
+    ret = configure_complex_filters();
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_FATAL, "Error configuring complex filters.\n");
+        goto fail;
+    }
+
 fail:
     uninit_parse_context(&octx);
     if (ret < 0) {
@@ -2390,7 +2517,9 @@ const OptionDef options[] = {
         "use HW accelerated decoding", "hwaccel name" },
     { "hwaccel_device",   OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
                           OPT_SPEC | OPT_INPUT,                                  { .off = OFFSET(hwaccel_devices) },
-        "select a device for HW acceleration" "devicename" },
+        "select a device for HW acceleration", "devicename" },
+    { "hwaccels",         OPT_EXIT,                                              { .func_arg = show_hwaccels },
+        "show available HW acceleration methods" },
     { "autorotate",       HAS_ARG | OPT_BOOL | OPT_SPEC |
                           OPT_EXPERT | OPT_INPUT,                                { .off = OFFSET(autorotate) },
         "automatically insert correct rotate filters" },