Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
FFmpeg
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
libremedia
Tethys
FFmpeg
Commits
a50ca6b3
Commit
a50ca6b3
authored
8 years ago
by
Paul B Mahol
Browse files
Options
Downloads
Patches
Plain Diff
avfilter/vf_convolution: add slice threading support
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
afeffd89
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
libavfilter/vf_convolution.c
+158
-63
158 additions, 63 deletions
libavfilter/vf_convolution.c
with
158 additions
and
63 deletions
libavfilter/vf_convolution.c
+
158
−
63
View file @
a50ca6b3
...
...
@@ -40,16 +40,19 @@ typedef struct ConvolutionContext {
int
size
[
4
];
int
depth
;
int
bpc
;
int
bstride
;
uint8_t
*
buffer
;
uint8_t
**
bptrs
;
int
nb_planes
;
int
nb_threads
;
int
planewidth
[
4
];
int
planeheight
[
4
];
int
matrix
[
4
][
25
];
int
matrix_length
[
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
;
#define OFFSET(x) offsetof(ConvolutionContext, x)
...
...
@@ -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
];
uint16_t
*
dst
=
(
uint16_t
*
)
out
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
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
stride
=
in
->
linesize
[
plane
]
/
2
;
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
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
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
*
p2
=
p1
+
bstride
;
uint16_t
*
orig
=
p0
,
*
end
=
p2
;
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
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
line_copy16
(
p2
,
src
,
width
,
1
);
...
...
@@ -179,29 +194,38 @@ static void filter16_prewitt(ConvolutionContext *s, AVFrame *in, AVFrame *out, i
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
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
];
uint16_t
*
dst
=
(
uint16_t
*
)
out
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
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
stride
=
in
->
linesize
[
plane
]
/
2
;
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
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
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
*
p2
=
p1
+
bstride
;
uint16_t
*
orig
=
p0
,
*
end
=
p2
;
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
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
line_copy16
(
p2
,
src
,
width
,
1
);
...
...
@@ -227,28 +251,37 @@ static void filter16_sobel(ConvolutionContext *s, AVFrame *in, AVFrame *out, int
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
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
];
uint8_t
*
dst
=
out
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
ThreadData
*
td
=
arg
;
AVFrame
*
in
=
td
->
in
;
AVFrame
*
out
=
td
->
out
;
const
int
plane
=
td
->
plane
;
const
int
stride
=
in
->
linesize
[
plane
];
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
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
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
*
p2
=
p1
+
bstride
;
uint8_t
*
orig
=
p0
,
*
end
=
p2
;
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
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
line_copy8
(
p2
,
src
,
width
,
1
);
...
...
@@ -274,28 +307,37 @@ static void filter_prewitt(ConvolutionContext *s, AVFrame *in, AVFrame *out, int
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
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
];
uint8_t
*
dst
=
out
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
ThreadData
*
td
=
arg
;
AVFrame
*
in
=
td
->
in
;
AVFrame
*
out
=
td
->
out
;
const
int
plane
=
td
->
plane
;
const
int
stride
=
in
->
linesize
[
plane
];
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
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
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
*
p2
=
p1
+
bstride
;
uint8_t
*
orig
=
p0
,
*
end
=
p2
;
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
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
line_copy8
(
p2
,
src
,
width
,
1
);
...
...
@@ -321,18 +363,27 @@ static void filter_sobel(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
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
];
uint16_t
*
dst
=
(
uint16_t
*
)
out
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
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
stride
=
in
->
linesize
[
plane
]
/
2
;
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
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
*
p2
=
p1
+
bstride
;
uint16_t
*
orig
=
p0
,
*
end
=
p2
;
...
...
@@ -341,10 +392,10 @@ static void filter16_3x3(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
const
float
bias
=
s
->
bias
[
plane
];
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
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
line_copy16
(
p2
,
src
,
width
,
1
);
...
...
@@ -367,18 +418,27 @@ static void filter16_3x3(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
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
];
uint16_t
*
dst
=
(
uint16_t
*
)
out
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
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
stride
=
in
->
linesize
[
plane
]
/
2
;
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
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
*
p2
=
p1
+
bstride
;
uint16_t
*
p3
=
p2
+
bstride
;
...
...
@@ -389,14 +449,13 @@ static void filter16_5x5(ConvolutionContext *s, AVFrame *in, AVFrame *out, int p
float
bias
=
s
->
bias
[
plane
];
int
y
,
x
,
i
;
line_copy16
(
p0
,
src
+
2
*
stride
,
width
,
2
);
line_copy16
(
p1
,
src
+
stride
,
width
,
2
);
line_copy16
(
p0
,
src
+
2
*
stride
*
(
slice_start
<
2
?
1
:
-
1
)
,
width
,
2
);
line_copy16
(
p1
,
src
+
stride
*
(
slice_start
==
0
?
1
:
-
1
)
,
width
,
2
);
line_copy16
(
p2
,
src
,
width
,
2
);
src
+=
stride
;
line_copy16
(
p3
,
src
,
width
,
2
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
uint16_t
*
array
[]
=
{
p0
-
2
,
p0
-
1
,
p0
,
p0
+
1
,
p0
+
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
p4
=
(
p4
==
end
)
?
orig
:
p4
+
bstride
;
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
];
uint8_t
*
dst
=
out
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
ThreadData
*
td
=
arg
;
AVFrame
*
in
=
td
->
in
;
AVFrame
*
out
=
td
->
out
;
const
int
plane
=
td
->
plane
;
const
int
stride
=
in
->
linesize
[
plane
];
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
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
*
p2
=
p1
+
bstride
;
uint8_t
*
orig
=
p0
,
*
end
=
p2
;
...
...
@@ -444,10 +512,10 @@ static void filter_3x3(ConvolutionContext *s, AVFrame *in, AVFrame *out, int pla
const
float
bias
=
s
->
bias
[
plane
];
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
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
src
+=
stride
*
(
y
<
height
-
1
?
1
:
-
1
);
line_copy8
(
p2
,
src
,
width
,
1
);
...
...
@@ -470,17 +538,26 @@ static void filter_3x3(ConvolutionContext *s, AVFrame *in, AVFrame *out, int pla
p2
=
(
p2
==
end
)
?
orig
:
p2
+
bstride
;
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
];
uint8_t
*
dst
=
out
->
data
[
plane
];
ConvolutionContext
*
s
=
ctx
->
priv
;
ThreadData
*
td
=
arg
;
AVFrame
*
in
=
td
->
in
;
AVFrame
*
out
=
td
->
out
;
const
int
plane
=
td
->
plane
;
const
int
stride
=
in
->
linesize
[
plane
];
const
int
bstride
=
s
->
bstride
;
const
int
height
=
s
->
planeheight
[
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
*
p2
=
p1
+
bstride
;
uint8_t
*
p3
=
p2
+
bstride
;
...
...
@@ -491,14 +568,14 @@ static void filter_5x5(ConvolutionContext *s, AVFrame *in, AVFrame *out, int pla
float
bias
=
s
->
bias
[
plane
];
int
y
,
x
,
i
;
line_copy8
(
p0
,
src
+
2
*
stride
,
width
,
2
);
line_copy8
(
p1
,
src
+
stride
,
width
,
2
);
line_copy8
(
p0
,
src
+
2
*
stride
*
(
slice_start
<
2
?
1
:
-
1
)
,
width
,
2
);
line_copy8
(
p1
,
src
+
stride
*
(
slice_start
==
0
?
1
:
-
1
)
,
width
,
2
);
line_copy8
(
p2
,
src
,
width
,
2
);
src
+=
stride
;
line_copy8
(
p3
,
src
,
width
,
2
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
uint8_t
*
array
[]
=
{
p0
-
2
,
p0
-
1
,
p0
,
p0
+
1
,
p0
+
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
p4
=
(
p4
==
end
)
?
orig
:
p4
+
bstride
;
dst
+=
out
->
linesize
[
plane
];
}
return
0
;
}
static
int
config_input
(
AVFilterLink
*
inlink
)
...
...
@@ -534,22 +613,31 @@ static int config_input(AVFilterLink *inlink)
AVFilterContext
*
ctx
=
inlink
->
dst
;
ConvolutionContext
*
s
=
ctx
->
priv
;
const
AVPixFmtDescriptor
*
desc
=
av_pix_fmt_desc_get
(
inlink
->
format
);
int
ret
,
p
;
int
p
;
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
[
0
]
=
s
->
planeheight
[
3
]
=
inlink
->
h
;
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
->
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
)
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
(
s
->
depth
>
8
)
{
for
(
p
=
0
;
p
<
s
->
nb_planes
;
p
++
)
{
...
...
@@ -574,8 +662,9 @@ static int config_input(AVFilterLink *inlink)
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
in
)
{
ConvolutionContext
*
s
=
inlink
->
dst
->
priv
;
AVFilterLink
*
outlink
=
inlink
->
dst
->
outputs
[
0
];
AVFilterContext
*
ctx
=
inlink
->
dst
;
ConvolutionContext
*
s
=
ctx
->
priv
;
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
AVFrame
*
out
;
int
plane
;
...
...
@@ -587,15 +676,20 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
av_frame_copy_props
(
out
,
in
);
for
(
plane
=
0
;
plane
<
s
->
nb_planes
;
plane
++
)
{
ThreadData
td
;
if
(
s
->
copy
[
plane
])
{
av_image_copy_plane
(
out
->
data
[
plane
],
out
->
linesize
[
plane
],
in
->
data
[
plane
],
in
->
linesize
[
plane
],
s
->
planewidth
[
plane
],
s
->
planewidth
[
plane
]
*
s
->
bpc
,
s
->
planeheight
[
plane
]);
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
);
...
...
@@ -661,6 +755,7 @@ static av_cold void uninit(AVFilterContext *ctx)
{
ConvolutionContext
*
s
=
ctx
->
priv
;
av_freep
(
&
s
->
bptrs
);
av_freep
(
&
s
->
buffer
);
}
...
...
@@ -694,7 +789,7 @@ AVFilter ff_vf_convolution = {
.
query_formats
=
query_formats
,
.
inputs
=
convolution_inputs
,
.
outputs
=
convolution_outputs
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
|
AVFILTER_FLAG_SLICE_THREADS
,
};
#endif
/* CONFIG_CONVOLUTION_FILTER */
...
...
@@ -720,7 +815,7 @@ AVFilter ff_vf_prewitt = {
.
query_formats
=
query_formats
,
.
inputs
=
convolution_inputs
,
.
outputs
=
convolution_outputs
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
|
AVFILTER_FLAG_SLICE_THREADS
,
};
#endif
/* CONFIG_PREWITT_FILTER */
...
...
@@ -746,7 +841,7 @@ AVFilter ff_vf_sobel = {
.
query_formats
=
query_formats
,
.
inputs
=
convolution_inputs
,
.
outputs
=
convolution_outputs
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
|
AVFILTER_FLAG_SLICE_THREADS
,
};
#endif
/* CONFIG_SOBEL_FILTER */
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment