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
a50ca6b3
Commit
a50ca6b3
authored
Sep 12, 2016
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/vf_convolution: add slice threading support
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
afeffd89
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
158 additions
and
63 deletions
+158
-63
vf_convolution.c
libavfilter/vf_convolution.c
+158
-63
No files found.
libavfilter/vf_convolution.c
View file @
a50ca6b3
...
@@ -40,16 +40,19 @@ typedef struct ConvolutionContext {
...
@@ -40,16 +40,19 @@ typedef struct ConvolutionContext {
int
size
[
4
];
int
size
[
4
];
int
depth
;
int
depth
;
int
bpc
;
int
bstride
;
int
bstride
;
uint8_t
*
buffer
;
uint8_t
*
buffer
;
uint8_t
**
bptrs
;
int
nb_planes
;
int
nb_planes
;
int
nb_threads
;
int
planewidth
[
4
];
int
planewidth
[
4
];
int
planeheight
[
4
];
int
planeheight
[
4
];
int
matrix
[
4
][
25
];
int
matrix
[
4
][
25
];
int
matrix_length
[
4
];
int
matrix_length
[
4
];
int
copy
[
4
];
int
copy
[
4
];
void
(
*
filter
[
4
])(
struct
ConvolutionContext
*
s
,
AVFrame
*
in
,
AVFrame
*
out
,
int
plane
);
int
(
*
filter
[
4
])(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
);
}
ConvolutionContext
;
}
ConvolutionContext
;
#define OFFSET(x) offsetof(ConvolutionContext, x)
#define OFFSET(x) offsetof(ConvolutionContext, x)
...
@@ -133,27 +136,39 @@ static inline void line_copy16(uint16_t *line, const uint16_t *srcp, int width,
...
@@ -133,27 +136,39 @@ static inline void line_copy16(uint16_t *line, const uint16_t *srcp, int width,
}
}
}
}
static
void
filter16_prewitt
(
ConvolutionContext
*
s
,
AVFrame
*
in
,
AVFrame
*
out
,
int
plane
)
typedef
struct
ThreadData
{
AVFrame
*
in
,
*
out
;
int
plane
;
}
ThreadData
;
static
int
filter16_prewitt
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
{
const
uint16_t
*
src
=
(
const
uint16_t
*
)
in
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
uint16_t
*
dst
=
(
uint16_t
*
)
out
->
data
[
plane
];
ThreadData
*
td
=
arg
;
AVFrame
*
in
=
td
->
in
;
AVFrame
*
out
=
td
->
out
;
const
int
plane
=
td
->
plane
;
const
int
peak
=
(
1
<<
s
->
depth
)
-
1
;
const
int
peak
=
(
1
<<
s
->
depth
)
-
1
;
const
int
stride
=
in
->
linesize
[
plane
]
/
2
;
const
int
stride
=
in
->
linesize
[
plane
]
/
2
;
const
int
bstride
=
s
->
bstride
;
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
plane
];
const
int
height
=
s
->
planeheight
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
const
int
slice_start
=
(
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
height
*
(
jobnr
+
1
))
/
nb_jobs
;
const
uint16_t
*
src
=
(
const
uint16_t
*
)
in
->
data
[
plane
]
+
slice_start
*
stride
;
uint16_t
*
dst
=
(
uint16_t
*
)
out
->
data
[
plane
]
+
slice_start
*
(
out
->
linesize
[
plane
]
/
2
);
const
float
scale
=
s
->
scale
;
const
float
scale
=
s
->
scale
;
const
float
delta
=
s
->
delta
;
const
float
delta
=
s
->
delta
;
uint16_t
*
p0
=
(
uint16_t
*
)
s
->
b
uffer
+
16
;
uint16_t
*
p0
=
(
uint16_t
*
)
s
->
b
ptrs
[
jobnr
]
+
16
;
uint16_t
*
p1
=
p0
+
bstride
;
uint16_t
*
p1
=
p0
+
bstride
;
uint16_t
*
p2
=
p1
+
bstride
;
uint16_t
*
p2
=
p1
+
bstride
;
uint16_t
*
orig
=
p0
,
*
end
=
p2
;
uint16_t
*
orig
=
p0
,
*
end
=
p2
;
int
y
,
x
;
int
y
,
x
;
line_copy16
(
p0
,
src
+
stride
,
width
,
1
);
line_copy16
(
p0
,
src
+
stride
*
(
slice_start
==
0
?
1
:
-
1
)
,
width
,
1
);
line_copy16
(
p1
,
src
,
width
,
1
);
line_copy16
(
p1
,
src
,
width
,
1
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
line_copy16
(
p2
,
src
,
width
,
1
);
line_copy16
(
p2
,
src
,
width
,
1
);
...
@@ -179,29 +194,38 @@ static void filter16_prewitt(ConvolutionContext *s, AVFrame *in, AVFrame *out, i
...
@@ -179,29 +194,38 @@ static void filter16_prewitt(ConvolutionContext *s, AVFrame *in, AVFrame *out, i
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
dst
+=
out
->
linesize
[
plane
]
/
2
;
dst
+=
out
->
linesize
[
plane
]
/
2
;
}
}
return
0
;
}
}
static
void
filter16_sobel
(
ConvolutionContext
*
s
,
AVFrame
*
in
,
AVFrame
*
out
,
int
plane
)
static
int
filter16_sobel
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
{
const
uint16_t
*
src
=
(
const
uint16_t
*
)
in
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
uint16_t
*
dst
=
(
uint16_t
*
)
out
->
data
[
plane
];
ThreadData
*
td
=
arg
;
AVFrame
*
in
=
td
->
in
;
AVFrame
*
out
=
td
->
out
;
const
int
plane
=
td
->
plane
;
const
int
peak
=
(
1
<<
s
->
depth
)
-
1
;
const
int
peak
=
(
1
<<
s
->
depth
)
-
1
;
const
int
stride
=
in
->
linesize
[
plane
]
/
2
;
const
int
stride
=
in
->
linesize
[
plane
]
/
2
;
const
int
bstride
=
s
->
bstride
;
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
plane
];
const
int
height
=
s
->
planeheight
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
const
int
slice_start
=
(
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
height
*
(
jobnr
+
1
))
/
nb_jobs
;
const
uint16_t
*
src
=
(
const
uint16_t
*
)
in
->
data
[
plane
]
+
slice_start
*
stride
;
uint16_t
*
dst
=
(
uint16_t
*
)
out
->
data
[
plane
]
+
slice_start
*
(
out
->
linesize
[
plane
]
/
2
);
const
float
scale
=
s
->
scale
;
const
float
scale
=
s
->
scale
;
const
float
delta
=
s
->
delta
;
const
float
delta
=
s
->
delta
;
uint16_t
*
p0
=
(
uint16_t
*
)
s
->
b
uffer
+
16
;
uint16_t
*
p0
=
(
uint16_t
*
)
s
->
b
ptrs
[
jobnr
]
+
16
;
uint16_t
*
p1
=
p0
+
bstride
;
uint16_t
*
p1
=
p0
+
bstride
;
uint16_t
*
p2
=
p1
+
bstride
;
uint16_t
*
p2
=
p1
+
bstride
;
uint16_t
*
orig
=
p0
,
*
end
=
p2
;
uint16_t
*
orig
=
p0
,
*
end
=
p2
;
int
y
,
x
;
int
y
,
x
;
line_copy16
(
p0
,
src
+
stride
,
width
,
1
);
line_copy16
(
p0
,
src
+
stride
*
(
slice_start
==
0
?
1
:
-
1
)
,
width
,
1
);
line_copy16
(
p1
,
src
,
width
,
1
);
line_copy16
(
p1
,
src
,
width
,
1
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
line_copy16
(
p2
,
src
,
width
,
1
);
line_copy16
(
p2
,
src
,
width
,
1
);
...
@@ -227,28 +251,37 @@ static void filter16_sobel(ConvolutionContext *s, AVFrame *in, AVFrame *out, int
...
@@ -227,28 +251,37 @@ static void filter16_sobel(ConvolutionContext *s, AVFrame *in, AVFrame *out, int
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
dst
+=
out
->
linesize
[
plane
]
/
2
;
dst
+=
out
->
linesize
[
plane
]
/
2
;
}
}
return
0
;
}
}
static
void
filter_prewitt
(
ConvolutionContext
*
s
,
AVFrame
*
in
,
AVFrame
*
out
,
int
plane
)
static
int
filter_prewitt
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
{
const
uint8_t
*
src
=
in
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
uint8_t
*
dst
=
out
->
data
[
plane
];
ThreadData
*
td
=
arg
;
AVFrame
*
in
=
td
->
in
;
AVFrame
*
out
=
td
->
out
;
const
int
plane
=
td
->
plane
;
const
int
stride
=
in
->
linesize
[
plane
];
const
int
stride
=
in
->
linesize
[
plane
];
const
int
bstride
=
s
->
bstride
;
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
plane
];
const
int
height
=
s
->
planeheight
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
const
int
slice_start
=
(
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
height
*
(
jobnr
+
1
))
/
nb_jobs
;
const
uint8_t
*
src
=
in
->
data
[
plane
]
+
slice_start
*
stride
;
uint8_t
*
dst
=
out
->
data
[
plane
]
+
slice_start
*
out
->
linesize
[
plane
];
const
float
scale
=
s
->
scale
;
const
float
scale
=
s
->
scale
;
const
float
delta
=
s
->
delta
;
const
float
delta
=
s
->
delta
;
uint8_t
*
p0
=
s
->
b
uffer
+
16
;
uint8_t
*
p0
=
s
->
b
ptrs
[
jobnr
]
+
16
;
uint8_t
*
p1
=
p0
+
bstride
;
uint8_t
*
p1
=
p0
+
bstride
;
uint8_t
*
p2
=
p1
+
bstride
;
uint8_t
*
p2
=
p1
+
bstride
;
uint8_t
*
orig
=
p0
,
*
end
=
p2
;
uint8_t
*
orig
=
p0
,
*
end
=
p2
;
int
y
,
x
;
int
y
,
x
;
line_copy8
(
p0
,
src
+
stride
,
width
,
1
);
line_copy8
(
p0
,
src
+
stride
*
(
slice_start
==
0
?
1
:
-
1
)
,
width
,
1
);
line_copy8
(
p1
,
src
,
width
,
1
);
line_copy8
(
p1
,
src
,
width
,
1
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
line_copy8
(
p2
,
src
,
width
,
1
);
line_copy8
(
p2
,
src
,
width
,
1
);
...
@@ -274,28 +307,37 @@ static void filter_prewitt(ConvolutionContext *s, AVFrame *in, AVFrame *out, int
...
@@ -274,28 +307,37 @@ static void filter_prewitt(ConvolutionContext *s, AVFrame *in, AVFrame *out, int
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
dst
+=
out
->
linesize
[
plane
];
dst
+=
out
->
linesize
[
plane
];
}
}
return
0
;
}
}
static
void
filter_sobel
(
ConvolutionContext
*
s
,
AVFrame
*
in
,
AVFrame
*
out
,
int
plane
)
static
int
filter_sobel
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
{
const
uint8_t
*
src
=
in
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
uint8_t
*
dst
=
out
->
data
[
plane
];
ThreadData
*
td
=
arg
;
AVFrame
*
in
=
td
->
in
;
AVFrame
*
out
=
td
->
out
;
const
int
plane
=
td
->
plane
;
const
int
stride
=
in
->
linesize
[
plane
];
const
int
stride
=
in
->
linesize
[
plane
];
const
int
bstride
=
s
->
bstride
;
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
plane
];
const
int
height
=
s
->
planeheight
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
const
int
slice_start
=
(
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
height
*
(
jobnr
+
1
))
/
nb_jobs
;
const
uint8_t
*
src
=
in
->
data
[
plane
]
+
slice_start
*
stride
;
uint8_t
*
dst
=
out
->
data
[
plane
]
+
slice_start
*
out
->
linesize
[
plane
];
const
float
scale
=
s
->
scale
;
const
float
scale
=
s
->
scale
;
const
float
delta
=
s
->
delta
;
const
float
delta
=
s
->
delta
;
uint8_t
*
p0
=
s
->
b
uffer
+
16
;
uint8_t
*
p0
=
s
->
b
ptrs
[
jobnr
]
+
16
;
uint8_t
*
p1
=
p0
+
bstride
;
uint8_t
*
p1
=
p0
+
bstride
;
uint8_t
*
p2
=
p1
+
bstride
;
uint8_t
*
p2
=
p1
+
bstride
;
uint8_t
*
orig
=
p0
,
*
end
=
p2
;
uint8_t
*
orig
=
p0
,
*
end
=
p2
;
int
y
,
x
;
int
y
,
x
;
line_copy8
(
p0
,
src
+
stride
,
width
,
1
);
line_copy8
(
p0
,
src
+
stride
*
(
slice_start
==
0
?
1
:
-
1
)
,
width
,
1
);
line_copy8
(
p1
,
src
,
width
,
1
);
line_copy8
(
p1
,
src
,
width
,
1
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
line_copy8
(
p2
,
src
,
width
,
1
);
line_copy8
(
p2
,
src
,
width
,
1
);
...
@@ -321,18 +363,27 @@ static void filter_sobel(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
...
@@ -321,18 +363,27 @@ static void filter_sobel(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
dst
+=
out
->
linesize
[
plane
];
dst
+=
out
->
linesize
[
plane
];
}
}
return
0
;
}
}
static
void
filter16_3x3
(
ConvolutionContext
*
s
,
AVFrame
*
in
,
AVFrame
*
out
,
int
plane
)
static
int
filter16_3x3
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
{
const
uint16_t
*
src
=
(
const
uint16_t
*
)
in
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
uint16_t
*
dst
=
(
uint16_t
*
)
out
->
data
[
plane
];
ThreadData
*
td
=
arg
;
AVFrame
*
in
=
td
->
in
;
AVFrame
*
out
=
td
->
out
;
const
int
plane
=
td
->
plane
;
const
int
peak
=
(
1
<<
s
->
depth
)
-
1
;
const
int
peak
=
(
1
<<
s
->
depth
)
-
1
;
const
int
stride
=
in
->
linesize
[
plane
]
/
2
;
const
int
stride
=
in
->
linesize
[
plane
]
/
2
;
const
int
bstride
=
s
->
bstride
;
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
plane
];
const
int
height
=
s
->
planeheight
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
uint16_t
*
p0
=
(
uint16_t
*
)
s
->
buffer
+
16
;
const
int
slice_start
=
(
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
height
*
(
jobnr
+
1
))
/
nb_jobs
;
const
uint16_t
*
src
=
(
const
uint16_t
*
)
in
->
data
[
plane
]
+
slice_start
*
stride
;
uint16_t
*
dst
=
(
uint16_t
*
)
out
->
data
[
plane
]
+
slice_start
*
(
out
->
linesize
[
plane
]
/
2
);
uint16_t
*
p0
=
(
uint16_t
*
)
s
->
bptrs
[
jobnr
]
+
16
;
uint16_t
*
p1
=
p0
+
bstride
;
uint16_t
*
p1
=
p0
+
bstride
;
uint16_t
*
p2
=
p1
+
bstride
;
uint16_t
*
p2
=
p1
+
bstride
;
uint16_t
*
orig
=
p0
,
*
end
=
p2
;
uint16_t
*
orig
=
p0
,
*
end
=
p2
;
...
@@ -341,10 +392,10 @@ static void filter16_3x3(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
...
@@ -341,10 +392,10 @@ static void filter16_3x3(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
const
float
bias
=
s
->
bias
[
plane
];
const
float
bias
=
s
->
bias
[
plane
];
int
y
,
x
;
int
y
,
x
;
line_copy16
(
p0
,
src
+
stride
,
width
,
1
);
line_copy16
(
p0
,
src
+
stride
*
(
slice_start
==
0
?
1
:
-
1
)
,
width
,
1
);
line_copy16
(
p1
,
src
,
width
,
1
);
line_copy16
(
p1
,
src
,
width
,
1
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
line_copy16
(
p2
,
src
,
width
,
1
);
line_copy16
(
p2
,
src
,
width
,
1
);
...
@@ -367,18 +418,27 @@ static void filter16_3x3(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
...
@@ -367,18 +418,27 @@ static void filter16_3x3(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
dst
+=
out
->
linesize
[
plane
]
/
2
;
dst
+=
out
->
linesize
[
plane
]
/
2
;
}
}
return
0
;
}
}
static
void
filter16_5x5
(
ConvolutionContext
*
s
,
AVFrame
*
in
,
AVFrame
*
out
,
int
plane
)
static
int
filter16_5x5
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
{
const
uint16_t
*
src
=
(
const
uint16_t
*
)
in
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
uint16_t
*
dst
=
(
uint16_t
*
)
out
->
data
[
plane
];
ThreadData
*
td
=
arg
;
AVFrame
*
in
=
td
->
in
;
AVFrame
*
out
=
td
->
out
;
const
int
plane
=
td
->
plane
;
const
int
peak
=
(
1
<<
s
->
depth
)
-
1
;
const
int
peak
=
(
1
<<
s
->
depth
)
-
1
;
const
int
stride
=
in
->
linesize
[
plane
]
/
2
;
const
int
stride
=
in
->
linesize
[
plane
]
/
2
;
const
int
bstride
=
s
->
bstride
;
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
plane
];
const
int
height
=
s
->
planeheight
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
uint16_t
*
p0
=
(
uint16_t
*
)
s
->
buffer
+
16
;
const
int
slice_start
=
(
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
height
*
(
jobnr
+
1
))
/
nb_jobs
;
const
uint16_t
*
src
=
(
const
uint16_t
*
)
in
->
data
[
plane
]
+
slice_start
*
stride
;
uint16_t
*
dst
=
(
uint16_t
*
)
out
->
data
[
plane
]
+
slice_start
*
(
out
->
linesize
[
plane
]
/
2
);
uint16_t
*
p0
=
(
uint16_t
*
)
s
->
bptrs
[
jobnr
]
+
16
;
uint16_t
*
p1
=
p0
+
bstride
;
uint16_t
*
p1
=
p0
+
bstride
;
uint16_t
*
p2
=
p1
+
bstride
;
uint16_t
*
p2
=
p1
+
bstride
;
uint16_t
*
p3
=
p2
+
bstride
;
uint16_t
*
p3
=
p2
+
bstride
;
...
@@ -389,14 +449,13 @@ static void filter16_5x5(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
...
@@ -389,14 +449,13 @@ static void filter16_5x5(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
float
bias
=
s
->
bias
[
plane
];
float
bias
=
s
->
bias
[
plane
];
int
y
,
x
,
i
;
int
y
,
x
,
i
;
line_copy16
(
p0
,
src
+
2
*
stride
,
width
,
2
);
line_copy16
(
p0
,
src
+
2
*
stride
*
(
slice_start
<
2
?
1
:
-
1
)
,
width
,
2
);
line_copy16
(
p1
,
src
+
stride
,
width
,
2
);
line_copy16
(
p1
,
src
+
stride
*
(
slice_start
==
0
?
1
:
-
1
)
,
width
,
2
);
line_copy16
(
p2
,
src
,
width
,
2
);
line_copy16
(
p2
,
src
,
width
,
2
);
src
+=
stride
;
src
+=
stride
;
line_copy16
(
p3
,
src
,
width
,
2
);
line_copy16
(
p3
,
src
,
width
,
2
);
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
for
(
y
=
0
;
y
<
height
;
y
++
)
{
uint16_t
*
array
[]
=
{
uint16_t
*
array
[]
=
{
p0
-
2
,
p0
-
1
,
p0
,
p0
+
1
,
p0
+
2
,
p0
-
2
,
p0
-
1
,
p0
,
p0
+
1
,
p0
+
2
,
p1
-
2
,
p1
-
1
,
p1
,
p1
+
1
,
p1
+
2
,
p1
-
2
,
p1
-
1
,
p1
,
p1
+
1
,
p1
+
2
,
...
@@ -425,17 +484,26 @@ static void filter16_5x5(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
...
@@ -425,17 +484,26 @@ static void filter16_5x5(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
p4
=
(
p4
==
end
)
?
orig
:
p4
+
bstride
;
p4
=
(
p4
==
end
)
?
orig
:
p4
+
bstride
;
dst
+=
out
->
linesize
[
plane
]
/
2
;
dst
+=
out
->
linesize
[
plane
]
/
2
;
}
}
return
0
;
}
}
static
void
filter_3x3
(
ConvolutionContext
*
s
,
AVFrame
*
in
,
AVFrame
*
out
,
int
plane
)
static
int
filter_3x3
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
{
const
uint8_t
*
src
=
in
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
uint8_t
*
dst
=
out
->
data
[
plane
];
ThreadData
*
td
=
arg
;
AVFrame
*
in
=
td
->
in
;
AVFrame
*
out
=
td
->
out
;
const
int
plane
=
td
->
plane
;
const
int
stride
=
in
->
linesize
[
plane
];
const
int
stride
=
in
->
linesize
[
plane
];
const
int
bstride
=
s
->
bstride
;
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
plane
];
const
int
height
=
s
->
planeheight
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
uint8_t
*
p0
=
s
->
buffer
+
16
;
const
int
slice_start
=
(
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
height
*
(
jobnr
+
1
))
/
nb_jobs
;
const
uint8_t
*
src
=
in
->
data
[
plane
]
+
slice_start
*
stride
;
uint8_t
*
dst
=
out
->
data
[
plane
]
+
slice_start
*
out
->
linesize
[
plane
];
uint8_t
*
p0
=
s
->
bptrs
[
jobnr
]
+
16
;
uint8_t
*
p1
=
p0
+
bstride
;
uint8_t
*
p1
=
p0
+
bstride
;
uint8_t
*
p2
=
p1
+
bstride
;
uint8_t
*
p2
=
p1
+
bstride
;
uint8_t
*
orig
=
p0
,
*
end
=
p2
;
uint8_t
*
orig
=
p0
,
*
end
=
p2
;
...
@@ -444,10 +512,10 @@ static void filter_3x3(ConvolutionContext *s, AVFrame *in, AVFrame *out, int pla
...
@@ -444,10 +512,10 @@ static void filter_3x3(ConvolutionContext *s, AVFrame *in, AVFrame *out, int pla
const
float
bias
=
s
->
bias
[
plane
];
const
float
bias
=
s
->
bias
[
plane
];
int
y
,
x
;
int
y
,
x
;
line_copy8
(
p0
,
src
+
stride
,
width
,
1
);
line_copy8
(
p0
,
src
+
stride
*
(
slice_start
==
0
?
1
:
-
1
)
,
width
,
1
);
line_copy8
(
p1
,
src
,
width
,
1
);
line_copy8
(
p1
,
src
,
width
,
1
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
line_copy8
(
p2
,
src
,
width
,
1
);
line_copy8
(
p2
,
src
,
width
,
1
);
...
@@ -470,17 +538,26 @@ static void filter_3x3(ConvolutionContext *s, AVFrame *in, AVFrame *out, int pla
...
@@ -470,17 +538,26 @@ static void filter_3x3(ConvolutionContext *s, AVFrame *in, AVFrame *out, int pla
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
dst
+=
out
->
linesize
[
plane
];
dst
+=
out
->
linesize
[
plane
];
}
}
return
0
;
}
}
static
void
filter_5x5
(
ConvolutionContext
*
s
,
AVFrame
*
in
,
AVFrame
*
out
,
int
plane
)
static
int
filter_5x5
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
{
const
uint8_t
*
src
=
in
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
uint8_t
*
dst
=
out
->
data
[
plane
];
ThreadData
*
td
=
arg
;
AVFrame
*
in
=
td
->
in
;
AVFrame
*
out
=
td
->
out
;
const
int
plane
=
td
->
plane
;
const
int
stride
=
in
->
linesize
[
plane
];
const
int
stride
=
in
->
linesize
[
plane
];
const
int
bstride
=
s
->
bstride
;
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
plane
];
const
int
height
=
s
->
planeheight
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
const
int
width
=
s
->
planewidth
[
plane
];
uint8_t
*
p0
=
s
->
buffer
+
16
;
const
int
slice_start
=
(
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
height
*
(
jobnr
+
1
))
/
nb_jobs
;
const
uint8_t
*
src
=
in
->
data
[
plane
]
+
slice_start
*
stride
;
uint8_t
*
dst
=
out
->
data
[
plane
]
+
slice_start
*
out
->
linesize
[
plane
];
uint8_t
*
p0
=
s
->
bptrs
[
jobnr
]
+
16
;
uint8_t
*
p1
=
p0
+
bstride
;
uint8_t
*
p1
=
p0
+
bstride
;
uint8_t
*
p2
=
p1
+
bstride
;
uint8_t
*
p2
=
p1
+
bstride
;
uint8_t
*
p3
=
p2
+
bstride
;
uint8_t
*
p3
=
p2
+
bstride
;
...
@@ -491,14 +568,14 @@ static void filter_5x5(ConvolutionContext *s, AVFrame *in, AVFrame *out, int pla
...
@@ -491,14 +568,14 @@ static void filter_5x5(ConvolutionContext *s, AVFrame *in, AVFrame *out, int pla
float
bias
=
s
->
bias
[
plane
];
float
bias
=
s
->
bias
[
plane
];
int
y
,
x
,
i
;
int
y
,
x
,
i
;
line_copy8
(
p0
,
src
+
2
*
stride
,
width
,
2
);
line_copy8
(
p0
,
src
+
2
*
stride
*
(
slice_start
<
2
?
1
:
-
1
)
,
width
,
2
);
line_copy8
(
p1
,
src
+
stride
,
width
,
2
);
line_copy8
(
p1
,
src
+
stride
*
(
slice_start
==
0
?
1
:
-
1
)
,
width
,
2
);
line_copy8
(
p2
,
src
,
width
,
2
);
line_copy8
(
p2
,
src
,
width
,
2
);
src
+=
stride
;
src
+=
stride
;
line_copy8
(
p3
,
src
,
width
,
2
);
line_copy8
(
p3
,
src
,
width
,
2
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
uint8_t
*
array
[]
=
{
uint8_t
*
array
[]
=
{
p0
-
2
,
p0
-
1
,
p0
,
p0
+
1
,
p0
+
2
,
p0
-
2
,
p0
-
1
,
p0
,
p0
+
1
,
p0
+
2
,
p1
-
2
,
p1
-
1
,
p1
,
p1
+
1
,
p1
+
2
,
p1
-
2
,
p1
-
1
,
p1
,
p1
+
1
,
p1
+
2
,
...
@@ -527,6 +604,8 @@ static void filter_5x5(ConvolutionContext *s, AVFrame *in, AVFrame *out, int pla
...
@@ -527,6 +604,8 @@ static void filter_5x5(ConvolutionContext *s, AVFrame *in, AVFrame *out, int pla
p4
=
(
p4
==
end
)
?
orig
:
p4
+
bstride
;
p4
=
(
p4
==
end
)
?
orig
:
p4
+
bstride
;
dst
+=
out
->
linesize
[
plane
];
dst
+=
out
->
linesize
[
plane
];
}
}
return
0
;
}
}
static
int
config_input
(
AVFilterLink
*
inlink
)
static
int
config_input
(
AVFilterLink
*
inlink
)
...
@@ -534,22 +613,31 @@ static int config_input(AVFilterLink *inlink)
...
@@ -534,22 +613,31 @@ static int config_input(AVFilterLink *inlink)
AVFilterContext
*
ctx
=
inlink
->
dst
;
AVFilterContext
*
ctx
=
inlink
->
dst
;
ConvolutionContext
*
s
=
ctx
->
priv
;
ConvolutionContext
*
s
=
ctx
->
priv
;
const
AVPixFmtDescriptor
*
desc
=
av_pix_fmt_desc_get
(
inlink
->
format
);
const
AVPixFmtDescriptor
*
desc
=
av_pix_fmt_desc_get
(
inlink
->
format
);
int
ret
,
p
;
int
p
;
s
->
depth
=
desc
->
comp
[
0
].
depth
;
s
->
depth
=
desc
->
comp
[
0
].
depth
;
if
((
ret
=
av_image_fill_linesizes
(
s
->
planewidth
,
inlink
->
format
,
inlink
->
w
))
<
0
)
return
ret
;
s
->
planewidth
[
1
]
=
s
->
planewidth
[
2
]
=
AV_CEIL_RSHIFT
(
inlink
->
w
,
desc
->
log2_chroma_w
);
s
->
planewidth
[
0
]
=
s
->
planewidth
[
3
]
=
inlink
->
w
;
s
->
planeheight
[
1
]
=
s
->
planeheight
[
2
]
=
AV_CEIL_RSHIFT
(
inlink
->
h
,
desc
->
log2_chroma_h
);
s
->
planeheight
[
1
]
=
s
->
planeheight
[
2
]
=
AV_CEIL_RSHIFT
(
inlink
->
h
,
desc
->
log2_chroma_h
);
s
->
planeheight
[
0
]
=
s
->
planeheight
[
3
]
=
inlink
->
h
;
s
->
planeheight
[
0
]
=
s
->
planeheight
[
3
]
=
inlink
->
h
;
s
->
nb_planes
=
av_pix_fmt_count_planes
(
inlink
->
format
);
s
->
nb_planes
=
av_pix_fmt_count_planes
(
inlink
->
format
);
s
->
nb_threads
=
ff_filter_get_nb_threads
(
ctx
);
s
->
bptrs
=
av_calloc
(
s
->
nb_threads
,
sizeof
(
*
s
->
bptrs
));
if
(
!
s
->
bptrs
)
return
AVERROR
(
ENOMEM
);
s
->
bstride
=
s
->
planewidth
[
0
]
+
32
;
s
->
bstride
=
s
->
planewidth
[
0
]
+
32
;
s
->
buffer
=
av_malloc_array
(
5
*
s
->
bstride
,
(
s
->
depth
+
7
)
/
8
);
s
->
bpc
=
(
s
->
depth
+
7
)
/
8
;
s
->
buffer
=
av_malloc_array
(
5
*
s
->
bstride
*
s
->
nb_threads
,
s
->
bpc
);
if
(
!
s
->
buffer
)
if
(
!
s
->
buffer
)
return
AVERROR
(
ENOMEM
);
return
AVERROR
(
ENOMEM
);
for
(
p
=
0
;
p
<
s
->
nb_threads
;
p
++
)
{
s
->
bptrs
[
p
]
=
s
->
buffer
+
5
*
s
->
bstride
*
s
->
bpc
*
p
;
}
if
(
!
strcmp
(
ctx
->
filter
->
name
,
"convolution"
))
{
if
(
!
strcmp
(
ctx
->
filter
->
name
,
"convolution"
))
{
if
(
s
->
depth
>
8
)
{
if
(
s
->
depth
>
8
)
{
for
(
p
=
0
;
p
<
s
->
nb_planes
;
p
++
)
{
for
(
p
=
0
;
p
<
s
->
nb_planes
;
p
++
)
{
...
@@ -574,8 +662,9 @@ static int config_input(AVFilterLink *inlink)
...
@@ -574,8 +662,9 @@ static int config_input(AVFilterLink *inlink)
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
in
)
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
in
)
{
{
ConvolutionContext
*
s
=
inlink
->
dst
->
priv
;
AVFilterContext
*
ctx
=
inlink
->
dst
;
AVFilterLink
*
outlink
=
inlink
->
dst
->
outputs
[
0
];
ConvolutionContext
*
s
=
ctx
->
priv
;
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
AVFrame
*
out
;
AVFrame
*
out
;
int
plane
;
int
plane
;
...
@@ -587,15 +676,20 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
...
@@ -587,15 +676,20 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
av_frame_copy_props
(
out
,
in
);
av_frame_copy_props
(
out
,
in
);
for
(
plane
=
0
;
plane
<
s
->
nb_planes
;
plane
++
)
{
for
(
plane
=
0
;
plane
<
s
->
nb_planes
;
plane
++
)
{
ThreadData
td
;
if
(
s
->
copy
[
plane
])
{
if
(
s
->
copy
[
plane
])
{
av_image_copy_plane
(
out
->
data
[
plane
],
out
->
linesize
[
plane
],
av_image_copy_plane
(
out
->
data
[
plane
],
out
->
linesize
[
plane
],
in
->
data
[
plane
],
in
->
linesize
[
plane
],
in
->
data
[
plane
],
in
->
linesize
[
plane
],
s
->
planewidth
[
plane
],
s
->
planewidth
[
plane
]
*
s
->
bpc
,
s
->
planeheight
[
plane
]);
s
->
planeheight
[
plane
]);
continue
;
continue
;
}
}
s
->
filter
[
plane
](
s
,
in
,
out
,
plane
);
td
.
in
=
in
;
td
.
out
=
out
;
td
.
plane
=
plane
;
ctx
->
internal
->
execute
(
ctx
,
s
->
filter
[
plane
],
&
td
,
NULL
,
FFMIN
(
s
->
planeheight
[
plane
],
s
->
nb_threads
));
}
}
av_frame_free
(
&
in
);
av_frame_free
(
&
in
);
...
@@ -661,6 +755,7 @@ static av_cold void uninit(AVFilterContext *ctx)
...
@@ -661,6 +755,7 @@ static av_cold void uninit(AVFilterContext *ctx)
{
{
ConvolutionContext
*
s
=
ctx
->
priv
;
ConvolutionContext
*
s
=
ctx
->
priv
;
av_freep
(
&
s
->
bptrs
);
av_freep
(
&
s
->
buffer
);
av_freep
(
&
s
->
buffer
);
}
}
...
@@ -694,7 +789,7 @@ AVFilter ff_vf_convolution = {
...
@@ -694,7 +789,7 @@ AVFilter ff_vf_convolution = {
.
query_formats
=
query_formats
,
.
query_formats
=
query_formats
,
.
inputs
=
convolution_inputs
,
.
inputs
=
convolution_inputs
,
.
outputs
=
convolution_outputs
,
.
outputs
=
convolution_outputs
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
|
AVFILTER_FLAG_SLICE_THREADS
,
};
};
#endif
/* CONFIG_CONVOLUTION_FILTER */
#endif
/* CONFIG_CONVOLUTION_FILTER */
...
@@ -720,7 +815,7 @@ AVFilter ff_vf_prewitt = {
...
@@ -720,7 +815,7 @@ AVFilter ff_vf_prewitt = {
.
query_formats
=
query_formats
,
.
query_formats
=
query_formats
,
.
inputs
=
convolution_inputs
,
.
inputs
=
convolution_inputs
,
.
outputs
=
convolution_outputs
,
.
outputs
=
convolution_outputs
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
|
AVFILTER_FLAG_SLICE_THREADS
,
};
};
#endif
/* CONFIG_PREWITT_FILTER */
#endif
/* CONFIG_PREWITT_FILTER */
...
@@ -746,7 +841,7 @@ AVFilter ff_vf_sobel = {
...
@@ -746,7 +841,7 @@ AVFilter ff_vf_sobel = {
.
query_formats
=
query_formats
,
.
query_formats
=
query_formats
,
.
inputs
=
convolution_inputs
,
.
inputs
=
convolution_inputs
,
.
outputs
=
convolution_outputs
,
.
outputs
=
convolution_outputs
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
|
AVFILTER_FLAG_SLICE_THREADS
,
};
};
#endif
/* CONFIG_SOBEL_FILTER */
#endif
/* CONFIG_SOBEL_FILTER */
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