Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Yushin Cho
aom-rav1e
Commits
2d924161
Commit
2d924161
authored
Feb 10, 2015
by
Adrian Grange
Committed by
Gerrit Code Review
Feb 10, 2015
Browse files
Merge "Auto-adaptive encoder frame resizing logic"
parents
f0eea5be
23ebacdb
Changes
8
Hide whitespace changes
Inline
Side-by-side
vp9/encoder/vp9_encoder.c
View file @
2d924161
...
...
@@ -2307,26 +2307,43 @@ static void scale_and_extend_frame(const YV12_BUFFER_CONFIG *src,
vp9_extend_frame_borders
(
dst
);
}
static
int
scale_down
(
VP9_COMP
*
cpi
,
int
q
)
{
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
GF_GROUP
*
const
gf_group
=
&
cpi
->
twopass
.
gf_group
;
int
scale
=
0
;
assert
(
frame_is_kf_gf_arf
(
cpi
));
if
(
rc
->
frame_size_selector
==
UNSCALED
&&
q
>=
rc
->
rf_level_maxq
[
gf_group
->
rf_level
[
gf_group
->
index
]])
{
const
int
max_size_thresh
=
(
int
)(
rate_thresh_mult
[
SCALE_STEP1
]
*
MAX
(
rc
->
this_frame_target
,
rc
->
avg_frame_bandwidth
));
scale
=
rc
->
projected_frame_size
>
max_size_thresh
?
1
:
0
;
}
return
scale
;
}
// Function to test for conditions that indicate we should loop
// back and recode a frame.
static
int
recode_loop_test
(
const
VP9_COMP
*
cpi
,
static
int
recode_loop_test
(
VP9_COMP
*
cpi
,
int
high_limit
,
int
low_limit
,
int
q
,
int
maxq
,
int
minq
)
{
const
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
const
VP9EncoderConfig
*
const
oxcf
=
&
cpi
->
oxcf
;
const
int
frame_is_kfgfarf
=
frame_is_kf_gf_arf
(
cpi
);
int
force_recode
=
0
;
// Special case trap if maximum allowed frame size exceeded.
if
(
rc
->
projected_frame_size
>
rc
->
max_frame_bandwidth
)
{
force_recode
=
1
;
// Is frame recode allowed.
// Yes if either recode mode 1 is selected or mode 2 is selected
// and the frame is a key frame, golden frame or alt_ref_frame
}
else
if
((
cpi
->
sf
.
recode_loop
==
ALLOW_RECODE
)
||
((
cpi
->
sf
.
recode_loop
==
ALLOW_RECODE_KFARFGF
)
&&
frame_is_kf_gf_arf
(
cpi
)))
{
// General over and under shoot tests
if
((
cpi
->
sf
.
recode_loop
==
ALLOW_RECODE
)
||
(
frame_is_kfgfarf
&&
(
cpi
->
sf
.
recode_loop
==
ALLOW_RECODE_KFARFGF
)))
{
if
(
frame_is_kfgfarf
&&
(
oxcf
->
resize_mode
==
RESIZE_DYNAMIC
)
&&
scale_down
(
cpi
,
q
))
{
// Code this group at a lower resolution.
cpi
->
resize_pending
=
1
;
return
1
;
}
// TODO(agrange) high_limit could be greater than the scale-down threshold.
if
((
rc
->
projected_frame_size
>
high_limit
&&
q
<
maxq
)
||
(
rc
->
projected_frame_size
<
low_limit
&&
q
>
minq
))
{
force_recode
=
1
;
...
...
@@ -2557,13 +2574,15 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) {
recon_err = vp9_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
if (cpi->twopass.total_left_stats.coded_error != 0.0)
fprintf(f, "%10u %10d %10d %10d %10d"
fprintf(f, "%10u
%dx%d
%10d %10d %10d %10d"
"%10"PRId64" %10"PRId64" %10"PRId64" %10"PRId64" %10d "
"%7.2lf %7.2lf %7.2lf %7.2lf %7.2lf"
"%6d %6d %5d %5d %5d "
"%10"PRId64" %10.3lf"
"%10lf %8u %10"PRId64" %10d %10d\n",
cpi->common.current_video_frame, cpi->rc.this_frame_target,
cpi->common.current_video_frame,
cm->width, cm->height,
cpi->rc.this_frame_target,
cpi->rc.projected_frame_size,
cpi->rc.projected_frame_size / cpi->common.MBs,
(cpi->rc.projected_frame_size - cpi->rc.this_frame_target),
...
...
@@ -2699,14 +2718,17 @@ static void init_motion_estimation(VP9_COMP *cpi) {
void
set_frame_size
(
VP9_COMP
*
cpi
)
{
int
ref_frame
;
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
const
VP9EncoderConfig
*
const
oxcf
=
&
cpi
->
oxcf
;
VP9EncoderConfig
*
const
oxcf
=
&
cpi
->
oxcf
;
MACROBLOCKD
*
const
xd
=
&
cpi
->
td
.
mb
.
e_mbd
;
if
(
oxcf
->
pass
==
2
&&
cm
->
current_video_frame
==
0
&&
oxcf
->
resize_mode
==
RESIZE_FIXED
&&
oxcf
->
rc_mode
==
VPX_VBR
)
{
// Internal scaling is triggered on the first frame.
oxcf
->
rc_mode
==
VPX_VBR
&&
((
oxcf
->
resize_mode
==
RESIZE_FIXED
&&
cm
->
current_video_frame
==
0
)
||
(
oxcf
->
resize_mode
==
RESIZE_DYNAMIC
&&
cpi
->
resize_pending
)))
{
calculate_coded_size
(
cpi
,
&
oxcf
->
scaled_frame_width
,
&
oxcf
->
scaled_frame_height
);
// There has been a change in frame size.
vp9_set_size_literal
(
cpi
,
oxcf
->
scaled_frame_width
,
oxcf
->
scaled_frame_height
);
}
...
...
@@ -2757,7 +2779,7 @@ void set_frame_size(VP9_COMP *cpi) {
static
void
encode_without_recode_loop
(
VP9_COMP
*
cpi
)
{
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
int
q
,
bottom_index
,
top_index
;
// Dummy variables.
int
q
=
0
,
bottom_index
=
0
,
top_index
=
0
;
// Dummy variables.
vp9_clear_system_state
();
...
...
@@ -2804,13 +2826,13 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
int
bottom_index
,
top_index
;
int
loop_count
=
0
;
int
loop_at_this_size
=
0
;
int
loop
=
0
;
int
overshoot_seen
=
0
;
int
undershoot_seen
=
0
;
int
frame_over_shoot_limit
;
int
frame_under_shoot_limit
;
int
q
=
0
,
q_low
=
0
,
q_high
=
0
;
int
frame_size_changed
=
0
;
set_size_independent_vars
(
cpi
);
...
...
@@ -2819,19 +2841,31 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
set_frame_size
(
cpi
);
if
(
loop_count
==
0
||
frame_size_changed
!=
0
)
{
if
(
loop_count
==
0
||
cpi
->
resize_pending
!=
0
)
{
set_size_dependent_vars
(
cpi
,
&
q
,
&
bottom_index
,
&
top_index
);
q_low
=
bottom_index
;
q_high
=
top_index
;
// TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed.
set_mv_search_params
(
cpi
);
// Reset the loop state for new frame size.
overshoot_seen
=
0
;
undershoot_seen
=
0
;
// Reconfiguration for change in frame size has concluded.
cpi
->
resize_pending
=
0
;
q_low
=
bottom_index
;
q_high
=
top_index
;
loop_at_this_size
=
0
;
}
// Decide frame size bounds
vp9_rc_compute_frame_size_bounds
(
cpi
,
rc
->
this_frame_target
,
&
frame_under_shoot_limit
,
&
frame_over_shoot_limit
);
// Decide frame size bounds first time through.
if
(
loop_count
==
0
)
{
vp9_rc_compute_frame_size_bounds
(
cpi
,
rc
->
this_frame_target
,
&
frame_under_shoot_limit
,
&
frame_over_shoot_limit
);
}
cpi
->
Source
=
vp9_scale_if_required
(
cm
,
cpi
->
un_scaled_source
,
&
cpi
->
scaled_source
);
...
...
@@ -2944,6 +2978,20 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
int
last_q
=
q
;
int
retries
=
0
;
if
(
cpi
->
resize_pending
==
1
)
{
// Change in frame size so go back around the recode loop.
cpi
->
rc
.
frame_size_selector
=
SCALE_STEP1
-
cpi
->
rc
.
frame_size_selector
;
cpi
->
rc
.
next_frame_size_selector
=
cpi
->
rc
.
frame_size_selector
;
#if CONFIG_INTERNAL_STATS
++
cpi
->
tot_recode_hits
;
#endif
++
loop_count
;
loop
=
1
;
continue
;
}
// Frame size out of permitted range:
// Update correction factor & compute new Q to try...
...
...
@@ -2956,7 +3004,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
// Raise Qlow as to at least the current value
q_low
=
q
<
q_high
?
q
+
1
:
q_high
;
if
(
undershoot_seen
||
loop_
count
>
1
)
{
if
(
undershoot_seen
||
loop_
at_this_size
>
1
)
{
// Update rate_correction_factor unless
vp9_rc_update_rate_correction_factors
(
cpi
);
...
...
@@ -2981,7 +3029,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
// Frame is too small
q_high
=
q
>
q_low
?
q
-
1
:
q_low
;
if
(
overshoot_seen
||
loop_
count
>
1
)
{
if
(
overshoot_seen
||
loop_
at_this_size
>
1
)
{
vp9_rc_update_rate_correction_factors
(
cpi
);
q
=
(
q_high
+
q_low
)
/
2
;
}
else
{
...
...
@@ -3011,7 +3059,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
// Clamp Q to upper and lower limits:
q
=
clamp
(
q
,
q_low
,
q_high
);
loop
=
q
!=
last_q
;
loop
=
(
q
!=
last_q
)
;
}
else
{
loop
=
0
;
}
...
...
@@ -3023,10 +3071,11 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
loop
=
0
;
if
(
loop
)
{
loop_count
++
;
++
loop_count
;
++
loop_at_this_size
;
#if CONFIG_INTERNAL_STATS
cpi
->
tot_recode_hits
++
;
++
cpi
->
tot_recode_hits
;
#endif
}
}
while
(
loop
);
...
...
vp9/encoder/vp9_encoder.h
View file @
2d924161
...
...
@@ -448,6 +448,8 @@ typedef struct VP9_COMP {
VP9_DENOISER
denoiser
;
#endif
int
resize_pending
;
// Multi-threading
int
num_workers
;
VP9Worker
*
workers
;
...
...
@@ -593,6 +595,8 @@ static INLINE int *cond_cost_list(const struct VP9_COMP *cpi, int *cost_list) {
return
cpi
->
sf
.
mv
.
subpel_search_method
!=
SUBPEL_TREE
?
cost_list
:
NULL
;
}
void
vp9_new_framerate
(
VP9_COMP
*
cpi
,
double
framerate
);
#ifdef __cplusplus
}
// extern "C"
#endif
...
...
vp9/encoder/vp9_firstpass.c
View file @
2d924161
...
...
@@ -1134,7 +1134,38 @@ static int get_twopass_worst_quality(const VP9_COMP *cpi,
}
}
extern
void
vp9_new_framerate
(
VP9_COMP
*
cpi
,
double
framerate
);
static
void
setup_rf_level_maxq
(
VP9_COMP
*
cpi
)
{
int
i
;
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
for
(
i
=
INTER_NORMAL
;
i
<
RATE_FACTOR_LEVELS
;
++
i
)
{
int
qdelta
=
vp9_frame_type_qdelta
(
cpi
,
i
,
rc
->
worst_quality
);
rc
->
rf_level_maxq
[
i
]
=
MAX
(
rc
->
worst_quality
+
qdelta
,
rc
->
best_quality
);
}
}
void
vp9_init_subsampling
(
VP9_COMP
*
cpi
)
{
const
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
const
int
w
=
cm
->
width
;
const
int
h
=
cm
->
height
;
int
i
;
for
(
i
=
0
;
i
<
FRAME_SCALE_STEPS
;
++
i
)
{
// Note: Frames with odd-sized dimensions may result from this scaling.
rc
->
frame_width
[
i
]
=
(
w
*
16
)
/
frame_scale_factor
[
i
];
rc
->
frame_height
[
i
]
=
(
h
*
16
)
/
frame_scale_factor
[
i
];
}
setup_rf_level_maxq
(
cpi
);
}
void
calculate_coded_size
(
VP9_COMP
*
cpi
,
int
*
scaled_frame_width
,
int
*
scaled_frame_height
)
{
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
*
scaled_frame_width
=
rc
->
frame_width
[
rc
->
frame_size_selector
];
*
scaled_frame_height
=
rc
->
frame_height
[
rc
->
frame_size_selector
];
}
void
vp9_init_second_pass
(
VP9_COMP
*
cpi
)
{
SVC
*
const
svc
=
&
cpi
->
svc
;
...
...
@@ -1204,6 +1235,10 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
// Static sequence monitor variables.
twopass
->
kf_zeromotion_pct
=
100
;
twopass
->
last_kfgroup_zeromotion_pct
=
100
;
if
(
oxcf
->
resize_mode
!=
RESIZE_NONE
)
{
vp9_init_subsampling
(
cpi
);
}
}
#define SR_DIFF_PART 0.0015
...
...
@@ -1696,8 +1731,9 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
// Analyse and define a gf/arf group.
static
void
define_gf_group
(
VP9_COMP
*
cpi
,
FIRSTPASS_STATS
*
this_frame
)
{
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
const
VP9EncoderConfig
*
const
oxcf
=
&
cpi
->
oxcf
;
VP9EncoderConfig
*
const
oxcf
=
&
cpi
->
oxcf
;
TWO_PASS
*
const
twopass
=
&
cpi
->
twopass
;
FIRSTPASS_STATS
next_frame
;
const
FIRSTPASS_STATS
*
const
start_pos
=
twopass
->
stats_in
;
...
...
@@ -1733,10 +1769,11 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
int64_t
gf_group_bits
;
double
gf_group_error_left
;
int
gf_arf_bits
;
int
is_key_frame
=
frame_is_intra_only
(
cm
);
// Reset the GF group data structures unless this is a key
// frame in which case it will already have been done.
if
(
cpi
->
common
.
frame_type
!=
KEY_FRAME
)
{
if
(
is_key_frame
==
0
)
{
vp9_zero
(
twopass
->
gf_group
);
}
...
...
@@ -1752,7 +1789,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// If this is a key frame or the overlay from a previous arf then
// the error score / cost of this frame has already been accounted for.
if
(
cpi
->
common
.
frame_type
==
KEY_FRAME
||
rc
->
source_alt_ref_active
)
{
if
(
is_key_frame
||
rc
->
source_alt_ref_active
)
{
gf_group_err
-=
gf_first_frame_err
;
#if GROUP_ADAPTIVE_MAXQ
gf_group_raw_error
-=
this_frame
->
coded_error
;
...
...
@@ -1864,7 +1901,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
rc
->
constrained_gf_group
=
(
i
>=
rc
->
frames_to_key
)
?
1
:
0
;
// Set the interval until the next gf.
if
(
cpi
->
common
.
frame_type
==
KEY_FRAME
||
rc
->
source_alt_ref_active
)
if
(
is_key_frame
||
rc
->
source_alt_ref_active
)
rc
->
baseline_gf_interval
=
i
-
1
;
else
rc
->
baseline_gf_interval
=
i
;
...
...
@@ -1927,9 +1964,9 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
get_twopass_worst_quality
(
cpi
,
group_av_err
,
vbr_group_bits_per_frame
,
twopass
->
kfgroup_inter_fraction
);
if
(
tmp_q
<
twopass
->
baseline_worst_quality
)
{
if
(
tmp_q
<
twopass
->
baseline_
active_
worst_quality
)
{
twopass
->
active_worst_quality
=
(
tmp_q
+
twopass
->
baseline_worst_quality
+
1
)
/
2
;
(
tmp_q
+
twopass
->
baseline_
active_
worst_quality
+
1
)
/
2
;
}
else
{
twopass
->
active_worst_quality
=
tmp_q
;
}
...
...
@@ -1951,7 +1988,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// also a key frame in which case it has already been accounted for.
if
(
rc
->
source_alt_ref_pending
)
{
gf_group_error_left
=
gf_group_err
-
mod_frame_err
;
}
else
if
(
cpi
->
common
.
frame_type
!=
KEY_FRAME
)
{
}
else
if
(
is_key_frame
==
0
)
{
gf_group_error_left
=
gf_group_err
-
gf_first_frame_err
;
}
else
{
gf_group_error_left
=
gf_group_err
;
...
...
@@ -1969,6 +2006,11 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
calculate_section_intra_ratio
(
start_pos
,
twopass
->
stats_in_end
,
rc
->
baseline_gf_interval
);
}
if
(
oxcf
->
resize_mode
==
RESIZE_DYNAMIC
)
{
// Default to starting GF groups at normal frame size.
cpi
->
rc
.
next_frame_size_selector
=
UNSCALED
;
}
}
// TODO(PGW) Re-examine the use of II ration in this code in the light of#
...
...
@@ -2293,6 +2335,11 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// The count of bits left is adjusted elsewhere based on real coded frame
// sizes.
twopass
->
modified_error_left
-=
kf_group_err
;
if
(
oxcf
->
resize_mode
==
RESIZE_DYNAMIC
)
{
// Default to normal-sized frame on keyframes.
cpi
->
rc
.
next_frame_size_selector
=
UNSCALED
;
}
}
// Define the reference buffers that will be updated post encode.
...
...
@@ -2433,7 +2480,7 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
section_target_bandwidth
,
DEFAULT_GRP_WEIGHT
);
twopass
->
active_worst_quality
=
tmp_q
;
twopass
->
baseline_worst_quality
=
tmp_q
;
twopass
->
baseline_
active_
worst_quality
=
tmp_q
;
rc
->
ni_av_qi
=
tmp_q
;
rc
->
last_q
[
INTER_FRAME
]
=
tmp_q
;
rc
->
avg_q
=
vp9_convert_qindex_to_q
(
tmp_q
,
cm
->
bit_depth
);
...
...
vp9/encoder/vp9_firstpass.h
View file @
2d924161
...
...
@@ -118,8 +118,8 @@ typedef struct {
int
kf_zeromotion_pct
;
int
last_kfgroup_zeromotion_pct
;
int
gf_zeromotion_pct
;
int
baseline_worst_quality
;
int
active_worst_quality
;
int
baseline_active_worst_quality
;
int
extend_minq
;
int
extend_maxq
;
...
...
@@ -138,6 +138,13 @@ void vp9_rc_get_second_pass_params(struct VP9_COMP *cpi);
// Post encode update of the rate control parameters for 2-pass
void
vp9_twopass_postencode_update
(
struct
VP9_COMP
*
cpi
);
void
vp9_init_subsampling
(
struct
VP9_COMP
*
cpi
);
void
calculate_coded_size
(
struct
VP9_COMP
*
cpi
,
int
*
scaled_frame_width
,
int
*
scaled_frame_height
);
#ifdef __cplusplus
}
// extern "C"
#endif
...
...
vp9/encoder/vp9_ratectrl.c
View file @
2d924161
...
...
@@ -360,26 +360,32 @@ int vp9_rc_drop_frame(VP9_COMP *cpi) {
static
double
get_rate_correction_factor
(
const
VP9_COMP
*
cpi
)
{
const
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
double
rcf
;
if
(
cpi
->
common
.
frame_type
==
KEY_FRAME
)
{
r
eturn
rc
->
rate_correction_factors
[
KF_STD
];
r
cf
=
rc
->
rate_correction_factors
[
KF_STD
];
}
else
if
(
cpi
->
oxcf
.
pass
==
2
)
{
RATE_FACTOR_LEVEL
rf_lvl
=
cpi
->
twopass
.
gf_group
.
rf_level
[
cpi
->
twopass
.
gf_group
.
index
];
r
eturn
rc
->
rate_correction_factors
[
rf_lvl
];
r
cf
=
rc
->
rate_correction_factors
[
rf_lvl
];
}
else
{
if
((
cpi
->
refresh_alt_ref_frame
||
cpi
->
refresh_golden_frame
)
&&
!
rc
->
is_src_frame_alt_ref
&&
!
cpi
->
use_svc
&&
(
cpi
->
oxcf
.
rc_mode
!=
VPX_CBR
||
cpi
->
oxcf
.
gf_cbr_boost_pct
>
20
))
r
eturn
rc
->
rate_correction_factors
[
GF_ARF_STD
];
r
cf
=
rc
->
rate_correction_factors
[
GF_ARF_STD
];
else
r
eturn
rc
->
rate_correction_factors
[
INTER_NORMAL
];
r
cf
=
rc
->
rate_correction_factors
[
INTER_NORMAL
];
}
rcf
*=
rcf_mult
[
rc
->
frame_size_selector
];
return
rcf
>
MAX_BPB_FACTOR
?
MAX_BPB_FACTOR
:
rcf
;
}
static
void
set_rate_correction_factor
(
VP9_COMP
*
cpi
,
double
factor
)
{
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
// Normalize RCF to account for the size-dependent scaling factor.
factor
/=
rcf_mult
[
cpi
->
rc
.
frame_size_selector
];
if
(
cpi
->
common
.
frame_type
==
KEY_FRAME
)
{
rc
->
rate_correction_factors
[
KF_STD
]
=
factor
;
}
else
if
(
cpi
->
oxcf
.
pass
==
2
)
{
...
...
@@ -911,6 +917,23 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi,
return
q
;
}
int
vp9_frame_type_qdelta
(
const
VP9_COMP
*
cpi
,
int
rf_level
,
int
q
)
{
static
const
double
rate_factor_deltas
[
RATE_FACTOR_LEVELS
]
=
{
1
.
00
,
// INTER_NORMAL
1
.
00
,
// INTER_HIGH
1
.
50
,
// GF_ARF_LOW
1
.
75
,
// GF_ARF_STD
2
.
00
,
// KF_STD
};
static
const
FRAME_TYPE
frame_type
[
RATE_FACTOR_LEVELS
]
=
{
INTER_FRAME
,
INTER_FRAME
,
INTER_FRAME
,
INTER_FRAME
,
KEY_FRAME
};
const
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
int
qdelta
=
vp9_compute_qdelta_by_rate
(
&
cpi
->
rc
,
frame_type
[
rf_level
],
q
,
rate_factor_deltas
[
rf_level
],
cm
->
bit_depth
);
return
qdelta
;
}
#define STATIC_MOTION_THRESH 95
static
int
rc_pick_q_and_bounds_two_pass
(
const
VP9_COMP
*
cpi
,
int
*
bottom_index
,
...
...
@@ -918,6 +941,7 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi,
const
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
const
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
const
VP9EncoderConfig
*
const
oxcf
=
&
cpi
->
oxcf
;
const
GF_GROUP
*
gf_group
=
&
cpi
->
twopass
.
gf_group
;
const
int
cq_level
=
get_active_cq_level
(
rc
,
oxcf
);
int
active_best_quality
;
int
active_worst_quality
=
cpi
->
twopass
.
active_worst_quality
;
...
...
@@ -999,7 +1023,6 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi,
if
(
!
cpi
->
refresh_alt_ref_frame
)
{
active_best_quality
=
cq_level
;
}
else
{
const
GF_GROUP
*
const
gf_group
=
&
cpi
->
twopass
.
gf_group
;
active_best_quality
=
get_gf_active_quality
(
rc
,
q
,
cm
->
bit_depth
);
// Modify best quality for second level arfs. For mode VPX_Q this
...
...
@@ -1025,7 +1048,7 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi,
}
}
// Extens
t
ion to max or min Q if undershoot or overshoot is outside
// Extension to max or min Q if undershoot or overshoot is outside
// the permitted range.
if
((
cpi
->
oxcf
.
rc_mode
==
VPX_VBR
)
&&
(
cpi
->
twopass
.
gf_zeromotion_pct
<
VLOW_MOTION_THRESHOLD
))
{
...
...
@@ -1046,25 +1069,21 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi,
if
(
!
((
frame_is_intra_only
(
cm
)
||
vp9_is_upper_layer_key_frame
(
cpi
)))
||
!
rc
->
this_key_frame_forced
||
(
cpi
->
twopass
.
last_kfgroup_zeromotion_pct
<
STATIC_MOTION_THRESH
))
{
const
GF_GROUP
*
const
gf_group
=
&
cpi
->
twopass
.
gf_group
;
const
double
rate_factor_deltas
[
RATE_FACTOR_LEVELS
]
=
{
1
.
00
,
// INTER_NORMAL
1
.
00
,
// INTER_HIGH
1
.
50
,
// GF_ARF_LOW
1
.
75
,
// GF_ARF_STD
2
.
00
,
// KF_STD
};
const
double
rate_factor
=
rate_factor_deltas
[
gf_group
->
rf_level
[
gf_group
->
index
]];
int
qdelta
=
vp9_compute_qdelta_by_rate
(
&
cpi
->
rc
,
cm
->
frame_type
,
active_worst_quality
,
rate_factor
,
cm
->
bit_depth
);
active_worst_quality
=
active_worst_quality
+
qdelta
;
active_worst_quality
=
MAX
(
active_worst_quality
,
active_best_quality
);
int
qdelta
=
vp9_frame_type_qdelta
(
cpi
,
gf_group
->
rf_level
[
gf_group
->
index
],
active_worst_quality
);
active_worst_quality
=
MAX
(
active_worst_quality
+
qdelta
,
active_best_quality
);
}
#endif
// Clip the active best and worst quality values to limits.
// Modify active_best_quality for downscaled normal frames.
if
(
rc
->
frame_size_selector
!=
UNSCALED
&&
!
frame_is_kf_gf_arf
(
cpi
))
{
int
qdelta
=
vp9_compute_qdelta_by_rate
(
rc
,
cm
->
frame_type
,
active_best_quality
,
2
.
0
,
cm
->
bit_depth
);
active_best_quality
=
MAX
(
active_best_quality
+
qdelta
,
rc
->
best_quality
);
}
active_best_quality
=
clamp
(
active_best_quality
,
rc
->
best_quality
,
rc
->
worst_quality
);
active_worst_quality
=
clamp
(
active_worst_quality
,
...
...
@@ -1151,6 +1170,12 @@ void vp9_rc_set_frame_target(VP9_COMP *cpi, int target) {
rc
->
this_frame_target
=
target
;
// Modify frame size target when down-scaling.
if
(
cpi
->
oxcf
.
resize_mode
==
RESIZE_DYNAMIC
&&
rc
->
frame_size_selector
!=
UNSCALED
)
rc
->
this_frame_target
=
rc
->
this_frame_target
*
rate_thresh_mult
[
rc
->
frame_size_selector
];
// Target rate per SB64 (including partial SB64s.
rc
->
sb64_target_rate
=
((
int64_t
)
rc
->
this_frame_target
*
64
*
64
)
/
(
cm
->
width
*
cm
->
height
);
...
...
@@ -1285,6 +1310,11 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
rc
->
frames_since_key
++
;
rc
->
frames_to_key
--
;
}
// Trigger the resizing of the next frame if it is scaled.
cpi
->
resize_pending
=
rc
->
next_frame_size_selector
!=
rc
->
frame_size_selector
;
rc
->
frame_size_selector
=
rc
->
next_frame_size_selector
;
}
void
vp9_rc_postencode_update_drop_frame
(
VP9_COMP
*
cpi
)
{
...
...
vp9/encoder/vp9_ratectrl.h
View file @
2d924161
...
...
@@ -33,6 +33,27 @@ typedef enum {
RATE_FACTOR_LEVELS
=
5
}
RATE_FACTOR_LEVEL
;
// Internal frame scaling level.
typedef
enum
{
UNSCALED
=
0
,
// Frame is unscaled.
SCALE_STEP1
=
1
,
// First-level down-scaling.
FRAME_SCALE_STEPS
}
FRAME_SCALE_LEVEL
;
// Frame dimensions multiplier wrt the native frame size, in 1/16ths,
// specified for the scale-up case.
// e.g. 24 => 16/24 = 2/3 of native size. The restriction to 1/16th is
// intended to match the capabilities of the normative scaling filters,
// giving precedence to the up-scaling accuracy.
static
const
int
frame_scale_factor
[
FRAME_SCALE_STEPS
]
=
{
16
,
24
};
// Multiplier of the target rate to be used as threshold for triggering scaling.
static
const
double
rate_thresh_mult
[
FRAME_SCALE_STEPS
]
=
{
1
.
0
,
2
.
0
};
// Scale dependent Rate Correction Factor multipliers. Compensates for the
// greater number of bits per pixel generated in down-scaled frames.
static
const
double
rcf_mult
[
FRAME_SCALE_STEPS
]
=
{
1
.
0
,
2
.
0
};
typedef
struct
{
// Rate targetting variables
int
base_frame_target
;
// A baseline frame target before adjustment
...
...
@@ -100,6 +121,7 @@ typedef struct {
int64_t
starting_buffer_level
;
int64_t
optimal_buffer_level
;
int64_t
maximum_buffer_size
;
// rate control history for last frame(1) and the frame before(2).
// -1: undershot
// 1: overshoot
...
...
@@ -108,6 +130,13 @@ typedef struct {
int
rc_2_frame
;
int
q_1_frame
;
int
q_2_frame
;
// Auto frame-scaling variables.
FRAME_SCALE_LEVEL
frame_size_selector
;
FRAME_SCALE_LEVEL
next_frame_size_selector
;
int
frame_width
[
FRAME_SCALE_STEPS
];
int
frame_height
[
FRAME_SCALE_STEPS
];
int
rf_level_maxq
[
RATE_FACTOR_LEVELS
];
}
RATE_CONTROL
;
struct
VP9_COMP
;
...
...
@@ -205,6 +234,8 @@ int vp9_compute_qdelta_by_rate(const RATE_CONTROL *rc, FRAME_TYPE frame_type,
int
qindex
,
double
rate_target_ratio
,
vpx_bit_depth_t
bit_depth
);
int
vp9_frame_type_qdelta
(
const
struct
VP9_COMP
*
cpi
,
int
rf_level
,
int
q
);
void
vp9_rc_update_framerate
(
struct
VP9_COMP
*
cpi
);
void
vp9_rc_set_gf_max_interval
(
const
struct
VP9_COMP
*
const
cpi
,
...
...
vp9/encoder/vp9_rdopt.c
View file @
2d924161
...
...
@@ -1859,7 +1859,7 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
for
(
midx
=
0
;
midx
<
INTER_MODES
;
++
midx
)
bsi
->
rdstat
[
iy
][
midx
].
brdcost
=
INT64_MAX
;
bsi
->
segment_rd
=
INT64_MAX
;
return
INT64_MAX
;
;