Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
cc235581
Commit
cc235581
authored
Dec 09, 2011
by
Clément Bœsch
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
life: add mold, mold_color, life_color and death_color options.
parent
c88d6b18
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
126 additions
and
21 deletions
+126
-21
filters.texi
doc/filters.texi
+20
-0
vsrc_life.c
libavfilter/vsrc_life.c
+106
-21
No files found.
doc/filters.texi
View file @
cc235581
...
@@ -2978,6 +2978,21 @@ If a filename is not specified, the size value defaults to "320x240"
...
@@ -2978,6 +2978,21 @@ If a filename is not specified, the size value defaults to "320x240"
@item stitch
@item stitch
If set to 1, stitch the left and right grid edges together, and the
If set to 1, stitch the left and right grid edges together, and the
top and bottom edges also. Defaults to 1.
top and bottom edges also. Defaults to 1.
@item mold
Set cell mold speed. If set, a dead cell will go from @option{death_color} to
@option{mold_color} with a step of @option{mold}. @option{mold} can have a
value from 0 to 255.
@item life_color
Set the color of living (or new born) cells.
@item death_color
Set the color of dead cells. If @option{mold} is set, this is the first color
used to represent a dead cell.
@item mold_color
Set mold color, for definitely dead and moldy cells.
@end table
@end table
@subsection Examples
@subsection Examples
...
@@ -3002,6 +3017,11 @@ Specify a custom rule for evolving a randomly generated grid:
...
@@ -3002,6 +3017,11 @@ Specify a custom rule for evolving a randomly generated grid:
life=rule=S14/B34
life=rule=S14/B34
@end example
@end example
@item
Full example with slow death effect (mold) using @command{ffplay}:
@example
ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_color=#00ff00,scale=1200:800:flags=16
@end example
@end itemize
@end itemize
@section nullsrc, rgbtestsrc, testsrc
@section nullsrc, rgbtestsrc, testsrc
...
...
libavfilter/vsrc_life.c
View file @
cc235581
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
/* #define DEBUG */
/* #define DEBUG */
#include "libavutil/file.h"
#include "libavutil/file.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/lfg.h"
#include "libavutil/lfg.h"
#include "libavutil/opt.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
#include "libavutil/parseutils.h"
...
@@ -39,7 +40,18 @@ typedef struct {
...
@@ -39,7 +40,18 @@ typedef struct {
char
*
rule_str
;
char
*
rule_str
;
uint8_t
*
file_buf
;
uint8_t
*
file_buf
;
size_t
file_bufsize
;
size_t
file_bufsize
;
char
*
buf
[
2
];
/**
* The two grid state buffers.
*
* A 0xFF (ALIVE_CELL) value means the cell is alive (or new born), while
* the decreasing values from 0xFE to 0 means the cell is dead; the range
* of values is used for the slow death effect, or mold (0xFE means dead,
* 0xFD means very dead, 0xFC means very very dead... and 0x00 means
* definitely dead/mold).
*/
uint8_t
*
buf
[
2
];
uint8_t
buf_idx
;
uint8_t
buf_idx
;
uint16_t
stay_rule
;
///< encode the behavior for filled cells
uint16_t
stay_rule
;
///< encode the behavior for filled cells
uint16_t
born_rule
;
///< encode the behavior for empty cells
uint16_t
born_rule
;
///< encode the behavior for empty cells
...
@@ -50,9 +62,18 @@ typedef struct {
...
@@ -50,9 +62,18 @@ typedef struct {
double
random_fill_ratio
;
double
random_fill_ratio
;
uint32_t
random_seed
;
uint32_t
random_seed
;
int
stitch
;
int
stitch
;
int
mold
;
char
*
life_color_str
;
char
*
death_color_str
;
char
*
mold_color_str
;
uint8_t
life_color
[
4
];
uint8_t
death_color
[
4
];
uint8_t
mold_color
[
4
];
AVLFG
lfg
;
AVLFG
lfg
;
void
(
*
draw
)(
AVFilterContext
*
,
AVFilterBufferRef
*
);
}
LifeContext
;
}
LifeContext
;
#define ALIVE_CELL 0xFF
#define OFFSET(x) offsetof(LifeContext, x)
#define OFFSET(x) offsetof(LifeContext, x)
static
const
AVOption
life_options
[]
=
{
static
const
AVOption
life_options
[]
=
{
...
@@ -68,6 +89,10 @@ static const AVOption life_options[] = {
...
@@ -68,6 +89,10 @@ static const AVOption life_options[] = {
{
"random_seed"
,
"set the seed for filling the initial grid randomly"
,
OFFSET
(
random_seed
),
AV_OPT_TYPE_INT
,
{.
dbl
=-
1
},
-
1
,
UINT32_MAX
},
{
"random_seed"
,
"set the seed for filling the initial grid randomly"
,
OFFSET
(
random_seed
),
AV_OPT_TYPE_INT
,
{.
dbl
=-
1
},
-
1
,
UINT32_MAX
},
{
"seed"
,
"set the seed for filling the initial grid randomly"
,
OFFSET
(
random_seed
),
AV_OPT_TYPE_INT
,
{.
dbl
=-
1
},
-
1
,
UINT32_MAX
},
{
"seed"
,
"set the seed for filling the initial grid randomly"
,
OFFSET
(
random_seed
),
AV_OPT_TYPE_INT
,
{.
dbl
=-
1
},
-
1
,
UINT32_MAX
},
{
"stitch"
,
"stitch boundaries"
,
OFFSET
(
stitch
),
AV_OPT_TYPE_INT
,
{.
dbl
=
1
},
0
,
1
},
{
"stitch"
,
"stitch boundaries"
,
OFFSET
(
stitch
),
AV_OPT_TYPE_INT
,
{.
dbl
=
1
},
0
,
1
},
{
"mold"
,
"set mold speed for dead cells"
,
OFFSET
(
mold
),
AV_OPT_TYPE_INT
,
{.
dbl
=
0
},
0
,
0xFF
},
{
"life_color"
,
"set life color"
,
OFFSET
(
life_color_str
),
AV_OPT_TYPE_STRING
,
{.
str
=
"white"
},
CHAR_MIN
,
CHAR_MAX
},
{
"death_color"
,
"set death color"
,
OFFSET
(
death_color_str
),
AV_OPT_TYPE_STRING
,
{.
str
=
"black"
},
CHAR_MIN
,
CHAR_MAX
},
{
"mold_color"
,
"set mold color"
,
OFFSET
(
mold_color_str
),
AV_OPT_TYPE_STRING
,
{.
str
=
"black"
},
CHAR_MIN
,
CHAR_MAX
},
{
NULL
},
{
NULL
},
};
};
...
@@ -135,7 +160,7 @@ static void show_life_grid(AVFilterContext *ctx)
...
@@ -135,7 +160,7 @@ static void show_life_grid(AVFilterContext *ctx)
return
;
return
;
for
(
i
=
0
;
i
<
life
->
h
;
i
++
)
{
for
(
i
=
0
;
i
<
life
->
h
;
i
++
)
{
for
(
j
=
0
;
j
<
life
->
w
;
j
++
)
for
(
j
=
0
;
j
<
life
->
w
;
j
++
)
line
[
j
]
=
life
->
buf
[
life
->
buf_idx
][
i
*
life
->
w
+
j
]
?
'@'
:
' '
;
line
[
j
]
=
life
->
buf
[
life
->
buf_idx
][
i
*
life
->
w
+
j
]
==
ALIVE_CELL
?
'@'
:
' '
;
line
[
j
]
=
0
;
line
[
j
]
=
0
;
av_log
(
ctx
,
AV_LOG_DEBUG
,
"%3d: %s
\n
"
,
i
,
line
);
av_log
(
ctx
,
AV_LOG_DEBUG
,
"%3d: %s
\n
"
,
i
,
line
);
}
}
...
@@ -192,7 +217,7 @@ static int init_pattern_from_file(AVFilterContext *ctx)
...
@@ -192,7 +217,7 @@ static int init_pattern_from_file(AVFilterContext *ctx)
if
(
*
p
==
'\n'
)
{
if
(
*
p
==
'\n'
)
{
p
++
;
break
;
p
++
;
break
;
}
else
}
else
life
->
buf
[
0
][
i
*
life
->
w
+
j
]
=
!!
isgraph
(
*
(
p
++
))
;
life
->
buf
[
0
][
i
*
life
->
w
+
j
]
=
isgraph
(
*
(
p
++
))
?
ALIVE_CELL
:
0
;
}
}
}
}
life
->
buf_idx
=
0
;
life
->
buf_idx
=
0
;
...
@@ -231,6 +256,22 @@ static int init(AVFilterContext *ctx, const char *args, void *opaque)
...
@@ -231,6 +256,22 @@ static int init(AVFilterContext *ctx, const char *args, void *opaque)
if
((
ret
=
parse_rule
(
&
life
->
born_rule
,
&
life
->
stay_rule
,
life
->
rule_str
,
ctx
))
<
0
)
if
((
ret
=
parse_rule
(
&
life
->
born_rule
,
&
life
->
stay_rule
,
life
->
rule_str
,
ctx
))
<
0
)
return
ret
;
return
ret
;
#define PARSE_COLOR(name) do { \
if ((ret = av_parse_color(life->name ## _color, life->name ## _color_str, -1, ctx))) { \
av_log(ctx, AV_LOG_ERROR, "Invalid " #name " color '%s'\n", \
life->name ## _color_str); \
return ret; \
} \
} while (0)
PARSE_COLOR
(
life
);
PARSE_COLOR
(
death
);
PARSE_COLOR
(
mold
);
if
(
!
life
->
mold
&&
memcmp
(
life
->
mold_color
,
"
\x00\x00\x00
"
,
3
))
av_log
(
ctx
,
AV_LOG_WARNING
,
"Mold color is set while mold isn't, ignoring the color.
\n
"
);
life
->
time_base
.
num
=
frame_rate
.
den
;
life
->
time_base
.
num
=
frame_rate
.
den
;
life
->
time_base
.
den
=
frame_rate
.
num
;
life
->
time_base
.
den
=
frame_rate
.
num
;
...
@@ -252,7 +293,7 @@ static int init(AVFilterContext *ctx, const char *args, void *opaque)
...
@@ -252,7 +293,7 @@ static int init(AVFilterContext *ctx, const char *args, void *opaque)
for
(
i
=
0
;
i
<
life
->
w
*
life
->
h
;
i
++
)
{
for
(
i
=
0
;
i
<
life
->
w
*
life
->
h
;
i
++
)
{
double
r
=
(
double
)
av_lfg_get
(
&
life
->
lfg
)
/
UINT32_MAX
;
double
r
=
(
double
)
av_lfg_get
(
&
life
->
lfg
)
/
UINT32_MAX
;
if
(
r
<=
life
->
random_fill_ratio
)
if
(
r
<=
life
->
random_fill_ratio
)
life
->
buf
[
0
][
i
]
=
1
;
life
->
buf
[
0
][
i
]
=
ALIVE_CELL
;
}
}
life
->
buf_idx
=
0
;
life
->
buf_idx
=
0
;
}
else
{
}
else
{
...
@@ -292,7 +333,7 @@ static int config_props(AVFilterLink *outlink)
...
@@ -292,7 +333,7 @@ static int config_props(AVFilterLink *outlink)
static
void
evolve
(
AVFilterContext
*
ctx
)
static
void
evolve
(
AVFilterContext
*
ctx
)
{
{
LifeContext
*
life
=
ctx
->
priv
;
LifeContext
*
life
=
ctx
->
priv
;
int
i
,
j
,
v
;
int
i
,
j
;
uint8_t
*
oldbuf
=
life
->
buf
[
life
->
buf_idx
];
uint8_t
*
oldbuf
=
life
->
buf
[
life
->
buf_idx
];
uint8_t
*
newbuf
=
life
->
buf
[
!
life
->
buf_idx
];
uint8_t
*
newbuf
=
life
->
buf
[
!
life
->
buf_idx
];
...
@@ -301,7 +342,7 @@ static void evolve(AVFilterContext *ctx)
...
@@ -301,7 +342,7 @@ static void evolve(AVFilterContext *ctx)
/* evolve the grid */
/* evolve the grid */
for
(
i
=
0
;
i
<
life
->
h
;
i
++
)
{
for
(
i
=
0
;
i
<
life
->
h
;
i
++
)
{
for
(
j
=
0
;
j
<
life
->
w
;
j
++
)
{
for
(
j
=
0
;
j
<
life
->
w
;
j
++
)
{
int
pos
[
8
][
2
],
n
;
int
pos
[
8
][
2
],
n
,
alive
,
cell
;
if
(
life
->
stitch
)
{
if
(
life
->
stitch
)
{
pos
[
NW
][
0
]
=
(
i
-
1
)
<
0
?
life
->
h
-
1
:
i
-
1
;
pos
[
NW
][
1
]
=
(
j
-
1
)
<
0
?
life
->
w
-
1
:
j
-
1
;
pos
[
NW
][
0
]
=
(
i
-
1
)
<
0
?
life
->
h
-
1
:
i
-
1
;
pos
[
NW
][
1
]
=
(
j
-
1
)
<
0
?
life
->
w
-
1
:
j
-
1
;
pos
[
N
][
0
]
=
(
i
-
1
)
<
0
?
life
->
h
-
1
:
i
-
1
;
pos
[
N
][
1
]
=
j
;
pos
[
N
][
0
]
=
(
i
-
1
)
<
0
?
life
->
h
-
1
:
i
-
1
;
pos
[
N
][
1
]
=
j
;
...
@@ -323,24 +364,28 @@ static void evolve(AVFilterContext *ctx)
...
@@ -323,24 +364,28 @@ static void evolve(AVFilterContext *ctx)
}
}
/* compute the number of live neighbor cells */
/* 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
]])
+
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
]])
+
(
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
]])
+
(
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
]])
+
(
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
]])
+
(
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
]])
+
(
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
]])
+
(
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
]]);
(
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
]
?
life
->
stay_rule
:
life
->
born_rule
));
cell
=
oldbuf
[
i
*
life
->
w
+
j
];
av_dlog
(
ctx
,
"i:%d j:%d live_neighbors:%d cell:%d -> cell:%d
\n
"
,
i
,
j
,
n
,
oldbuf
[
i
*
life
->
w
+
j
],
v
);
alive
=
1
<<
n
&
(
cell
==
ALIVE_CELL
?
life
->
stay_rule
:
life
->
born_rule
);
newbuf
[
i
*
life
->
w
+
j
]
=
v
;
if
(
alive
)
*
newbuf
=
ALIVE_CELL
;
// new cell is alive
else
if
(
cell
)
*
newbuf
=
cell
-
1
;
// new cell is dead and in the process of mold
else
*
newbuf
=
0
;
// new cell is definitely dead
av_dlog
(
ctx
,
"i:%d j:%d live_neighbors:%d cell:%d -> cell:%d
\n
"
,
i
,
j
,
n
,
cell
,
*
newbuf
);
newbuf
++
;
}
}
}
}
life
->
buf_idx
=
!
life
->
buf_idx
;
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
;
LifeContext
*
life
=
ctx
->
priv
;
uint8_t
*
buf
=
life
->
buf
[
life
->
buf_idx
];
uint8_t
*
buf
=
life
->
buf
[
life
->
buf_idx
];
...
@@ -351,7 +396,7 @@ static void fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
...
@@ -351,7 +396,7 @@ static void fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
uint8_t
byte
=
0
;
uint8_t
byte
=
0
;
uint8_t
*
p
=
picref
->
data
[
0
]
+
i
*
picref
->
linesize
[
0
];
uint8_t
*
p
=
picref
->
data
[
0
]
+
i
*
picref
->
linesize
[
0
];
for
(
k
=
0
,
j
=
0
;
j
<
life
->
w
;
j
++
)
{
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
)
{
if
(
k
==
8
||
j
==
life
->
w
-
1
)
{
k
=
0
;
k
=
0
;
*
p
++
=
byte
;
*
p
++
=
byte
;
...
@@ -361,6 +406,37 @@ static void fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
...
@@ -361,6 +406,37 @@ static void fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
}
}
}
}
// divide by 255 and round to nearest
// apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
#define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
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
];
if
(
life
->
mold
&&
v
!=
ALIVE_CELL
)
{
const
uint8_t
*
c1
=
life
->
mold_color
;
const
uint8_t
*
c2
=
life
->
death_color
;
int
death_age
=
FFMIN
((
0xff
-
v
)
*
life
->
mold
,
0xff
);
*
p
++
=
FAST_DIV255
((
c2
[
0
]
<<
8
)
+
((
int
)
c1
[
0
]
-
(
int
)
c2
[
0
])
*
death_age
);
*
p
++
=
FAST_DIV255
((
c2
[
1
]
<<
8
)
+
((
int
)
c1
[
1
]
-
(
int
)
c2
[
1
])
*
death_age
);
*
p
++
=
FAST_DIV255
((
c2
[
2
]
<<
8
)
+
((
int
)
c1
[
2
]
-
(
int
)
c2
[
2
])
*
death_age
);
}
else
{
const
uint8_t
*
c
=
v
==
ALIVE_CELL
?
life
->
life_color
:
life
->
death_color
;
AV_WB24
(
p
,
c
[
0
]
<<
16
|
c
[
1
]
<<
8
|
c
[
2
]);
p
+=
3
;
}
}
}
}
static
int
request_frame
(
AVFilterLink
*
outlink
)
static
int
request_frame
(
AVFilterLink
*
outlink
)
{
{
LifeContext
*
life
=
outlink
->
src
->
priv
;
LifeContext
*
life
=
outlink
->
src
->
priv
;
...
@@ -369,7 +445,7 @@ static int request_frame(AVFilterLink *outlink)
...
@@ -369,7 +445,7 @@ static int request_frame(AVFilterLink *outlink)
picref
->
pts
=
life
->
pts
++
;
picref
->
pts
=
life
->
pts
++
;
picref
->
pos
=
-
1
;
picref
->
pos
=
-
1
;
fill_picture
(
outlink
->
src
,
picref
);
life
->
draw
(
outlink
->
src
,
picref
);
evolve
(
outlink
->
src
);
evolve
(
outlink
->
src
);
#ifdef DEBUG
#ifdef DEBUG
show_life_grid
(
outlink
->
src
);
show_life_grid
(
outlink
->
src
);
...
@@ -385,7 +461,16 @@ static int request_frame(AVFilterLink *outlink)
...
@@ -385,7 +461,16 @@ static int request_frame(AVFilterLink *outlink)
static
int
query_formats
(
AVFilterContext
*
ctx
)
static
int
query_formats
(
AVFilterContext
*
ctx
)
{
{
static
const
enum
PixelFormat
pix_fmts
[]
=
{
PIX_FMT_MONOBLACK
,
PIX_FMT_NONE
};
LifeContext
*
life
=
ctx
->
priv
;
enum
PixelFormat
pix_fmts
[]
=
{
PIX_FMT_NONE
,
PIX_FMT_NONE
};
if
(
life
->
mold
||
memcmp
(
life
->
life_color
,
"
\xff\xff\xff
"
,
3
)
||
memcmp
(
life
->
death_color
,
"
\x00\x00\x00
"
,
3
))
{
pix_fmts
[
0
]
=
PIX_FMT_RGB24
;
life
->
draw
=
fill_picture_rgb
;
}
else
{
pix_fmts
[
0
]
=
PIX_FMT_MONOBLACK
;
life
->
draw
=
fill_picture_monoblack
;
}
avfilter_set_common_pixel_formats
(
ctx
,
avfilter_make_format_list
(
pix_fmts
));
avfilter_set_common_pixel_formats
(
ctx
,
avfilter_make_format_list
(
pix_fmts
));
return
0
;
return
0
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment