+ return 0;
+}
+
+int show_sample_fmts(void *optctx, const char *opt, const char *arg)
+{
+ int i;
+ char fmt_str[128];
+ for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
+ printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
+ return 0;
+}
+
+static void show_help_codec(const char *name, int encoder)
+{
+ const AVCodecDescriptor *desc;
+ const AVCodec *codec;
+
+ if (!name) {
+ av_log(NULL, AV_LOG_ERROR, "No codec name specified.\n");
+ return;
+ }
+
+ codec = encoder ? avcodec_find_encoder_by_name(name) :
+ avcodec_find_decoder_by_name(name);
+
+ if (codec)
+ print_codec(codec);
+ else if ((desc = avcodec_descriptor_get_by_name(name))) {
+ int printed = 0;
+
+ while ((codec = next_codec_for_id(desc->id, codec, encoder))) {
+ printed = 1;
+ print_codec(codec);
+ }
+
+ if (!printed) {
+ av_log(NULL, AV_LOG_ERROR, "Codec '%s' is known to Libav, "
+ "but no %s for it are available. Libav might need to be "
+ "recompiled with additional external libraries.\n",
+ name, encoder ? "encoders" : "decoders");
+ }
+ } else {
+ av_log(NULL, AV_LOG_ERROR, "Codec '%s' is not recognized by Libav.\n",
+ name);
+ }
+}
+
+static void show_help_demuxer(const char *name)
+{
+ const AVInputFormat *fmt = av_find_input_format(name);
+
+ if (!fmt) {
+ av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
+ return;
+ }
+
+ printf("Demuxer %s [%s]:\n", fmt->name, fmt->long_name);
+
+ if (fmt->extensions)
+ printf(" Common extensions: %s.\n", fmt->extensions);
+
+ if (fmt->priv_class)
+ show_help_children(fmt->priv_class, AV_OPT_FLAG_DECODING_PARAM);
+}
+
+static void show_help_muxer(const char *name)
+{
+ const AVCodecDescriptor *desc;
+ const AVOutputFormat *fmt = av_guess_format(name, NULL, NULL);
+
+ if (!fmt) {
+ av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
+ return;
+ }
+
+ printf("Muxer %s [%s]:\n", fmt->name, fmt->long_name);
+
+ if (fmt->extensions)
+ printf(" Common extensions: %s.\n", fmt->extensions);
+ if (fmt->mime_type)
+ printf(" Mime type: %s.\n", fmt->mime_type);
+ if (fmt->video_codec != AV_CODEC_ID_NONE &&
+ (desc = avcodec_descriptor_get(fmt->video_codec))) {
+ printf(" Default video codec: %s.\n", desc->name);
+ }
+ if (fmt->audio_codec != AV_CODEC_ID_NONE &&
+ (desc = avcodec_descriptor_get(fmt->audio_codec))) {
+ printf(" Default audio codec: %s.\n", desc->name);
+ }
+ if (fmt->subtitle_codec != AV_CODEC_ID_NONE &&
+ (desc = avcodec_descriptor_get(fmt->subtitle_codec))) {
+ printf(" Default subtitle codec: %s.\n", desc->name);
+ }
+
+ if (fmt->priv_class)
+ show_help_children(fmt->priv_class, AV_OPT_FLAG_ENCODING_PARAM);
+}
+
+#if CONFIG_AVFILTER
+static void show_help_filter(const char *name)
+{
+ const AVFilter *f = avfilter_get_by_name(name);
+ int i, count;
+
+ if (!name) {
+ av_log(NULL, AV_LOG_ERROR, "No filter name specified.\n");
+ return;
+ } else if (!f) {
+ av_log(NULL, AV_LOG_ERROR, "Unknown filter '%s'.\n", name);
+ return;
+ }
+
+ printf("Filter %s [%s]:\n", f->name, f->description);
+
+ if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
+ printf(" slice threading supported\n");
+
+ printf(" Inputs:\n");
+ count = avfilter_pad_count(f->inputs);
+ for (i = 0; i < count; i++) {
+ printf(" %d %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
+ media_type_string(avfilter_pad_get_type(f->inputs, i)));
+ }
+ if (f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)
+ printf(" dynamic (depending on the options)\n");
+
+ printf(" Outputs:\n");
+ count = avfilter_pad_count(f->outputs);
+ for (i = 0; i < count; i++) {
+ printf(" %d %s (%s)\n", i, avfilter_pad_get_name(f->outputs, i),
+ media_type_string(avfilter_pad_get_type(f->outputs, i)));
+ }
+ if (f->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS)
+ printf(" dynamic (depending on the options)\n");
+
+ if (f->priv_class)
+ show_help_children(f->priv_class, AV_OPT_FLAG_VIDEO_PARAM |
+ AV_OPT_FLAG_AUDIO_PARAM);
+}
+#endif
+
+int show_help(void *optctx, const char *opt, const char *arg)
+{
+ char *topic, *par;
+ av_log_set_callback(log_callback_help);
+
+ topic = av_strdup(arg ? arg : "");
+ par = strchr(topic, '=');
+ if (par)
+ *par++ = 0;
+
+ if (!*topic) {
+ show_help_default(topic, par);
+ } else if (!strcmp(topic, "decoder")) {
+ show_help_codec(par, 0);
+ } else if (!strcmp(topic, "encoder")) {
+ show_help_codec(par, 1);
+ } else if (!strcmp(topic, "demuxer")) {
+ show_help_demuxer(par);
+ } else if (!strcmp(topic, "muxer")) {
+ show_help_muxer(par);
+#if CONFIG_AVFILTER
+ } else if (!strcmp(topic, "filter")) {
+ show_help_filter(par);
+#endif
+ } else {
+ show_help_default(topic, par);
+ }
+
+ av_freep(&topic);
+ return 0;