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
312b00de
Commit
312b00de
authored
Dec 04, 2017
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/vf_convolution: add 7x7 filter
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
cc2ba526
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
172 additions
and
7 deletions
+172
-7
filters.texi
doc/filters.texi
+2
-2
vf_convolution.c
libavfilter/vf_convolution.c
+170
-5
No files found.
doc/filters.texi
View file @
312b00de
...
...
@@ -6025,7 +6025,7 @@ colorspace=smpte240m
@section convolution
Apply convolution 3x3
or 5x5
filter.
Apply convolution 3x3
, 5x5 or 7x7
filter.
The filter accepts the following options:
...
...
@@ -6035,7 +6035,7 @@ The filter accepts the following options:
@item 2m
@item 3m
Set matrix for each plane.
Matrix is sequence of 9
or 25
signed integers.
Matrix is sequence of 9
, 25 or 49
signed integers.
@item 0rdiv
@item 1rdiv
...
...
libavfilter/vf_convolution.c
View file @
312b00de
...
...
@@ -48,7 +48,7 @@ typedef struct ConvolutionContext {
int
nb_threads
;
int
planewidth
[
4
];
int
planeheight
[
4
];
int
matrix
[
4
][
25
];
int
matrix
[
4
][
49
];
int
matrix_length
[
4
];
int
copy
[
4
];
...
...
@@ -86,6 +86,14 @@ static const int same5x5[25] = {0, 0, 0, 0, 0,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
static
const
int
same7x7
[
49
]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
static
int
query_formats
(
AVFilterContext
*
ctx
)
{
static
const
enum
AVPixelFormat
pix_fmts
[]
=
{
...
...
@@ -585,6 +593,81 @@ static int filter16_5x5(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
return
0
;
}
static
int
filter16_7x7
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
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
);
uint16_t
*
p0
=
(
uint16_t
*
)
s
->
bptrs
[
jobnr
]
+
32
;
uint16_t
*
p1
=
p0
+
bstride
;
uint16_t
*
p2
=
p1
+
bstride
;
uint16_t
*
p3
=
p2
+
bstride
;
uint16_t
*
p4
=
p3
+
bstride
;
uint16_t
*
p5
=
p4
+
bstride
;
uint16_t
*
p6
=
p5
+
bstride
;
uint16_t
*
orig
=
p0
,
*
end
=
p6
;
const
int
*
matrix
=
s
->
matrix
[
plane
];
float
rdiv
=
s
->
rdiv
[
plane
];
float
bias
=
s
->
bias
[
plane
];
int
y
,
x
,
i
;
line_copy16
(
p0
,
src
+
3
*
stride
*
(
slice_start
<
3
?
1
:
-
1
),
width
,
3
);
line_copy16
(
p1
,
src
+
2
*
stride
*
(
slice_start
<
2
?
1
:
-
1
),
width
,
3
);
line_copy16
(
p2
,
src
+
stride
*
(
slice_start
==
0
?
1
:
-
1
),
width
,
3
);
line_copy16
(
p3
,
src
,
width
,
3
);
src
+=
stride
;
line_copy16
(
p4
,
src
,
width
,
3
);
src
+=
stride
;
line_copy16
(
p5
,
src
,
width
,
3
);
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
uint16_t
*
array
[]
=
{
p0
-
3
,
p0
-
2
,
p0
-
1
,
p0
,
p0
+
1
,
p0
+
2
,
p0
+
3
,
p1
-
3
,
p1
-
2
,
p1
-
1
,
p1
,
p1
+
1
,
p1
+
2
,
p1
+
3
,
p2
-
3
,
p2
-
2
,
p2
-
1
,
p2
,
p2
+
1
,
p2
+
2
,
p2
+
3
,
p3
-
3
,
p3
-
2
,
p3
-
1
,
p3
,
p3
+
1
,
p3
+
2
,
p3
+
3
,
p4
-
3
,
p4
-
2
,
p4
-
1
,
p4
,
p4
+
1
,
p4
+
2
,
p4
+
3
,
p5
-
3
,
p5
-
2
,
p5
-
1
,
p5
,
p5
+
1
,
p5
+
2
,
p5
+
3
,
p6
-
3
,
p6
-
2
,
p6
-
1
,
p6
,
p6
+
1
,
p6
+
2
,
p6
+
3
,
};
src
+=
stride
*
(
y
<
height
-
3
?
1
:
-
1
);
line_copy16
(
p6
,
src
,
width
,
3
);
for
(
x
=
0
;
x
<
width
;
x
++
)
{
int
sum
=
0
;
for
(
i
=
0
;
i
<
25
;
i
++
)
{
sum
+=
*
(
array
[
i
]
+
x
)
*
matrix
[
i
];
}
sum
=
(
int
)(
sum
*
rdiv
+
bias
+
0
.
5
f
);
dst
[
x
]
=
av_clip
(
sum
,
0
,
peak
);
}
p0
=
p1
;
p1
=
p2
;
p2
=
p3
;
p3
=
p4
;
p4
=
p5
;
p5
=
p6
;
p6
=
(
p6
==
end
)
?
orig
:
p6
+
bstride
;
dst
+=
out
->
linesize
[
plane
]
/
2
;
}
return
0
;
}
static
int
filter_3x3
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
ConvolutionContext
*
s
=
ctx
->
priv
;
...
...
@@ -705,6 +788,80 @@ static int filter_5x5(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
return
0
;
}
static
int
filter_7x7
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
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
];
uint8_t
*
p0
=
s
->
bptrs
[
jobnr
]
+
32
;
uint8_t
*
p1
=
p0
+
bstride
;
uint8_t
*
p2
=
p1
+
bstride
;
uint8_t
*
p3
=
p2
+
bstride
;
uint8_t
*
p4
=
p3
+
bstride
;
uint8_t
*
p5
=
p4
+
bstride
;
uint8_t
*
p6
=
p5
+
bstride
;
uint8_t
*
orig
=
p0
,
*
end
=
p6
;
const
int
*
matrix
=
s
->
matrix
[
plane
];
float
rdiv
=
s
->
rdiv
[
plane
];
float
bias
=
s
->
bias
[
plane
];
int
y
,
x
,
i
;
line_copy8
(
p0
,
src
+
3
*
stride
*
(
slice_start
<
3
?
1
:
-
1
),
width
,
3
);
line_copy8
(
p1
,
src
+
2
*
stride
*
(
slice_start
<
2
?
1
:
-
1
),
width
,
3
);
line_copy8
(
p2
,
src
+
stride
*
(
slice_start
==
0
?
1
:
-
1
),
width
,
3
);
line_copy8
(
p3
,
src
,
width
,
3
);
src
+=
stride
;
line_copy8
(
p4
,
src
,
width
,
3
);
src
+=
stride
;
line_copy8
(
p5
,
src
,
width
,
3
);
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
uint8_t
*
array
[]
=
{
p0
-
3
,
p0
-
2
,
p0
-
1
,
p0
,
p0
+
1
,
p0
+
2
,
p0
+
3
,
p1
-
3
,
p1
-
2
,
p1
-
1
,
p1
,
p1
+
1
,
p1
+
2
,
p1
+
3
,
p2
-
3
,
p2
-
2
,
p2
-
1
,
p2
,
p2
+
1
,
p2
+
2
,
p2
+
3
,
p3
-
3
,
p3
-
2
,
p3
-
1
,
p3
,
p3
+
1
,
p3
+
2
,
p3
+
3
,
p4
-
3
,
p4
-
2
,
p4
-
1
,
p4
,
p4
+
1
,
p4
+
2
,
p4
+
3
,
p5
-
3
,
p5
-
2
,
p5
-
1
,
p5
,
p5
+
1
,
p5
+
2
,
p5
+
3
,
p6
-
3
,
p6
-
2
,
p6
-
1
,
p6
,
p6
+
1
,
p6
+
2
,
p6
+
3
,
};
src
+=
stride
*
(
y
<
height
-
3
?
1
:
-
1
);
line_copy8
(
p6
,
src
,
width
,
3
);
for
(
x
=
0
;
x
<
width
;
x
++
)
{
int
sum
=
0
;
for
(
i
=
0
;
i
<
49
;
i
++
)
{
sum
+=
*
(
array
[
i
]
+
x
)
*
matrix
[
i
];
}
sum
=
(
int
)(
sum
*
rdiv
+
bias
+
0
.
5
f
);
dst
[
x
]
=
av_clip_uint8
(
sum
);
}
p0
=
p1
;
p1
=
p2
;
p2
=
p3
;
p3
=
p4
;
p4
=
p5
;
p5
=
p6
;
p6
=
(
p6
==
end
)
?
orig
:
p6
+
bstride
;
dst
+=
out
->
linesize
[
plane
];
}
return
0
;
}
static
int
config_input
(
AVFilterLink
*
inlink
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
...
...
@@ -725,14 +882,14 @@ static int config_input(AVFilterLink *inlink)
if
(
!
s
->
bptrs
)
return
AVERROR
(
ENOMEM
);
s
->
bstride
=
s
->
planewidth
[
0
]
+
32
;
s
->
bstride
=
s
->
planewidth
[
0
]
+
64
;
s
->
bpc
=
(
s
->
depth
+
7
)
/
8
;
s
->
buffer
=
av_malloc_array
(
5
*
s
->
bstride
*
s
->
nb_threads
,
s
->
bpc
);
s
->
buffer
=
av_malloc_array
(
7
*
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
;
s
->
bptrs
[
p
]
=
s
->
buffer
+
7
*
s
->
bstride
*
s
->
bpc
*
p
;
}
if
(
!
strcmp
(
ctx
->
filter
->
name
,
"convolution"
))
{
...
...
@@ -742,6 +899,8 @@ static int config_input(AVFilterLink *inlink)
s
->
filter
[
p
]
=
filter16_3x3
;
else
if
(
s
->
size
[
p
]
==
5
)
s
->
filter
[
p
]
=
filter16_5x5
;
else
if
(
s
->
size
[
p
]
==
7
)
s
->
filter
[
p
]
=
filter16_7x7
;
}
}
}
else
if
(
!
strcmp
(
ctx
->
filter
->
name
,
"prewitt"
))
{
...
...
@@ -808,7 +967,7 @@ static av_cold int init(AVFilterContext *ctx)
char
*
p
,
*
arg
,
*
saveptr
=
NULL
;
p
=
s
->
matrix_str
[
i
];
while
(
s
->
matrix_length
[
i
]
<
25
)
{
while
(
s
->
matrix_length
[
i
]
<
49
)
{
if
(
!
(
arg
=
av_strtok
(
p
,
" "
,
&
saveptr
)))
break
;
...
...
@@ -829,6 +988,12 @@ static av_cold int init(AVFilterContext *ctx)
s
->
copy
[
i
]
=
1
;
else
s
->
filter
[
i
]
=
filter_5x5
;
}
else
if
(
s
->
matrix_length
[
i
]
==
49
)
{
s
->
size
[
i
]
=
7
;
if
(
!
memcmp
(
matrix
,
same7x7
,
sizeof
(
same7x7
)))
s
->
copy
[
i
]
=
1
;
else
s
->
filter
[
i
]
=
filter_7x7
;
}
else
{
return
AVERROR
(
EINVAL
);
}
...
...
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