Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
A
aom-rav1e
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
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
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Xiph.Org
aom-rav1e
Commits
6c0a2692
Commit
6c0a2692
authored
10 years ago
by
Tim Kopp
Committed by
Gerrit Code Review
10 years ago
Browse files
Options
Downloads
Plain Diff
Merge "VP9 denoiser implemented FILTER_BLOCK case"
parents
3302147f
03a3ba4a
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
vp9/encoder/vp9_denoiser.c
+107
-42
107 additions, 42 deletions
vp9/encoder/vp9_denoiser.c
with
107 additions
and
42 deletions
vp9/encoder/vp9_denoiser.c
+
107
−
42
View file @
6c0a2692
...
...
@@ -33,30 +33,66 @@ static void make_grayscale(YV12_BUFFER_CONFIG *yuv);
static
const
int
widths
[]
=
{
4
,
4
,
8
,
8
,
8
,
16
,
16
,
16
,
32
,
32
,
32
,
64
,
64
};
static
const
int
heights
[]
=
{
4
,
8
,
4
,
8
,
16
,
8
,
16
,
32
,
16
,
32
,
64
,
32
,
64
};
static
VP9_DENOISER_DECISION
update_running_avg
(
const
uint8_t
*
mc_avg
,
int
mc_avg_stride
,
uint8_t
*
avg
,
int
avg_stride
,
const
uint8_t
*
sig
,
int
sig_stride
,
int
increase_denoising
,
BLOCK_SIZE
bs
)
{
static
int
absdiff_thresh
(
BLOCK_SIZE
bs
,
int
increase_denoising
)
{
(
void
)
bs
;
return
3
+
(
increase_denoising
?
1
:
0
);
}
static
int
delta_thresh
(
BLOCK_SIZE
bs
,
int
increase_denoising
)
{
(
void
)
bs
;
(
void
)
increase_denoising
;
return
4
;
}
static
int
noise_motion_thresh
(
BLOCK_SIZE
bs
,
int
increase_denoising
)
{
(
void
)
bs
;
(
void
)
increase_denoising
;
return
25
*
25
;
}
static
unsigned
int
sse_thresh
(
BLOCK_SIZE
bs
,
int
increase_denoising
)
{
return
widths
[
bs
]
*
heights
[
bs
]
*
(
increase_denoising
?
60
:
40
);
}
static
int
sse_diff_thresh
(
BLOCK_SIZE
bs
,
int
increase_denoising
,
int
mv_row
,
int
mv_col
)
{
if
(
mv_row
*
mv_row
+
mv_col
*
mv_col
>
noise_motion_thresh
(
bs
,
increase_denoising
))
{
return
0
;
}
else
{
return
widths
[
bs
]
*
heights
[
bs
]
*
20
;
}
}
static
int
total_adj_strong_thresh
(
BLOCK_SIZE
bs
,
int
increase_denoising
)
{
return
widths
[
bs
]
*
heights
[
bs
]
*
(
increase_denoising
?
3
:
2
);
}
static
int
total_adj_weak_thresh
(
BLOCK_SIZE
bs
,
int
increase_denoising
)
{
return
widths
[
bs
]
*
heights
[
bs
]
*
(
increase_denoising
?
3
:
2
);
}
static
VP9_DENOISER_DECISION
denoiser_filter
(
const
uint8_t
*
sig
,
int
sig_stride
,
const
uint8_t
*
mc_avg
,
int
mc_avg_stride
,
uint8_t
*
avg
,
int
avg_stride
,
int
increase_denoising
,
BLOCK_SIZE
bs
)
{
int
r
,
c
;
int
diff
,
adj
,
absdiff
;
int
shift_inc1
=
0
,
shift_inc2
=
1
;
const
uint8_t
*
sig_start
=
sig
;
const
uint8_t
*
mc_avg_start
=
mc_avg
;
uint8_t
*
avg_start
=
avg
;
int
diff
,
adj
,
absdiff
,
delta
;
int
adj_val
[]
=
{
3
,
4
,
6
};
int
total_adj
=
0
;
if
(
increase_denoising
)
{
shift_inc1
=
1
;
shift_inc2
=
2
;
}
// First attempt to apply a strong temporal denoising filter.
for
(
r
=
0
;
r
<
heights
[
bs
];
++
r
)
{
for
(
c
=
0
;
c
<
widths
[
bs
];
++
c
)
{
diff
=
mc_avg
[
c
]
-
sig
[
c
];
absdiff
=
abs
(
diff
);
if
(
absdiff
<=
3
+
shift_inc1
)
{
if
(
absdiff
<=
absdiff_thresh
(
bs
,
increase_denoising
)
)
{
avg
[
c
]
=
mc_avg
[
c
];
total_adj
+=
diff
;
}
else
{
...
...
@@ -84,7 +120,47 @@ static VP9_DENOISER_DECISION update_running_avg(const uint8_t *mc_avg,
avg
+=
avg_stride
;
mc_avg
+=
mc_avg_stride
;
}
return
total_adj
;
// If the strong filter did not modify the signal too much, we're all set.
if
(
abs
(
total_adj
)
<=
total_adj_strong_thresh
(
bs
,
increase_denoising
))
{
return
FILTER_BLOCK
;
}
// Otherwise, we try to dampen the filter if the delta is not too high.
delta
=
((
abs
(
total_adj
)
-
total_adj_strong_thresh
(
bs
,
increase_denoising
))
>>
8
)
+
1
;
if
(
delta
>
delta_thresh
(
bs
,
increase_denoising
))
{
return
COPY_BLOCK
;
}
mc_avg
=
mc_avg_start
;
avg
=
avg_start
;
sig
=
sig_start
;
for
(
r
=
0
;
r
<
heights
[
bs
];
++
r
)
{
for
(
c
=
0
;
c
<
widths
[
bs
];
++
c
)
{
diff
=
mc_avg
[
c
]
-
sig
[
c
];
adj
=
abs
(
diff
);
if
(
adj
>
delta
)
{
adj
=
delta
;
}
if
(
diff
>
0
)
{
avg
[
c
]
=
MAX
(
0
,
avg
[
c
]
-
adj
);
total_adj
+=
adj
;
}
else
{
avg
[
c
]
=
MIN
(
UINT8_MAX
,
avg
[
c
]
+
adj
);
total_adj
-=
adj
;
}
}
sig
+=
sig_stride
;
avg
+=
avg_stride
;
mc_avg
+=
mc_avg_stride
;
}
// We can use the filter if it has been sufficiently dampened
if
(
abs
(
total_adj
)
<=
total_adj_weak_thresh
(
bs
,
increase_denoising
))
{
return
FILTER_BLOCK
;
}
return
COPY_BLOCK
;
}
static
uint8_t
*
block_start
(
uint8_t
*
framebuf
,
int
stride
,
...
...
@@ -108,18 +184,8 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser,
int
increase_denoising
,
int
mi_row
,
int
mi_col
)
{
// constants
// TODO(tkopp): empirically determine good constants, or functions of block
// size.
int
NOISE_MOTION_THRESHOLD
=
25
*
25
;
int
SSE_DIFF_THRESHOLD
=
heights
[
bs
]
*
widths
[
bs
]
*
20
;
unsigned
int
SSE_THRESH
=
heights
[
bs
]
*
widths
[
bs
]
*
40
;
unsigned
int
SSE_THRESH_HI
=
heights
[
bs
]
*
widths
[
bs
]
*
60
;
int
mv_col
,
mv_row
;
int
sse_diff
=
denoiser
->
zero_mv_sse
-
denoiser
->
best_sse
;
int
sse_diff_thresh
;
int
sse_thresh
;
MV_REFERENCE_FRAME
frame
;
MACROBLOCKD
*
filter_mbd
=
&
mb
->
e_mbd
;
MB_MODE_INFO
*
mbmi
=
&
filter_mbd
->
mi
[
0
]
->
mbmi
;
...
...
@@ -131,20 +197,15 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser,
saved_pre
[
0
]
=
filter_mbd
->
plane
[
0
].
pre
[
0
];
saved_pre
[
1
]
=
filter_mbd
->
plane
[
0
].
pre
[
1
];
// Decide the threshold for sum squared error.
mv_col
=
denoiser
->
best_sse_mv
.
as_mv
.
col
;
mv_row
=
denoiser
->
best_sse_mv
.
as_mv
.
row
;
if
(
mv_row
*
mv_row
+
mv_col
*
mv_col
>
NOISE_MOTION_THRESHOLD
)
{
sse_diff_thresh
=
0
;
}
else
{
sse_diff_thresh
=
SSE_DIFF_THRESHOLD
;
}
frame
=
denoiser
->
best_reference_frame
;
// If the best reference frame uses inter-prediction and there is enough of a
// difference in sum-squared-error, use it.
if
(
frame
!=
INTRA_FRAME
&&
sse_diff
>
sse_diff_thresh
)
{
if
(
frame
!=
INTRA_FRAME
&&
sse_diff
>
sse_diff_thresh
(
bs
,
increase_denoising
,
mv_row
,
mv_col
))
{
mbmi
->
ref_frame
[
0
]
=
denoiser
->
best_reference_frame
;
mbmi
->
mode
=
denoiser
->
best_sse_inter_mode
;
mbmi
->
mv
[
0
]
=
denoiser
->
best_sse_mv
;
...
...
@@ -227,11 +288,12 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser,
mv_row
=
denoiser
->
best_sse_mv
.
as_mv
.
row
;
mv_col
=
denoiser
->
best_sse_mv
.
as_mv
.
col
;
sse_thresh
=
denoiser
->
increase_denoising
?
SSE_THRESH_HI
:
SSE_THRESH
;
// TODO(tkopp) why 8?
if
(
denoiser
->
best_sse
>
sse_thresh
||
mv_row
*
mv_row
+
mv_col
*
mv_col
>
8
*
NOISE_MOTION_THRESHOLD
)
{
if
(
denoiser
->
best_sse
>
sse_thresh
(
bs
,
increase_denoising
))
{
return
COPY_BLOCK
;
}
if
(
mv_row
*
mv_row
+
mv_col
*
mv_col
>
8
*
noise_motion_thresh
(
bs
,
increase_denoising
))
{
return
COPY_BLOCK
;
}
return
FILTER_BLOCK
;
...
...
@@ -240,7 +302,6 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser,
void
vp9_denoiser_denoise
(
VP9_DENOISER
*
denoiser
,
MACROBLOCK
*
mb
,
int
mi_row
,
int
mi_col
,
BLOCK_SIZE
bs
)
{
VP9_DENOISER_DECISION
decision
=
FILTER_BLOCK
;
YV12_BUFFER_CONFIG
avg
=
denoiser
->
running_avg_y
[
INTRA_FRAME
];
YV12_BUFFER_CONFIG
mc_avg
=
denoiser
->
mc_running_avg_y
;
uint8_t
*
avg_start
=
block_start
(
avg
.
y_buffer
,
avg
.
y_stride
,
mi_row
,
mi_col
);
...
...
@@ -251,13 +312,17 @@ void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb,
decision
=
perform_motion_compensation
(
denoiser
,
mb
,
bs
,
denoiser
->
increase_denoising
,
mi_row
,
mi_col
);
update_running_avg
(
mc_avg_start
,
mc_avg
.
y_stride
,
avg_start
,
avg
.
y_stride
,
mb
->
plane
[
0
].
src
.
buf
,
mb
->
plane
[
0
].
src
.
stride
,
0
,
bs
);
if
(
decision
==
FILTER_BLOCK
)
{
// TODO(tkopp)
decision
=
denoiser_filter
(
src
.
buf
,
src
.
stride
,
mc_avg_start
,
mc_avg
.
y_stride
,
avg_start
,
avg
.
y_stride
,
0
,
bs
);
}
if
(
decision
==
COPY_BLOCK
)
{
if
(
decision
==
FILTER_BLOCK
)
{
copy_block
(
src
.
buf
,
src
.
stride
,
avg_start
,
avg
.
y_stride
,
bs
);
}
else
{
// COPY_BLOCK
copy_block
(
avg_start
,
avg
.
y_stride
,
src
.
buf
,
src
.
stride
,
bs
);
}
}
...
...
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