vsrc_life.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) Stefano Sabatini 2010
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * life video source, based on John Conways' Life Game
24  */
25 
26 /* #define DEBUG */
27 
28 #include "libavutil/file.h"
29 #include "libavutil/intreadwrite.h"
30 #include "libavutil/lfg.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/parseutils.h"
33 #include "libavutil/random_seed.h"
34 #include "libavutil/avstring.h"
35 #include "avfilter.h"
36 #include "internal.h"
37 #include "formats.h"
38 #include "video.h"
39 
40 typedef struct {
41  const AVClass *class;
42  int w, h;
43  char *filename;
44  char *rule_str;
46  size_t file_bufsize;
47 
48  /**
49  * The two grid state buffers.
50  *
51  * A 0xFF (ALIVE_CELL) value means the cell is alive (or new born), while
52  * the decreasing values from 0xFE to 0 means the cell is dead; the range
53  * of values is used for the slow death effect, or mold (0xFE means dead,
54  * 0xFD means very dead, 0xFC means very very dead... and 0x00 means
55  * definitely dead/mold).
56  */
57  uint8_t *buf[2];
58 
60  uint16_t stay_rule; ///< encode the behavior for filled cells
61  uint16_t born_rule; ///< encode the behavior for empty cells
62  uint64_t pts;
65  uint32_t random_seed;
66  int stitch;
67  int mold;
71  uint8_t life_color[4];
72  uint8_t death_color[4];
73  uint8_t mold_color[4];
76 } LifeContext;
77 
78 #define ALIVE_CELL 0xFF
79 #define OFFSET(x) offsetof(LifeContext, x)
80 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
81 
82 static const AVOption life_options[] = {
83  { "filename", "set source file", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
84  { "f", "set source file", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
85  { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, FLAGS },
86  { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, FLAGS },
87  { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },
88  { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },
89  { "rule", "set rule", OFFSET(rule_str), AV_OPT_TYPE_STRING, {.str = "B3/S23"}, CHAR_MIN, CHAR_MAX, FLAGS },
90  { "random_fill_ratio", "set fill ratio for filling initial grid randomly", OFFSET(random_fill_ratio), AV_OPT_TYPE_DOUBLE, {.dbl=1/M_PHI}, 0, 1, FLAGS },
91  { "ratio", "set fill ratio for filling initial grid randomly", OFFSET(random_fill_ratio), AV_OPT_TYPE_DOUBLE, {.dbl=1/M_PHI}, 0, 1, FLAGS },
92  { "random_seed", "set the seed for filling the initial grid randomly", OFFSET(random_seed), AV_OPT_TYPE_INT, {.i64=-1}, -1, UINT32_MAX, FLAGS },
93  { "seed", "set the seed for filling the initial grid randomly", OFFSET(random_seed), AV_OPT_TYPE_INT, {.i64=-1}, -1, UINT32_MAX, FLAGS },
94  { "stitch", "stitch boundaries", OFFSET(stitch), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS },
95  { "mold", "set mold speed for dead cells", OFFSET(mold), AV_OPT_TYPE_INT, {.i64=0}, 0, 0xFF, FLAGS },
96  { "life_color", "set life color", OFFSET( life_color_str), AV_OPT_TYPE_STRING, {.str="white"}, CHAR_MIN, CHAR_MAX, FLAGS },
97  { "death_color", "set death color", OFFSET(death_color_str), AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS },
98  { "mold_color", "set mold color", OFFSET( mold_color_str), AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS },
99  { NULL },
100 };
101 
103 
104 static int parse_rule(uint16_t *born_rule, uint16_t *stay_rule,
105  const char *rule_str, void *log_ctx)
106 {
107  char *tail;
108  const char *p = rule_str;
109  *born_rule = 0;
110  *stay_rule = 0;
111 
112  if (strchr("bBsS", *p)) {
113  /* parse rule as a Born / Stay Alive code, see
114  * http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life */
115  do {
116  uint16_t *rule = (*p == 'b' || *p == 'B') ? born_rule : stay_rule;
117  p++;
118  while (*p >= '0' && *p <= '8') {
119  *rule += 1<<(*p - '0');
120  p++;
121  }
122  if (*p != '/')
123  break;
124  p++;
125  } while (strchr("bBsS", *p));
126 
127  if (*p)
128  goto error;
129  } else {
130  /* parse rule as a number, expressed in the form STAY|(BORN<<9),
131  * where STAY and BORN encode the corresponding 9-bits rule */
132  long int rule = strtol(rule_str, &tail, 10);
133  if (*tail)
134  goto error;
135  *born_rule = ((1<<9)-1) & rule;
136  *stay_rule = rule >> 9;
137  }
138 
139  return 0;
140 
141 error:
142  av_log(log_ctx, AV_LOG_ERROR, "Invalid rule code '%s' provided\n", rule_str);
143  return AVERROR(EINVAL);
144 }
145 
146 #ifdef DEBUG
147 static void show_life_grid(AVFilterContext *ctx)
148 {
149  LifeContext *life = ctx->priv;
150  int i, j;
151 
152  char *line = av_malloc(life->w + 1);
153  if (!line)
154  return;
155  for (i = 0; i < life->h; i++) {
156  for (j = 0; j < life->w; j++)
157  line[j] = life->buf[life->buf_idx][i*life->w + j] == ALIVE_CELL ? '@' : ' ';
158  line[j] = 0;
159  av_log(ctx, AV_LOG_DEBUG, "%3d: %s\n", i, line);
160  }
161  av_free(line);
162 }
163 #endif
164 
166 {
167  LifeContext *life = ctx->priv;
168  char *p;
169  int ret, i, i0, j, h = 0, w, max_w = 0;
170 
171  if ((ret = av_file_map(life->filename, &life->file_buf, &life->file_bufsize,
172  0, ctx)) < 0)
173  return ret;
174  av_freep(&life->filename);
175 
176  /* prescan file to get the number of lines and the maximum width */
177  w = 0;
178  for (i = 0; i < life->file_bufsize; i++) {
179  if (life->file_buf[i] == '\n') {
180  h++; max_w = FFMAX(w, max_w); w = 0;
181  } else {
182  w++;
183  }
184  }
185  av_log(ctx, AV_LOG_DEBUG, "h:%d max_w:%d\n", h, max_w);
186 
187  if (life->w) {
188  if (max_w > life->w || h > life->h) {
189  av_log(ctx, AV_LOG_ERROR,
190  "The specified size is %dx%d which cannot contain the provided file size of %dx%d\n",
191  life->w, life->h, max_w, h);
192  return AVERROR(EINVAL);
193  }
194  } else {
195  /* size was not specified, set it to size of the grid */
196  life->w = max_w;
197  life->h = h;
198  }
199 
200  if (!(life->buf[0] = av_mallocz(sizeof(char) * life->h * life->w)) ||
201  !(life->buf[1] = av_mallocz(sizeof(char) * life->h * life->w))) {
202  av_free(life->buf[0]);
203  av_free(life->buf[1]);
204  return AVERROR(ENOMEM);
205  }
206 
207  /* fill buf[0] */
208  p = life->file_buf;
209  for (i0 = 0, i = (life->h - h)/2; i0 < h; i0++, i++) {
210  for (j = (life->w - max_w)/2;; j++) {
211  av_log(ctx, AV_LOG_DEBUG, "%d:%d %c\n", i, j, *p == '\n' ? 'N' : *p);
212  if (*p == '\n') {
213  p++; break;
214  } else
215  life->buf[0][i*life->w + j] = av_isgraph(*(p++)) ? ALIVE_CELL : 0;
216  }
217  }
218  life->buf_idx = 0;
219 
220  return 0;
221 }
222 
223 static int init(AVFilterContext *ctx)
224 {
225  LifeContext *life = ctx->priv;
226  int ret;
227 
228  if (!life->w && !life->filename)
229  av_opt_set(life, "size", "320x240", 0);
230 
231  if ((ret = parse_rule(&life->born_rule, &life->stay_rule, life->rule_str, ctx)) < 0)
232  return ret;
233 
234 #define PARSE_COLOR(name) do { \
235  if ((ret = av_parse_color(life->name ## _color, life->name ## _color_str, -1, ctx))) { \
236  av_log(ctx, AV_LOG_ERROR, "Invalid " #name " color '%s'\n", \
237  life->name ## _color_str); \
238  return ret; \
239  } \
240  av_freep(&life->name ## _color_str); \
241 } while (0)
242 
243  PARSE_COLOR(life);
244  PARSE_COLOR(death);
245  PARSE_COLOR(mold);
246 
247  if (!life->mold && memcmp(life->mold_color, "\x00\x00\x00", 3))
248  av_log(ctx, AV_LOG_WARNING,
249  "Mold color is set while mold isn't, ignoring the color.\n");
250 
251  if (!life->filename) {
252  /* fill the grid randomly */
253  int i;
254 
255  if (!(life->buf[0] = av_mallocz(sizeof(char) * life->h * life->w)) ||
256  !(life->buf[1] = av_mallocz(sizeof(char) * life->h * life->w))) {
257  av_free(life->buf[0]);
258  av_free(life->buf[1]);
259  return AVERROR(ENOMEM);
260  }
261  if (life->random_seed == -1)
263 
264  av_lfg_init(&life->lfg, life->random_seed);
265 
266  for (i = 0; i < life->w * life->h; i++) {
267  double r = (double)av_lfg_get(&life->lfg) / UINT32_MAX;
268  if (r <= life->random_fill_ratio)
269  life->buf[0][i] = ALIVE_CELL;
270  }
271  life->buf_idx = 0;
272  } else {
273  if ((ret = init_pattern_from_file(ctx)) < 0)
274  return ret;
275  }
276 
277  av_log(ctx, AV_LOG_VERBOSE,
278  "s:%dx%d r:%d/%d rule:%s stay_rule:%d born_rule:%d stitch:%d seed:%u\n",
279  life->w, life->h, life->frame_rate.num, life->frame_rate.den,
280  life->rule_str, life->stay_rule, life->born_rule, life->stitch,
281  life->random_seed);
282  return 0;
283 }
284 
285 static av_cold void uninit(AVFilterContext *ctx)
286 {
287  LifeContext *life = ctx->priv;
288 
289  av_file_unmap(life->file_buf, life->file_bufsize);
290  av_freep(&life->rule_str);
291  av_freep(&life->buf[0]);
292  av_freep(&life->buf[1]);
293 }
294 
295 static int config_props(AVFilterLink *outlink)
296 {
297  LifeContext *life = outlink->src->priv;
298 
299  outlink->w = life->w;
300  outlink->h = life->h;
301  outlink->time_base = av_inv_q(life->frame_rate);
302 
303  return 0;
304 }
305 
306 static void evolve(AVFilterContext *ctx)
307 {
308  LifeContext *life = ctx->priv;
309  int i, j;
310  uint8_t *oldbuf = life->buf[ life->buf_idx];
311  uint8_t *newbuf = life->buf[!life->buf_idx];
312 
313  enum { NW, N, NE, W, E, SW, S, SE };
314 
315  /* evolve the grid */
316  for (i = 0; i < life->h; i++) {
317  for (j = 0; j < life->w; j++) {
318  int pos[8][2], n, alive, cell;
319  if (life->stitch) {
320  pos[NW][0] = (i-1) < 0 ? life->h-1 : i-1; pos[NW][1] = (j-1) < 0 ? life->w-1 : j-1;
321  pos[N ][0] = (i-1) < 0 ? life->h-1 : i-1; pos[N ][1] = j ;
322  pos[NE][0] = (i-1) < 0 ? life->h-1 : i-1; pos[NE][1] = (j+1) == life->w ? 0 : j+1;
323  pos[W ][0] = i ; pos[W ][1] = (j-1) < 0 ? life->w-1 : j-1;
324  pos[E ][0] = i ; pos[E ][1] = (j+1) == life->w ? 0 : j+1;
325  pos[SW][0] = (i+1) == life->h ? 0 : i+1; pos[SW][1] = (j-1) < 0 ? life->w-1 : j-1;
326  pos[S ][0] = (i+1) == life->h ? 0 : i+1; pos[S ][1] = j ;
327  pos[SE][0] = (i+1) == life->h ? 0 : i+1; pos[SE][1] = (j+1) == life->w ? 0 : j+1;
328  } else {
329  pos[NW][0] = (i-1) < 0 ? -1 : i-1; pos[NW][1] = (j-1) < 0 ? -1 : j-1;
330  pos[N ][0] = (i-1) < 0 ? -1 : i-1; pos[N ][1] = j ;
331  pos[NE][0] = (i-1) < 0 ? -1 : i-1; pos[NE][1] = (j+1) == life->w ? -1 : j+1;
332  pos[W ][0] = i ; pos[W ][1] = (j-1) < 0 ? -1 : j-1;
333  pos[E ][0] = i ; pos[E ][1] = (j+1) == life->w ? -1 : j+1;
334  pos[SW][0] = (i+1) == life->h ? -1 : i+1; pos[SW][1] = (j-1) < 0 ? -1 : j-1;
335  pos[S ][0] = (i+1) == life->h ? -1 : i+1; pos[S ][1] = j ;
336  pos[SE][0] = (i+1) == life->h ? -1 : i+1; pos[SE][1] = (j+1) == life->w ? -1 : j+1;
337  }
338 
339  /* compute the number of live neighbor cells */
340  n = (pos[NW][0] == -1 || pos[NW][1] == -1 ? 0 : oldbuf[pos[NW][0]*life->w + pos[NW][1]] == ALIVE_CELL) +
341  (pos[N ][0] == -1 || pos[N ][1] == -1 ? 0 : oldbuf[pos[N ][0]*life->w + pos[N ][1]] == ALIVE_CELL) +
342  (pos[NE][0] == -1 || pos[NE][1] == -1 ? 0 : oldbuf[pos[NE][0]*life->w + pos[NE][1]] == ALIVE_CELL) +
343  (pos[W ][0] == -1 || pos[W ][1] == -1 ? 0 : oldbuf[pos[W ][0]*life->w + pos[W ][1]] == ALIVE_CELL) +
344  (pos[E ][0] == -1 || pos[E ][1] == -1 ? 0 : oldbuf[pos[E ][0]*life->w + pos[E ][1]] == ALIVE_CELL) +
345  (pos[SW][0] == -1 || pos[SW][1] == -1 ? 0 : oldbuf[pos[SW][0]*life->w + pos[SW][1]] == ALIVE_CELL) +
346  (pos[S ][0] == -1 || pos[S ][1] == -1 ? 0 : oldbuf[pos[S ][0]*life->w + pos[S ][1]] == ALIVE_CELL) +
347  (pos[SE][0] == -1 || pos[SE][1] == -1 ? 0 : oldbuf[pos[SE][0]*life->w + pos[SE][1]] == ALIVE_CELL);
348  cell = oldbuf[i*life->w + j];
349  alive = 1<<n & (cell == ALIVE_CELL ? life->stay_rule : life->born_rule);
350  if (alive) *newbuf = ALIVE_CELL; // new cell is alive
351  else if (cell) *newbuf = cell - 1; // new cell is dead and in the process of mold
352  else *newbuf = 0; // new cell is definitely dead
353  av_dlog(ctx, "i:%d j:%d live_neighbors:%d cell:%d -> cell:%d\n", i, j, n, cell, *newbuf);
354  newbuf++;
355  }
356  }
357 
358  life->buf_idx = !life->buf_idx;
359 }
360 
362 {
363  LifeContext *life = ctx->priv;
364  uint8_t *buf = life->buf[life->buf_idx];
365  int i, j, k;
366 
367  /* fill the output picture with the old grid buffer */
368  for (i = 0; i < life->h; i++) {
369  uint8_t byte = 0;
370  uint8_t *p = picref->data[0] + i * picref->linesize[0];
371  for (k = 0, j = 0; j < life->w; j++) {
372  byte |= (buf[i*life->w+j] == ALIVE_CELL)<<(7-k++);
373  if (k==8 || j == life->w-1) {
374  k = 0;
375  *p++ = byte;
376  byte = 0;
377  }
378  }
379  }
380 }
381 
382 // divide by 255 and round to nearest
383 // apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
384 #define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
385 
386 static void fill_picture_rgb(AVFilterContext *ctx, AVFrame *picref)
387 {
388  LifeContext *life = ctx->priv;
389  uint8_t *buf = life->buf[life->buf_idx];
390  int i, j;
391 
392  /* fill the output picture with the old grid buffer */
393  for (i = 0; i < life->h; i++) {
394  uint8_t *p = picref->data[0] + i * picref->linesize[0];
395  for (j = 0; j < life->w; j++) {
396  uint8_t v = buf[i*life->w + j];
397  if (life->mold && v != ALIVE_CELL) {
398  const uint8_t *c1 = life-> mold_color;
399  const uint8_t *c2 = life->death_color;
400  int death_age = FFMIN((0xff - v) * life->mold, 0xff);
401  *p++ = FAST_DIV255((c2[0] << 8) + ((int)c1[0] - (int)c2[0]) * death_age);
402  *p++ = FAST_DIV255((c2[1] << 8) + ((int)c1[1] - (int)c2[1]) * death_age);
403  *p++ = FAST_DIV255((c2[2] << 8) + ((int)c1[2] - (int)c2[2]) * death_age);
404  } else {
405  const uint8_t *c = v == ALIVE_CELL ? life->life_color : life->death_color;
406  AV_WB24(p, c[0]<<16 | c[1]<<8 | c[2]);
407  p += 3;
408  }
409  }
410  }
411 }
412 
413 static int request_frame(AVFilterLink *outlink)
414 {
415  LifeContext *life = outlink->src->priv;
416  AVFrame *picref = ff_get_video_buffer(outlink, life->w, life->h);
417  if (!picref)
418  return AVERROR(ENOMEM);
419  picref->sample_aspect_ratio = (AVRational) {1, 1};
420  picref->pts = life->pts++;
421 
422  life->draw(outlink->src, picref);
423  evolve(outlink->src);
424 #ifdef DEBUG
425  show_life_grid(outlink->src);
426 #endif
427  return ff_filter_frame(outlink, picref);
428 }
429 
431 {
432  LifeContext *life = ctx->priv;
433  enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_NONE, AV_PIX_FMT_NONE };
434  if (life->mold || memcmp(life-> life_color, "\xff\xff\xff", 3)
435  || memcmp(life->death_color, "\x00\x00\x00", 3)) {
436  pix_fmts[0] = AV_PIX_FMT_RGB24;
437  life->draw = fill_picture_rgb;
438  } else {
439  pix_fmts[0] = AV_PIX_FMT_MONOBLACK;
441  }
443  return 0;
444 }
445 
446 static const AVFilterPad life_outputs[] = {
447  {
448  .name = "default",
449  .type = AVMEDIA_TYPE_VIDEO,
450  .request_frame = request_frame,
451  .config_props = config_props,
452  },
453  { NULL}
454 };
455 
457  .name = "life",
458  .description = NULL_IF_CONFIG_SMALL("Create life."),
459  .priv_size = sizeof(LifeContext),
460  .init = init,
461  .uninit = uninit,
463  .inputs = NULL,
464  .outputs = life_outputs,
465  .priv_class = &life_class,
466 };
Definition: lfg.h:25
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
float v
uint32_t random_seed
Definition: vsrc_life.c:65
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
uint16_t stay_rule
encode the behavior for filled cells
Definition: vsrc_life.c:60
#define c2
Definition: idct_sh4.c:27
AVOption.
Definition: opt.h:251
static const AVFilterPad outputs[]
Definition: af_ashowinfo.c:117
external API header
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:70
static const AVFilterPad life_outputs[]
Definition: vsrc_life.c:446
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
int num
numerator
Definition: rational.h:44
static void fill_picture_monoblack(AVFilterContext *ctx, AVFrame *picref)
Definition: vsrc_life.c:361
static int request_frame(AVFilterLink *outlink)
Definition: vsrc_life.c:413
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
static void fill_picture_rgb(AVFilterContext *ctx, AVFrame *picref)
Definition: vsrc_life.c:386
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:143
output residual component w
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:308
AVLFG lfg
Definition: vsrc_life.c:74
const char * name
Pad name.
struct cell_s cell
In the ELBG jargon, a cell is the set of points that are closest to a codebook entry.
uint8_t
it can be given away to ff_start_frame *A reference passed to ff_filter_frame(or the deprecated ff_start_frame) is given away and must no longer be used.*A reference created with avfilter_ref_buffer belongs to the code that created it.*A reference obtained with ff_get_video_buffer or ff_get_audio_buffer belongs to the code that requested it.*A reference given as return value by the get_video_buffer or get_audio_buffer method is given away and must no longer be used.Link reference fields---------------------The AVFilterLink structure has a few AVFilterBufferRef fields.The cur_buf and out_buf were used with the deprecated start_frame/draw_slice/end_frame API and should no longer be used.src_buf
#define av_cold
Definition: attributes.h:78
AVOptions.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:159
static int query_formats(AVFilterContext *ctx)
Definition: vsrc_life.c:430
#define N
Definition: vf_pp7.c:200
uint8_t death_color[4]
Definition: vsrc_life.c:72
Misc file utilities.
char * rule_str
Definition: vsrc_life.c:44
char * life_color_str
Definition: vsrc_life.c:68
void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:545
A filter pad used for either input or output.
void av_file_unmap(uint8_t *bufptr, size_t size)
Unmap or free the buffer bufptr created by av_file_map().
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, int log_offset, void *log_ctx)
Read the file with name filename, and put its content in a newly allocated buffer or map it with mmap...
static int config_props(AVFilterLink *outlink)
Definition: vsrc_life.c:295
#define S(s, c, i)
static av_cold void uninit(AVFilterContext *ctx)
Definition: vsrc_life.c:285
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
const char * r
Definition: vf_curves.c:94
void * priv
private data for use by the filter
Definition: avfilter.h:545
Definition: graph2dot.c:48
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
#define FAST_DIV255(x)
Definition: vsrc_life.c:384
static int init(AVFilterContext *ctx)
Definition: vsrc_life.c:223
static void evolve(AVFilterContext *ctx)
Definition: vsrc_life.c:306
int stitch
Definition: vsrc_life.c:66
#define FFMAX(a, b)
Definition: common.h:56
uint8_t buf_idx
Definition: vsrc_life.c:59
#define PARSE_COLOR(name)
#define OFFSET(x)
Definition: vsrc_life.c:79
#define AV_LOG_VERBOSE
Definition: log.h:157
struct AVRational AVRational
rational number numerator/denominator
#define FFMIN(a, b)
Definition: common.h:58
uint8_t * file_buf
Definition: vsrc_life.c:45
ret
Definition: avfilter.c:821
AVFILTER_DEFINE_CLASS(life)
uint8_t life_color[4]
Definition: vsrc_life.c:71
#define FLAGS
Definition: vsrc_life.c:80
char * death_color_str
Definition: vsrc_life.c:69
#define AV_WB24(p, d)
Definition: intreadwrite.h:442
AVFilter avfilter_vsrc_life
Definition: vsrc_life.c:456
static int init_pattern_from_file(AVFilterContext *ctx)
Definition: vsrc_life.c:165
#define E
#define ALIVE_CELL
Definition: vsrc_life.c:78
for k
NULL
Definition: eval.c:55
double random_fill_ratio
Definition: vsrc_life.c:64
typedef void(RENAME(mix_any_func_type))
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
void(* draw)(AVFilterContext *, AVFrame *)
Definition: vsrc_life.c:75
uint16_t born_rule
encode the behavior for empty cells
Definition: vsrc_life.c:61
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:154
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition: lfg.h:38
void * buf
Definition: avisynth_c.h:594
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
Describe the class of an AVClass context structure.
Definition: log.h:50
Filter definition.
Definition: avfilter.h:436
synthesis window for stochastic i
rational number numerator/denominator
Definition: rational.h:43
#define M_PHI
Definition: mathematics.h:43
offset must point to AVRational
Definition: opt.h:233
char * mold_color_str
Definition: vsrc_life.c:70
const char * name
filter name
Definition: avfilter.h:437
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition: lfg.c:30
offset must point to two consecutive integers
Definition: opt.h:230
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
misc parsing utilities
uint64_t pts
Definition: vsrc_life.c:62
static int parse_rule(uint16_t *born_rule, uint16_t *stay_rule, const char *rule_str, void *log_ctx)
Definition: vsrc_life.c:104
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:122
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:78
int av_isgraph(int c)
Locale-independent conversion of ASCII isgraph.
Definition: avstring.c:293
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
static double c[64]
int den
denominator
Definition: rational.h:45
AVRational frame_rate
Definition: vsrc_life.c:63
static const AVOption life_options[]
Definition: vsrc_life.c:82
An instance of a filter.
Definition: avfilter.h:524
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
Definition: random_seed.c:105
size_t file_bufsize
Definition: vsrc_life.c:46
internal API functions
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:252
uint8_t mold_color[4]
Definition: vsrc_life.c:73
uint8_t * buf[2]
The two grid state buffers.
Definition: vsrc_life.c:57
#define c1
Definition: idct_sh4.c:26
normalize window W
Definition: stft_peak.m:10
char * filename
Definition: vsrc_life.c:43