[FFmpeg-devel] [PATCH] life: add slow_death, life_color and death_color options.

Stefano Sabatini stefasab at gmail.com
Fri Dec 9 15:24:59 CET 2011


On date Friday 2011-12-09 03:14:03 +0100, Clément Bœsch encoded:
> On Fri, Dec 09, 2011 at 02:47:36AM +0100, Clément Bœsch wrote:
> [...]
> > From 30bb08c858790c43a7af3794f48e14706c53e92f Mon Sep 17 00:00:00 2001
> > From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= <ubitux at gmail.com>
> > Date: Fri, 9 Dec 2011 02:33:01 +0100
> > Subject: [PATCH] life: add mold, mold_color, life_color and death_color
> >  options.
> > 
> 
> New version with minor changes attached. Sorry for the noise.
> 
> -- 
> Clément B.

> From 6385a0a9188a195fb0be260759b81d49d1a84ae6 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= <ubitux at gmail.com>
> Date: Fri, 9 Dec 2011 02:33:01 +0100
> Subject: [PATCH] life: add mold, mold_color, life_color and death_color
>  options.
> 
> ---
>  doc/filters.texi        |   20 ++++++++
>  libavfilter/vsrc_life.c |  114 +++++++++++++++++++++++++++++++++++++++--------
>  2 files changed, 115 insertions(+), 19 deletions(-)
[...]
>              /* compute the number of live neighbor cells */
> -            n = (pos[NW][0] == -1 || pos[NW][1] == -1 ? 0 : oldbuf[pos[NW][0]*life->w + pos[NW][1]]) +
> -                (pos[N ][0] == -1 || pos[N ][1] == -1 ? 0 : oldbuf[pos[N ][0]*life->w + pos[N ][1]]) +
> -                (pos[NE][0] == -1 || pos[NE][1] == -1 ? 0 : oldbuf[pos[NE][0]*life->w + pos[NE][1]]) +
> -                (pos[W ][0] == -1 || pos[W ][1] == -1 ? 0 : oldbuf[pos[W ][0]*life->w + pos[W ][1]]) +
> -                (pos[E ][0] == -1 || pos[E ][1] == -1 ? 0 : oldbuf[pos[E ][0]*life->w + pos[E ][1]]) +
> -                (pos[SW][0] == -1 || pos[SW][1] == -1 ? 0 : oldbuf[pos[SW][0]*life->w + pos[SW][1]]) +
> -                (pos[S ][0] == -1 || pos[S ][1] == -1 ? 0 : oldbuf[pos[S ][0]*life->w + pos[S ][1]]) +
> -                (pos[SE][0] == -1 || pos[SE][1] == -1 ? 0 : oldbuf[pos[SE][0]*life->w + pos[SE][1]]);
> -            v = !!(1<<n & (oldbuf[i*life->w + j] ? life->stay_rule : life->born_rule));
> -            av_dlog(ctx, "i:%d j:%d live_neighbors:%d cell:%d -> cell:%d\n", i, j, n, oldbuf[i*life->w + j], v);
> -            newbuf[i*life->w+j] = v;
> +            n = (pos[NW][0] == -1 || pos[NW][1] == -1 ? 0 : oldbuf[pos[NW][0]*life->w + pos[NW][1]] == ALIVE_CELL) +
> +                (pos[N ][0] == -1 || pos[N ][1] == -1 ? 0 : oldbuf[pos[N ][0]*life->w + pos[N ][1]] == ALIVE_CELL) +
> +                (pos[NE][0] == -1 || pos[NE][1] == -1 ? 0 : oldbuf[pos[NE][0]*life->w + pos[NE][1]] == ALIVE_CELL) +
> +                (pos[W ][0] == -1 || pos[W ][1] == -1 ? 0 : oldbuf[pos[W ][0]*life->w + pos[W ][1]] == ALIVE_CELL) +
> +                (pos[E ][0] == -1 || pos[E ][1] == -1 ? 0 : oldbuf[pos[E ][0]*life->w + pos[E ][1]] == ALIVE_CELL) +
> +                (pos[SW][0] == -1 || pos[SW][1] == -1 ? 0 : oldbuf[pos[SW][0]*life->w + pos[SW][1]] == ALIVE_CELL) +
> +                (pos[S ][0] == -1 || pos[S ][1] == -1 ? 0 : oldbuf[pos[S ][0]*life->w + pos[S ][1]] == ALIVE_CELL) +
> +                (pos[SE][0] == -1 || pos[SE][1] == -1 ? 0 : oldbuf[pos[SE][0]*life->w + pos[SE][1]] == ALIVE_CELL);
> +            v = 1<<n & (oldbuf[i*life->w + j] == ALIVE_CELL ? life->stay_rule : life->born_rule);

