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
2c2e69b3
Commit
2c2e69b3
authored
May 24, 2013
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavfi/blend: support slice threading
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
e0f2e0fc
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
53 additions
and
26 deletions
+53
-26
vf_blend.c
libavfilter/vf_blend.c
+53
-26
No files found.
libavfilter/vf_blend.c
View file @
2c2e69b3
...
...
@@ -65,16 +65,24 @@ enum { VAR_X, VAR_Y, VAR_W, VAR_H, VAR_SW, VAR
typedef
struct
FilterParams
{
enum
BlendMode
mode
;
double
values
[
VAR_VARS_NB
];
double
opacity
;
AVExpr
*
e
;
char
*
expr_str
;
void
(
*
blend
)(
const
uint8_t
*
top
,
int
top_linesize
,
const
uint8_t
*
bottom
,
int
bottom_linesize
,
uint8_t
*
dst
,
int
dst_linesize
,
int
width
,
int
height
,
struct
FilterParams
*
param
);
int
width
,
int
start
,
int
end
,
struct
FilterParams
*
param
,
double
*
values
);
}
FilterParams
;
typedef
struct
ThreadData
{
AVFrame
*
top
,
*
bottom
,
*
dst
;
AVFilterLink
*
inlink
;
int
plane
;
int
w
,
h
;
FilterParams
*
param
;
}
ThreadData
;
typedef
struct
{
const
AVClass
*
class
;
struct
FFBufQueue
queue_top
;
...
...
@@ -140,21 +148,23 @@ AVFILTER_DEFINE_CLASS(blend);
static
void
blend_normal
(
const
uint8_t
*
top
,
int
top_linesize
,
const
uint8_t
*
bottom
,
int
bottom_linesize
,
uint8_t
*
dst
,
int
dst_linesize
,
int
width
,
int
height
,
FilterParams
*
param
)
int
width
,
int
start
,
int
end
,
FilterParams
*
param
,
double
*
values
)
{
av_image_copy_plane
(
dst
,
dst_linesize
,
top
,
top_linesize
,
width
,
heigh
t
);
av_image_copy_plane
(
dst
,
dst_linesize
,
top
,
top_linesize
,
width
,
end
-
star
t
);
}
#define DEFINE_BLEND(name, expr) \
static void blend_## name(const uint8_t *top, int top_linesize, \
const uint8_t *bottom, int bottom_linesize, \
uint8_t *dst, int dst_linesize, \
int width, int height, FilterParams *param) \
int width, int start, int end, \
FilterParams *param, double *values) \
{ \
double opacity = param->opacity; \
int i, j; \
\
for (i =
0; i < height; i++) {
\
for (i =
start; i < end; i++) {
\
for (j = 0; j < width; j++) { \
dst[j] = top[j] + ((expr) - top[j]) * opacity; \
} \
...
...
@@ -199,14 +209,13 @@ DEFINE_BLEND(vividlight, (B < 128) ? BURN(A, 2 * B) : DODGE(A, 2 * (B - 128)))
static
void
blend_expr
(
const
uint8_t
*
top
,
int
top_linesize
,
const
uint8_t
*
bottom
,
int
bottom_linesize
,
uint8_t
*
dst
,
int
dst_linesize
,
int
width
,
int
height
,
FilterParams
*
param
)
int
width
,
int
start
,
int
end
,
FilterParams
*
param
,
double
*
values
)
{
AVExpr
*
e
=
param
->
e
;
double
*
values
=
param
->
values
;
int
y
,
x
;
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
start
;
y
<
end
;
y
++
)
{
values
[
VAR_Y
]
=
y
;
for
(
x
=
0
;
x
<
width
;
x
++
)
{
values
[
VAR_X
]
=
x
;
...
...
@@ -359,6 +368,33 @@ static int request_frame(AVFilterLink *outlink)
return
0
;
}
static
int
filter_slice
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
ThreadData
*
td
=
arg
;
int
slice_start
=
(
td
->
h
*
jobnr
)
/
nb_jobs
;
int
slice_end
=
(
td
->
h
*
(
jobnr
+
1
))
/
nb_jobs
;
const
uint8_t
*
top
=
td
->
top
->
data
[
td
->
plane
];
const
uint8_t
*
bottom
=
td
->
bottom
->
data
[
td
->
plane
];
uint8_t
*
dst
=
td
->
dst
->
data
[
td
->
plane
];
double
values
[
VAR_VARS_NB
];
values
[
VAR_N
]
=
td
->
inlink
->
frame_count
;
values
[
VAR_T
]
=
td
->
dst
->
pts
==
AV_NOPTS_VALUE
?
NAN
:
td
->
dst
->
pts
*
av_q2d
(
td
->
inlink
->
time_base
);
values
[
VAR_W
]
=
td
->
w
;
values
[
VAR_H
]
=
td
->
h
;
values
[
VAR_SW
]
=
td
->
w
/
(
double
)
td
->
dst
->
width
;
values
[
VAR_SH
]
=
td
->
h
/
(
double
)
td
->
dst
->
height
;
td
->
param
->
blend
(
top
+
slice_start
*
td
->
top
->
linesize
[
td
->
plane
],
td
->
top
->
linesize
[
td
->
plane
],
bottom
+
slice_start
*
td
->
bottom
->
linesize
[
td
->
plane
],
td
->
bottom
->
linesize
[
td
->
plane
],
dst
+
slice_start
*
td
->
dst
->
linesize
[
td
->
plane
],
td
->
dst
->
linesize
[
td
->
plane
],
td
->
w
,
slice_start
,
slice_end
,
td
->
param
,
&
values
[
0
]);
return
0
;
}
static
void
blend_frame
(
AVFilterContext
*
ctx
,
AVFrame
*
top_buf
,
AVFrame
*
bottom_buf
,
...
...
@@ -366,7 +402,6 @@ static void blend_frame(AVFilterContext *ctx,
{
BlendContext
*
b
=
ctx
->
priv
;
AVFilterLink
*
inlink
=
ctx
->
inputs
[
0
];
FilterParams
*
param
;
int
plane
;
for
(
plane
=
0
;
plane
<
b
->
nb_planes
;
plane
++
)
{
...
...
@@ -374,20 +409,12 @@ static void blend_frame(AVFilterContext *ctx,
int
vsub
=
plane
==
1
||
plane
==
2
?
b
->
vsub
:
0
;
int
outw
=
FF_CEIL_RSHIFT
(
dst_buf
->
width
,
hsub
);
int
outh
=
FF_CEIL_RSHIFT
(
dst_buf
->
height
,
vsub
);
uint8_t
*
dst
=
dst_buf
->
data
[
plane
];
uint8_t
*
top
=
top_buf
->
data
[
plane
];
uint8_t
*
bottom
=
bottom_buf
->
data
[
plane
];
param
=
&
b
->
params
[
plane
];
param
->
values
[
VAR_N
]
=
inlink
->
frame_count
;
param
->
values
[
VAR_T
]
=
dst_buf
->
pts
==
AV_NOPTS_VALUE
?
NAN
:
dst_buf
->
pts
*
av_q2d
(
inlink
->
time_base
);
param
->
values
[
VAR_W
]
=
outw
;
param
->
values
[
VAR_H
]
=
outh
;
param
->
values
[
VAR_SW
]
=
outw
/
(
double
)
dst_buf
->
width
;
param
->
values
[
VAR_SH
]
=
outh
/
(
double
)
dst_buf
->
height
;
param
->
blend
(
top
,
top_buf
->
linesize
[
plane
],
bottom
,
bottom_buf
->
linesize
[
plane
],
dst
,
dst_buf
->
linesize
[
plane
],
outw
,
outh
,
param
);
FilterParams
*
param
=
&
b
->
params
[
plane
];
ThreadData
td
=
{
.
top
=
top_buf
,
.
bottom
=
bottom_buf
,
.
dst
=
dst_buf
,
.
w
=
outw
,
.
h
=
outh
,
.
param
=
param
,
.
plane
=
plane
,
.
inlink
=
inlink
};
ctx
->
internal
->
execute
(
ctx
,
filter_slice
,
&
td
,
NULL
,
FFMIN
(
outh
,
ctx
->
graph
->
nb_threads
));
}
}
...
...
@@ -465,5 +492,5 @@ AVFilter avfilter_vf_blend = {
.
inputs
=
blend_inputs
,
.
outputs
=
blend_outputs
,
.
priv_class
=
&
blend_class
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
|
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