(po->name && !strcmp(optname, po->name)))
return i;
- if (po->flags & HAS_ARG)
+ if (!po->name || po->flags & HAS_ARG)
i++;
}
return 0;
report_file = fopen(filename.str, "w");
if (!report_file) {
+ int ret = AVERROR(errno);
av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
filename.str, strerror(errno));
- return AVERROR(errno);
+ return ret;
}
av_log_set_callback(log_callback_report);
av_log(NULL, AV_LOG_INFO,
int show_filters(void *optctx, const char *opt, const char *arg)
{
- const AVFilter av_unused(*filter) = NULL;
+#if CONFIG_AVFILTER
+ const AVFilter *filter = NULL;
char descr[64], *descr_cur;
int i, j;
const AVFilterPad *pad;
" V = Video input/output\n"
" N = Dynamic number and/or type of input/output\n"
" | = Source or sink filter\n");
-#if CONFIG_AVFILTER
while ((filter = avfilter_next(filter))) {
descr_cur = descr;
for (i = 0; i < 2; i++) {
filter->process_command ? 'C' : '.',
filter->name, descr, filter->description);
}
+#else
+ printf("No filters available: libavfilter disabled\n");
#endif
return 0;
}
FILE *f = av_fopen_utf8(filename, "rb");
if (!f) {
+ ret = AVERROR(errno);
av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename,
strerror(errno));
- return AVERROR(errno);
+ return ret;
}
fseek(f, 0, SEEK_END);
*size = ftell(f);
fseek(f, 0, SEEK_SET);
if (*size == (size_t)-1) {
+ ret = AVERROR(errno);
av_log(NULL, AV_LOG_ERROR, "IO error: %s\n", strerror(errno));
fclose(f);
- return AVERROR(errno);
+ return ret;
}
*bufptr = av_malloc(*size + 1);
if (!*bufptr) {
if (ret < *size) {
av_free(*bufptr);
if (ferror(f)) {
+ ret = AVERROR(errno);
av_log(NULL, AV_LOG_ERROR, "Error while reading file '%s': %s\n",
filename, strerror(errno));
- ret = AVERROR(errno);
} else
ret = AVERROR_EOF;
} else {
switch (check_stream_specifier(s, st, p + 1)) {
case 1: *p = 0; break;
case 0: continue;
- default: return NULL;
+ default: exit_program(1);
}
if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
}
return array;
}
+
+#if CONFIG_AVDEVICE
+static int print_device_sources(AVInputFormat *fmt, AVDictionary *opts)
+{
+ int ret, i;
+ AVFormatContext *dev = NULL;
+ AVDeviceInfoList *device_list = NULL;
+ AVDictionary *tmp_opts = NULL;
+
+ if (!fmt || !fmt->priv_class || !AV_IS_INPUT_DEVICE(fmt->priv_class->category))
+ return AVERROR(EINVAL);
+
+ printf("Audo-detected sources for %s:\n", fmt->name);
+ if (!fmt->get_device_list) {
+ ret = AVERROR(ENOSYS);
+ printf("Cannot list sources. Not implemented.\n");
+ goto fail;
+ }
+
+ /* TODO: avformat_open_input calls read_header callback which is not necessary.
+ Function like avformat_alloc_output_context2 for input could be helpful here. */
+ av_dict_copy(&tmp_opts, opts, 0);
+ if ((ret = avformat_open_input(&dev, NULL, fmt, &tmp_opts)) < 0) {
+ printf("Cannot open device: %s.\n", fmt->name);
+ goto fail;
+ }
+
+ if ((ret = avdevice_list_devices(dev, &device_list)) < 0) {
+ printf("Cannot list sources.\n");
+ goto fail;
+ }
+
+ for (i = 0; i < device_list->nb_devices; i++) {
+ printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ",
+ device_list->devices[i]->device_name, device_list->devices[i]->device_description);
+ }
+
+ fail:
+ av_dict_free(&tmp_opts);
+ avdevice_free_list_devices(&device_list);
+ avformat_close_input(&dev);
+ return ret;
+}
+
+static int print_device_sinks(AVOutputFormat *fmt, AVDictionary *opts)
+{
+ int ret, i;
+ AVFormatContext *dev = NULL;
+ AVDeviceInfoList *device_list = NULL;
+ AVDictionary *tmp_opts = NULL;
+
+ if (!fmt || !fmt->priv_class || !AV_IS_OUTPUT_DEVICE(fmt->priv_class->category))
+ return AVERROR(EINVAL);
+
+ printf("Audo-detected sinks for %s:\n", fmt->name);
+ if (!fmt->get_device_list) {
+ ret = AVERROR(ENOSYS);
+ printf("Cannot list sinks. Not implemented.\n");
+ goto fail;
+ }
+
+ if ((ret = avformat_alloc_output_context2(&dev, fmt, NULL, NULL)) < 0) {
+ printf("Cannot open device: %s.\n", fmt->name);
+ goto fail;
+ }
+ av_dict_copy(&tmp_opts, opts, 0);
+ av_opt_set_dict2(dev, &tmp_opts, AV_OPT_SEARCH_CHILDREN);
+
+ if ((ret = avdevice_list_devices(dev, &device_list)) < 0) {
+ printf("Cannot list sinks.\n");
+ goto fail;
+ }
+
+ for (i = 0; i < device_list->nb_devices; i++) {
+ printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ",
+ device_list->devices[i]->device_name, device_list->devices[i]->device_description);
+ }
+
+ fail:
+ av_dict_free(&tmp_opts);
+ avdevice_free_list_devices(&device_list);
+ avformat_free_context(dev);
+ return ret;
+}
+
+static int show_sinks_sources_parse_arg(const char *arg, char **dev, AVDictionary **opts)
+{
+ int ret;
+ if (arg) {
+ char *opts_str = NULL;
+ av_assert0(dev && opts);
+ *dev = av_strdup(arg);
+ if (!*dev)
+ return AVERROR(ENOMEM);
+ if ((opts_str = strchr(*dev, ','))) {
+ *(opts_str++) = '\0';
+ if (opts_str[0] && ((ret = av_dict_parse_string(opts, opts_str, "=", ":", 0)) < 0)) {
+ av_freep(dev);
+ return ret;
+ }
+ }
+ } else
+ printf("\nDevice name is not provided.\n"
+ "You can pass devicename[,opt1=val1[,opt2=val2...]] as an argument.\n\n");
+ return 0;
+}
+
+int show_sources(void *optctx, const char *opt, const char *arg)
+{
+ AVInputFormat *fmt = NULL;
+ char *dev = NULL;
+ AVDictionary *opts = NULL;
+ int ret = 0;
+ int error_level = av_log_get_level();
+
+ av_log_set_level(AV_LOG_ERROR);
+
+ if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
+ goto fail;
+
+ do {
+ fmt = av_input_audio_device_next(fmt);
+ if (fmt) {
+ if (!strcmp(fmt->name, "lavfi"))
+ continue; //it's pointless to probe lavfi
+ if (dev && strcmp(fmt->name, dev))
+ continue;
+ print_device_sources(fmt, opts);
+ }
+ } while (fmt);
+ do {
+ fmt = av_input_video_device_next(fmt);
+ if (fmt) {
+ if (dev && strcmp(fmt->name, dev))
+ continue;
+ print_device_sources(fmt, opts);
+ }
+ } while (fmt);
+ fail:
+ av_dict_free(&opts);
+ av_free(dev);
+ av_log_set_level(error_level);
+ return ret;
+}
+
+int show_sinks(void *optctx, const char *opt, const char *arg)
+{
+ AVOutputFormat *fmt = NULL;
+ char *dev = NULL;
+ AVDictionary *opts = NULL;
+ int ret = 0;
+ int error_level = av_log_get_level();
+
+ av_log_set_level(AV_LOG_ERROR);
+
+ if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
+ goto fail;
+
+ do {
+ fmt = av_output_audio_device_next(fmt);
+ if (fmt) {
+ if (dev && strcmp(fmt->name, dev))
+ continue;
+ print_device_sinks(fmt, opts);
+ }
+ } while (fmt);
+ do {
+ fmt = av_output_video_device_next(fmt);
+ if (fmt) {
+ if (dev && strcmp(fmt->name, dev))
+ continue;
+ print_device_sinks(fmt, opts);
+ }
+ } while (fmt);
+ fail:
+ av_dict_free(&opts);
+ av_free(dev);
+ av_log_set_level(error_level);
+ return ret;
+}
+#endif