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
7cb7588b
Commit
7cb7588b
authored
Dec 03, 2014
by
Marco
Committed by
Gerrit Code Review
Dec 03, 2014
Browse files
Options
Browse Files
Download
Plain Diff
Merge "Various updates to vp8."
parents
33e61df7
af898b56
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1627 additions
and
371 deletions
+1627
-371
examples/vp8_multi_resolution_encoder.c
examples/vp8_multi_resolution_encoder.c
+696
-258
examples/vpx_temporal_svc_encoder.c
examples/vpx_temporal_svc_encoder.c
+6
-0
test/error_resilience_test.cc
test/error_resilience_test.cc
+199
-1
vp8/common/blockd.h
vp8/common/blockd.h
+4
-0
vp8/common/onyx.h
vp8/common/onyx.h
+1
-0
vp8/encoder/block.h
vp8/encoder/block.h
+4
-0
vp8/encoder/denoising.c
vp8/encoder/denoising.c
+13
-6
vp8/encoder/denoising.h
vp8/encoder/denoising.h
+2
-2
vp8/encoder/encodeframe.c
vp8/encoder/encodeframe.c
+7
-1
vp8/encoder/ethreading.c
vp8/encoder/ethreading.c
+7
-2
vp8/encoder/onyx_if.c
vp8/encoder/onyx_if.c
+264
-44
vp8/encoder/onyx_int.h
vp8/encoder/onyx_int.h
+9
-0
vp8/encoder/pickinter.c
vp8/encoder/pickinter.c
+293
-32
vp8/encoder/quantize.c
vp8/encoder/quantize.c
+16
-2
vp8/encoder/ratectrl.c
vp8/encoder/ratectrl.c
+7
-1
vp8/vp8_cx_iface.c
vp8/vp8_cx_iface.c
+77
-21
vpx/vp8cx.h
vpx/vp8cx.h
+17
-0
vpxenc.c
vpxenc.c
+5
-1
No files found.
examples/vp8_multi_resolution_encoder.c
View file @
7cb7588b
This diff is collapsed.
Click to expand it.
examples/vpx_temporal_svc_encoder.c
View file @
7cb7588b
...
...
@@ -675,6 +675,9 @@ int main(int argc, char **argv) {
die_codec
(
&
codec
,
"Failed to set SVC"
);
}
}
if
(
strncmp
(
encoder
->
name
,
"vp8"
,
3
)
==
0
)
{
vpx_codec_control
(
&
codec
,
VP8E_SET_SCREEN_CONTENT_MODE
,
0
);
}
vpx_codec_control
(
&
codec
,
VP8E_SET_STATIC_THRESHOLD
,
1
);
vpx_codec_control
(
&
codec
,
VP8E_SET_TOKEN_PARTITIONS
,
1
);
// This controls the maximum target size of the key frame.
...
...
@@ -697,6 +700,9 @@ int main(int argc, char **argv) {
cfg
.
ts_layer_id
[
frame_cnt
%
cfg
.
ts_periodicity
];
if
(
strncmp
(
encoder
->
name
,
"vp9"
,
3
)
==
0
)
{
vpx_codec_control
(
&
codec
,
VP9E_SET_SVC_LAYER_ID
,
&
layer_id
);
}
else
if
(
strncmp
(
encoder
->
name
,
"vp8"
,
3
)
==
0
)
{
vpx_codec_control
(
&
codec
,
VP8E_SET_TEMPORAL_LAYER_ID
,
layer_id
.
temporal_layer_id
);
}
flags
=
layer_flags
[
frame_cnt
%
flag_periodicity
];
frame_avail
=
vpx_img_read
(
&
raw
,
infile
);
...
...
test/error_resilience_test.cc
View file @
7cb7588b
...
...
@@ -316,7 +316,205 @@ TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
Reset
();
}
class
ErrorResilienceTestLargeCodecControls
:
public
::
libvpx_test
::
EncoderTest
,
public
::
libvpx_test
::
CodecTestWithParam
<
libvpx_test
::
TestMode
>
{
protected:
ErrorResilienceTestLargeCodecControls
()
:
EncoderTest
(
GET_PARAM
(
0
)),
encoding_mode_
(
GET_PARAM
(
1
))
{
Reset
();
}
virtual
~
ErrorResilienceTestLargeCodecControls
()
{}
void
Reset
()
{
last_pts_
=
0
;
tot_frame_number_
=
0
;
// For testing up to 3 layers.
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
bits_total_
[
i
]
=
0
;
}
duration_
=
0.0
;
}
virtual
void
SetUp
()
{
InitializeConfig
();
SetMode
(
encoding_mode_
);
}
//
// Frame flags and layer id for temporal layers.
//
// For two layers, test pattern is:
// 1 3
// 0 2 .....
// For three layers, test pattern is:
// 1 3 5 7
// 2 6
// 0 4 ....
// LAST is always update on base/layer 0, GOLDEN is updated on layer 1,
// and ALTREF is updated on top layer for 3 layer pattern.
int
SetFrameFlags
(
int
frame_num
,
int
num_temp_layers
)
{
int
frame_flags
=
0
;
if
(
num_temp_layers
==
2
)
{
if
(
frame_num
%
2
==
0
)
{
// Layer 0: predict from L and ARF, update L.
frame_flags
=
VP8_EFLAG_NO_REF_GF
|
VP8_EFLAG_NO_UPD_GF
|
VP8_EFLAG_NO_UPD_ARF
;
}
else
{
// Layer 1: predict from L, G and ARF, and update G.
frame_flags
=
VP8_EFLAG_NO_UPD_ARF
|
VP8_EFLAG_NO_UPD_LAST
|
VP8_EFLAG_NO_UPD_ENTROPY
;
}
}
else
if
(
num_temp_layers
==
3
)
{
if
(
frame_num
%
4
==
0
)
{
// Layer 0: predict from L, update L.
frame_flags
=
VP8_EFLAG_NO_UPD_GF
|
VP8_EFLAG_NO_UPD_ARF
|
VP8_EFLAG_NO_REF_GF
|
VP8_EFLAG_NO_REF_ARF
;
}
else
if
((
frame_num
-
2
)
%
4
==
0
)
{
// Layer 1: predict from L, G, update G.
frame_flags
=
VP8_EFLAG_NO_UPD_ARF
|
VP8_EFLAG_NO_UPD_LAST
|
VP8_EFLAG_NO_REF_ARF
;
}
else
if
((
frame_num
-
1
)
%
2
==
0
)
{
// Layer 2: predict from L, G, ARF; update ARG.
frame_flags
=
VP8_EFLAG_NO_UPD_GF
|
VP8_EFLAG_NO_UPD_LAST
;
}
}
return
frame_flags
;
}
int
SetLayerId
(
int
frame_num
,
int
num_temp_layers
)
{
int
layer_id
=
0
;
if
(
num_temp_layers
==
2
)
{
if
(
frame_num
%
2
==
0
)
{
layer_id
=
0
;
}
else
{
layer_id
=
1
;
}
}
else
if
(
num_temp_layers
==
3
)
{
if
(
frame_num
%
4
==
0
)
{
layer_id
=
0
;
}
else
if
((
frame_num
-
2
)
%
4
==
0
)
{
layer_id
=
1
;
}
else
if
((
frame_num
-
1
)
%
2
==
0
)
{
layer_id
=
2
;
}
}
return
layer_id
;
}
virtual
void
PreEncodeFrameHook
(
libvpx_test
::
VideoSource
*
video
,
libvpx_test
::
Encoder
*
encoder
)
{
if
(
cfg_
.
ts_number_layers
>
1
)
{
int
layer_id
=
SetLayerId
(
video
->
frame
(),
cfg_
.
ts_number_layers
);
int
frame_flags
=
SetFrameFlags
(
video
->
frame
(),
cfg_
.
ts_number_layers
);
if
(
video
->
frame
()
>
0
)
{
encoder
->
Control
(
VP8E_SET_TEMPORAL_LAYER_ID
,
layer_id
);
encoder
->
Control
(
VP8E_SET_FRAME_FLAGS
,
frame_flags
);
}
const
vpx_rational_t
tb
=
video
->
timebase
();
timebase_
=
static_cast
<
double
>
(
tb
.
num
)
/
tb
.
den
;
duration_
=
0
;
return
;
}
}
virtual
void
FramePktHook
(
const
vpx_codec_cx_pkt_t
*
pkt
)
{
// Time since last timestamp = duration.
vpx_codec_pts_t
duration
=
pkt
->
data
.
frame
.
pts
-
last_pts_
;
if
(
duration
>
1
)
{
// Update counter for total number of frames (#frames input to encoder).
// Needed for setting the proper layer_id below.
tot_frame_number_
+=
static_cast
<
int
>
(
duration
-
1
);
}
int
layer
=
SetLayerId
(
tot_frame_number_
,
cfg_
.
ts_number_layers
);
const
size_t
frame_size_in_bits
=
pkt
->
data
.
frame
.
sz
*
8
;
// Update the total encoded bits. For temporal layers, update the cumulative
// encoded bits per layer.
for
(
int
i
=
layer
;
i
<
static_cast
<
int
>
(
cfg_
.
ts_number_layers
);
++
i
)
{
bits_total_
[
i
]
+=
frame_size_in_bits
;
}
// Update the most recent pts.
last_pts_
=
pkt
->
data
.
frame
.
pts
;
++
tot_frame_number_
;
}
virtual
void
EndPassHook
(
void
)
{
duration_
=
(
last_pts_
+
1
)
*
timebase_
;
if
(
cfg_
.
ts_number_layers
>
1
)
{
for
(
int
layer
=
0
;
layer
<
static_cast
<
int
>
(
cfg_
.
ts_number_layers
);
++
layer
)
{
if
(
bits_total_
[
layer
])
{
// Effective file datarate:
effective_datarate_
[
layer
]
=
(
bits_total_
[
layer
]
/
1000.0
)
/
duration_
;
}
}
}
}
double
effective_datarate_
[
3
];
private:
libvpx_test
::
TestMode
encoding_mode_
;
vpx_codec_pts_t
last_pts_
;
double
timebase_
;
int64_t
bits_total_
[
3
];
double
duration_
;
int
tot_frame_number_
;
};
// Check two codec controls used for:
// (1) for setting temporal layer id, and (2) for settings encoder flags.
// This test invokes those controls for each frame, and verifies encoder/decoder
// mismatch and basic rate control response.
// TODO(marpan): Maybe move this test to datarate_test.cc.
TEST_P
(
ErrorResilienceTestLargeCodecControls
,
CodecControl3TemporalLayers
)
{
cfg_
.
rc_buf_initial_sz
=
500
;
cfg_
.
rc_buf_optimal_sz
=
500
;
cfg_
.
rc_buf_sz
=
1000
;
cfg_
.
rc_dropframe_thresh
=
1
;
cfg_
.
rc_min_quantizer
=
2
;
cfg_
.
rc_max_quantizer
=
56
;
cfg_
.
rc_end_usage
=
VPX_CBR
;
cfg_
.
rc_dropframe_thresh
=
1
;
cfg_
.
g_lag_in_frames
=
0
;
cfg_
.
kf_mode
=
VPX_KF_DISABLED
;
cfg_
.
g_error_resilient
=
1
;
// 3 Temporal layers. Framerate decimation (4, 2, 1).
cfg_
.
ts_number_layers
=
3
;
cfg_
.
ts_rate_decimator
[
0
]
=
4
;
cfg_
.
ts_rate_decimator
[
1
]
=
2
;
cfg_
.
ts_rate_decimator
[
2
]
=
1
;
cfg_
.
ts_periodicity
=
4
;
cfg_
.
ts_layer_id
[
0
]
=
0
;
cfg_
.
ts_layer_id
[
1
]
=
2
;
cfg_
.
ts_layer_id
[
2
]
=
1
;
cfg_
.
ts_layer_id
[
3
]
=
2
;
::
libvpx_test
::
I420VideoSource
video
(
"hantro_collage_w352h288.yuv"
,
352
,
288
,
30
,
1
,
0
,
200
);
for
(
int
i
=
200
;
i
<=
800
;
i
+=
200
)
{
cfg_
.
rc_target_bitrate
=
i
;
Reset
();
// 40-20-40 bitrate allocation for 3 temporal layers.
cfg_
.
ts_target_bitrate
[
0
]
=
40
*
cfg_
.
rc_target_bitrate
/
100
;
cfg_
.
ts_target_bitrate
[
1
]
=
60
*
cfg_
.
rc_target_bitrate
/
100
;
cfg_
.
ts_target_bitrate
[
2
]
=
cfg_
.
rc_target_bitrate
;
ASSERT_NO_FATAL_FAILURE
(
RunLoop
(
&
video
));
for
(
int
j
=
0
;
j
<
static_cast
<
int
>
(
cfg_
.
ts_number_layers
);
++
j
)
{
ASSERT_GE
(
effective_datarate_
[
j
],
cfg_
.
ts_target_bitrate
[
j
]
*
0.75
)
<<
" The datarate for the file is lower than target by too much, "
"for layer: "
<<
j
;
ASSERT_LE
(
effective_datarate_
[
j
],
cfg_
.
ts_target_bitrate
[
j
]
*
1.25
)
<<
" The datarate for the file is greater than target by too much, "
"for layer: "
<<
j
;
}
}
}
VP8_INSTANTIATE_TEST_CASE
(
ErrorResilienceTestLarge
,
ONE_PASS_TEST_MODES
);
VP8_INSTANTIATE_TEST_CASE
(
ErrorResilienceTestLargeCodecControls
,
ONE_PASS_TEST_MODES
);
VP9_INSTANTIATE_TEST_CASE
(
ErrorResilienceTestLarge
,
ONE_PASS_TEST_MODES
);
}
// namespace
vp8/common/blockd.h
View file @
7cb7588b
...
...
@@ -187,8 +187,12 @@ typedef struct
{
FRAME_TYPE
frame_type
;
int
is_frame_dropped
;
// The frame rate for the lowest resolution.
double
low_res_framerate
;
/* The frame number of each reference frames */
unsigned
int
low_res_ref_frames
[
MAX_REF_FRAMES
];
// The video frame counter value for the key frame, for lowest resolution.
unsigned
int
key_frame_counter_value
;
LOWER_RES_MB_INFO
*
mb_info
;
}
LOWER_RES_FRAME_INFO
;
#endif
...
...
vp8/common/onyx.h
View file @
7cb7588b
...
...
@@ -122,6 +122,7 @@ extern "C"
int
Sharpness
;
int
cpu_used
;
unsigned
int
rc_max_intra_bitrate_pct
;
unsigned
int
screen_content_mode
;
/* mode ->
*(0)=Realtime/Live Encoding. This mode is optimized for realtim
...
...
vp8/encoder/block.h
View file @
7cb7588b
...
...
@@ -125,6 +125,8 @@ typedef struct macroblock
int
optimize
;
int
q_index
;
int
is_skin
;
int
denoise_zeromv
;
#if CONFIG_TEMPORAL_DENOISING
int
increase_denoising
;
...
...
@@ -161,6 +163,8 @@ typedef struct macroblock
void
(
*
short_walsh4x4
)(
short
*
input
,
short
*
output
,
int
pitch
);
void
(
*
quantize_b
)(
BLOCK
*
b
,
BLOCKD
*
d
);
unsigned
int
mbs_zero_last_dot_suppress
;
int
zero_last_dot_suppress
;
}
MACROBLOCK
;
...
...
vp8/encoder/denoising.c
View file @
7cb7588b
...
...
@@ -391,7 +391,7 @@ void vp8_denoiser_set_parameters(VP8_DENOISER *denoiser, int mode) {
denoiser
->
denoise_pars
.
scale_increase_filter
=
1
;
denoiser
->
denoise_pars
.
denoise_mv_bias
=
60
;
denoiser
->
denoise_pars
.
pickmode_mv_bias
=
75
;
denoiser
->
denoise_pars
.
qp_thresh
=
8
5
;
denoiser
->
denoise_pars
.
qp_thresh
=
8
0
;
denoiser
->
denoise_pars
.
consec_zerolast
=
15
;
denoiser
->
denoise_pars
.
spatial_blur
=
0
;
}
...
...
@@ -456,10 +456,10 @@ int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height,
denoiser
->
bitrate_threshold
=
400000
;
// (bits/sec).
denoiser
->
threshold_aggressive_mode
=
80
;
if
(
width
*
height
>
1280
*
720
)
{
denoiser
->
bitrate_threshold
=
25
00000
;
denoiser
->
threshold_aggressive_mode
=
18
0
;
denoiser
->
bitrate_threshold
=
30
00000
;
denoiser
->
threshold_aggressive_mode
=
20
0
;
}
else
if
(
width
*
height
>
960
*
540
)
{
denoiser
->
bitrate_threshold
=
1
0
00000
;
denoiser
->
bitrate_threshold
=
1
2
00000
;
denoiser
->
threshold_aggressive_mode
=
120
;
}
else
if
(
width
*
height
>
640
*
480
)
{
denoiser
->
bitrate_threshold
=
600000
;
...
...
@@ -483,7 +483,6 @@ void vp8_denoiser_free(VP8_DENOISER *denoiser)
vpx_free
(
denoiser
->
denoise_state
);
}
void
vp8_denoiser_denoise_mb
(
VP8_DENOISER
*
denoiser
,
MACROBLOCK
*
x
,
unsigned
int
best_sse
,
...
...
@@ -554,6 +553,7 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
* Note that any changes to the mode info only affects the
* denoising.
*/
x
->
denoise_zeromv
=
1
;
mbmi
->
ref_frame
=
x
->
best_zeromv_reference_frame
;
...
...
@@ -603,6 +603,12 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
motion_threshold
=
denoiser
->
denoise_pars
.
scale_motion_thresh
*
NOISE_MOTION_THRESHOLD
;
// If block is considered to be skin area, lower the motion threshold.
// In current version set threshold = 1, so only denoise very low
// (i.e., zero) mv on skin.
if
(
x
->
is_skin
)
motion_threshold
=
1
;
if
(
motion_magnitude2
<
denoiser
->
denoise_pars
.
scale_increase_filter
*
NOISE_MOTION_THRESHOLD
)
x
->
increase_denoising
=
1
;
...
...
@@ -662,6 +668,7 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
/* No filtering of this block; it differs too much from the predictor,
* or the motion vector magnitude is considered too big.
*/
x
->
denoise_zeromv
=
0
;
vp8_copy_mem16x16
(
x
->
thismb
,
16
,
denoiser
->
yv12_running_avg
[
INTRA_FRAME
].
y_buffer
+
recon_yoffset
,
...
...
@@ -692,7 +699,7 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
int
uv_stride
=
denoiser
->
yv12_running_avg
[
INTRA_FRAME
].
uv_stride
;
// Fix filter level to some nominal value for now.
int
filter_level
=
32
;
int
filter_level
=
48
;
int
hev_index
=
lfi_n
->
hev_thr_lut
[
INTER_FRAME
][
filter_level
];
lfi
.
mblim
=
lfi_n
->
mblim
[
filter_level
];
...
...
vp8/encoder/denoising.h
View file @
7cb7588b
...
...
@@ -19,7 +19,7 @@ extern "C" {
#endif
#define SUM_DIFF_THRESHOLD (16 * 16 * 2)
#define SUM_DIFF_THRESHOLD_HIGH (600)
#define SUM_DIFF_THRESHOLD_HIGH (600)
// ~(16 * 16 * 1.5)
#define MOTION_MAGNITUDE_THRESHOLD (8*3)
#define SUM_DIFF_THRESHOLD_UV (96) // (8 * 8 * 1.5)
...
...
@@ -27,7 +27,7 @@ extern "C" {
#define SUM_DIFF_FROM_AVG_THRESH_UV (8 * 8 * 8)
#define MOTION_MAGNITUDE_THRESHOLD_UV (8*3)
#define MAX_GF_ARF_DENOISE_RANGE (
16
)
#define MAX_GF_ARF_DENOISE_RANGE (
8
)
enum
vp8_denoiser_decision
{
...
...
vp8/encoder/encodeframe.c
View file @
7cb7588b
...
...
@@ -522,7 +522,8 @@ void encode_mb_row(VP8_COMP *cpi,
}
#endif
// Keep track of how many (consecutive) times a block is coded
// 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
)
{
...
...
@@ -531,9 +532,14 @@ void encode_mb_row(VP8_COMP *cpi,
// Increment, check for wrap-around.
if
(
cpi
->
consec_zero_last
[
map_index
+
mb_col
]
<
255
)
cpi
->
consec_zero_last
[
map_index
+
mb_col
]
+=
1
;
if
(
cpi
->
consec_zero_last_mvbias
[
map_index
+
mb_col
]
<
255
)
cpi
->
consec_zero_last_mvbias
[
map_index
+
mb_col
]
+=
1
;
}
else
{
cpi
->
consec_zero_last
[
map_index
+
mb_col
]
=
0
;
cpi
->
consec_zero_last_mvbias
[
map_index
+
mb_col
]
=
0
;
}
if
(
x
->
zero_last_dot_suppress
)
cpi
->
consec_zero_last_mvbias
[
map_index
+
mb_col
]
=
0
;
}
/* Special case code for cyclic refresh
...
...
vp8/encoder/ethreading.c
View file @
7cb7588b
...
...
@@ -215,11 +215,15 @@ THREAD_FUNCTION thread_encoding_proc(void *p_data)
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
;
cpi
->
consec_zero_last
[
map_index
+
mb_col
]
+=
1
;
if
(
cpi
->
consec_zero_last_mvbias
[
map_index
+
mb_col
]
<
255
)
cpi
->
consec_zero_last_mvbias
[
map_index
+
mb_col
]
+=
1
;
}
else
{
cpi
->
consec_zero_last
[
map_index
+
mb_col
]
=
0
;
cpi
->
consec_zero_last_mvbias
[
map_index
+
mb_col
]
=
0
;
}
if
(
x
->
zero_last_dot_suppress
)
cpi
->
consec_zero_last_mvbias
[
map_index
+
mb_col
]
=
0
;
}
/* Special case code for cyclic refresh
...
...
@@ -505,6 +509,7 @@ void vp8cx_init_mbrthread_data(VP8_COMP *cpi,
mb
->
intra_error
=
0
;
vp8_zero
(
mb
->
count_mb_ref_frame_usage
);
mb
->
mbs_tested_so_far
=
0
;
mb
->
mbs_zero_last_dot_suppress
=
0
;
}
}
...
...
vp8/encoder/onyx_if.c
View file @
7cb7588b
This diff is collapsed.
Click to expand it.
vp8/encoder/onyx_int.h
View file @
7cb7588b
...
...
@@ -513,10 +513,18 @@ typedef struct VP8_COMP
signed
char
*
cyclic_refresh_map
;
// Count on how many (consecutive) times a macroblock uses ZER0MV_LAST.
unsigned
char
*
consec_zero_last
;
// Counter that is reset when a block is checked for a mode-bias against
// ZEROMV_LASTREF.
unsigned
char
*
consec_zero_last_mvbias
;
// Frame counter for the temporal pattern. Counter is rest when the temporal
// layers are changed dynamically (run-time change).
unsigned
int
temporal_pattern_counter
;
// Temporal layer id.
int
temporal_layer_id
;
// Measure of average squared difference between source and denoised signal.
int
mse_source_denoised
;
#if CONFIG_MULTITHREAD
/* multithread data */
...
...
@@ -687,6 +695,7 @@ typedef struct VP8_COMP
#endif
/* The frame number of each reference frames */
unsigned
int
current_ref_frames
[
MAX_REF_FRAMES
];
// Closest reference frame to current frame.
MV_REFERENCE_FRAME
closest_reference_frame
;
struct
rd_costs_struct
...
...
vp8/encoder/pickinter.c
View file @
7cb7588b
...
...
@@ -40,6 +40,134 @@ 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
]);
// Fixed point implementation of a skin color classifier. Skin color
// is model by a Gaussian distribution in the CbCr color space.
// See ../../test/skin_color_detector_test.cc where the reference
// skin color classifier is defined.
// Fixed-point skin color model parameters.
static
const
int
skin_mean
[
2
]
=
{
7463
,
9614
};
// q6
static
const
int
skin_inv_cov
[
4
]
=
{
4107
,
1663
,
1663
,
2157
};
// q16
static
const
int
skin_threshold
=
1570636
;
// q18
// Evaluates the Mahalanobis distance measure for the input CbCr values.
static
int
evaluate_skin_color_difference
(
int
cb
,
int
cr
)
{
const
int
cb_q6
=
cb
<<
6
;
const
int
cr_q6
=
cr
<<
6
;
const
int
cb_diff_q12
=
(
cb_q6
-
skin_mean
[
0
])
*
(
cb_q6
-
skin_mean
[
0
]);
const
int
cbcr_diff_q12
=
(
cb_q6
-
skin_mean
[
0
])
*
(
cr_q6
-
skin_mean
[
1
]);
const
int
cr_diff_q12
=
(
cr_q6
-
skin_mean
[
1
])
*
(
cr_q6
-
skin_mean
[
1
]);
const
int
cb_diff_q2
=
(
cb_diff_q12
+
(
1
<<
9
))
>>
10
;
const
int
cbcr_diff_q2
=
(
cbcr_diff_q12
+
(
1
<<
9
))
>>
10
;
const
int
cr_diff_q2
=
(
cr_diff_q12
+
(
1
<<
9
))
>>
10
;
const
int
skin_diff
=
skin_inv_cov
[
0
]
*
cb_diff_q2
+
skin_inv_cov
[
1
]
*
cbcr_diff_q2
+
skin_inv_cov
[
2
]
*
cbcr_diff_q2
+
skin_inv_cov
[
3
]
*
cr_diff_q2
;
return
skin_diff
;
}
static
int
macroblock_corner_grad
(
unsigned
char
*
signal
,
int
stride
,
int
offsetx
,
int
offsety
,
int
sgnx
,
int
sgny
)
{
int
y1
=
signal
[
offsetx
*
stride
+
offsety
];
int
y2
=
signal
[
offsetx
*
stride
+
offsety
+
sgny
];
int
y3
=
signal
[(
offsetx
+
sgnx
)
*
stride
+
offsety
];
int
y4
=
signal
[(
offsetx
+
sgnx
)
*
stride
+
offsety
+
sgny
];
return
MAX
(
MAX
(
abs
(
y1
-
y2
),
abs
(
y1
-
y3
)),
abs
(
y1
-
y4
));
}
static
int
check_dot_artifact_candidate
(
VP8_COMP
*
cpi
,
MACROBLOCK
*
x
,
unsigned
char
*
target_last
,
int
stride
,
unsigned
char
*
last_ref
,
int
mb_row
,
int
mb_col
,
int
channel
)
{
int
threshold1
=
6
;
int
threshold2
=
3
;
unsigned
int
max_num
=
(
cpi
->
common
.
MBs
)
/
10
;
int
grad_last
=
0
;
int
grad_source
=
0
;
int
index
=
mb_row
*
cpi
->
common
.
mb_cols
+
mb_col
;
// Threshold for #consecutive (base layer) frames using zero_last mode.
int
num_frames
=
30
;
int
shift
=
15
;
if
(
channel
>
0
)
{
shift
=
7
;
}
if
(
cpi
->
oxcf
.
number_of_layers
>
1
)
{
num_frames
=
20
;
}
x
->
zero_last_dot_suppress
=
0
;
// Blocks on base layer frames that have been using ZEROMV_LAST repeatedly
// (i.e, at least |x| consecutive frames are candidates for increasing the
// rd adjustment for zero_last mode.
// Only allow this for at most |max_num| blocks per frame.
// Don't allow this for screen content input.
if
(
cpi
->
current_layer
==
0
&&
cpi
->
consec_zero_last_mvbias
[
index
]
>
num_frames
&&
x
->
mbs_zero_last_dot_suppress
<
max_num
&&
!
cpi
->
oxcf
.
screen_content_mode
)
{
// If this block is checked here, label it so we don't check it again until
// ~|x| framaes later.
x
->
zero_last_dot_suppress
=
1
;
// Dot artifact is noticeable as strong gradient at corners of macroblock,
// for flat areas. As a simple detector for now, we look for a high
// corner gradient on last ref, and a smaller gradient on source.
// Check 4 corners, return if any satisfy condition.
// Top-left:
grad_last
=
macroblock_corner_grad
(
last_ref
,
stride
,
0
,
0
,
1
,
1
);
grad_source
=
macroblock_corner_grad
(
target_last
,
stride
,
0
,
0
,
1
,
1
);
if
(
grad_last
>=
threshold1
&&
grad_source
<=
threshold2
)
{
x
->
mbs_zero_last_dot_suppress
++
;
return
1
;
}
// Top-right:
grad_last
=
macroblock_corner_grad
(
last_ref
,
stride
,
0
,
shift
,
1
,
-
1
);
grad_source
=
macroblock_corner_grad
(
target_last
,
stride
,
0
,
shift
,
1
,
-
1
);
if
(
grad_last
>=
threshold1
&&
grad_source
<=
threshold2
)
{
x
->
mbs_zero_last_dot_suppress
++
;
return
1
;
}
// Bottom-left:
grad_last
=
macroblock_corner_grad
(
last_ref
,
stride
,
shift
,
0
,
-
1
,
1
);
grad_source
=
macroblock_corner_grad
(
target_last
,
stride
,
shift
,
0
,
-
1
,
1
);
if
(
grad_last
>=
threshold1
&&
grad_source
<=
threshold2
)
{
x
->
mbs_zero_last_dot_suppress
++
;
return
1
;
}
// Bottom-right:
grad_last
=
macroblock_corner_grad
(
last_ref
,
stride
,
shift
,
shift
,
-
1
,
-
1
);
grad_source
=
macroblock_corner_grad
(
target_last
,
stride
,
shift
,
shift
,
-
1
,
-
1
);
if
(
grad_last
>=
threshold1
&&
grad_source
<=
threshold2
)
{
x
->
mbs_zero_last_dot_suppress
++
;
return
1
;
}
return
0
;
}
return
0
;
}
// Checks if the input yCbCr values corresponds to skin color.
static
int
is_skin_color
(
int
y
,
int
cb
,
int
cr
)
{
if
(
y
<
40
||
y
>
220
)
{
return
0
;
}
return
(
evaluate_skin_color_difference
(
cb
,
cr
)
<
skin_threshold
);
}
int
vp8_skip_fractional_mv_step
(
MACROBLOCK
*
mb
,
BLOCK
*
b
,
BLOCKD
*
d
,
int_mv
*
bestmv
,
int_mv
*
ref_mv
,
int
error_per_bit
,
...
...
@@ -514,10 +642,17 @@ static int evaluate_inter_mode(unsigned int* sse, int rate2, int* distortion2,
#endif
// Adjust rd for ZEROMV and LAST, if LAST is the closest reference frame.
if
(
this_mode
==
ZEROMV
&&
x
->
e_mbd
.
mode_info_context
->
mbmi
.
ref_frame
==
LAST_FRAME
&&
(
denoise_aggressive
||
cpi
->
closest_reference_frame
==
LAST_FRAME
))
{
this_rd
=
((
int64_t
)
this_rd
)
*
rd_adj
/
100
;
// TODO: We should also add condition on distance of closest to current.
if
(
!
cpi
->
oxcf
.
screen_content_mode
&&
this_mode
==
ZEROMV
&&
x
->
e_mbd
.
mode_info_context
->
mbmi
.
ref_frame
==
LAST_FRAME
&&
(
denoise_aggressive
||
(
cpi
->
closest_reference_frame
==
LAST_FRAME
)))
{
// No adjustment if block is considered to be skin area.
if
(
x
->
is_skin
)
rd_adj
=
100
;
this_rd
=
((
int64_t
)
this_rd
)
*
rd_adj
/
100
;
}
check_for_encode_breakout
(
*
sse
,
x
);
...
...
@@ -597,6 +732,15 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
#endif
int
sf_improved_mv_pred
=
cpi
->
sf
.
improved_mv_pred
;
#if CONFIG_MULTI_RES_ENCODING
int
dissim
=
INT_MAX
;
int
parent_ref_frame
=
0
;
int_mv
parent_ref_mv
;
MB_PREDICTION_MODE
parent_mode
=
0
;
int
parent_ref_valid
=
0
;
#endif
int_mv
mvp
;