[FFmpeg-devel] [PATCH] lavfi/vf_extractplanes: set input formats to reduce conversions.
Paul B Mahol
onemda at gmail.com
Tue May 7 09:14:41 CEST 2013
On 5/6/13, Nicolas George <nicolas.george at normalesup.org> wrote:
> Only accept formats that will not require color-space conversion
> and with the same bit depth as actually available on input.
>
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
> ---
> libavfilter/vf_extractplanes.c | 67
> ++++++++++++++++++++++++++--------------
> 1 file changed, 44 insertions(+), 23 deletions(-)
>
>
> Note tht for some reason, GBRP16?E are not considered valid output formats
> for lsws, so handling RGB in 16 bpp will not work. But that is completely
> unrelated.
>
>
Nope, this is wrong way how to do this, it complicates code for no gain.
Why would filter accepts only formats that do not need conversion?
This is again wrong.
> diff --git a/libavfilter/vf_extractplanes.c
> b/libavfilter/vf_extractplanes.c
> index 028813a..373a789 100644
> --- a/libavfilter/vf_extractplanes.c
> +++ b/libavfilter/vf_extractplanes.c
> @@ -18,6 +18,7 @@
> * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
> USA
> */
>
> +#include "libavutil/avassert.h"
> #include "libavutil/avstring.h"
> #include "libavutil/imgutils.h"
> #include "libavutil/opt.h"
> @@ -33,6 +34,12 @@
> #define PLANE_U 0x20
> #define PLANE_V 0x40
>
> +#define FLAG_DEPTH_8 0x10000
> +#define FLAG_DEPTH_16LE 0x20000
> +#define FLAG_DEPTH_16BE 0x40000
> +#define FLAG_DEPTH_OTHER 0x80000
> +#define FLAG_DEPTHS 0xF0000
> +
> typedef struct {
> const AVClass *class;
> int requested_planes;
> @@ -56,6 +63,21 @@ static const AVOption extractplanes_options[] = {
>
> AVFILTER_DEFINE_CLASS(extractplanes);
>
> +static unsigned pix_fmt_to_bitmask(enum AVPixelFormat fmt)
> +{
> + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
> + unsigned depth = desc->comp[0].depth_minus1 + 1;
> +
> + return ((desc->flags & PIX_FMT_RGB) ? PLANE_R|PLANE_G|PLANE_B :
> + PLANE_Y |
> + ((desc->nb_components > 2) ? PLANE_U|PLANE_V : 0))
> |
> + ((desc->flags & PIX_FMT_ALPHA) ? PLANE_A : 0) |
> + (depth == 8 ? FLAG_DEPTH_8 :
> + depth == 16 ? (desc->flags & PIX_FMT_BE) ? FLAG_DEPTH_16BE :
> + FLAG_DEPTH_16LE :
> + FLAG_DEPTH_OTHER);
> +}
> +
> static int query_formats(AVFilterContext *ctx)
> {
> static const enum AVPixelFormat in_pixfmts[] = {
> @@ -77,42 +99,45 @@ static int query_formats(AVFilterContext *ctx)
> AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_GRAY16BE,
> AV_PIX_FMT_GBRP,
> AV_PIX_FMT_GBRP16LE, AV_PIX_FMT_GBRP16BE,
> - AV_PIX_FMT_NONE,
> };
> static const enum AVPixelFormat out8_pixfmts[] = { AV_PIX_FMT_GRAY8,
> AV_PIX_FMT_NONE };
> static const enum AVPixelFormat out16le_pixfmts[] = {
> AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_NONE };
> static const enum AVPixelFormat out16be_pixfmts[] = {
> AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_NONE };
> const enum AVPixelFormat *out_pixfmts;
> - const AVPixFmtDescriptor *desc;
> - AVFilterFormats *avff;
> - int i, depth = 0, be = 0;
> + AVFilterFormats *avff, *in_formats = NULL;
> + unsigned i, fmt_mask, max_fmt_mask = 0;
>
> if (!ctx->inputs[0]->in_formats ||
> !ctx->inputs[0]->in_formats->format_count) {
> return AVERROR(EAGAIN);
> }
>
> - if (!ctx->inputs[0]->out_formats)
> - ff_formats_ref(ff_make_format_list(in_pixfmts),
> &ctx->inputs[0]->out_formats);
> -
> avff = ctx->inputs[0]->in_formats;
> - desc = av_pix_fmt_desc_get(avff->formats[0]);
> - depth = desc->comp[0].depth_minus1;
> - be = desc->flags & PIX_FMT_BE;
> - for (i = 1; i < avff->format_count; i++) {
> - desc = av_pix_fmt_desc_get(avff->formats[i]);
> - if (depth != desc->comp[0].depth_minus1 ||
> - be != (desc->flags & PIX_FMT_BE)) {
> + for (i = 0; i < avff->format_count; i++) {
> + fmt_mask = pix_fmt_to_bitmask(avff->formats[i]);
> + if ((fmt_mask & ~max_fmt_mask) && (max_fmt_mask & ~fmt_mask))
> return AVERROR(EAGAIN);
> - }
> + max_fmt_mask |= fmt_mask;
> }
>
> - if (depth == 7)
> + if ((max_fmt_mask & FLAG_DEPTH_8)) {
> out_pixfmts = out8_pixfmts;
> - else if (be)
> + } else if ((max_fmt_mask & FLAG_DEPTH_16BE)) {
> out_pixfmts = out16be_pixfmts;
> - else
> + } else if ((max_fmt_mask & FLAG_DEPTH_16BE)) {
> out_pixfmts = out16le_pixfmts;
> + } else {
> + av_log(ctx, AV_LOG_ERROR, "No supported bit depth in input\n");
> + return AVERROR(EINVAL);
> + }
> +
> + if (!ctx->inputs[0]->out_formats) {
> + for (i = 0; i < FF_ARRAY_ELEMS(in_pixfmts); i++)
> + if (!(pix_fmt_to_bitmask(in_pixfmts[i]) & ~max_fmt_mask))
> + ff_add_format(&in_formats, in_pixfmts[i]);
> + av_assert0(in_formats);
> + ff_formats_ref(in_formats, &ctx->inputs[0]->out_formats);
> + }
>
> for (i = 0; i < ctx->nb_outputs; i++)
> ff_formats_ref(ff_make_format_list(out_pixfmts),
> &ctx->outputs[i]->in_formats);
> @@ -123,13 +148,9 @@ static int config_input(AVFilterLink *inlink)
> {
> AVFilterContext *ctx = inlink->dst;
> ExtractPlanesContext *e = ctx->priv;
> - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
> int plane_avail, ret;
>
> - plane_avail = ((desc->flags & PIX_FMT_RGB) ? PLANE_R|PLANE_G|PLANE_B :
> - PLANE_Y |
> - ((desc->nb_components > 2) ?
> PLANE_U|PLANE_V : 0)) |
> - ((desc->flags & PIX_FMT_ALPHA) ? PLANE_A : 0);
> + plane_avail = pix_fmt_to_bitmask(inlink->format) & ~FLAG_DEPTHS;
> if (e->requested_planes & ~plane_avail) {
> av_log(ctx, AV_LOG_ERROR, "Requested planes not available.\n");
> return AVERROR(EINVAL);
> --
> 1.7.10.4
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
More information about the ffmpeg-devel
mailing list