]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/formats.c
avfilter/formats: Remove avfilter_make_format64_list()
[ffmpeg] / libavfilter / formats.c
index 8918118b8e9344de5c3b10f2556c7a17766591a6..6c05b118c9c5b4cc20229c3330d072f6e3b4a1f2 100644 (file)
@@ -24,7 +24,6 @@
 #include "libavutil/common.h"
 #include "libavutil/eval.h"
 #include "libavutil/pixdesc.h"
-#include "libavutil/parseutils.h"
 #include "avfilter.h"
 #include "internal.h"
 #include "formats.h"
@@ -305,17 +304,9 @@ AVFilterChannelLayouts *ff_make_format64_list(const int64_t *fmts)
     return formats;
 }
 
-#if LIBAVFILTER_VERSION_MAJOR < 8
-AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts)
-{
-    return ff_make_format64_list(fmts);
-}
-#endif
-
 #define ADD_FORMAT(f, fmt, unref_fn, type, list, nb)        \
 do {                                                        \
     type *fmts;                                             \
-    void *oldf = *f;                                        \
                                                             \
     if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) {         \
         return AVERROR(ENOMEM);                             \
@@ -325,8 +316,6 @@ do {                                                        \
                             sizeof(*(*f)->list));           \
     if (!fmts) {                                            \
         unref_fn(f);                                        \
-        if (!oldf)                                          \
-            av_freep(f);                                    \
         return AVERROR(ENOMEM);                             \
     }                                                       \
                                                             \
@@ -450,7 +439,7 @@ AVFilterChannelLayouts *ff_all_channel_counts(void)
 #define FORMATS_REF(f, ref, unref_fn)                                           \
     void *tmp;                                                                  \
                                                                                 \
-    if (!f || !ref)                                                             \
+    if (!f)                                                                     \
         return AVERROR(ENOMEM);                                                 \
                                                                                 \
     tmp = av_realloc_array(f->refs, sizeof(*f->refs), f->refcount + 1);         \
@@ -487,16 +476,17 @@ do {                                        \
 do {                                                               \
     int idx = -1;                                                  \
                                                                    \
-    if (!ref || !*ref || !(*ref)->refs)                            \
+    if (!*ref)                                                     \
         return;                                                    \
                                                                    \
     FIND_REF_INDEX(ref, idx);                                      \
                                                                    \
-    if (idx >= 0)                                                  \
+    if (idx >= 0) {                                                \
         memmove((*ref)->refs + idx, (*ref)->refs + idx + 1,        \
             sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
-                                                                   \
-    if(!--(*ref)->refcount) {                                      \
+        --(*ref)->refcount;                                        \
+    }                                                              \
+    if (!(*ref)->refcount) {                                       \
         av_free((*ref)->list);                                     \
         av_free((*ref)->refs);                                     \
         av_free(*ref);                                             \
@@ -538,33 +528,25 @@ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
     FORMATS_CHANGEREF(oldref, newref);
 }
 
-#define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref_fn, unref_fn, list) \
+#define SET_COMMON_FORMATS(ctx, fmts, ref_fn, unref_fn)             \
     int count = 0, i;                                               \
                                                                     \
     if (!fmts)                                                      \
         return AVERROR(ENOMEM);                                     \
                                                                     \
     for (i = 0; i < ctx->nb_inputs; i++) {                          \
-        if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) {          \
-            int ret = ref_fn(fmts, &ctx->inputs[i]->out_fmts);      \
+        if (ctx->inputs[i] && !ctx->inputs[i]->outcfg.fmts) {       \
+            int ret = ref_fn(fmts, &ctx->inputs[i]->outcfg.fmts);   \
             if (ret < 0) {                                          \
-                unref_fn(&fmts);                                    \
-                if (fmts)                                           \
-                    av_freep(&fmts->list);                          \
-                av_freep(&fmts);                                    \
                 return ret;                                         \
             }                                                       \
             count++;                                                \
         }                                                           \
     }                                                               \
     for (i = 0; i < ctx->nb_outputs; i++) {                         \
-        if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) {         \
-            int ret = ref_fn(fmts, &ctx->outputs[i]->in_fmts);      \
+        if (ctx->outputs[i] && !ctx->outputs[i]->incfg.fmts) {      \
+            int ret = ref_fn(fmts, &ctx->outputs[i]->incfg.fmts);   \
             if (ret < 0) {                                          \
-                unref_fn(&fmts);                                    \
-                if (fmts)                                           \
-                    av_freep(&fmts->list);                          \
-                av_freep(&fmts);                                    \
                 return ret;                                         \
             }                                                       \
             count++;                                                \
@@ -572,25 +554,23 @@ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
     }                                                               \
                                                                     \
     if (!count) {                                                   \
-        av_freep(&fmts->list);                                      \
-        av_freep(&fmts->refs);                                      \
-        av_freep(&fmts);                                            \
+        unref_fn(&fmts);                                            \
     }                                                               \
                                                                     \
     return 0;
 
 int ff_set_common_channel_layouts(AVFilterContext *ctx,
-                                  AVFilterChannelLayouts *layouts)
+                                  AVFilterChannelLayouts *channel_layouts)
 {
-    SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
-                       ff_channel_layouts_ref, ff_channel_layouts_unref, channel_layouts);
+    SET_COMMON_FORMATS(ctx, channel_layouts,
+                       ff_channel_layouts_ref, ff_channel_layouts_unref);
 }
 
 int ff_set_common_samplerates(AVFilterContext *ctx,
                               AVFilterFormats *samplerates)
 {
-    SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
-                       ff_formats_ref, ff_formats_unref, formats);
+    SET_COMMON_FORMATS(ctx, samplerates,
+                       ff_formats_ref, ff_formats_unref);
 }
 
 /**
@@ -600,23 +580,22 @@ int ff_set_common_samplerates(AVFilterContext *ctx,
  */
 int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
 {
-    SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
-                       ff_formats_ref, ff_formats_unref, formats);
+    SET_COMMON_FORMATS(ctx, formats,
+                       ff_formats_ref, ff_formats_unref);
 }
 
-static int default_query_formats_common(AVFilterContext *ctx,
-                                        AVFilterChannelLayouts *(layouts)(void))
+int ff_default_query_formats(AVFilterContext *ctx)
 {
     int ret;
-    enum AVMediaType type = ctx->inputs  && ctx->inputs [0] ? ctx->inputs [0]->type :
-                            ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
+    enum AVMediaType type = ctx->nb_inputs  ? ctx->inputs [0]->type :
+                            ctx->nb_outputs ? ctx->outputs[0]->type :
                             AVMEDIA_TYPE_VIDEO;
 
     ret = ff_set_common_formats(ctx, ff_all_formats(type));
     if (ret < 0)
         return ret;
     if (type == AVMEDIA_TYPE_AUDIO) {
-        ret = ff_set_common_channel_layouts(ctx, layouts());
+        ret = ff_set_common_channel_layouts(ctx, ff_all_channel_counts());
         if (ret < 0)
             return ret;
         ret = ff_set_common_samplerates(ctx, ff_all_samplerates());
@@ -627,16 +606,6 @@ static int default_query_formats_common(AVFilterContext *ctx,
     return 0;
 }
 
-int ff_default_query_formats(AVFilterContext *ctx)
-{
-    return default_query_formats_common(ctx, ff_all_channel_counts);
-}
-
-int ff_query_formats_all_layouts(AVFilterContext *ctx)
-{
-    return default_query_formats_common(ctx, ff_all_channel_layouts);
-}
-
 /* internal functions for parsing audio format arguments */
 
 int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
@@ -654,32 +623,6 @@ int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ct
     return 0;
 }
 
-int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
-{
-    char *tail;
-    int sfmt = av_get_sample_fmt(arg);
-    if (sfmt == AV_SAMPLE_FMT_NONE) {
-        sfmt = strtol(arg, &tail, 0);
-        if (*tail || av_get_bytes_per_sample(sfmt)<=0) {
-            av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
-            return AVERROR(EINVAL);
-        }
-    }
-    *ret = sfmt;
-    return 0;
-}
-
-int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx)
-{
-    AVRational r;
-    if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0  ||r.den<=0) {
-        av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg);
-        return AVERROR(EINVAL);
-    }
-    *ret = r;
-    return 0;
-}
-
 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
 {
     char *tail;
@@ -712,3 +655,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;
+}