Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Releases
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Stefan Westerfeld
ffmpeg
Commits
72532867
Commit
72532867
authored
Jan 19, 2023
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/vf_vibrance: reduce copy operations
parent
acd87d41
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
96 additions
and
21 deletions
+96
-21
vf_vibrance.c
libavfilter/vf_vibrance.c
+96
-21
No files found.
libavfilter/vf_vibrance.c
View file @
72532867
...
...
@@ -29,6 +29,7 @@
#define R 0
#define G 1
#define B 2
#define A 3
typedef
struct
VibranceContext
{
const
AVClass
*
class
;
...
...
@@ -51,10 +52,16 @@ static inline float lerpf(float v0, float v1, float f)
return
v0
+
(
v1
-
v0
)
*
f
;
}
typedef
struct
ThreadData
{
AVFrame
*
out
,
*
in
;
}
ThreadData
;
static
int
vibrance_slice8
(
AVFilterContext
*
avctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
VibranceContext
*
s
=
avctx
->
priv
;
AVFrame
*
frame
=
arg
;
ThreadData
*
td
=
arg
;
AVFrame
*
frame
=
td
->
out
;
AVFrame
*
in
=
td
->
in
;
const
int
width
=
frame
->
width
;
const
int
height
=
frame
->
height
;
const
float
scale
=
1
.
f
/
255
.
f
;
...
...
@@ -74,15 +81,25 @@ static int vibrance_slice8(AVFilterContext *avctx, void *arg, int jobnr, int nb_
const
int
glinesize
=
frame
->
linesize
[
0
];
const
int
blinesize
=
frame
->
linesize
[
1
];
const
int
rlinesize
=
frame
->
linesize
[
2
];
const
int
alinesize
=
frame
->
linesize
[
3
];
const
int
gslinesize
=
in
->
linesize
[
0
];
const
int
bslinesize
=
in
->
linesize
[
1
];
const
int
rslinesize
=
in
->
linesize
[
2
];
const
int
aslinesize
=
in
->
linesize
[
3
];
const
uint8_t
*
gsrc
=
in
->
data
[
0
]
+
slice_start
*
glinesize
;
const
uint8_t
*
bsrc
=
in
->
data
[
1
]
+
slice_start
*
blinesize
;
const
uint8_t
*
rsrc
=
in
->
data
[
2
]
+
slice_start
*
rlinesize
;
uint8_t
*
gptr
=
frame
->
data
[
0
]
+
slice_start
*
glinesize
;
uint8_t
*
bptr
=
frame
->
data
[
1
]
+
slice_start
*
blinesize
;
uint8_t
*
rptr
=
frame
->
data
[
2
]
+
slice_start
*
rlinesize
;
const
uint8_t
*
asrc
=
in
->
data
[
3
];
uint8_t
*
aptr
=
frame
->
data
[
3
];
for
(
int
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
for
(
int
x
=
0
;
x
<
width
;
x
++
)
{
float
g
=
g
ptr
[
x
]
*
scale
;
float
b
=
b
ptr
[
x
]
*
scale
;
float
r
=
r
ptr
[
x
]
*
scale
;
float
g
=
g
src
[
x
]
*
scale
;
float
b
=
b
src
[
x
]
*
scale
;
float
r
=
r
src
[
x
]
*
scale
;
float
max_color
=
FFMAX3
(
r
,
g
,
b
);
float
min_color
=
FFMIN3
(
r
,
g
,
b
);
float
color_saturation
=
max_color
-
min_color
;
...
...
@@ -100,6 +117,12 @@ static int vibrance_slice8(AVFilterContext *avctx, void *arg, int jobnr, int nb_
rptr
[
x
]
=
av_clip_uint8
(
r
*
255
.
f
);
}
if
(
aptr
&&
alinesize
&&
frame
!=
in
)
memcpy
(
aptr
+
alinesize
*
y
,
asrc
+
aslinesize
*
y
,
width
);
gsrc
+=
gslinesize
;
bsrc
+=
bslinesize
;
rsrc
+=
rslinesize
;
gptr
+=
glinesize
;
bptr
+=
blinesize
;
rptr
+=
rlinesize
;
...
...
@@ -111,7 +134,9 @@ static int vibrance_slice8(AVFilterContext *avctx, void *arg, int jobnr, int nb_
static
int
vibrance_slice16
(
AVFilterContext
*
avctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
VibranceContext
*
s
=
avctx
->
priv
;
AVFrame
*
frame
=
arg
;
ThreadData
*
td
=
arg
;
AVFrame
*
frame
=
td
->
out
;
AVFrame
*
in
=
td
->
in
;
const
int
depth
=
s
->
depth
;
const
float
max
=
(
1
<<
depth
)
-
1
;
const
float
scale
=
1
.
f
/
max
;
...
...
@@ -130,18 +155,28 @@ static int vibrance_slice16(AVFilterContext *avctx, void *arg, int jobnr, int nb
const
float
srintensity
=
alternate
*
FFSIGN
(
rintensity
);
const
int
slice_start
=
(
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
height
*
(
jobnr
+
1
))
/
nb_jobs
;
const
int
gslinesize
=
in
->
linesize
[
0
]
/
2
;
const
int
bslinesize
=
in
->
linesize
[
1
]
/
2
;
const
int
rslinesize
=
in
->
linesize
[
2
]
/
2
;
const
int
aslinesize
=
in
->
linesize
[
3
]
/
2
;
const
int
glinesize
=
frame
->
linesize
[
0
]
/
2
;
const
int
blinesize
=
frame
->
linesize
[
1
]
/
2
;
const
int
rlinesize
=
frame
->
linesize
[
2
]
/
2
;
const
int
alinesize
=
frame
->
linesize
[
3
]
/
2
;
const
uint16_t
*
gsrc
=
(
const
uint16_t
*
)
in
->
data
[
0
]
+
slice_start
*
gslinesize
;
const
uint16_t
*
bsrc
=
(
const
uint16_t
*
)
in
->
data
[
1
]
+
slice_start
*
bslinesize
;
const
uint16_t
*
rsrc
=
(
const
uint16_t
*
)
in
->
data
[
2
]
+
slice_start
*
rslinesize
;
uint16_t
*
gptr
=
(
uint16_t
*
)
frame
->
data
[
0
]
+
slice_start
*
glinesize
;
uint16_t
*
bptr
=
(
uint16_t
*
)
frame
->
data
[
1
]
+
slice_start
*
blinesize
;
uint16_t
*
rptr
=
(
uint16_t
*
)
frame
->
data
[
2
]
+
slice_start
*
rlinesize
;
const
uint16_t
*
asrc
=
(
const
uint16_t
*
)
in
->
data
[
3
];
uint16_t
*
aptr
=
(
uint16_t
*
)
frame
->
data
[
3
];
for
(
int
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
for
(
int
x
=
0
;
x
<
width
;
x
++
)
{
float
g
=
g
ptr
[
x
]
*
scale
;
float
b
=
b
ptr
[
x
]
*
scale
;
float
r
=
r
ptr
[
x
]
*
scale
;
float
g
=
g
src
[
x
]
*
scale
;
float
b
=
b
src
[
x
]
*
scale
;
float
r
=
r
src
[
x
]
*
scale
;
float
max_color
=
FFMAX3
(
r
,
g
,
b
);
float
min_color
=
FFMIN3
(
r
,
g
,
b
);
float
color_saturation
=
max_color
-
min_color
;
...
...
@@ -159,6 +194,12 @@ static int vibrance_slice16(AVFilterContext *avctx, void *arg, int jobnr, int nb
rptr
[
x
]
=
av_clip_uintp2_c
(
r
*
max
,
depth
);
}
if
(
aptr
&&
alinesize
&&
frame
!=
in
)
memcpy
(
aptr
+
alinesize
*
y
,
asrc
+
aslinesize
*
y
,
width
*
2
);
gsrc
+=
gslinesize
;
bsrc
+=
bslinesize
;
rsrc
+=
rslinesize
;
gptr
+=
glinesize
;
bptr
+=
blinesize
;
rptr
+=
rlinesize
;
...
...
@@ -170,7 +211,9 @@ static int vibrance_slice16(AVFilterContext *avctx, void *arg, int jobnr, int nb
static
int
vibrance_slice8p
(
AVFilterContext
*
avctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
VibranceContext
*
s
=
avctx
->
priv
;
AVFrame
*
frame
=
arg
;
ThreadData
*
td
=
arg
;
AVFrame
*
frame
=
td
->
out
;
AVFrame
*
in
=
td
->
in
;
const
int
step
=
s
->
step
;
const
int
width
=
frame
->
width
;
const
int
height
=
frame
->
height
;
...
...
@@ -181,6 +224,7 @@ static int vibrance_slice8p(AVFilterContext *avctx, void *arg, int jobnr, int nb
const
uint8_t
roffset
=
s
->
rgba_map
[
R
];
const
uint8_t
goffset
=
s
->
rgba_map
[
G
];
const
uint8_t
boffset
=
s
->
rgba_map
[
B
];
const
uint8_t
aoffset
=
s
->
rgba_map
[
A
];
const
float
intensity
=
s
->
intensity
;
const
float
alternate
=
s
->
alternate
?
1
.
f
:
-
1
.
f
;
const
float
gintensity
=
intensity
*
s
->
balance
[
0
];
...
...
@@ -192,13 +236,15 @@ static int vibrance_slice8p(AVFilterContext *avctx, void *arg, int jobnr, int nb
const
int
slice_start
=
(
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
height
*
(
jobnr
+
1
))
/
nb_jobs
;
const
int
linesize
=
frame
->
linesize
[
0
];
const
int
slinesize
=
in
->
linesize
[
0
];
const
uint8_t
*
src
=
in
->
data
[
0
]
+
slice_start
*
slinesize
;
uint8_t
*
ptr
=
frame
->
data
[
0
]
+
slice_start
*
linesize
;
for
(
int
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
for
(
int
x
=
0
;
x
<
width
;
x
++
)
{
float
g
=
ptr
[
x
*
step
+
goffset
]
*
scale
;
float
b
=
ptr
[
x
*
step
+
boffset
]
*
scale
;
float
r
=
ptr
[
x
*
step
+
roffset
]
*
scale
;
float
g
=
src
[
x
*
step
+
goffset
]
*
scale
;
float
b
=
src
[
x
*
step
+
boffset
]
*
scale
;
float
r
=
src
[
x
*
step
+
roffset
]
*
scale
;
float
max_color
=
FFMAX3
(
r
,
g
,
b
);
float
min_color
=
FFMIN3
(
r
,
g
,
b
);
float
color_saturation
=
max_color
-
min_color
;
...
...
@@ -214,9 +260,13 @@ static int vibrance_slice8p(AVFilterContext *avctx, void *arg, int jobnr, int nb
ptr
[
x
*
step
+
goffset
]
=
av_clip_uint8
(
g
*
255
.
f
);
ptr
[
x
*
step
+
boffset
]
=
av_clip_uint8
(
b
*
255
.
f
);
ptr
[
x
*
step
+
roffset
]
=
av_clip_uint8
(
r
*
255
.
f
);
if
(
frame
!=
in
)
ptr
[
x
*
step
+
aoffset
]
=
src
[
x
*
step
+
aoffset
];
}
ptr
+=
linesize
;
src
+=
slinesize
;
}
return
0
;
...
...
@@ -225,7 +275,9 @@ static int vibrance_slice8p(AVFilterContext *avctx, void *arg, int jobnr, int nb
static
int
vibrance_slice16p
(
AVFilterContext
*
avctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
VibranceContext
*
s
=
avctx
->
priv
;
AVFrame
*
frame
=
arg
;
ThreadData
*
td
=
arg
;
AVFrame
*
frame
=
td
->
out
;
AVFrame
*
in
=
td
->
in
;
const
int
step
=
s
->
step
;
const
int
depth
=
s
->
depth
;
const
float
max
=
(
1
<<
depth
)
-
1
;
...
...
@@ -236,6 +288,7 @@ static int vibrance_slice16p(AVFilterContext *avctx, void *arg, int jobnr, int n
const
uint8_t
roffset
=
s
->
rgba_map
[
R
];
const
uint8_t
goffset
=
s
->
rgba_map
[
G
];
const
uint8_t
boffset
=
s
->
rgba_map
[
B
];
const
uint8_t
aoffset
=
s
->
rgba_map
[
A
];
const
int
width
=
frame
->
width
;
const
int
height
=
frame
->
height
;
const
float
intensity
=
s
->
intensity
;
...
...
@@ -249,13 +302,15 @@ static int vibrance_slice16p(AVFilterContext *avctx, void *arg, int jobnr, int n
const
int
slice_start
=
(
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
height
*
(
jobnr
+
1
))
/
nb_jobs
;
const
int
linesize
=
frame
->
linesize
[
0
]
/
2
;
const
int
slinesize
=
in
->
linesize
[
0
]
/
2
;
const
uint16_t
*
src
=
(
const
uint16_t
*
)
in
->
data
[
0
]
+
slice_start
*
slinesize
;
uint16_t
*
ptr
=
(
uint16_t
*
)
frame
->
data
[
0
]
+
slice_start
*
linesize
;
for
(
int
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
for
(
int
x
=
0
;
x
<
width
;
x
++
)
{
float
g
=
ptr
[
x
*
step
+
goffset
]
*
scale
;
float
b
=
ptr
[
x
*
step
+
boffset
]
*
scale
;
float
r
=
ptr
[
x
*
step
+
roffset
]
*
scale
;
float
g
=
src
[
x
*
step
+
goffset
]
*
scale
;
float
b
=
src
[
x
*
step
+
boffset
]
*
scale
;
float
r
=
src
[
x
*
step
+
roffset
]
*
scale
;
float
max_color
=
FFMAX3
(
r
,
g
,
b
);
float
min_color
=
FFMIN3
(
r
,
g
,
b
);
float
color_saturation
=
max_color
-
min_color
;
...
...
@@ -271,25 +326,46 @@ static int vibrance_slice16p(AVFilterContext *avctx, void *arg, int jobnr, int n
ptr
[
x
*
step
+
goffset
]
=
av_clip_uintp2_c
(
g
*
max
,
depth
);
ptr
[
x
*
step
+
boffset
]
=
av_clip_uintp2_c
(
b
*
max
,
depth
);
ptr
[
x
*
step
+
roffset
]
=
av_clip_uintp2_c
(
r
*
max
,
depth
);
if
(
frame
!=
in
)
ptr
[
x
*
step
+
aoffset
]
=
src
[
x
*
step
+
aoffset
];
}
ptr
+=
linesize
;
src
+=
slinesize
;
}
return
0
;
}
static
int
filter_frame
(
AVFilterLink
*
link
,
AVFrame
*
frame
)
static
int
filter_frame
(
AVFilterLink
*
link
,
AVFrame
*
in
)
{
AVFilterContext
*
avctx
=
link
->
dst
;
AVFilterLink
*
outlink
=
avctx
->
outputs
[
0
];
VibranceContext
*
s
=
avctx
->
priv
;
ThreadData
td
;
AVFrame
*
out
;
int
res
;
if
(
res
=
ff_filter_execute
(
avctx
,
s
->
do_slice
,
frame
,
NULL
,
FFMIN
(
frame
->
height
,
ff_filter_get_nb_threads
(
avctx
))))
if
(
av_frame_is_writable
(
in
))
{
out
=
in
;
}
else
{
out
=
ff_get_video_buffer
(
outlink
,
outlink
->
w
,
outlink
->
h
);
if
(
!
out
)
{
av_frame_free
(
&
in
);
return
AVERROR
(
ENOMEM
);
}
av_frame_copy_props
(
out
,
in
);
}
td
.
out
=
out
;
td
.
in
=
in
;
if
(
res
=
ff_filter_execute
(
avctx
,
s
->
do_slice
,
&
td
,
NULL
,
FFMIN
(
out
->
height
,
ff_filter_get_nb_threads
(
avctx
))))
return
res
;
return
ff_filter_frame
(
avctx
->
outputs
[
0
],
frame
);
if
(
out
!=
in
)
av_frame_free
(
&
in
);
return
ff_filter_frame
(
outlink
,
out
);
}
static
const
enum
AVPixelFormat
pixel_fmts
[]
=
{
...
...
@@ -335,7 +411,6 @@ static const AVFilterPad vibrance_inputs[] = {
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
flags
=
AVFILTERPAD_FLAG_NEEDS_WRITABLE
,
.
filter_frame
=
filter_frame
,
.
config_props
=
config_input
,
},
...
...
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