[FFmpeg-devel] Copyplane filter

Stefano Sabatini stefano.sabatini-lala at poste.it
Thu Aug 25 02:00:05 CEST 2011


On date Wednesday 2011-08-24 10:37:34 +0100, Gavin Kinsey encoded:
> I've written a filter that copies RGBA image planes.  I'm using it to create 
> an alpha mask from a b&w image.  I'd like to make it work for YUV data too, 
> but before I do that I'd like to get some feedback on the current code.
> 
> This is my first attempt at doing anything with avfilter and a lot of it is 
> just blindly copying from other filters, so there is probably a lot of stuff 
> in there that doesn't need to be and likely important stuff missing too.
> 
> Appreciate any feedback.
[...]
> +/**
> + * @file
> + * Copy plane filter.
> + * based on pixdesc test filter
> + */
> +
> +#include "libavutil/eval.h"
> +#include "libavutil/opt.h"
> +#include "libavutil/pixdesc.h"
> +#include "avfilter.h"
> +
> +typedef struct {
> +    const AVClass *class;
> +    char   *comp_expr_str[4];

> +    AVExpr *comp_expr[4];

is this ever used?

[...]
> +static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
> +{
> +    CopyPlaneContext *cp      = inlink->dst->priv;
> +    AVFilterBufferRef *inpic  = inlink->cur_buf;
> +    AVFilterBufferRef *outpic = inlink->dst->outputs[0]->out_buf;
> +    int i, c, w = inlink->w;
> +
> +    for (c = 0; c < cp->pix_desc->nb_components; c++) {
> +        int w1 = c == 1 || c == 2 ? w>>cp->pix_desc->log2_chroma_w : w;
> +        int h1 = c == 1 || c == 2 ? h>>cp->pix_desc->log2_chroma_h : h;
> +        int y1 = c == 1 || c == 2 ? y>>cp->pix_desc->log2_chroma_h : y;
> +
> +        for (i = y1; i < y1 + h1; i++) {
> +            if (cp->copyplane[c] >= 0)  {
> +                av_read_image_line(cp->line, 
> +                                   (const uint8_t **)inpic->data,
> +                                   inpic->linesize,
> +                                   cp->pix_desc,
> +                                   0, i, cp->copyplane[c], w1, 0);
> +                av_write_image_line(cp->line,
> +                                    outpic->data,
> +                                    outpic->linesize,
> +                                    cp->pix_desc,
> +                                    0, i, c, w1);
> +            }
> +            if (!cp->skipplane[c])  {
> +                av_read_image_line(cp->line, 
> +                                   (const uint8_t **)inpic->data,
> +                                   inpic->linesize,
> +                                   cp->pix_desc,
> +                                   0, i, c, w1, 0);
> +                av_write_image_line(cp->line,
> +                                    outpic->data,
> +                                    outpic->linesize,
> +                                    cp->pix_desc,
> +                                    0, i, c, w1);
> +            }                

Look, since you don't need generic support a simple memcpy should be
more efficient.

Also note that this filter job can be done in a much more general way
using an eval filter, e.g.:

evalrgb=a=r

Check the applyfn filter in the archive, also you could consider using
the mp=geq filter (not sure it supports alpha).

On the other hand the eval filter would be much slower (an expression
is evaluated for each pixel component), so maybe the copyplane idea is
acceptable.
-- 
FFmpeg = Fundamental Fancy Mean Pacific Enchanting God


More information about the ffmpeg-devel mailing list