Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
d4fd3f24
Commit
d4fd3f24
authored
Dec 04, 2014
by
Stefano Sabatini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavfi: add tblend filter
parent
05e74ac2
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
142 additions
and
49 deletions
+142
-49
Changelog
Changelog
+1
-0
filters.texi
doc/filters.texi
+18
-6
Makefile
libavfilter/Makefile
+1
-0
allfilters.c
libavfilter/allfilters.c
+1
-0
version.h
libavfilter/version.h
+2
-2
vf_blend.c
libavfilter/vf_blend.c
+119
-41
No files found.
Changelog
View file @
d4fd3f24
...
@@ -8,6 +8,7 @@ version <next>:
...
@@ -8,6 +8,7 @@ version <next>:
- RIFX format for *.wav files
- RIFX format for *.wav files
- RTP/mpegts muxer
- RTP/mpegts muxer
- non continuous cache protocol support
- non continuous cache protocol support
- tblend filter
version 2.5:
version 2.5:
...
...
doc/filters.texi
View file @
d4fd3f24
...
@@ -2634,13 +2634,17 @@ The threshold below which a pixel value is considered black; it defaults to
...
@@ -2634,13 +2634,17 @@ The threshold below which a pixel value is considered black; it defaults to
@end table
@end table
@section blend
@section blend
, tblend
Blend two video frames into each other.
Blend two video frames into each other.
It takes two input streams and outputs one stream, the first input is the
The @code{blend} filter takes two input streams and outputs one
"top" layer and second input is "bottom" layer.
stream, the first input is the "top" layer and second input is
Output terminates when shortest input terminates.
"bottom" layer. Output terminates when shortest input terminates.
The @code{tblend} (time blend) filter takes two consecutive frames
from one single stream, and outputs the result obtained by blending
the new frame on top of the old frame.
A description of the accepted options follows.
A description of the accepted options follows.
...
@@ -2730,11 +2734,13 @@ Value of pixel component at current location for second video frame (bottom laye
...
@@ -2730,11 +2734,13 @@ Value of pixel component at current location for second video frame (bottom laye
@end table
@end table
@item shortest
@item shortest
Force termination when the shortest input terminates. Default is @code{0}.
Force termination when the shortest input terminates. Default is
@code{0}. This option is only defined for the @code{blend} filter.
@item repeatlast
@item repeatlast
Continue applying the last bottom frame after the end of the stream. A value of
Continue applying the last bottom frame after the end of the stream. A value of
@code{0} disable the filter after the last frame of the bottom layer is reached.
@code{0} disable the filter after the last frame of the bottom layer is reached.
Default is @code{1}.
Default is @code{1}.
This option is only defined for the @code{blend} filter.
@end table
@end table
@subsection Examples
@subsection Examples
...
@@ -2769,6 +2775,12 @@ Apply uncover up-left effect:
...
@@ -2769,6 +2775,12 @@ Apply uncover up-left effect:
@example
@example
blend=all_expr='if(gte(T*SH*40+Y,H)*gte((T*40*SW+X)*W/H,W),A,B)'
blend=all_expr='if(gte(T*SH*40+Y,H)*gte((T*40*SW+X)*W/H,W),A,B)'
@end example
@end example
@item
Display differences between the current and the previous frame:
@example
tblend=all_mode=difference128
@end example
@end itemize
@end itemize
@section boxblur
@section boxblur
...
...
libavfilter/Makefile
View file @
d4fd3f24
...
@@ -188,6 +188,7 @@ OBJS-$(CONFIG_STEREO3D_FILTER) += vf_stereo3d.o
...
@@ -188,6 +188,7 @@ OBJS-$(CONFIG_STEREO3D_FILTER) += vf_stereo3d.o
OBJS-$(CONFIG_SUBTITLES_FILTER)
+=
vf_subtitles.o
OBJS-$(CONFIG_SUBTITLES_FILTER)
+=
vf_subtitles.o
OBJS-$(CONFIG_SUPER2XSAI_FILTER)
+=
vf_super2xsai.o
OBJS-$(CONFIG_SUPER2XSAI_FILTER)
+=
vf_super2xsai.o
OBJS-$(CONFIG_SWAPUV_FILTER)
+=
vf_swapuv.o
OBJS-$(CONFIG_SWAPUV_FILTER)
+=
vf_swapuv.o
OBJS-$(CONFIG_TBLEND_FILTER)
+=
vf_blend.o
OBJS-$(CONFIG_TELECINE_FILTER)
+=
vf_telecine.o
OBJS-$(CONFIG_TELECINE_FILTER)
+=
vf_telecine.o
OBJS-$(CONFIG_THUMBNAIL_FILTER)
+=
vf_thumbnail.o
OBJS-$(CONFIG_THUMBNAIL_FILTER)
+=
vf_thumbnail.o
OBJS-$(CONFIG_TILE_FILTER)
+=
vf_tile.o
OBJS-$(CONFIG_TILE_FILTER)
+=
vf_tile.o
...
...
libavfilter/allfilters.c
View file @
d4fd3f24
...
@@ -203,6 +203,7 @@ void avfilter_register_all(void)
...
@@ -203,6 +203,7 @@ void avfilter_register_all(void)
REGISTER_FILTER
(
SUBTITLES
,
subtitles
,
vf
);
REGISTER_FILTER
(
SUBTITLES
,
subtitles
,
vf
);
REGISTER_FILTER
(
SUPER2XSAI
,
super2xsai
,
vf
);
REGISTER_FILTER
(
SUPER2XSAI
,
super2xsai
,
vf
);
REGISTER_FILTER
(
SWAPUV
,
swapuv
,
vf
);
REGISTER_FILTER
(
SWAPUV
,
swapuv
,
vf
);
REGISTER_FILTER
(
TBLEND
,
tblend
,
vf
);
REGISTER_FILTER
(
TELECINE
,
telecine
,
vf
);
REGISTER_FILTER
(
TELECINE
,
telecine
,
vf
);
REGISTER_FILTER
(
THUMBNAIL
,
thumbnail
,
vf
);
REGISTER_FILTER
(
THUMBNAIL
,
thumbnail
,
vf
);
REGISTER_FILTER
(
TILE
,
tile
,
vf
);
REGISTER_FILTER
(
TILE
,
tile
,
vf
);
...
...
libavfilter/version.h
View file @
d4fd3f24
...
@@ -30,8 +30,8 @@
...
@@ -30,8 +30,8 @@
#include "libavutil/version.h"
#include "libavutil/version.h"
#define LIBAVFILTER_VERSION_MAJOR 5
#define LIBAVFILTER_VERSION_MAJOR 5
#define LIBAVFILTER_VERSION_MINOR
5
#define LIBAVFILTER_VERSION_MINOR
6
#define LIBAVFILTER_VERSION_MICRO 10
2
#define LIBAVFILTER_VERSION_MICRO 10
0
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \
LIBAVFILTER_VERSION_MINOR, \
...
...
libavfilter/vf_blend.c
View file @
d4fd3f24
...
@@ -96,52 +96,57 @@ typedef struct {
...
@@ -96,52 +96,57 @@ typedef struct {
double
all_opacity
;
double
all_opacity
;
FilterParams
params
[
4
];
FilterParams
params
[
4
];
int
tblend
;
AVFrame
*
prev_frame
;
/* only used with tblend */
}
BlendContext
;
}
BlendContext
;
#define COMMON_OPTIONS \
{ "c0_mode", "set component #0 blend mode", OFFSET(params[0].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},\
{ "c1_mode", "set component #1 blend mode", OFFSET(params[1].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},\
{ "c2_mode", "set component #2 blend mode", OFFSET(params[2].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},\
{ "c3_mode", "set component #3 blend mode", OFFSET(params[3].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},\
{ "all_mode", "set blend mode for all components", OFFSET(all_mode), AV_OPT_TYPE_INT, {.i64=-1},-1, BLEND_NB-1, FLAGS, "mode"},\
{ "addition", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_ADDITION}, 0, 0, FLAGS, "mode" },\
{ "and", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AND}, 0, 0, FLAGS, "mode" },\
{ "average", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AVERAGE}, 0, 0, FLAGS, "mode" },\
{ "burn", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_BURN}, 0, 0, FLAGS, "mode" },\
{ "darken", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DARKEN}, 0, 0, FLAGS, "mode" },\
{ "difference", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIFFERENCE}, 0, 0, FLAGS, "mode" },\
{ "difference128", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIFFERENCE128}, 0, 0, FLAGS, "mode" },\
{ "divide", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIVIDE}, 0, 0, FLAGS, "mode" },\
{ "dodge", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DODGE}, 0, 0, FLAGS, "mode" },\
{ "exclusion", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_EXCLUSION}, 0, 0, FLAGS, "mode" },\
{ "hardlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_HARDLIGHT}, 0, 0, FLAGS, "mode" },\
{ "lighten", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_LIGHTEN}, 0, 0, FLAGS, "mode" },\
{ "multiply", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_MULTIPLY}, 0, 0, FLAGS, "mode" },\
{ "negation", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_NEGATION}, 0, 0, FLAGS, "mode" },\
{ "normal", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_NORMAL}, 0, 0, FLAGS, "mode" },\
{ "or", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_OR}, 0, 0, FLAGS, "mode" },\
{ "overlay", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_OVERLAY}, 0, 0, FLAGS, "mode" },\
{ "phoenix", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_PHOENIX}, 0, 0, FLAGS, "mode" },\
{ "pinlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_PINLIGHT}, 0, 0, FLAGS, "mode" },\
{ "reflect", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_REFLECT}, 0, 0, FLAGS, "mode" },\
{ "screen", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SCREEN}, 0, 0, FLAGS, "mode" },\
{ "softlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SOFTLIGHT}, 0, 0, FLAGS, "mode" },\
{ "subtract", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SUBTRACT}, 0, 0, FLAGS, "mode" },\
{ "vividlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_VIVIDLIGHT}, 0, 0, FLAGS, "mode" },\
{ "xor", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_XOR}, 0, 0, FLAGS, "mode" },\
{ "c0_expr", "set color component #0 expression", OFFSET(params[0].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },\
{ "c1_expr", "set color component #1 expression", OFFSET(params[1].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },\
{ "c2_expr", "set color component #2 expression", OFFSET(params[2].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },\
{ "c3_expr", "set color component #3 expression", OFFSET(params[3].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },\
{ "all_expr", "set expression for all color components", OFFSET(all_expr), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },\
{ "c0_opacity", "set color component #0 opacity", OFFSET(params[0].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },\
{ "c1_opacity", "set color component #1 opacity", OFFSET(params[1].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },\
{ "c2_opacity", "set color component #2 opacity", OFFSET(params[2].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },\
{ "c3_opacity", "set color component #3 opacity", OFFSET(params[3].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },\
{ "all_opacity", "set opacity for all color components", OFFSET(all_opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}
#define OFFSET(x) offsetof(BlendContext, x)
#define OFFSET(x) offsetof(BlendContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
static
const
AVOption
blend_options
[]
=
{
static
const
AVOption
blend_options
[]
=
{
{
"c0_mode"
,
"set component #0 blend mode"
,
OFFSET
(
params
[
0
].
mode
),
AV_OPT_TYPE_INT
,
{.
i64
=
0
},
0
,
BLEND_NB
-
1
,
FLAGS
,
"mode"
},
COMMON_OPTIONS
,
{
"c1_mode"
,
"set component #1 blend mode"
,
OFFSET
(
params
[
1
].
mode
),
AV_OPT_TYPE_INT
,
{.
i64
=
0
},
0
,
BLEND_NB
-
1
,
FLAGS
,
"mode"
},
{
"c2_mode"
,
"set component #2 blend mode"
,
OFFSET
(
params
[
2
].
mode
),
AV_OPT_TYPE_INT
,
{.
i64
=
0
},
0
,
BLEND_NB
-
1
,
FLAGS
,
"mode"
},
{
"c3_mode"
,
"set component #3 blend mode"
,
OFFSET
(
params
[
3
].
mode
),
AV_OPT_TYPE_INT
,
{.
i64
=
0
},
0
,
BLEND_NB
-
1
,
FLAGS
,
"mode"
},
{
"all_mode"
,
"set blend mode for all components"
,
OFFSET
(
all_mode
),
AV_OPT_TYPE_INT
,
{.
i64
=-
1
},
-
1
,
BLEND_NB
-
1
,
FLAGS
,
"mode"
},
{
"addition"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_ADDITION
},
0
,
0
,
FLAGS
,
"mode"
},
{
"and"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_AND
},
0
,
0
,
FLAGS
,
"mode"
},
{
"average"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_AVERAGE
},
0
,
0
,
FLAGS
,
"mode"
},
{
"burn"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_BURN
},
0
,
0
,
FLAGS
,
"mode"
},
{
"darken"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_DARKEN
},
0
,
0
,
FLAGS
,
"mode"
},
{
"difference"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_DIFFERENCE
},
0
,
0
,
FLAGS
,
"mode"
},
{
"difference128"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_DIFFERENCE128
},
0
,
0
,
FLAGS
,
"mode"
},
{
"divide"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_DIVIDE
},
0
,
0
,
FLAGS
,
"mode"
},
{
"dodge"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_DODGE
},
0
,
0
,
FLAGS
,
"mode"
},
{
"exclusion"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_EXCLUSION
},
0
,
0
,
FLAGS
,
"mode"
},
{
"hardlight"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_HARDLIGHT
},
0
,
0
,
FLAGS
,
"mode"
},
{
"lighten"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_LIGHTEN
},
0
,
0
,
FLAGS
,
"mode"
},
{
"multiply"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_MULTIPLY
},
0
,
0
,
FLAGS
,
"mode"
},
{
"negation"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_NEGATION
},
0
,
0
,
FLAGS
,
"mode"
},
{
"normal"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_NORMAL
},
0
,
0
,
FLAGS
,
"mode"
},
{
"or"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_OR
},
0
,
0
,
FLAGS
,
"mode"
},
{
"overlay"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_OVERLAY
},
0
,
0
,
FLAGS
,
"mode"
},
{
"phoenix"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_PHOENIX
},
0
,
0
,
FLAGS
,
"mode"
},
{
"pinlight"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_PINLIGHT
},
0
,
0
,
FLAGS
,
"mode"
},
{
"reflect"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_REFLECT
},
0
,
0
,
FLAGS
,
"mode"
},
{
"screen"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_SCREEN
},
0
,
0
,
FLAGS
,
"mode"
},
{
"softlight"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_SOFTLIGHT
},
0
,
0
,
FLAGS
,
"mode"
},
{
"subtract"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_SUBTRACT
},
0
,
0
,
FLAGS
,
"mode"
},
{
"vividlight"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_VIVIDLIGHT
},
0
,
0
,
FLAGS
,
"mode"
},
{
"xor"
,
""
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
BLEND_XOR
},
0
,
0
,
FLAGS
,
"mode"
},
{
"c0_expr"
,
"set color component #0 expression"
,
OFFSET
(
params
[
0
].
expr_str
),
AV_OPT_TYPE_STRING
,
{.
str
=
NULL
},
CHAR_MIN
,
CHAR_MAX
,
FLAGS
},
{
"c1_expr"
,
"set color component #1 expression"
,
OFFSET
(
params
[
1
].
expr_str
),
AV_OPT_TYPE_STRING
,
{.
str
=
NULL
},
CHAR_MIN
,
CHAR_MAX
,
FLAGS
},
{
"c2_expr"
,
"set color component #2 expression"
,
OFFSET
(
params
[
2
].
expr_str
),
AV_OPT_TYPE_STRING
,
{.
str
=
NULL
},
CHAR_MIN
,
CHAR_MAX
,
FLAGS
},
{
"c3_expr"
,
"set color component #3 expression"
,
OFFSET
(
params
[
3
].
expr_str
),
AV_OPT_TYPE_STRING
,
{.
str
=
NULL
},
CHAR_MIN
,
CHAR_MAX
,
FLAGS
},
{
"all_expr"
,
"set expression for all color components"
,
OFFSET
(
all_expr
),
AV_OPT_TYPE_STRING
,
{.
str
=
NULL
},
CHAR_MIN
,
CHAR_MAX
,
FLAGS
},
{
"c0_opacity"
,
"set color component #0 opacity"
,
OFFSET
(
params
[
0
].
opacity
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
0
,
1
,
FLAGS
},
{
"c1_opacity"
,
"set color component #1 opacity"
,
OFFSET
(
params
[
1
].
opacity
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
0
,
1
,
FLAGS
},
{
"c2_opacity"
,
"set color component #2 opacity"
,
OFFSET
(
params
[
2
].
opacity
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
0
,
1
,
FLAGS
},
{
"c3_opacity"
,
"set color component #3 opacity"
,
OFFSET
(
params
[
3
].
opacity
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
0
,
1
,
FLAGS
},
{
"all_opacity"
,
"set opacity for all color components"
,
OFFSET
(
all_opacity
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
0
,
1
,
FLAGS
},
{
"shortest"
,
"force termination when the shortest input terminates"
,
OFFSET
(
dinput
.
shortest
),
AV_OPT_TYPE_INT
,
{.
i64
=
0
},
0
,
1
,
FLAGS
},
{
"shortest"
,
"force termination when the shortest input terminates"
,
OFFSET
(
dinput
.
shortest
),
AV_OPT_TYPE_INT
,
{.
i64
=
0
},
0
,
1
,
FLAGS
},
{
"repeatlast"
,
"repeat last bottom frame"
,
OFFSET
(
dinput
.
repeatlast
),
AV_OPT_TYPE_INT
,
{.
i64
=
1
},
0
,
1
,
FLAGS
},
{
"repeatlast"
,
"repeat last bottom frame"
,
OFFSET
(
dinput
.
repeatlast
),
AV_OPT_TYPE_INT
,
{.
i64
=
1
},
0
,
1
,
FLAGS
},
{
NULL
}
{
NULL
}
...
@@ -288,7 +293,8 @@ static AVFrame *blend_frame(AVFilterContext *ctx, AVFrame *top_buf,
...
@@ -288,7 +293,8 @@ static AVFrame *blend_frame(AVFilterContext *ctx, AVFrame *top_buf,
ctx
->
internal
->
execute
(
ctx
,
filter_slice
,
&
td
,
NULL
,
FFMIN
(
outh
,
ctx
->
graph
->
nb_threads
));
ctx
->
internal
->
execute
(
ctx
,
filter_slice
,
&
td
,
NULL
,
FFMIN
(
outh
,
ctx
->
graph
->
nb_threads
));
}
}
av_frame_free
(
&
top_buf
);
if
(
!
b
->
tblend
)
av_frame_free
(
&
top_buf
);
return
dst_buf
;
return
dst_buf
;
}
}
...
@@ -298,6 +304,8 @@ static av_cold int init(AVFilterContext *ctx)
...
@@ -298,6 +304,8 @@ static av_cold int init(AVFilterContext *ctx)
BlendContext
*
b
=
ctx
->
priv
;
BlendContext
*
b
=
ctx
->
priv
;
int
ret
,
plane
;
int
ret
,
plane
;
b
->
tblend
=
!
strcmp
(
ctx
->
filter
->
name
,
"tblend"
);
for
(
plane
=
0
;
plane
<
FF_ARRAY_ELEMS
(
b
->
params
);
plane
++
)
{
for
(
plane
=
0
;
plane
<
FF_ARRAY_ELEMS
(
b
->
params
);
plane
++
)
{
FilterParams
*
param
=
&
b
->
params
[
plane
];
FilterParams
*
param
=
&
b
->
params
[
plane
];
...
@@ -416,6 +424,8 @@ static av_cold void uninit(AVFilterContext *ctx)
...
@@ -416,6 +424,8 @@ static av_cold void uninit(AVFilterContext *ctx)
int
i
;
int
i
;
ff_dualinput_uninit
(
&
b
->
dinput
);
ff_dualinput_uninit
(
&
b
->
dinput
);
av_freep
(
&
b
->
prev_frame
);
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
b
->
params
);
i
++
)
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
b
->
params
);
i
++
)
av_expr_free
(
b
->
params
[
i
].
e
);
av_expr_free
(
b
->
params
[
i
].
e
);
}
}
...
@@ -467,3 +477,71 @@ AVFilter ff_vf_blend = {
...
@@ -467,3 +477,71 @@ AVFilter ff_vf_blend = {
.
priv_class
=
&
blend_class
,
.
priv_class
=
&
blend_class
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
|
AVFILTER_FLAG_SLICE_THREADS
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
|
AVFILTER_FLAG_SLICE_THREADS
,
};
};
static
int
tblend_config_output
(
AVFilterLink
*
outlink
)
{
AVFilterContext
*
ctx
=
outlink
->
src
;
AVFilterLink
*
inlink
=
ctx
->
inputs
[
0
];
BlendContext
*
b
=
ctx
->
priv
;
const
AVPixFmtDescriptor
*
pix_desc
=
av_pix_fmt_desc_get
(
inlink
->
format
);
b
->
hsub
=
pix_desc
->
log2_chroma_w
;
b
->
vsub
=
pix_desc
->
log2_chroma_h
;
b
->
nb_planes
=
av_pix_fmt_count_planes
(
inlink
->
format
);
outlink
->
flags
|=
FF_LINK_FLAG_REQUEST_LOOP
;
return
0
;
}
static
int
tblend_filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
frame
)
{
BlendContext
*
b
=
inlink
->
dst
->
priv
;
AVFilterLink
*
outlink
=
inlink
->
dst
->
outputs
[
0
];
if
(
b
->
prev_frame
)
{
AVFrame
*
out
=
blend_frame
(
inlink
->
dst
,
frame
,
b
->
prev_frame
);
av_frame_free
(
&
b
->
prev_frame
);
b
->
prev_frame
=
frame
;
return
ff_filter_frame
(
outlink
,
out
);
}
b
->
prev_frame
=
frame
;
return
0
;
}
static
const
AVOption
tblend_options
[]
=
{
COMMON_OPTIONS
,
{
NULL
}
};
AVFILTER_DEFINE_CLASS
(
tblend
);
static
const
AVFilterPad
tblend_inputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
filter_frame
=
tblend_filter_frame
,
},
{
NULL
}
};
static
const
AVFilterPad
tblend_outputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
config_props
=
tblend_config_output
,
},
{
NULL
}
};
AVFilter
ff_vf_tblend
=
{
.
name
=
"tblend"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Blend successive frames."
),
.
priv_size
=
sizeof
(
BlendContext
),
.
priv_class
=
&
blend_class
,
.
query_formats
=
query_formats
,
.
init
=
init
,
.
uninit
=
uninit
,
.
inputs
=
tblend_inputs
,
.
outputs
=
tblend_outputs
,
.
flags
=
AVFILTER_FLAG_SLICE_THREADS
,
};
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