Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Guillaume Martres
aom-rav1e
Commits
2fb81fba
Commit
2fb81fba
authored
Feb 05, 2014
by
Deb Mukherjee
Committed by
Gerrit Code Review
Feb 05, 2014
Browse files
Merge "One-pass rate control cleanups/fixes/refactoring"
parents
a5362372
40e63d4b
Changes
6
Hide whitespace changes
Inline
Side-by-side
vp9/encoder/vp9_firstpass.c
View file @
2fb81fba
...
...
@@ -49,8 +49,9 @@
#define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x) - 0.000001 : (x) + 0.000001)
#define MIN_BOOST 300
#define KEY_FRAME_BOOST 2000
#define MIN_KF_BOOST 300
#define DISABLE_RC_LONG_TERM_MEM 0
static
void
swap_yv12
(
YV12_BUFFER_CONFIG
*
a
,
YV12_BUFFER_CONFIG
*
b
)
{
YV12_BUFFER_CONFIG
temp
=
*
a
;
...
...
@@ -1725,7 +1726,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
(
!
rc
->
source_alt_ref_pending
&&
(
cpi
->
common
.
frame_type
!=
KEY_FRAME
)))
{
// Per frame bit target for this frame
rc
->
per_frame_bandwidth
=
gf_bits
;
vp9_rc_set_frame_target
(
cpi
,
gf_bits
)
;
}
}
...
...
@@ -1827,12 +1828,7 @@ static void assign_std_frame_bits(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
cpi
->
twopass
.
gf_group_bits
=
0
;
// Per frame bit target for this frame.
cpi
->
rc
.
per_frame_bandwidth
=
target_frame_size
;
}
static
int
test_for_kf_one_pass
(
VP9_COMP
*
cpi
)
{
// Placeholder function for auto key frame
return
0
;
vp9_rc_set_frame_target
(
cpi
,
target_frame_size
);
}
static
int
test_candidate_kf
(
VP9_COMP
*
cpi
,
...
...
@@ -2170,8 +2166,8 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
if
(
kf_boost
<
(
rc
->
frames_to_key
*
3
))
kf_boost
=
(
rc
->
frames_to_key
*
3
);
if
(
kf_boost
<
MIN_BOOST
)
kf_boost
=
MIN_BOOST
;
if
(
kf_boost
<
MIN_
KF_
BOOST
)
kf_boost
=
MIN_
KF_
BOOST
;
// Make a note of baseline boost and the zero motion
// accumulator value for use elsewhere.
...
...
@@ -2235,13 +2231,9 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
twopass
->
kf_bits
=
alt_kf_bits
;
}
}
twopass
->
kf_group_bits
-=
twopass
->
kf_bits
;
// Peer frame bit target for this frame
rc
->
per_frame_bandwidth
=
twopass
->
kf_bits
;
// Convert to a per second bitrate
cpi
->
target_bandwidth
=
(
int
)(
twopass
->
kf_bits
*
cpi
->
output_framerate
);
// Per frame bit target for this frame.
vp9_rc_set_frame_target
(
cpi
,
twopass
->
kf_bits
);
}
// Note the total error score of the kf group minus the key frame itself
...
...
@@ -2253,176 +2245,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
twopass
->
modified_error_left
-=
kf_group_err
;
}
void
vp9_get_svc_params
(
VP9_COMP
*
cpi
)
{
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
if
((
cm
->
current_video_frame
==
0
)
||
(
cm
->
frame_flags
&
FRAMEFLAGS_KEY
)
||
(
cpi
->
oxcf
.
auto_key
&&
(
cpi
->
rc
.
frames_since_key
%
cpi
->
key_frame_frequency
==
0
)))
{
cm
->
frame_type
=
KEY_FRAME
;
cpi
->
rc
.
source_alt_ref_active
=
0
;
}
else
{
cm
->
frame_type
=
INTER_FRAME
;
}
cpi
->
rc
.
frames_till_gf_update_due
=
INT_MAX
;
cpi
->
rc
.
baseline_gf_interval
=
INT_MAX
;
}
// Use this macro to turn on/off use of alt-refs in one-pass mode.
#define USE_ALTREF_FOR_ONE_PASS 1
void
vp9_get_one_pass_params
(
VP9_COMP
*
cpi
)
{
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
if
(
!
cpi
->
refresh_alt_ref_frame
&&
(
cm
->
current_video_frame
==
0
||
cm
->
frame_flags
&
FRAMEFLAGS_KEY
||
cpi
->
rc
.
frames_to_key
==
0
||
(
cpi
->
oxcf
.
auto_key
&&
test_for_kf_one_pass
(
cpi
))))
{
cm
->
frame_type
=
KEY_FRAME
;
cpi
->
rc
.
this_key_frame_forced
=
cm
->
current_video_frame
!=
0
&&
cpi
->
rc
.
frames_to_key
==
0
;
cpi
->
rc
.
frames_to_key
=
cpi
->
key_frame_frequency
;
cpi
->
rc
.
kf_boost
=
KEY_FRAME_BOOST
;
cpi
->
rc
.
source_alt_ref_active
=
0
;
cpi
->
rc
.
per_frame_bandwidth
=
cpi
->
rc
.
av_per_frame_bandwidth
*
8
;
if
(
cm
->
current_video_frame
==
0
)
{
cpi
->
rc
.
active_worst_quality
=
cpi
->
rc
.
worst_quality
;
}
else
{
// Choose active worst quality twice as large as the last q.
cpi
->
rc
.
active_worst_quality
=
cpi
->
rc
.
last_q
[
KEY_FRAME
]
*
2
;
if
(
cpi
->
rc
.
active_worst_quality
>
cpi
->
rc
.
worst_quality
)
cpi
->
rc
.
active_worst_quality
=
cpi
->
rc
.
worst_quality
;
}
}
else
{
cm
->
frame_type
=
INTER_FRAME
;
cpi
->
rc
.
per_frame_bandwidth
=
cpi
->
rc
.
av_per_frame_bandwidth
;
if
(
cm
->
current_video_frame
==
1
)
{
cpi
->
rc
.
active_worst_quality
=
cpi
->
rc
.
worst_quality
;
}
else
{
// Choose active worst quality twice as large as the last q.
cpi
->
rc
.
active_worst_quality
=
cpi
->
rc
.
last_q
[
INTER_FRAME
]
*
2
;
if
(
cpi
->
rc
.
active_worst_quality
>
cpi
->
rc
.
worst_quality
)
cpi
->
rc
.
active_worst_quality
=
cpi
->
rc
.
worst_quality
;
}
}
if
(
cpi
->
rc
.
frames_till_gf_update_due
==
0
)
{
cpi
->
rc
.
baseline_gf_interval
=
DEFAULT_GF_INTERVAL
;
cpi
->
rc
.
frames_till_gf_update_due
=
cpi
->
rc
.
baseline_gf_interval
;
// NOTE: frames_till_gf_update_due must be <= frames_to_key.
if
(
cpi
->
rc
.
frames_till_gf_update_due
>
cpi
->
rc
.
frames_to_key
)
cpi
->
rc
.
frames_till_gf_update_due
=
cpi
->
rc
.
frames_to_key
;
cpi
->
refresh_golden_frame
=
1
;
cpi
->
rc
.
source_alt_ref_pending
=
USE_ALTREF_FOR_ONE_PASS
;
cpi
->
rc
.
gfu_boost
=
2000
;
}
}
// Adjust active_worst_quality level based on buffer level.
static
int
calc_active_worst_quality_from_buffer_level
(
const
VP9_COMP
*
cpi
)
{
// Adjust active_worst_quality: If buffer is above the optimal/target level,
// bring active_worst_quality down depending on fullness of buffer.
// If buffer is below the optimal level, let the active_worst_quality go from
// ambient Q (at buffer = optimal level) to worst_quality level
// (at buffer = critical level).
const
VP9_CONFIG
*
oxcf
=
&
cpi
->
oxcf
;
const
RATE_CONTROL
*
rc
=
&
cpi
->
rc
;
int
active_worst_quality
=
rc
->
active_worst_quality
;
// Maximum limit for down adjustment, ~20%.
int
max_adjustment_down
=
active_worst_quality
/
5
;
// Buffer level below which we push active_worst to worst_quality.
int
critical_level
=
oxcf
->
optimal_buffer_level
>>
2
;
int
adjustment
=
0
;
int
buff_lvl_step
=
0
;
if
(
rc
->
buffer_level
>
oxcf
->
optimal_buffer_level
)
{
// Adjust down.
if
(
max_adjustment_down
)
{
buff_lvl_step
=
(
int
)((
oxcf
->
maximum_buffer_size
-
oxcf
->
optimal_buffer_level
)
/
max_adjustment_down
);
if
(
buff_lvl_step
)
adjustment
=
(
int
)((
rc
->
buffer_level
-
oxcf
->
optimal_buffer_level
)
/
buff_lvl_step
);
active_worst_quality
-=
adjustment
;
}
}
else
if
(
rc
->
buffer_level
>
critical_level
)
{
// Adjust up from ambient Q.
if
(
critical_level
)
{
buff_lvl_step
=
(
oxcf
->
optimal_buffer_level
-
critical_level
);
if
(
buff_lvl_step
)
{
adjustment
=
(
rc
->
worst_quality
-
rc
->
avg_frame_qindex
[
INTER_FRAME
])
*
(
oxcf
->
optimal_buffer_level
-
rc
->
buffer_level
)
/
buff_lvl_step
;
}
active_worst_quality
=
rc
->
avg_frame_qindex
[
INTER_FRAME
]
+
adjustment
;
}
}
else
{
// Set to worst_quality if buffer is below critical level.
active_worst_quality
=
rc
->
worst_quality
;
}
return
active_worst_quality
;
}
static
int
calc_pframe_target_size_one_pass_cbr
(
const
VP9_COMP
*
cpi
)
{
const
VP9_CONFIG
*
oxcf
=
&
cpi
->
oxcf
;
const
RATE_CONTROL
*
rc
=
&
cpi
->
rc
;
int
target
=
rc
->
av_per_frame_bandwidth
;
const
int64_t
diff
=
oxcf
->
optimal_buffer_level
-
rc
->
buffer_level
;
const
int
one_pct_bits
=
1
+
oxcf
->
optimal_buffer_level
/
100
;
if
(
diff
>
0
)
{
// Lower the target bandwidth for this frame.
const
int
pct_low
=
MIN
(
diff
/
one_pct_bits
,
oxcf
->
under_shoot_pct
);
target
-=
(
target
*
pct_low
)
/
200
;
}
else
if
(
diff
<
0
)
{
// Increase the target bandwidth for this frame.
const
int
pct_high
=
MIN
(
-
diff
/
one_pct_bits
,
oxcf
->
over_shoot_pct
);
target
+=
(
target
*
pct_high
)
/
200
;
}
return
target
;
}
static
int
calc_iframe_target_size_one_pass_cbr
(
const
VP9_COMP
*
cpi
)
{
int
per_frame_bandwidth
;
const
RATE_CONTROL
*
rc
=
&
cpi
->
rc
;
if
(
cpi
->
common
.
current_video_frame
==
0
)
{
per_frame_bandwidth
=
cpi
->
oxcf
.
starting_buffer_level
/
2
;
}
else
{
int
initial_boost
=
32
;
int
kf_boost
=
MAX
(
initial_boost
,
(
int
)(
2
*
cpi
->
output_framerate
-
16
));
if
(
rc
->
frames_since_key
<
cpi
->
output_framerate
/
2
)
{
kf_boost
=
(
int
)(
kf_boost
*
rc
->
frames_since_key
/
(
cpi
->
output_framerate
/
2
));
}
per_frame_bandwidth
=
((
16
+
kf_boost
)
*
rc
->
av_per_frame_bandwidth
)
>>
4
;
}
return
per_frame_bandwidth
;
}
void
vp9_get_one_pass_cbr_params
(
VP9_COMP
*
cpi
)
{
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
if
((
cm
->
current_video_frame
==
0
||
cm
->
frame_flags
&
FRAMEFLAGS_KEY
||
cpi
->
rc
.
frames_to_key
==
0
||
(
cpi
->
oxcf
.
auto_key
&&
test_for_kf_one_pass
(
cpi
))))
{
cm
->
frame_type
=
KEY_FRAME
;
cpi
->
rc
.
this_key_frame_forced
=
cm
->
current_video_frame
!=
0
&&
cpi
->
rc
.
frames_to_key
==
0
;
cpi
->
rc
.
frames_to_key
=
cpi
->
key_frame_frequency
;
cpi
->
rc
.
kf_boost
=
KEY_FRAME_BOOST
;
cpi
->
rc
.
source_alt_ref_active
=
0
;
cpi
->
rc
.
per_frame_bandwidth
=
calc_iframe_target_size_one_pass_cbr
(
cpi
);
cpi
->
rc
.
active_worst_quality
=
cpi
->
rc
.
worst_quality
;
}
else
{
cm
->
frame_type
=
INTER_FRAME
;
cpi
->
rc
.
per_frame_bandwidth
=
calc_pframe_target_size_one_pass_cbr
(
cpi
);
cpi
->
rc
.
active_worst_quality
=
calc_active_worst_quality_from_buffer_level
(
cpi
);
}
// Don't use gf_update by default in CBR mode.
cpi
->
rc
.
frames_till_gf_update_due
=
INT_MAX
;
cpi
->
rc
.
baseline_gf_interval
=
INT_MAX
;
}
void
vp9_get_first_pass_params
(
VP9_COMP
*
cpi
)
{
void
vp9_rc_get_first_pass_params
(
VP9_COMP
*
cpi
)
{
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
if
(
!
cpi
->
refresh_alt_ref_frame
&&
(
cm
->
current_video_frame
==
0
||
...
...
@@ -2435,7 +2258,7 @@ void vp9_get_first_pass_params(VP9_COMP *cpi) {
cpi
->
rc
.
frames_to_key
=
INT_MAX
;
}
void
vp9_get_second_pass_params
(
VP9_COMP
*
cpi
)
{
void
vp9_
rc_
get_second_pass_params
(
VP9_COMP
*
cpi
)
{
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
struct
twopass_rc
*
const
twopass
=
&
cpi
->
twopass
;
...
...
@@ -2446,13 +2269,14 @@ void vp9_get_second_pass_params(VP9_COMP *cpi) {
double
this_frame_intra_error
;
double
this_frame_coded_error
;
int
target
;
if
(
!
twopass
->
stats_in
)
return
;
if
(
cpi
->
refresh_alt_ref_frame
)
{
cm
->
frame_type
=
INTER_FRAME
;
rc
->
per_frame_bandwidth
=
twopass
->
gf_bits
;
vp9_rc_set_frame_target
(
cpi
,
twopass
->
gf_bits
)
;
return
;
}
...
...
@@ -2463,7 +2287,7 @@ void vp9_get_second_pass_params(VP9_COMP *cpi) {
}
else
if
(
cm
->
current_video_frame
==
0
)
{
// Special case code for first frame.
const
int
section_target_bandwidth
=
(
int
)(
twopass
->
bits_left
/
frames_left
);
frames_left
);
const
int
tmp_q
=
estimate_max_q
(
cpi
,
&
twopass
->
total_left_stats
,
section_target_bandwidth
);
...
...
@@ -2539,11 +2363,11 @@ void vp9_get_second_pass_params(VP9_COMP *cpi) {
}
}
// Set nominal per second bandwidth for this frame
cpi
->
target_bandwidth
=
(
int
)(
rc
->
per_frame_bandwidth
*
cpi
->
output_framerate
);
if
(
cpi
->
target_bandwidth
<
0
)
cpi
->
target
_bandwidth
=
0
;
if
(
cpi
->
common
.
frame_type
==
KEY_FRAME
)
target
=
vp9_rc_clamp_iframe_target_size
(
cpi
,
rc
->
this_frame_target
);
else
target
=
vp9_rc_clamp_pframe_target_size
(
cpi
,
rc
->
this_frame_target
);
vp9_rc_set_frame_target
(
cpi
,
target
)
;
// Update the total stats remaining structure
subtract_stats
(
&
twopass
->
total_left_stats
,
&
this_frame
);
...
...
@@ -2554,5 +2378,18 @@ void vp9_twopass_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
cpi
->
twopass
.
bits_left
-=
cpi
->
rc
.
this_frame_target
;
#else
cpi
->
twopass
.
bits_left
-=
8
*
bytes_used
;
// Update bits left to the kf and gf groups to account for overshoot or
// undershoot on these frames
if
(
cm
->
frame_type
==
KEY_FRAME
)
{
cpi
->
twopass
.
kf_group_bits
+=
cpi
->
rc
.
this_frame_target
-
cpi
->
rc
.
projected_frame_size
;
cpi
->
twopass
.
kf_group_bits
=
MAX
(
cpi
->
twopass
.
kf_group_bits
,
0
);
}
else
if
(
cpi
->
refresh_golden_frame
||
cpi
->
refresh_alt_ref_frame
)
{
cpi
->
twopass
.
gf_group_bits
+=
cpi
->
rc
.
this_frame_target
-
cpi
->
rc
.
projected_frame_size
;
cpi
->
twopass
.
gf_group_bits
=
MAX
(
cpi
->
twopass
.
gf_group_bits
,
0
);
}
#endif
}
vp9/encoder/vp9_firstpass.h
View file @
2fb81fba
...
...
@@ -17,18 +17,17 @@ extern "C" {
#endif
void
vp9_init_first_pass
(
VP9_COMP
*
cpi
);
void
vp9_rc_get_first_pass_params
(
VP9_COMP
*
cpi
);
void
vp9_first_pass
(
VP9_COMP
*
cpi
);
void
vp9_end_first_pass
(
VP9_COMP
*
cpi
);
void
vp9_init_second_pass
(
VP9_COMP
*
cpi
);
void
vp9_get_second_pass_params
(
VP9_COMP
*
cpi
);
void
vp9_
rc_
get_second_pass_params
(
VP9_COMP
*
cpi
);
void
vp9_end_second_pass
(
VP9_COMP
*
cpi
);
void
vp9_get_first_pass_params
(
VP9_COMP
*
cpi
);
void
vp9_get_one_pass_params
(
VP9_COMP
*
cpi
);
void
vp9_get_one_pass_cbr_params
(
VP9_COMP
*
cpi
);
void
vp9_get_svc_params
(
VP9_COMP
*
cpi
);
// Post encode update of the rate control parameters for 2-pass
void
vp9_twopass_postencode_update
(
struct
VP9_COMP
*
cpi
,
uint64_t
bytes_used
);
#ifdef __cplusplus
}
// extern "C"
#endif
...
...
vp9/encoder/vp9_onyx_if.c
View file @
2fb81fba
...
...
@@ -1104,8 +1104,6 @@ void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
cpi
->
oxcf
.
framerate
=
framerate
;
cpi
->
output_framerate
=
cpi
->
oxcf
.
framerate
;
cpi
->
rc
.
per_frame_bandwidth
=
(
int
)(
cpi
->
oxcf
.
target_bandwidth
/
cpi
->
output_framerate
);
cpi
->
rc
.
av_per_frame_bandwidth
=
(
int
)(
cpi
->
oxcf
.
target_bandwidth
/
cpi
->
output_framerate
);
cpi
->
rc
.
min_frame_bandwidth
=
(
int
)(
cpi
->
rc
.
av_per_frame_bandwidth
*
...
...
@@ -1344,8 +1342,6 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) {
cm
->
interp_filter
=
DEFAULT_INTERP_FILTER
;
cpi
->
target_bandwidth
=
cpi
->
oxcf
.
target_bandwidth
;
cm
->
display_width
=
cpi
->
oxcf
.
width
;
cm
->
display_height
=
cpi
->
oxcf
.
height
;
...
...
@@ -3025,10 +3021,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
if
(
cpi
->
pass
==
0
&&
cpi
->
oxcf
.
end_usage
==
USAGE_STREAM_FROM_SERVER
&&
cm
->
frame_type
!=
KEY_FRAME
)
{
if
(
vp9_drop_frame
(
cpi
))
{
// Update buffer level with zero size, update frame counters, and return.
vp9_update_buffer_level
(
cpi
,
0
);
cm
->
last_frame_type
=
cm
->
frame_type
;
if
(
vp9_rc_drop_frame
(
cpi
))
{
vp9_rc_postencode_update_drop_frame
(
cpi
);
cm
->
current_video_frame
++
;
return
;
...
...
@@ -3068,9 +3061,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
vp9_write_yuv_frame
(
cpi
->
Source
);
#endif
// Decide how big to make the frame.
vp9_rc_pick_frame_size_target
(
cpi
);
// Decide frame size bounds
vp9_rc_compute_frame_size_bounds
(
cpi
,
cpi
->
rc
.
this_frame_target
,
&
frame_under_shoot_limit
,
...
...
@@ -3171,10 +3161,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
vp9_update_mode_context_stats
(
cpi
);
#endif
/* Move storing frame_type out of the above loop since it is also
* needed in motion search besides loopfilter */
cm
->
last_frame_type
=
cm
->
frame_type
;
#if 0
output_frame_level_debug_stats(cpi);
#endif
...
...
@@ -3262,16 +3248,16 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
static
void
SvcEncode
(
VP9_COMP
*
cpi
,
size_t
*
size
,
uint8_t
*
dest
,
unsigned
int
*
frame_flags
)
{
vp9_get_svc_params
(
cpi
);
vp9_
rc_
get_svc_params
(
cpi
);
encode_frame_to_data_rate
(
cpi
,
size
,
dest
,
frame_flags
);
}
static
void
Pass0Encode
(
VP9_COMP
*
cpi
,
size_t
*
size
,
uint8_t
*
dest
,
unsigned
int
*
frame_flags
)
{
if
(
cpi
->
oxcf
.
end_usage
==
USAGE_STREAM_FROM_SERVER
)
{
vp9_get_one_pass_cbr_params
(
cpi
);
vp9_
rc_
get_one_pass_cbr_params
(
cpi
);
}
else
{
vp9_get_one_pass_params
(
cpi
);
vp9_
rc_
get_one_pass_
vbr_
params
(
cpi
);
}
encode_frame_to_data_rate
(
cpi
,
size
,
dest
,
frame_flags
);
}
...
...
@@ -3282,7 +3268,7 @@ static void Pass1Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest,
(
void
)
dest
;
(
void
)
frame_flags
;
vp9_get_first_pass_params
(
cpi
);
vp9_
rc_
get_first_pass_params
(
cpi
);
vp9_set_quantizer
(
cpi
,
find_fp_qindex
());
vp9_first_pass
(
cpi
);
}
...
...
@@ -3291,7 +3277,7 @@ static void Pass2Encode(VP9_COMP *cpi, size_t *size,
uint8_t
*
dest
,
unsigned
int
*
frame_flags
)
{
cpi
->
enable_encode_breakout
=
1
;
vp9_get_second_pass_params
(
cpi
);
vp9_
rc_
get_second_pass_params
(
cpi
);
encode_frame_to_data_rate
(
cpi
,
size
,
dest
,
frame_flags
);
vp9_twopass_postencode_update
(
cpi
,
*
size
);
...
...
vp9/encoder/vp9_onyx_int.h
View file @
2fb81fba
...
...
@@ -36,7 +36,6 @@
extern
"C"
{
#endif
#define DISABLE_RC_LONG_TERM_MEM 0
// #define MODE_TEST_HIT_STATS
// #define SPEEDSTATS 1
...
...
@@ -47,6 +46,7 @@ extern "C" {
#define MIN_GF_INTERVAL 4
#endif
#define DEFAULT_GF_INTERVAL 7
#define DEFAULT_KF_BOOST 2000
#define KEY_FRAME_CONTEXT 5
...
...
@@ -530,7 +530,6 @@ typedef struct VP9_COMP {
vp9_coeff_probs_model
frame_coef_probs
[
TX_SIZES
][
PLANE_TYPES
];
vp9_coeff_stats
frame_branch_ct
[
TX_SIZES
][
PLANE_TYPES
];
int64_t
target_bandwidth
;
struct
vpx_codec_pkt_list
*
output_pkt_list
;
MBGRAPH_FRAME_STATS
mbgraph_stats
[
MAX_LAG_BUFFERS
];
...
...
vp9/encoder/vp9_ratectrl.c
View file @
2fb81fba
...
...
@@ -209,24 +209,40 @@ static int estimate_bits_at_q(int frame_kind, int q, int mbs,
:
(
bpm
*
mbs
)
>>
BPER_MB_NORMBITS
;
}
int
vp9_rc_clamp_pframe_target_size
(
const
VP9_COMP
*
const
cpi
,
int
target
)
{
const
RATE_CONTROL
*
rc
=
&
cpi
->
rc
;
const
int
min_frame_target
=
MAX
(
rc
->
min_frame_bandwidth
,
rc
->
av_per_frame_bandwidth
>>
5
);
if
(
target
<
min_frame_target
)
target
=
min_frame_target
;
if
(
cpi
->
refresh_golden_frame
&&
rc
->
source_alt_ref_active
)
{
// If there is an active ARF at this location use the minimum
// bits on this frame even if it is a constructed arf.
// The active maximum quantizer insures that an appropriate
// number of bits will be spent if needed for constructed ARFs.
target
=
0
;
}
// Clip the frame target to the maximum allowed value.
if
(
target
>
rc
->
max_frame_bandwidth
)
target
=
rc
->
max_frame_bandwidth
;
return
target
;
}
static
void
calc_iframe_target_size
(
VP9_COMP
*
cpi
)
{
int
vp9_rc_clamp_iframe_target_size
(
const
VP9_COMP
*
const
cpi
,
int
target
)
{
const
RATE_CONTROL
*
rc
=
&
cpi
->
rc
;
const
VP9_CONFIG
*
oxcf
=
&
cpi
->
oxcf
;
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
int
target
=
rc
->
per_frame_bandwidth
;
vp9_clear_system_state
();
// __asm emms;
if
(
oxcf
->
rc_max_intra_bitrate_pct
)
{
const
int
max_rate
=
rc
->
per_frame_bandwidth
*
const
int
max_rate
=
rc
->
av_
per_frame_bandwidth
*
oxcf
->
rc_max_intra_bitrate_pct
/
100
;
target
=
MIN
(
target
,
max_rate
);
}
rc
->
this_frame_target
=
target
;
if
(
target
>
rc
->
max_frame_bandwidth
)
target
=
rc
->
max_frame_bandwidth
;
return
target
;
}
// Update the buffer level: leaky bucket model.
void
vp9_
update_buffer_level
(
VP9_COMP
*
cpi
,
int
encoded_frame_size
)
{
static
void
update_buffer_level
(
VP9_COMP
*
cpi
,
int
encoded_frame_size
)
{
const
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
const
VP9_CONFIG
*
oxcf
=
&
cpi
->
oxcf
;
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
...
...
@@ -242,7 +258,7 @@ void vp9_update_buffer_level(VP9_COMP *cpi, int encoded_frame_size) {
rc
->
buffer_level
=
MIN
(
rc
->
bits_off_target
,
oxcf
->
maximum_buffer_size
);
}
int
vp9_drop_frame
(
VP9_COMP
*
cpi
)
{
int
vp9_
rc_
drop_frame
(
VP9_COMP
*
cpi
)
{
const
VP9_CONFIG
*
oxcf
=
&
cpi
->
oxcf
;
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
...
...
@@ -281,53 +297,6 @@ int vp9_drop_frame(VP9_COMP *cpi) {
}
}
static
void
calc_pframe_target_size
(
VP9_COMP
*
const
cpi
)
{
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
const
VP9_CONFIG
*
const
oxcf
=
&
cpi
->
oxcf
;
int
min_frame_target
;
rc
->
this_frame_target
=
rc
->
per_frame_bandwidth
;
if
(
cpi
->
pass
==
0
&&
oxcf
->
end_usage
==
USAGE_STREAM_FROM_SERVER
)
{
// Need to decide how low min_frame_target should be for 1-pass CBR.
// For now, use: cpi->rc.av_per_frame_bandwidth / 16:
min_frame_target
=
MAX
(
rc
->
av_per_frame_bandwidth
>>
4
,
FRAME_OVERHEAD_BITS
);
if
(
rc
->
this_frame_target
<
min_frame_target
)
rc
->
this_frame_target
=
min_frame_target
;
return
;
}
// Check that the total sum of adjustments is not above the maximum allowed.
// That is, having allowed for the KF and GF penalties, we have not pushed
// the current inter-frame target too low. If the adjustment we apply here is
// not capable of recovering all the extra bits we have spent in the KF or GF,
// then the remainder will have to be recovered over a longer time span via
// other buffer / rate control mechanisms.
min_frame_target
=
MAX
(
rc
->
min_frame_bandwidth
,
rc
->
av_per_frame_bandwidth
>>
5
);
if
(
rc
->
this_frame_target
<
min_frame_target
)
rc
->
this_frame_target
=
min_frame_target
;
// Adjust target frame size for Golden Frames:
if
(
cpi
->
refresh_golden_frame
)
{
// If we are using alternate ref instead of gf then do not apply the boost
// It will instead be applied to the altref update
// Jims modified boost
if
(
!
rc
->
source_alt_ref_active
)
{
// The spend on the GF is defined in the two pass code
// for two pass encodes
rc
->
this_frame_target
=
rc
->
per_frame_bandwidth
;
}
else
{
// If there is an active ARF at this location use the minimum
// bits on this frame even if it is a constructed arf.
// The active maximum quantizer insures that an appropriate
// number of bits will be spent if needed for constructed ARFs.
rc
->
this_frame_target
=
0
;
}
}
}
static
double
get_rate_correction_factor
(
const
VP9_COMP
*
cpi
)
{
if
(
cpi
->
common
.
frame_type
==
KEY_FRAME
)
{
return
cpi
->
rc
.
key_frame_rate_correction_factor
;
...
...
@@ -899,24 +868,14 @@ void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi,
}
}
// return of 0 means drop frame
int
vp9_rc_pick_frame_size_target
(
VP9_COMP
*
cpi
)
{
void
vp9_rc_set_frame_target
(
VP9_COMP
*
cpi
,
int
target
)
{
const
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
if
(
cm
->
frame_type
==
KEY_FRAME
)
calc_iframe_target_size
(
cpi
);
else
calc_pframe_target_size
(
cpi
);
// Clip the frame target to the maximum allowed value.
if
(
rc
->
this_frame_target
>
rc
->
max_frame_bandwidth
)
rc
->
this_frame_target
=
rc
->
max_frame_bandwidth
;
rc
->
this_frame_target
=
target
;
// Target rate per SB64 (including partial SB64s.
rc
->
sb64_target_rate
=
((
int64_t
)
rc
->
this_frame_target
*
64
*
64
)
/
(
cm
->
width
*
cm
->
height
);
return
1
;
}
static
void
update_alt_ref_frame_stats
(
VP9_COMP
*
cpi
)
{
...
...
@@ -960,6 +919,8 @@ static void update_golden_frame_stats(VP9_COMP *cpi) {
void
vp9_rc_postencode_update
(
VP9_COMP
*
cpi
,
uint64_t
bytes_used
)
{
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
RATE_CONTROL
*
const
rc
=
&
cpi
->
rc
;
cm
->
last_frame_type
=
cm
->
frame_type
;
// Update rate control heuristics
rc
->
projected_frame_size
=
(
bytes_used
<<
3
);
...
...
@@ -1002,7 +963,7 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
rc
->
last_boosted_qindex
=
cm
->
base_qindex
;
}
vp9_
update_buffer_level
(
cpi
,
rc
->
projected_frame_size
);
update_buffer_level
(
cpi
,
rc
->
projected_frame_size
);
// Rolling monitors of whether we are over or underspending used to help
// regulate min and Max Q in two pass.
...
...
@@ -1024,22 +985,6 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
rc
->
total_target_vs_actual
+=
(
rc
->
this_frame_target
-
rc
->
projected_frame_size
);
#ifndef DISABLE_RC_LONG_TERM_MEM
// Update bits left to the kf and gf groups to account for overshoot or
// undershoot on these frames
if
(
cm
->
frame_type
==
KEY_FRAME
)
{
cpi
->
twopass
.
kf_group_bits
+=
cpi
->
rc
.
this_frame_target
-
cpi
->
rc
.
projected_frame_size
;