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
e6876c7b
Commit
e6876c7b
authored
Aug 19, 2013
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavfi/hue: use lookup tables
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
ca7f637a
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
49 additions
and
30 deletions
+49
-30
vf_hue.c
libavfilter/vf_hue.c
+49
-30
No files found.
libavfilter/vf_hue.c
View file @
e6876c7b
...
...
@@ -73,6 +73,8 @@ typedef struct {
int32_t
hue_sin
;
int32_t
hue_cos
;
double
var_values
[
VAR_NB
];
uint8_t
lut_u
[
256
][
256
];
uint8_t
lut_v
[
256
][
256
];
}
HueContext
;
#define OFFSET(x) offsetof(HueContext, x)
...
...
@@ -94,12 +96,43 @@ static inline void compute_sin_and_cos(HueContext *hue)
/*
* Scale the value to the norm of the resulting (U,V) vector, that is
* the saturation.
* This will be useful in the
process_chrominance
function.
* This will be useful in the
apply_lut
function.
*/
hue
->
hue_sin
=
rint
(
sin
(
hue
->
hue
)
*
(
1
<<
16
)
*
hue
->
saturation
);
hue
->
hue_cos
=
rint
(
cos
(
hue
->
hue
)
*
(
1
<<
16
)
*
hue
->
saturation
);
}
static
inline
void
create_chrominance_lut
(
HueContext
*
h
,
const
int32_t
c
,
const
int32_t
s
)
{
int32_t
i
,
j
,
u
,
v
,
new_u
,
new_v
;
/*
* If we consider U and V as the components of a 2D vector then its angle
* is the hue and the norm is the saturation
*/
for
(
i
=
0
;
i
<
256
;
i
++
)
{
for
(
j
=
0
;
j
<
256
;
j
++
)
{
/* Normalize the components from range [16;140] to [-112;112] */
u
=
i
-
128
;
v
=
j
-
128
;
/*
* Apply the rotation of the vector : (c * u) - (s * v)
* (s * u) + (c * v)
* De-normalize the components (without forgetting to scale 128
* by << 16)
* Finally scale back the result by >> 16
*/
new_u
=
((
c
*
u
)
-
(
s
*
v
)
+
(
1
<<
15
)
+
(
128
<<
16
))
>>
16
;
new_v
=
((
s
*
u
)
+
(
c
*
v
)
+
(
1
<<
15
)
+
(
128
<<
16
))
>>
16
;
/* Prevent a potential overflow */
h
->
lut_u
[
i
][
j
]
=
av_clip_uint8_c
(
new_u
);
h
->
lut_v
[
i
][
j
]
=
av_clip_uint8_c
(
new_v
);
}
}
}
static
int
set_expr
(
AVExpr
**
pexpr_ptr
,
char
**
expr_ptr
,
const
char
*
expr
,
const
char
*
option
,
void
*
log_ctx
)
{
...
...
@@ -202,36 +235,20 @@ static int config_props(AVFilterLink *inlink)
return
0
;
}
static
void
process_chrominance
(
uint8_t
*
udst
,
uint8_t
*
vdst
,
const
int
dst_linesize
,
uint8_t
*
usrc
,
uint8_t
*
vsrc
,
const
int
src
_linesize
,
int
w
,
int
h
,
const
int32_t
c
,
const
int32_t
s
)
static
void
apply_lut
(
HueContext
*
s
,
uint8_t
*
udst
,
uint8_t
*
vdst
,
const
int
dst
_linesize
,
uint8_t
*
usrc
,
uint8_t
*
vsrc
,
const
int
src_linesize
,
int
w
,
int
h
)
{
int32_t
u
,
v
,
new_u
,
new_v
;
int
i
;
/*
* If we consider U and V as the components of a 2D vector then its angle
* is the hue and the norm is the saturation
*/
while
(
h
--
)
{
for
(
i
=
0
;
i
<
w
;
i
++
)
{
/* Normalize the components from range [16;140] to [-112;112] */
u
=
usrc
[
i
]
-
128
;
v
=
vsrc
[
i
]
-
128
;
/*
* Apply the rotation of the vector : (c * u) - (s * v)
* (s * u) + (c * v)
* De-normalize the components (without forgetting to scale 128
* by << 16)
* Finally scale back the result by >> 16
*/
new_u
=
((
c
*
u
)
-
(
s
*
v
)
+
(
1
<<
15
)
+
(
128
<<
16
))
>>
16
;
new_v
=
((
s
*
u
)
+
(
c
*
v
)
+
(
1
<<
15
)
+
(
128
<<
16
))
>>
16
;
const
int
u
=
usrc
[
i
];
const
int
v
=
vsrc
[
i
];
/* Prevent a potential overflow */
udst
[
i
]
=
av_clip_uint8_c
(
new_u
);
vdst
[
i
]
=
av_clip_uint8_c
(
new_v
);
udst
[
i
]
=
s
->
lut_u
[
u
][
v
];
vdst
[
i
]
=
s
->
lut_v
[
u
][
v
];
}
usrc
+=
src_linesize
;
...
...
@@ -249,6 +266,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
HueContext
*
hue
=
inlink
->
dst
->
priv
;
AVFilterLink
*
outlink
=
inlink
->
dst
->
outputs
[
0
];
AVFrame
*
outpic
;
const
int32_t
old_hue_sin
=
hue
->
hue_sin
,
old_hue_cos
=
hue
->
hue_cos
;
int
direct
=
0
;
if
(
av_frame_is_writable
(
inpic
))
{
...
...
@@ -292,6 +310,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
hue
->
var_values
[
VAR_T
],
(
int
)
hue
->
var_values
[
VAR_N
]);
compute_sin_and_cos
(
hue
);
if
(
old_hue_sin
!=
hue
->
hue_sin
||
old_hue_cos
!=
hue
->
hue_cos
)
create_chrominance_lut
(
hue
,
hue
->
hue_cos
,
hue
->
hue_sin
);
if
(
!
direct
)
{
av_image_copy_plane
(
outpic
->
data
[
0
],
outpic
->
linesize
[
0
],
...
...
@@ -303,11 +323,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
inlink
->
w
,
inlink
->
h
);
}
process_chrominance
(
outpic
->
data
[
1
],
outpic
->
data
[
2
],
outpic
->
linesize
[
1
],
inpic
->
data
[
1
],
inpic
->
data
[
2
],
inpic
->
linesize
[
1
],
FF_CEIL_RSHIFT
(
inlink
->
w
,
hue
->
hsub
),
FF_CEIL_RSHIFT
(
inlink
->
h
,
hue
->
vsub
),
hue
->
hue_cos
,
hue
->
hue_sin
);
apply_lut
(
hue
,
outpic
->
data
[
1
],
outpic
->
data
[
2
],
outpic
->
linesize
[
1
],
inpic
->
data
[
1
],
inpic
->
data
[
2
],
inpic
->
linesize
[
1
],
FF_CEIL_RSHIFT
(
inlink
->
w
,
hue
->
hsub
),
FF_CEIL_RSHIFT
(
inlink
->
h
,
hue
->
vsub
));
if
(
!
direct
)
av_frame_free
(
&
inpic
);
...
...
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