[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