[FFmpeg-devel] [PATCH 1/3] drawutils: implement uniform and mask blending.

Stefano Sabatini stefasab at gmail.com
Mon Apr 2 00:12:00 CEST 2012


On date Wednesday 2012-03-28 16:25:57 +0200, Nicolas George encoded:
> 
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
> ---
>  libavfilter/drawutils.c |  224 +++++++++++++++++++++++++++++++++++++++++++++++
>  libavfilter/drawutils.h |   33 +++++++
>  2 files changed, 257 insertions(+), 0 deletions(-)
> 
> 
> There is room for optimization, but I believe it can already applied.
> 
> Note that the handling of subsampling is more accurate than the code
> currently present in drawtext; the difference is very much visible in
> yuv410p.
> 
> 
> diff --git a/libavfilter/drawutils.c b/libavfilter/drawutils.c
> index 0243a17..7268967 100644
> --- a/libavfilter/drawutils.c
> +++ b/libavfilter/drawutils.c
> @@ -132,6 +132,8 @@ int ff_draw_init(FFDrawContext *draw, enum PixelFormat format, unsigned flags)
>      unsigned i, nb_planes = 0;
>      int pixelstep[MAX_PLANES] = { 0 };
>  
> +    if (!desc->name)
> +        return AVERROR(EINVAL);
>      if (desc->flags & ~(PIX_FMT_PLANAR | PIX_FMT_RGB))
>          return AVERROR(ENOSYS);
>      for (i = 0; i < desc->nb_components; i++) {
> @@ -146,6 +148,8 @@ int ff_draw_init(FFDrawContext *draw, enum PixelFormat format, unsigned flags)
>              pixelstep[c->plane] != c->step_minus1 + 1)
>              return AVERROR(ENOSYS);
>          pixelstep[c->plane] = c->step_minus1 + 1;
> +        if (pixelstep[c->plane] >= 8)
> +            return AVERROR(ENOSYS);
>          nb_planes = FFMAX(nb_planes, c->plane + 1);
>      }
>      if ((desc->log2_chroma_w || desc->log2_chroma_h) && nb_planes < 3)
> @@ -159,6 +163,9 @@ int ff_draw_init(FFDrawContext *draw, enum PixelFormat format, unsigned flags)
>          draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w;
>          draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h;
>      }
> +    for (i = 0; i < ((desc->nb_components - 1) | 1); i++)
> +        draw->comp_mask[desc->comp[i].plane] |=
> +            1 << (desc->comp[i].offset_plus1 - 1);
>      return 0;
>  }
>  
> @@ -167,6 +174,8 @@ void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, uint8_t rgba[4])
>      unsigned i;
>      uint8_t rgba_map[4];
>  
> +    if (rgba != color->rgba)
> +        memcpy(color->rgba, rgba, sizeof(color->rgba));
>      if ((draw->desc->flags & PIX_FMT_RGB) && draw->nb_planes == 1 &&
>          ff_fill_rgba_map(rgba_map, draw->format) >= 0) {
>          for (i = 0; i < 4; i++)
> @@ -246,6 +255,221 @@ void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color,
>      }
>  }
>  

> +static void clip_interval(int wmax, int *x, int *w, int *dx)

Please some doxy, I suggest:

Clip values in the interval [x, x+w], so that they are contained in the [0,
maxw] interval. Note: the resulting w may be negative.

dx -> not really sure what is meant to be.

> +{
> +    if (dx)
> +        *dx = 0;
> +    if (*x < 0) {
> +        if (dx)
> +            *dx = -*x;
> +        *w += *x;
> +        *x = 0;
> +    }
> +    if (*x + *w > wmax)
> +        *w = wmax - *x;
> +}
> +

> +static void subsampling_bounds(int sub, int *x, int *w, int *start, int *end)

same here, nit++ missing verb

> +{
> +    int mask = (1 << sub) - 1;
> +
> +    *start = (-*x) & mask;
> +    *x += *start;
> +    *start = FFMIN(*start, *w);
> +    *w -= *start;
> +    *end = *w & mask;
> +    *w >>= sub;
> +}
> +
[...]
>  int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir,
>                           int value)
>  {
> diff --git a/libavfilter/drawutils.h b/libavfilter/drawutils.h
> index 9e98f4e..766f0cc 100644
> --- a/libavfilter/drawutils.h
> +++ b/libavfilter/drawutils.h
> @@ -50,6 +50,7 @@ typedef struct FFDrawContext {
>      enum PixelFormat format;
>      unsigned nb_planes;
>      int pixelstep[MAX_PLANES]; /*< offset between pixels */

> +    uint8_t comp_mask[MAX_PLANES]; /*< component is used (except alpha) */

This description is a bit too dry, possibly misleading assuming that it is a
*mask* and not a simple binary flag.

[...]

I'd like to review the rest of the code more accurately, but if I don't come
with it in one day or two feel free to commit, thanks.
-- 
FFmpeg = Friendly Foolish Mystic Patchable Efficient Guru


More information about the ffmpeg-devel mailing list