Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Xiph.Org
aom-rav1e
Commits
91801176
Commit
91801176
authored
Jul 24, 2014
by
Marco Paniconi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
vp8: Add an aggressive denoising mode.
Change-Id: Ie4686e1b15af6bcc8d59d585bbeb996f38224522
parent
ac1f0618
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
136 additions
and
17 deletions
+136
-17
examples/vpx_temporal_svc_encoder.c
examples/vpx_temporal_svc_encoder.c
+1
-1
vp8/common/onyx.h
vp8/common/onyx.h
+2
-2
vp8/encoder/denoising.c
vp8/encoder/denoising.c
+40
-10
vp8/encoder/denoising.h
vp8/encoder/denoising.h
+25
-1
vp8/encoder/encodeframe.c
vp8/encoder/encodeframe.c
+13
-0
vp8/encoder/ethreading.c
vp8/encoder/ethreading.c
+15
-0
vp8/encoder/onyx_if.c
vp8/encoder/onyx_if.c
+30
-1
vp8/encoder/onyx_int.h
vp8/encoder/onyx_int.h
+2
-0
vp8/encoder/pickinter.c
vp8/encoder/pickinter.c
+8
-2
No files found.
examples/vpx_temporal_svc_encoder.c
View file @
91801176
...
...
@@ -579,7 +579,7 @@ int main(int argc, char **argv) {
if
(
strncmp
(
encoder
->
name
,
"vp8"
,
3
)
==
0
)
{
vpx_codec_control
(
&
codec
,
VP8E_SET_CPUUSED
,
-
speed
);
vpx_codec_control
(
&
codec
,
VP8E_SET_NOISE_SENSITIVITY
,
kDenoiserOnYOnly
);
vpx_codec_control
(
&
codec
,
VP8E_SET_NOISE_SENSITIVITY
,
kDenoiserOnYOnly
);
}
else
if
(
strncmp
(
encoder
->
name
,
"vp9"
,
3
)
==
0
)
{
vpx_codec_control
(
&
codec
,
VP8E_SET_CPUUSED
,
speed
);
vpx_codec_control
(
&
codec
,
VP9E_SET_AQ_MODE
,
3
);
...
...
vp8/common/onyx.h
View file @
91801176
...
...
@@ -108,8 +108,8 @@ extern "C"
* For temporal denoiser: noise_sensitivity = 0 means off,
* noise_sensitivity = 1 means temporal denoiser on for Y channel only,
* noise_sensitivity = 2 means temporal denoiser on for all channels.
* noise_sensitivity = 3
will be used for aggressive mode in futur
e.
* Temporal denoiser is enabled via the
build
option
* noise_sensitivity = 3
means aggressive denoising mod
e.
* Temporal denoiser is enabled via the
configuration
option
:
* CONFIG_TEMPORAL_DENOISING.
* For spatial denoiser: noise_sensitivity controls the amount of
* pre-processing blur: noise_sensitivity = 0 means off.
...
...
vp8/encoder/denoising.c
View file @
91801176
...
...
@@ -8,6 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <limits.h>
#include "denoising.h"
#include "vp8/common/reconinter.h"
...
...
@@ -333,12 +335,33 @@ int vp8_denoiser_filter_uv_c(unsigned char *mc_running_avg_uv,
return
FILTER_BLOCK
;
}
void
vp8_denoiser_set_parameters
(
VP8_DENOISER
*
denoiser
)
{
if
(
!
denoiser
->
aggressive_mode
)
{
denoiser
->
denoise_pars
.
scale_sse_thresh
=
1
;
denoiser
->
denoise_pars
.
scale_motion_thresh
=
8
;
denoiser
->
denoise_pars
.
scale_increase_filter
=
0
;
denoiser
->
denoise_pars
.
denoise_mv_bias
=
95
;
denoiser
->
denoise_pars
.
pickmode_mv_bias
=
100
;
denoiser
->
denoise_pars
.
qp_thresh
=
0
;
denoiser
->
denoise_pars
.
consec_zerolast
=
UINT_MAX
;
}
else
{
denoiser
->
denoise_pars
.
scale_sse_thresh
=
2
;
denoiser
->
denoise_pars
.
scale_motion_thresh
=
16
;
denoiser
->
denoise_pars
.
scale_increase_filter
=
1
;
denoiser
->
denoise_pars
.
denoise_mv_bias
=
60
;
denoiser
->
denoise_pars
.
pickmode_mv_bias
=
60
;
denoiser
->
denoise_pars
.
qp_thresh
=
100
;
denoiser
->
denoise_pars
.
consec_zerolast
=
10
;
}
}
int
vp8_denoiser_allocate
(
VP8_DENOISER
*
denoiser
,
int
width
,
int
height
,
int
num_mb_rows
,
int
num_mb_cols
)
int
num_mb_rows
,
int
num_mb_cols
,
int
mode
)
{
int
i
;
assert
(
denoiser
);
denoiser
->
num_mb_cols
=
num_mb_cols
;
denoiser
->
aggressive_mode
=
mode
;
for
(
i
=
0
;
i
<
MAX_REF_FRAMES
;
i
++
)
{
...
...
@@ -369,10 +392,11 @@ int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height,
denoiser
->
denoise_state
=
vpx_calloc
((
num_mb_rows
*
num_mb_cols
),
1
);
vpx_memset
(
denoiser
->
denoise_state
,
0
,
(
num_mb_rows
*
num_mb_cols
));
vp8_denoiser_set_parameters
(
denoiser
);
return
0
;
}
void
vp8_denoiser_free
(
VP8_DENOISER
*
denoiser
)
{
int
i
;
...
...
@@ -401,6 +425,7 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
{
int
mv_row
;
int
mv_col
;
unsigned
int
motion_threshold
;
unsigned
int
motion_magnitude2
;
unsigned
int
sse_thresh
;
int
sse_diff_thresh
=
0
;
...
...
@@ -424,7 +449,7 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
MB_MODE_INFO
*
mbmi
=
&
filter_xd
->
mode_info_context
->
mbmi
;
int
sse_diff
=
0
;
// Bias on zero motion vector sse.
int
zero_bias
=
95
;
const
int
zero_bias
=
denoiser
->
denoise_pars
.
denoise_mv_bias
;
zero_mv_sse
=
(
unsigned
int
)((
int64_t
)
zero_mv_sse
*
zero_bias
/
100
);
sse_diff
=
zero_mv_sse
-
best_sse
;
...
...
@@ -502,14 +527,19 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
mv_row
=
x
->
best_sse_mv
.
as_mv
.
row
;
mv_col
=
x
->
best_sse_mv
.
as_mv
.
col
;
motion_magnitude2
=
mv_row
*
mv_row
+
mv_col
*
mv_col
;
sse
_thresh
=
SSE_THRESHOLD
;
if
(
x
->
increase_denoising
)
sse_thresh
=
SSE
_THRESHOLD
_HIGH
;
motion
_thresh
old
=
denoiser
->
denoise_pars
.
scale_motion_thresh
*
NOISE_MOTION
_THRESHOLD
;
if
(
best_sse
>
sse_thresh
||
motion_magnitude2
>
8
*
NOISE_MOTION_THRESHOLD
)
{
decision
=
COPY_BLOCK
;
}
if
(
motion_magnitude2
<
denoiser
->
denoise_pars
.
scale_increase_filter
*
NOISE_MOTION_THRESHOLD
)
x
->
increase_denoising
=
1
;
sse_thresh
=
denoiser
->
denoise_pars
.
scale_sse_thresh
*
SSE_THRESHOLD
;
if
(
x
->
increase_denoising
)
sse_thresh
=
denoiser
->
denoise_pars
.
scale_sse_thresh
*
SSE_THRESHOLD_HIGH
;
if
(
best_sse
>
sse_thresh
||
motion_magnitude2
>
motion_threshold
)
decision
=
COPY_BLOCK
;
if
(
decision
==
FILTER_BLOCK
)
{
...
...
vp8/encoder/denoising.h
View file @
91801176
...
...
@@ -39,16 +39,40 @@ enum vp8_denoiser_filter_state {
kFilterNonZeroMV
};
typedef
struct
{
// Scale factor on sse threshold above which no denoising is done.
unsigned
int
scale_sse_thresh
;
// Scale factor on motion magnitude threshold above which no
// denoising is done.
unsigned
int
scale_motion_thresh
;
// Scale factor on motion magnitude below which we increase the strength of
// the temporal filter (in function vp8_denoiser_filter).
unsigned
int
scale_increase_filter
;
// Scale factor to bias to ZEROMV for denoising.
unsigned
int
denoise_mv_bias
;
// Scale factor to bias to ZEROMV for coding mode selection.
unsigned
int
pickmode_mv_bias
;
// Quantizer threshold below which we use the segmentation map to switch off
// loop filter for blocks that have been coded as ZEROMV-LAST a certain number
// (consec_zerolast) of consecutive frames. Note that the delta-QP is set to
// 0 when segmentation map is used for shutting off loop filter.
unsigned
int
qp_thresh
;
// Threshold for number of consecutive frames for blocks coded as ZEROMV-LAST.
unsigned
int
consec_zerolast
;
}
denoise_params
;
typedef
struct
vp8_denoiser
{
YV12_BUFFER_CONFIG
yv12_running_avg
[
MAX_REF_FRAMES
];
YV12_BUFFER_CONFIG
yv12_mc_running_avg
;
unsigned
char
*
denoise_state
;
int
num_mb_cols
;
int
aggressive_mode
;
denoise_params
denoise_pars
;
}
VP8_DENOISER
;
int
vp8_denoiser_allocate
(
VP8_DENOISER
*
denoiser
,
int
width
,
int
height
,
int
num_mb_rows
,
int
num_mb_cols
);
int
num_mb_rows
,
int
num_mb_cols
,
int
mode
);
void
vp8_denoiser_free
(
VP8_DENOISER
*
denoiser
);
...
...
vp8/encoder/encodeframe.c
View file @
91801176
...
...
@@ -522,6 +522,19 @@ void encode_mb_row(VP8_COMP *cpi,
}
#endif
// Keep track of how many (consecutive) times a block is coded
// as ZEROMV_LASTREF, for base layer frames.
// Reset to 0 if its coded as anything else.
if
(
cpi
->
current_layer
==
0
)
{
if
(
xd
->
mode_info_context
->
mbmi
.
mode
==
ZEROMV
&&
xd
->
mode_info_context
->
mbmi
.
ref_frame
==
LAST_FRAME
)
{
// Increment, check for wrap-around.
if
(
cpi
->
consec_zero_last
[
map_index
+
mb_col
]
<
255
)
cpi
->
consec_zero_last
[
map_index
+
mb_col
]
+=
1
;
}
else
{
cpi
->
consec_zero_last
[
map_index
+
mb_col
]
=
0
;
}
}
/* Special case code for cyclic refresh
* If cyclic update enabled then copy xd->mbmi.segment_id; (which
...
...
vp8/encoder/ethreading.c
View file @
91801176
...
...
@@ -206,6 +206,21 @@ THREAD_FUNCTION thread_encoding_proc(void *p_data)
}
#endif
// Keep track of how many (consecutive) times a block
// is coded as ZEROMV_LASTREF, for base layer frames.
// Reset to 0 if its coded as anything else.
if
(
cpi
->
current_layer
==
0
)
{
if
(
xd
->
mode_info_context
->
mbmi
.
mode
==
ZEROMV
&&
xd
->
mode_info_context
->
mbmi
.
ref_frame
==
LAST_FRAME
)
{
// Increment, check for wrap-around.
if
(
cpi
->
consec_zero_last
[
map_index
+
mb_col
]
<
255
)
cpi
->
consec_zero_last
[
map_index
+
mb_col
]
+=
1
;
}
else
{
cpi
->
consec_zero_last
[
map_index
+
mb_col
]
=
0
;
}
}
/* Special case code for cyclic refresh
* If cyclic update enabled then copy
...
...
vp8/encoder/onyx_if.c
View file @
91801176
...
...
@@ -613,6 +613,24 @@ static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment)
while
(
block_count
&&
i
!=
cpi
->
cyclic_refresh_mode_index
);
cpi
->
cyclic_refresh_mode_index
=
i
;
#if CONFIG_TEMPORAL_DENOISING
if
(
cpi
->
denoiser
.
aggressive_mode
!=
0
&&
Q
<
cpi
->
denoiser
.
denoise_pars
.
qp_thresh
)
{
// Under aggressive denoising mode, use segmentation to turn off loop
// filter below some qp thresh. The loop filter is turned off for all
// blocks that have been encoded as ZEROMV LAST x frames in a row,
// where x is set by cpi->denoiser.denoise_pars.consec_zerolast.
// This is to avoid "dot" artifacts that can occur from repeated
// loop filtering on noisy input source.
cpi
->
cyclic_refresh_q
=
Q
;
lf_adjustment
=
-
MAX_LOOP_FILTER
;
for
(
i
=
0
;
i
<
mbs_in_frame
;
++
i
)
{
seg_map
[
i
]
=
(
cpi
->
consec_zero_last
[
i
]
>
cpi
->
denoiser
.
denoise_pars
.
consec_zerolast
)
?
1
:
0
;
}
}
#endif
}
/* Activate segmentation. */
...
...
@@ -1752,7 +1770,8 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf)
int
width
=
(
cpi
->
oxcf
.
Width
+
15
)
&
~
15
;
int
height
=
(
cpi
->
oxcf
.
Height
+
15
)
&
~
15
;
vp8_denoiser_allocate
(
&
cpi
->
denoiser
,
width
,
height
,
cpi
->
common
.
mb_rows
,
cpi
->
common
.
mb_cols
);
cm
->
mb_rows
,
cm
->
mb_cols
,
((
cpi
->
oxcf
.
noise_sensitivity
==
3
)
?
1
:
0
));
}
}
#endif
...
...
@@ -1896,6 +1915,9 @@ struct VP8_COMP* vp8_create_compressor(VP8_CONFIG *oxcf)
else
cpi
->
cyclic_refresh_map
=
(
signed
char
*
)
NULL
;
CHECK_MEM_ERROR
(
cpi
->
consec_zero_last
,
vpx_calloc
(
cpi
->
common
.
mb_rows
*
cpi
->
common
.
mb_cols
,
1
));
#ifdef VP8_ENTROPY_STATS
init_context_counters
();
#endif
...
...
@@ -2416,6 +2438,7 @@ void vp8_remove_compressor(VP8_COMP **ptr)
vpx_free
(
cpi
->
mb
.
ss
);
vpx_free
(
cpi
->
tok
);
vpx_free
(
cpi
->
cyclic_refresh_map
);
vpx_free
(
cpi
->
consec_zero_last
);
vp8_remove_common
(
&
cpi
->
common
);
vpx_free
(
cpi
);
...
...
@@ -3478,6 +3501,9 @@ static void encode_frame_to_data_rate
{
cpi
->
mb
.
rd_thresh_mult
[
i
]
=
128
;
}
// Reset the zero_last counter to 0 on key frame.
vpx_memset
(
cpi
->
consec_zero_last
,
0
,
cm
->
mb_rows
*
cm
->
mb_cols
);
}
#if 0
...
...
@@ -3899,6 +3925,7 @@ static void encode_frame_to_data_rate
#endif
#ifdef OUTPUT_YUV_SRC
vp8_write_yuv_frame
(
yuv_file
,
cpi
->
Source
);
#endif
...
...
@@ -3994,6 +4021,8 @@ static void encode_frame_to_data_rate
else
disable_segmentation
(
cpi
);
}
// Reset the consec_zero_last counter on key frame.
vpx_memset
(
cpi
->
consec_zero_last
,
0
,
cm
->
mb_rows
*
cm
->
mb_cols
);
vp8_set_quantizer
(
cpi
,
Q
);
}
...
...
vp8/encoder/onyx_int.h
View file @
91801176
...
...
@@ -511,6 +511,8 @@ typedef struct VP8_COMP
int
cyclic_refresh_mode_index
;
int
cyclic_refresh_q
;
signed
char
*
cyclic_refresh_map
;
// Count on how many (consecutive) times a macroblock uses ZER0MV_LAST.
unsigned
char
*
consec_zero_last
;
// Frame counter for the temporal pattern. Counter is rest when the temporal
// layers are changed dynamically (run-time change).
...
...
vp8/encoder/pickinter.c
View file @
91801176
...
...
@@ -40,7 +40,6 @@ extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES];
extern
int
vp8_cost_mv_ref
(
MB_PREDICTION_MODE
m
,
const
int
near_mv_ref_ct
[
4
]);
int
vp8_skip_fractional_mv_step
(
MACROBLOCK
*
mb
,
BLOCK
*
b
,
BLOCKD
*
d
,
int_mv
*
bestmv
,
int_mv
*
ref_mv
,
int
error_per_bit
,
...
...
@@ -694,6 +693,13 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
*/
calculate_zeromv_rd_adjustment
(
cpi
,
x
,
&
rd_adjustment
);
#if CONFIG_TEMPORAL_DENOISING
if
(
cpi
->
oxcf
.
noise_sensitivity
)
{
rd_adjustment
=
(
int
)(
rd_adjustment
*
cpi
->
denoiser
.
denoise_pars
.
pickmode_mv_bias
/
100
);
}
#endif
/* if we encode a new mv this is important
* find the best new motion vector
*/
...
...
@@ -1168,7 +1174,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
#if CONFIG_TEMPORAL_DENOISING
if
(
cpi
->
oxcf
.
noise_sensitivity
)
{
int
uv_denoise
=
(
cpi
->
oxcf
.
noise_sensitivity
=
=
2
)
?
1
:
0
;
int
uv_denoise
=
(
cpi
->
oxcf
.
noise_sensitivity
>
=
2
)
?
1
:
0
;
int
block_index
=
mb_row
*
cpi
->
common
.
mb_cols
+
mb_col
;
if
(
x
->
best_sse_inter_mode
==
DC_PRED
)
{
...
...
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