History

avfilter/avfiltergraph: add logging for filter formats

There is no convenient way, from the command line, to figure out which formats a filter actually supports. This commit changes that by adding a log output, at debug level, to simply print the list of formats each filter advertises on its links, before any negotiation. Furthermore, we can use the exact same helper function to also print out the corresponding filter links when there is an error during format negotiation. We need to use AV_BRINT_SIZE_UNLIMITED because the default format list for filters like vf_scale is about 1700 characters long, significantly larger than the the 1 kB default buffer.

Niklas Haas committed 1 year ago

Commit 03b91801 parent 1a61db91 file · +63 −1Browse files

Showing the changes to libavfilter (1 of 1 file). Show all

Unified · Split

libavfilter/avfiltergraph.c+63−1
@@ -440,6 +440,62 @@ static int formats_declared(AVFilterContext *f) · 439 unmodified lines
440440 return 1;
441441 }
442442
443+static void print_formats(void *log_ctx, int level, enum AVMediaType type,
444+ const AVFilterFormats *formats)
445+{
446+ AVBPrint bp;
447+ av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
448+
449+ switch (type) {
450+ case AVMEDIA_TYPE_VIDEO:
451+ for (unsigned i = 0; i < formats->nb_formats; i++)
452+ av_bprintf(&bp, "%s%s", bp.len ? " " : "", av_get_pix_fmt_name(formats->formats[i]));
453+ break;
454+ case AVMEDIA_TYPE_AUDIO:
455+ for (unsigned i = 0; i < formats->nb_formats; i++)
456+ av_bprintf(&bp, "%s%s", bp.len ? " " : "", av_get_sample_fmt_name(formats->formats[i]));
457+ break;
458+ default:
459+ av_bprintf(&bp, "(unknown)");
460+ break;
461+ }
462+
463+ if (av_bprint_is_complete(&bp)) {
464+ av_log(log_ctx, level, "%s\n", bp.str);
465+ } else {
466+ av_log(log_ctx, level, "(out of memory)\n");
467+ }
468+ av_bprint_finalize(&bp, NULL);
469+}
470+
471+static void print_link_formats(void *log_ctx, int level, const AVFilterLink *l)
472+{
473+ if (av_log_get_level() < level)
474+ return;
475+
476+ av_log(log_ctx, level, "Link '%s.%s' -> '%s.%s':\n"
477+ " src: ", l->src->name, l->srcpad->name, l->dst->name, l->dstpad->name);
478+ print_formats(log_ctx, level, l->type, l->incfg.formats);
479+ av_log(log_ctx, level, " dst: ");
480+ print_formats(log_ctx, level, l->type, l->outcfg.formats);
481+}
482+
483+static void print_filter_formats(void *log_ctx, int level, const AVFilterContext *f)
484+{
485+ if (av_log_get_level() < level)
486+ return;
487+
488+ av_log(log_ctx, level, "Filter '%s' formats:\n", f->name);
489+ for (int i = 0; i < f->nb_inputs; i++) {
490+ av_log(log_ctx, level, " in[%d] '%s': ", i, f->input_pads[i].name);
491+ print_formats(log_ctx, level, f->inputs[i]->type, f->inputs[i]->outcfg.formats);
492+ }
493+ for (int i = 0; i < f->nb_outputs; i++) {
494+ av_log(log_ctx, level, " out[%d] '%s': ", i, f->output_pads[i].name);
495+ print_formats(log_ctx, level, f->outputs[i]->type, f->outputs[i]->incfg.formats);
496+ }
497+}
498+
443499 /**
444500 * Perform one round of query_formats() and merging formats lists on the
445501 * filter graph.
@@ -467,7 +523,10 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx) · 21 unmodified lines
467523 if (ret < 0 && ret != AVERROR(EAGAIN))
468524 return ret;
469525 /* note: EAGAIN could indicate a partial success, not counted yet */
470− count_queried += ret >= 0;
526+ if (ret >= 0) {
527+ print_filter_formats(log_ctx, AV_LOG_DEBUG, f);
528+ count_queried++;
529+ }
471530 }
472531
473532 /* go through and merge as many format lists as possible */
@@ -524,6 +583,7 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx) · 50 unmodified lines
524583 "The filters '%s' and '%s' do not have a common format "
525584 "and automatic conversion is disabled.\n",
526585 link->src->name, link->dst->name);
586+ print_link_formats(log_ctx, AV_LOG_ERROR, link);
527587 return AVERROR(EINVAL);
528588 }
529589
@@ -532,6 +592,7 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx) · 2 unmodified lines
532592 av_log(log_ctx, AV_LOG_ERROR,
533593 "'%s' filter not present, cannot convert formats.\n",
534594 neg->conversion_filter);
595+ print_link_formats(log_ctx, AV_LOG_ERROR, link);
535596 return AVERROR(EINVAL);
536597 }
537598 snprintf(inst_name, sizeof(inst_name), "auto_%s_%d",
@@ -583,6 +644,7 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx) · 45 unmodified lines
583644 av_log(log_ctx, AV_LOG_ERROR,
584645 "Impossible to convert between the formats supported by the filter "
585646 "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
647+ print_link_formats(log_ctx, AV_LOG_ERROR, link);
586648 return AVERROR(ENOSYS);
587649 }
588650 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t