Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Xiph.Org
aom-rav1e
Commits
6c0a2692
Commit
6c0a2692
authored
Jul 02, 2014
by
Tim Kopp
Committed by
Gerrit Code Review
Jul 02, 2014
Browse files
Merge "VP9 denoiser implemented FILTER_BLOCK case"
parents
3302147f
03a3ba4a
Changes
1
Hide whitespace changes
Inline
Side-by-side
vp9/encoder/vp9_denoiser.c
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
);
}
}
...
...
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