diff --git a/libavfilter/vf_shuffleplanes.c b/libavfilter/vf_shuffleplanes.c index 2ac4d7d0ee..6c718893ce 100644 --- a/libavfilter/vf_shuffleplanes.c +++ b/libavfilter/vf_shuffleplanes.c @@ -40,41 +40,50 @@ typedef struct ShufflePlanesContext { int copy; } ShufflePlanesContext; +static int query_formats(AVFilterContext *ctx) +{ + AVFilterFormats *formats = NULL; + ShufflePlanesContext *s = ctx->priv; + int fmt, ret, i; + + for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); + int planes = av_pix_fmt_count_planes(fmt); + + if (!(desc->flags & AV_PIX_FMT_FLAG_PAL) && + !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { + for (i = 0; i < 4; i++) { + if (s->map[i] >= planes) + break; + + if ((desc->log2_chroma_h || desc->log2_chroma_w) && + (i == 1 || i == 2) != (s->map[i] == 1 || s->map[i] == 2)) + break; + } + + if (i != 4) + continue; + if ((ret = ff_add_format(&formats, fmt)) < 0) { + ff_formats_unref(&formats); + return ret; + } + } + } + + return ff_set_common_formats(ctx, formats); +} + static av_cold int shuffleplanes_config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; ShufflePlanesContext *s = ctx->priv; - const AVPixFmtDescriptor *desc; int used[4] = { 0 }; int i; s->copy = 0; s->planes = av_pix_fmt_count_planes(inlink->format); - desc = av_pix_fmt_desc_get(inlink->format); for (i = 0; i < s->planes; i++) { - if (s->map[i] >= s->planes) { - av_log(ctx, AV_LOG_ERROR, - "Non-existing input plane #%d mapped to output plane #%d.\n", - s->map[i], i); - return AVERROR(EINVAL); - } - - if ((desc->log2_chroma_h || desc->log2_chroma_w) && - (i == 1 || i == 2) != (s->map[i] == 1 || s->map[i] == 2)) { - av_log(ctx, AV_LOG_ERROR, - "Cannot map between a subsampled chroma plane and a luma " - "or alpha plane.\n"); - return AVERROR(EINVAL); - } - - if ((desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & FF_PSEUDOPAL) && - (i == 1) != (s->map[i] == 1)) { - av_log(ctx, AV_LOG_ERROR, - "Cannot map between a palette plane and a data plane.\n"); - return AVERROR(EINVAL); - } if (used[s->map[i]]) s->copy = 1; used[s->map[i]]++; @@ -127,10 +136,10 @@ fail: #define OFFSET(x) offsetof(ShufflePlanesContext, x) #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM) static const AVOption shuffleplanes_options[] = { - { "map0", "Index of the input plane to be used as the first output plane ", OFFSET(map[0]), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 4, FLAGS }, - { "map1", "Index of the input plane to be used as the second output plane ", OFFSET(map[1]), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 4, FLAGS }, - { "map2", "Index of the input plane to be used as the third output plane ", OFFSET(map[2]), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, 4, FLAGS }, - { "map3", "Index of the input plane to be used as the fourth output plane ", OFFSET(map[3]), AV_OPT_TYPE_INT, { .i64 = 3 }, 0, 4, FLAGS }, + { "map0", "Index of the input plane to be used as the first output plane ", OFFSET(map[0]), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 3, FLAGS }, + { "map1", "Index of the input plane to be used as the second output plane ", OFFSET(map[1]), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 3, FLAGS }, + { "map2", "Index of the input plane to be used as the third output plane ", OFFSET(map[2]), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, 3, FLAGS }, + { "map3", "Index of the input plane to be used as the fourth output plane ", OFFSET(map[3]), AV_OPT_TYPE_INT, { .i64 = 3 }, 0, 3, FLAGS }, { NULL }, }; @@ -159,6 +168,7 @@ AVFilter ff_vf_shuffleplanes = { .description = NULL_IF_CONFIG_SMALL("Shuffle video planes."), .priv_size = sizeof(ShufflePlanesContext), .priv_class = &shuffleplanes_class, + .query_formats = query_formats, .inputs = shuffleplanes_inputs, .outputs = shuffleplanes_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index 0c6ee72432..72d95ae415 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -360,7 +360,7 @@ FATE_SHUFFLEPLANES += fate-filter-shuffleplanes-dup-luma fate-filter-shuffleplanes-dup-luma: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf format=yuva444p,shuffleplanes=0:0:0:0 FATE_SHUFFLEPLANES += fate-filter-shuffleplanes-swapuv -fate-filter-shuffleplanes-swapuv: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf shuffleplanes=0:2:1 +fate-filter-shuffleplanes-swapuv: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf shuffleplanes=0:2:1:0 FATE_FILTER_VSYNTH-$(CONFIG_SHUFFLEPLANES_FILTER) += $(FATE_SHUFFLEPLANES)