summaryrefslogtreecommitdiff
path: root/libavfilter/formats.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavfilter/formats.c')
-rw-r--r--libavfilter/formats.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index 695d28ea8e..95361170c5 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -662,3 +662,73 @@ int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
return 0;
}
+
+static int check_list(void *log, const char *name, const AVFilterFormats *fmts)
+{
+ unsigned i, j;
+
+ if (!fmts)
+ return 0;
+ if (!fmts->nb_formats) {
+ av_log(log, AV_LOG_ERROR, "Empty %s list\n", name);
+ return AVERROR(EINVAL);
+ }
+ for (i = 0; i < fmts->nb_formats; i++) {
+ for (j = i + 1; j < fmts->nb_formats; j++) {
+ if (fmts->formats[i] == fmts->formats[j]) {
+ av_log(log, AV_LOG_ERROR, "Duplicated %s\n", name);
+ return AVERROR(EINVAL);
+ }
+ }
+ }
+ return 0;
+}
+
+int ff_formats_check_pixel_formats(void *log, const AVFilterFormats *fmts)
+{
+ return check_list(log, "pixel format", fmts);
+}
+
+int ff_formats_check_sample_formats(void *log, const AVFilterFormats *fmts)
+{
+ return check_list(log, "sample format", fmts);
+}
+
+int ff_formats_check_sample_rates(void *log, const AVFilterFormats *fmts)
+{
+ if (!fmts || !fmts->nb_formats)
+ return 0;
+ return check_list(log, "sample rate", fmts);
+}
+
+static int layouts_compatible(uint64_t a, uint64_t b)
+{
+ return a == b ||
+ (KNOWN(a) && !KNOWN(b) && av_get_channel_layout_nb_channels(a) == FF_LAYOUT2COUNT(b)) ||
+ (KNOWN(b) && !KNOWN(a) && av_get_channel_layout_nb_channels(b) == FF_LAYOUT2COUNT(a));
+}
+
+int ff_formats_check_channel_layouts(void *log, const AVFilterChannelLayouts *fmts)
+{
+ unsigned i, j;
+
+ if (!fmts)
+ return 0;
+ if (fmts->all_layouts < fmts->all_counts) {
+ av_log(log, AV_LOG_ERROR, "Inconsistent generic list\n");
+ return AVERROR(EINVAL);
+ }
+ if (!fmts->all_layouts && !fmts->nb_channel_layouts) {
+ av_log(log, AV_LOG_ERROR, "Empty channel layout list\n");
+ return AVERROR(EINVAL);
+ }
+ for (i = 0; i < fmts->nb_channel_layouts; i++) {
+ for (j = i + 1; j < fmts->nb_channel_layouts; j++) {
+ if (layouts_compatible(fmts->channel_layouts[i], fmts->channel_layouts[j])) {
+ av_log(log, AV_LOG_ERROR, "Duplicated or redundant channel layout\n");
+ return AVERROR(EINVAL);
+ }
+ }
+ }
+ return 0;
+}