History

lavfi/vsrc_life: avoid modifying the context in query_formats()

It is supposed to be free of side effects. Do it in init instead.

Anton Khirnov committed 2 years ago

Commit 2094a721 parent d08feb91 file · +63 −62Browse files

Unified · Split

libavfilter/vsrc_life.c+63−62
@@ -160,6 +160,58 @@ static void show_life_grid(AVFilterContext *ctx) · 159 unmodified lines
160}160}
161#endif161#endif
162 162
163static void fill_picture_monoblack(AVFilterContext *ctx, AVFrame *picref)
164{
165 LifeContext *life = ctx->priv;
166 uint8_t *buf = life->buf[life->buf_idx];
167 int i, j, k;
168
169 /* fill the output picture with the old grid buffer */
170 for (i = 0; i < life->h; i++) {
171 uint8_t byte = 0;
172 uint8_t *p = picref->data[0] + i * picref->linesize[0];
173 for (k = 0, j = 0; j < life->w; j++) {
174 byte |= (buf[i*life->w+j] == ALIVE_CELL)<<(7-k++);
175 if (k==8 || j == life->w-1) {
176 k = 0;
177 *p++ = byte;
178 byte = 0;
179 }
180 }
181 }
182}
183
184// divide by 255 and round to nearest
185// apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
186#define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
187
188static void fill_picture_rgb(AVFilterContext *ctx, AVFrame *picref)
189{
190 LifeContext *life = ctx->priv;
191 uint8_t *buf = life->buf[life->buf_idx];
192 int i, j;
193
194 /* fill the output picture with the old grid buffer */
195 for (i = 0; i < life->h; i++) {
196 uint8_t *p = picref->data[0] + i * picref->linesize[0];
197 for (j = 0; j < life->w; j++) {
198 uint8_t v = buf[i*life->w + j];
199 if (life->mold && v != ALIVE_CELL) {
200 const uint8_t *c1 = life-> mold_color;
201 const uint8_t *c2 = life->death_color;
202 int death_age = FFMIN((0xff - v) * life->mold, 0xff);
203 *p++ = FAST_DIV255((c2[0] << 8) + ((int)c1[0] - (int)c2[0]) * death_age);
204 *p++ = FAST_DIV255((c2[1] << 8) + ((int)c1[1] - (int)c2[1]) * death_age);
205 *p++ = FAST_DIV255((c2[2] << 8) + ((int)c1[2] - (int)c2[2]) * death_age);
206 } else {
207 const uint8_t *c = v == ALIVE_CELL ? life->life_color : life->death_color;
208 AV_WB24(p, c[0]<<16 | c[1]<<8 | c[2]);
209 p += 3;
210 }
211 }
212 }
213}
214
163static int init_pattern_from_file(AVFilterContext *ctx)215static int init_pattern_from_file(AVFilterContext *ctx)
164{216{
165 LifeContext *life = ctx->priv;217 LifeContext *life = ctx->priv;
@@ -259,6 +311,13 @@ static av_cold int init(AVFilterContext *ctx) · 93 unmodified lines
259 return ret;311 return ret;
260 }312 }
261 313
314 if (life->mold || memcmp(life-> life_color, "\xff\xff\xff", 3)
315 || memcmp(life->death_color, "\x00\x00\x00", 3)) {
316 life->draw = fill_picture_rgb;
317 } else {
318 life->draw = fill_picture_monoblack;
319 }
320
262 av_log(ctx, AV_LOG_VERBOSE,321 av_log(ctx, AV_LOG_VERBOSE,
263 "s:%dx%d r:%d/%d rule:%s stay_rule:%d born_rule:%d stitch:%d seed:%"PRId64"\n",322 "s:%dx%d r:%d/%d rule:%s stay_rule:%d born_rule:%d stitch:%d seed:%"PRId64"\n",
264 life->w, life->h, life->frame_rate.num, life->frame_rate.den,323 life->w, life->h, life->frame_rate.num, life->frame_rate.den,
@@ -345,58 +404,6 @@ static void evolve(AVFilterContext *ctx) · 80 unmodified lines
345 life->buf_idx = !life->buf_idx;404 life->buf_idx = !life->buf_idx;
346}405}
347 406
348static void fill_picture_monoblack(AVFilterContext *ctx, AVFrame *picref)
349{
350 LifeContext *life = ctx->priv;
351 uint8_t *buf = life->buf[life->buf_idx];
352 int i, j, k;
353
354 /* fill the output picture with the old grid buffer */
355 for (i = 0; i < life->h; i++) {
356 uint8_t byte = 0;
357 uint8_t *p = picref->data[0] + i * picref->linesize[0];
358 for (k = 0, j = 0; j < life->w; j++) {
359 byte |= (buf[i*life->w+j] == ALIVE_CELL)<<(7-k++);
360 if (k==8 || j == life->w-1) {
361 k = 0;
362 *p++ = byte;
363 byte = 0;
364 }
365 }
366 }
367}
368
369// divide by 255 and round to nearest
370// apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
371#define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
372
373static void fill_picture_rgb(AVFilterContext *ctx, AVFrame *picref)
374{
375 LifeContext *life = ctx->priv;
376 uint8_t *buf = life->buf[life->buf_idx];
377 int i, j;
378
379 /* fill the output picture with the old grid buffer */
380 for (i = 0; i < life->h; i++) {
381 uint8_t *p = picref->data[0] + i * picref->linesize[0];
382 for (j = 0; j < life->w; j++) {
383 uint8_t v = buf[i*life->w + j];
384 if (life->mold && v != ALIVE_CELL) {
385 const uint8_t *c1 = life-> mold_color;
386 const uint8_t *c2 = life->death_color;
387 int death_age = FFMIN((0xff - v) * life->mold, 0xff);
388 *p++ = FAST_DIV255((c2[0] << 8) + ((int)c1[0] - (int)c2[0]) * death_age);
389 *p++ = FAST_DIV255((c2[1] << 8) + ((int)c1[1] - (int)c2[1]) * death_age);
390 *p++ = FAST_DIV255((c2[2] << 8) + ((int)c1[2] - (int)c2[2]) * death_age);
391 } else {
392 const uint8_t *c = v == ALIVE_CELL ? life->life_color : life->death_color;
393 AV_WB24(p, c[0]<<16 | c[1]<<8 | c[2]);
394 p += 3;
395 }
396 }
397 }
398}
399
400static int request_frame(AVFilterLink *outlink)407static int request_frame(AVFilterLink *outlink)
401{408{
402 LifeContext *life = outlink->src->priv;409 LifeContext *life = outlink->src->priv;
@@ -418,16 +425,10 @@ static int request_frame(AVFilterLink *outlink) · 15 unmodified lines
418static int query_formats(AVFilterContext *ctx)425static int query_formats(AVFilterContext *ctx)
419{426{
420 LifeContext *life = ctx->priv;427 LifeContext *life = ctx->priv;
421 enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_NONE, AV_PIX_FMT_NONE };428 const enum AVPixelFormat pix_fmts[] = {
422 429 life->draw == fill_picture_rgb ? AV_PIX_FMT_RGB24 : AV_PIX_FMT_MONOBLACK,
423 if (life->mold || memcmp(life-> life_color, "\xff\xff\xff", 3)430 AV_PIX_FMT_NONE
424 || memcmp(life->death_color, "\x00\x00\x00", 3)) {431 };
425 pix_fmts[0] = AV_PIX_FMT_RGB24;
426 life->draw = fill_picture_rgb;
427 } else {
428 pix_fmts[0] = AV_PIX_FMT_MONOBLACK;
429 life->draw = fill_picture_monoblack;
430 }
431 432
432 return ff_set_common_formats_from_list(ctx, pix_fmts);433 return ff_set_common_formats_from_list(ctx, pix_fmts);
433}434}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t