> +            *newbuf = v ? ALIVE_CELL : *newbuf - (*newbuf != 0);

Maybe a bit too convoluted, possible suggestion:
if (v == ALIVE_CELL) *newbuf = v;
else if (*newbuf)   (*newbuf)--;

> +            av_dlog(ctx, "i:%d j:%d live_neighbors:%d cell:%d -> cell:%d\n", i, j, n, oldbuf[i*life->w + j], *newbuf);
> +            newbuf++;
>          }
>      }
>  
>      life->buf_idx = !life->buf_idx;
>  }
>  
> -static void fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
> +static void fill_picture_monoblack(AVFilterContext *ctx, AVFilterBufferRef *picref)
>  {
>      LifeContext *life = ctx->priv;
>      uint8_t *buf = life->buf[life->buf_idx];
> @@ -350,7 +391,7 @@ static void fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
>          uint8_t byte = 0;
>          uint8_t *p = picref->data[0] + i * picref->linesize[0];
>          for (k = 0, j = 0; j < life->w; j++) {
> -            byte |= buf[i*life->w+j]<<(7-k++);
> +            byte |= (buf[i*life->w+j] == ALIVE_CELL)<<(7-k++);
>              if (k==8 || j == life->w-1) {
>                  k = 0;
>                  *p++ = byte;
> @@ -360,6 +401,32 @@ static void fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
>      }
>  }
>  
> +static void fill_picture_rgb(AVFilterContext *ctx, AVFilterBufferRef *picref)
> +{
> +    LifeContext *life = ctx->priv;
> +    uint8_t *buf = life->buf[life->buf_idx];
> +    int i, j;
> +
> +    /* fill the output picture with the old grid buffer */
> +    for (i = 0; i < life->h; i++) {
> +        uint8_t *p = picref->data[0] + i * picref->linesize[0];
> +        for (j = 0; j < life->w; j++) {
> +            uint8_t  v = buf[i*life->w + j];
> +            uint8_t *c = v == ALIVE_CELL ? life->life_color : life->death_color;
> +            if (life->mold) {

> +                int death_age = (0xff - v) * life->mold;
> +                *p++ = FFMAX((int)c[0] - death_age, life->mold_color[0]);
> +                *p++ = FFMAX((int)c[1] - death_age, life->mold_color[1]);
> +                *p++ = FFMAX((int)c[2] - death_age, life->mold_color[2]);

why not a proper interpolation? The above doesn't work if for example death_color < mold_color

double left_energy = (double)(0xff - v) / 256;
*p++ = mold_color[comp] + ((int)death_color[comp] - (int)mold_color[comp]) * left_energy;

For avoiding divisions (not tested):
int left_energy = 0xff - v;
*p++ = ((mold_color[comp]<<8) + ((int)death_color[comp] - (int)mold_color[comp]) * left_energy)>>8;

> +            } else {
> +                *p++ = c[0];
> +                *p++ = c[1];
> +                *p++ = c[2];
> +            }

AV_WB24(p, c); p += 3;

also you can drop the obfuscating c temporary, and directly use
life/death_color.

[...]
-- 
FFmpeg = Faithless Faithful Muttering Prodigious Earthshaking Gadget


More information about the ffmpeg-devel mailing list