Merge branch 'master' into nextgenv2

With a few manual fixes of merge conflicts.

Change-Id: I0dd65ff90f9fa8606e5563f528659e2607b12376
This commit is contained in:
Yaowu Xu
2015-12-16 08:03:59 -08:00
15 changed files with 195 additions and 94 deletions

View File

@@ -1221,24 +1221,13 @@ static INLINE int read_delta_q(struct vpx_read_bit_buffer *rb) {
vpx_rb_read_inv_signed_literal(rb, 6) : 0; vpx_rb_read_inv_signed_literal(rb, 6) : 0;
} }
static void setup_quantization(VP10_COMMON *const cm, MACROBLOCKD *const xd, static void setup_quantization(VP10_COMMON *const cm,
struct vpx_read_bit_buffer *rb) { struct vpx_read_bit_buffer *rb) {
int i;
cm->base_qindex = vpx_rb_read_literal(rb, QINDEX_BITS); cm->base_qindex = vpx_rb_read_literal(rb, QINDEX_BITS);
cm->y_dc_delta_q = read_delta_q(rb); cm->y_dc_delta_q = read_delta_q(rb);
cm->uv_dc_delta_q = read_delta_q(rb); cm->uv_dc_delta_q = read_delta_q(rb);
cm->uv_ac_delta_q = read_delta_q(rb); cm->uv_ac_delta_q = read_delta_q(rb);
cm->dequant_bit_depth = cm->bit_depth; cm->dequant_bit_depth = cm->bit_depth;
for (i = 0; i < MAX_SEGMENTS; ++i) {
const int qindex = CONFIG_MISC_FIXES && cm->seg.enabled ?
vp10_get_qindex(&cm->seg, i, cm->base_qindex) :
cm->base_qindex;
xd->lossless[i] = qindex == 0 &&
cm->y_dc_delta_q == 0 &&
cm->uv_dc_delta_q == 0 &&
cm->uv_ac_delta_q == 0;
}
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
xd->bd = (int)cm->bit_depth; xd->bd = (int)cm->bit_depth;
@@ -2216,11 +2205,25 @@ static size_t read_uncompressed_header(VP10Decoder *pbi,
vp10_setup_past_independence(cm); vp10_setup_past_independence(cm);
setup_loopfilter(&cm->lf, rb); setup_loopfilter(&cm->lf, rb);
setup_quantization(cm, &pbi->mb, rb); setup_quantization(cm, rb);
setup_segmentation(cm, rb); setup_segmentation(cm, rb);
{
int i;
for (i = 0; i < MAX_SEGMENTS; ++i) {
const int qindex = CONFIG_MISC_FIXES && cm->seg.enabled ?
vp10_get_qindex(&cm->seg, i, cm->base_qindex) :
cm->base_qindex;
xd->lossless[i] = qindex == 0 &&
cm->y_dc_delta_q == 0 &&
cm->uv_dc_delta_q == 0 &&
cm->uv_ac_delta_q == 0;
}
}
setup_segmentation_dequant(cm); setup_segmentation_dequant(cm);
cm->tx_mode = (!cm->seg.enabled && xd->lossless[0]) ? ONLY_4X4 cm->tx_mode = (xd->lossless[0]) ? ONLY_4X4
: read_tx_mode(rb); : read_tx_mode(rb);
cm->reference_mode = read_frame_reference_mode(cm, rb); cm->reference_mode = read_frame_reference_mode(cm, rb);
setup_tile_info(cm, rb); setup_tile_info(cm, rb);

View File

@@ -1401,6 +1401,7 @@ static void write_txfm_mode(TX_MODE mode, struct vpx_write_bit_buffer *wb) {
vpx_wb_write_literal(wb, mode, 2); vpx_wb_write_literal(wb, mode, 2);
} }
static void update_txfm_probs(VP10_COMMON *cm, vpx_writer *w, static void update_txfm_probs(VP10_COMMON *cm, vpx_writer *w,
FRAME_COUNTS *counts) { FRAME_COUNTS *counts) {
if (cm->tx_mode == TX_MODE_SELECT) { if (cm->tx_mode == TX_MODE_SELECT) {
@@ -1750,7 +1751,7 @@ static void write_uncompressed_header(VP10_COMP *cpi,
encode_loopfilter(&cm->lf, wb); encode_loopfilter(&cm->lf, wb);
encode_quantization(cm, wb); encode_quantization(cm, wb);
encode_segmentation(cm, xd, wb); encode_segmentation(cm, xd, wb);
if (!cm->seg.enabled && xd->lossless[0]) if (xd->lossless[0])
cm->tx_mode = TX_4X4; cm->tx_mode = TX_4X4;
else else
write_txfm_mode(cm->tx_mode, wb); write_txfm_mode(cm->tx_mode, wb);

View File

@@ -1426,7 +1426,11 @@ void vp10_change_config(struct VP10_COMP *cpi, const VP10EncoderConfig *oxcf) {
cpi->td.mb.e_mbd.bd = (int)cm->bit_depth; cpi->td.mb.e_mbd.bd = (int)cm->bit_depth;
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2; if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) {
rc->baseline_gf_interval = FIXED_GF_INTERVAL;
} else {
rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2;
}
cpi->refresh_golden_frame = 0; cpi->refresh_golden_frame = 0;
cpi->refresh_last_frame = 1; cpi->refresh_last_frame = 1;

View File

@@ -794,16 +794,18 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP10_COMP *cpi,
ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq); ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq);
if (frame_is_intra_only(cm)) { if (frame_is_intra_only(cm)) {
if (oxcf->rc_mode == VPX_Q) {
// Handle the special case for key frames forced when we have reached int qindex = cq_level;
// the maximum key frame interval. Here force the Q to a range double q = vp10_convert_qindex_to_q(qindex, cm->bit_depth);
// based on the ambient Q to reduce the risk of popping. int delta_qindex = vp10_compute_qdelta(rc, q, q * 0.25,
if (rc->this_key_frame_forced) { cm->bit_depth);
active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality);
} else if (rc->this_key_frame_forced) {
int qindex = rc->last_boosted_qindex; int qindex = rc->last_boosted_qindex;
double last_boosted_q = vp10_convert_qindex_to_q(qindex, cm->bit_depth); double last_boosted_q = vp10_convert_qindex_to_q(qindex, cm->bit_depth);
int delta_qindex = vp10_compute_qdelta(rc, last_boosted_q, int delta_qindex = vp10_compute_qdelta(rc, last_boosted_q,
last_boosted_q * 0.75, last_boosted_q * 0.75,
cm->bit_depth); cm->bit_depth);
active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality);
} else { } else {
// not first frame of one pass and kf_boost is set // not first frame of one pass and kf_boost is set
@@ -823,8 +825,8 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP10_COMP *cpi,
// on active_best_quality. // on active_best_quality.
q_val = vp10_convert_qindex_to_q(active_best_quality, cm->bit_depth); q_val = vp10_convert_qindex_to_q(active_best_quality, cm->bit_depth);
active_best_quality += vp10_compute_qdelta(rc, q_val, active_best_quality += vp10_compute_qdelta(rc, q_val,
q_val * q_adj_factor, q_val * q_adj_factor,
cm->bit_depth); cm->bit_depth);
} }
} else if (!rc->is_src_frame_alt_ref && } else if (!rc->is_src_frame_alt_ref &&
(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
@@ -848,17 +850,28 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP10_COMP *cpi,
active_best_quality = active_best_quality * 15 / 16; active_best_quality = active_best_quality * 15 / 16;
} else if (oxcf->rc_mode == VPX_Q) { } else if (oxcf->rc_mode == VPX_Q) {
if (!cpi->refresh_alt_ref_frame) { int qindex = cq_level;
active_best_quality = cq_level; double q = vp10_convert_qindex_to_q(qindex, cm->bit_depth);
} else { int delta_qindex;
active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); if (cpi->refresh_alt_ref_frame)
} delta_qindex = vp10_compute_qdelta(rc, q, q * 0.40, cm->bit_depth);
else
delta_qindex = vp10_compute_qdelta(rc, q, q * 0.50, cm->bit_depth);
active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality);
} else { } else {
active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth);
} }
} else { } else {
if (oxcf->rc_mode == VPX_Q) { if (oxcf->rc_mode == VPX_Q) {
active_best_quality = cq_level; int qindex = cq_level;
double q = vp10_convert_qindex_to_q(qindex, cm->bit_depth);
double delta_rate[FIXED_GF_INTERVAL] =
{0.50, 1.0, 0.85, 1.0, 0.70, 1.0, 0.85, 1.0};
int delta_qindex =
vp10_compute_qdelta(rc, q,
q * delta_rate[cm->current_video_frame %
FIXED_GF_INTERVAL], cm->bit_depth);
active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality);
} else { } else {
// Use the lower of active_worst_quality and recent/average Q. // Use the lower of active_worst_quality and recent/average Q.
if (cm->current_video_frame > 1) if (cm->current_video_frame > 1)
@@ -1254,7 +1267,7 @@ void vp10_rc_postencode_update(VP10_COMP *cpi, uint64_t bytes_used) {
rc->avg_frame_qindex[KEY_FRAME] = rc->avg_frame_qindex[KEY_FRAME] =
ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[KEY_FRAME] + qindex, 2); ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[KEY_FRAME] + qindex, 2);
} else { } else {
if (rc->is_src_frame_alt_ref || if (!rc->is_src_frame_alt_ref &&
!(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { !(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
rc->last_q[INTER_FRAME] = qindex; rc->last_q[INTER_FRAME] = qindex;
rc->avg_frame_qindex[INTER_FRAME] = rc->avg_frame_qindex[INTER_FRAME] =
@@ -1562,29 +1575,36 @@ void vp10_rc_set_gf_interval_range(const VP10_COMP *const cpi,
RATE_CONTROL *const rc) { RATE_CONTROL *const rc) {
const VP10EncoderConfig *const oxcf = &cpi->oxcf; const VP10EncoderConfig *const oxcf = &cpi->oxcf;
// Set Maximum gf/arf interval // Special case code for 1 pass fixed Q mode tests
rc->max_gf_interval = oxcf->max_gf_interval; if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) {
rc->min_gf_interval = oxcf->min_gf_interval; rc->max_gf_interval = FIXED_GF_INTERVAL;
if (rc->min_gf_interval == 0) rc->min_gf_interval = FIXED_GF_INTERVAL;
rc->min_gf_interval = vp10_rc_get_default_min_gf_interval( rc->static_scene_max_gf_interval = FIXED_GF_INTERVAL;
oxcf->width, oxcf->height, cpi->framerate); } else {
if (rc->max_gf_interval == 0) // Set Maximum gf/arf interval
rc->max_gf_interval = vp10_rc_get_default_max_gf_interval( rc->max_gf_interval = oxcf->max_gf_interval;
cpi->framerate, rc->min_gf_interval); rc->min_gf_interval = oxcf->min_gf_interval;
if (rc->min_gf_interval == 0)
rc->min_gf_interval = vp10_rc_get_default_min_gf_interval(
oxcf->width, oxcf->height, cpi->framerate);
if (rc->max_gf_interval == 0)
rc->max_gf_interval = vp10_rc_get_default_max_gf_interval(
cpi->framerate, rc->min_gf_interval);
// Extended interval for genuinely static scenes // Extended interval for genuinely static scenes
rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2; rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2;
if (is_altref_enabled(cpi)) { if (is_altref_enabled(cpi)) {
if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1) if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1)
rc->static_scene_max_gf_interval = oxcf->lag_in_frames - 1; rc->static_scene_max_gf_interval = oxcf->lag_in_frames - 1;
}
if (rc->max_gf_interval > rc->static_scene_max_gf_interval)
rc->max_gf_interval = rc->static_scene_max_gf_interval;
// Clamp min to max
rc->min_gf_interval = VPXMIN(rc->min_gf_interval, rc->max_gf_interval);
} }
if (rc->max_gf_interval > rc->static_scene_max_gf_interval)
rc->max_gf_interval = rc->static_scene_max_gf_interval;
// Clamp min to max
rc->min_gf_interval = VPXMIN(rc->min_gf_interval, rc->max_gf_interval);
} }
void vp10_rc_update_framerate(VP10_COMP *cpi) { void vp10_rc_update_framerate(VP10_COMP *cpi) {

View File

@@ -26,6 +26,7 @@ extern "C" {
#define MIN_GF_INTERVAL 4 #define MIN_GF_INTERVAL 4
#define MAX_GF_INTERVAL 16 #define MAX_GF_INTERVAL 16
#define FIXED_GF_INTERVAL 8 // Used in some testing modes only
typedef enum { typedef enum {
INTER_NORMAL = 0, INTER_NORMAL = 0,

View File

@@ -1050,7 +1050,7 @@ static void super_block_yrd(VP10_COMP *cpi, MACROBLOCK *x, int *rate,
assert(bs == xd->mi[0]->mbmi.sb_type); assert(bs == xd->mi[0]->mbmi.sb_type);
if (xd->lossless[xd->mi[0]->mbmi.segment_id]) { if (xd->lossless[0]) {
choose_smallest_tx_size(cpi, x, rate, distortion, skip, ret_sse, choose_smallest_tx_size(cpi, x, rate, distortion, skip, ret_sse,
ref_best_rd, bs); ref_best_rd, bs);
} else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) { } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {

View File

@@ -496,7 +496,7 @@ static void set_vbp_thresholds(VP9_COMP *cpi, int64_t thresholds[], int q) {
threshold_base = 3 * threshold_base; threshold_base = 3 * threshold_base;
else if (noise_level == kMedium) else if (noise_level == kMedium)
threshold_base = threshold_base << 1; threshold_base = threshold_base << 1;
else if (noise_level == kLowLow) else if (noise_level < kLow)
threshold_base = (7 * threshold_base) >> 3; threshold_base = (7 * threshold_base) >> 3;
} }
if (cm->width <= 352 && cm->height <= 288) { if (cm->width <= 352 && cm->height <= 288) {

View File

@@ -1478,7 +1478,11 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
cpi->td.mb.e_mbd.bd = (int)cm->bit_depth; cpi->td.mb.e_mbd.bd = (int)cm->bit_depth;
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2; if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) {
rc->baseline_gf_interval = FIXED_GF_INTERVAL;
} else {
rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2;
}
cpi->refresh_golden_frame = 0; cpi->refresh_golden_frame = 0;
cpi->refresh_last_frame = 1; cpi->refresh_last_frame = 1;
@@ -2793,6 +2797,22 @@ void vp9_update_reference_frames(VP9_COMP *cpi) {
cpi->resize_pending); cpi->resize_pending);
} }
#endif #endif
if (is_one_pass_cbr_svc(cpi)) {
// Keep track of frame index for each reference frame.
SVC *const svc = &cpi->svc;
if (cm->frame_type == KEY_FRAME) {
svc->ref_frame_index[cpi->lst_fb_idx] = svc->current_superframe;
svc->ref_frame_index[cpi->gld_fb_idx] = svc->current_superframe;
svc->ref_frame_index[cpi->alt_fb_idx] = svc->current_superframe;
} else {
if (cpi->refresh_last_frame)
svc->ref_frame_index[cpi->lst_fb_idx] = svc->current_superframe;
if (cpi->refresh_golden_frame)
svc->ref_frame_index[cpi->gld_fb_idx] = svc->current_superframe;
if (cpi->refresh_alt_ref_frame)
svc->ref_frame_index[cpi->alt_fb_idx] = svc->current_superframe;
}
}
} }
static void loopfilter_frame(VP9_COMP *cpi, VP9_COMMON *cm) { static void loopfilter_frame(VP9_COMP *cpi, VP9_COMMON *cm) {

View File

@@ -25,7 +25,7 @@ void vp9_noise_estimate_init(NOISE_ESTIMATE *const ne,
int width, int width,
int height) { int height) {
ne->enabled = 0; ne->enabled = 0;
ne->level = kUnknown; ne->level = kLowLow;
ne->value = 0; ne->value = 0;
ne->count = 0; ne->count = 0;
ne->thresh = 90; ne->thresh = 90;
@@ -83,7 +83,7 @@ static void copy_frame(YV12_BUFFER_CONFIG * const dest,
} }
NOISE_LEVEL vp9_noise_estimate_extract_level(NOISE_ESTIMATE *const ne) { NOISE_LEVEL vp9_noise_estimate_extract_level(NOISE_ESTIMATE *const ne) {
int noise_level = kUnknown; int noise_level = kLowLow;
if (ne->value > (ne->thresh << 1)) { if (ne->value > (ne->thresh << 1)) {
noise_level = kHigh; noise_level = kHigh;
} else { } else {

View File

@@ -24,7 +24,6 @@ extern "C" {
#endif #endif
typedef enum noise_level { typedef enum noise_level {
kUnknown,
kLowLow, kLowLow,
kLow, kLow,
kMedium, kMedium,

View File

@@ -1094,6 +1094,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) { BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) {
VP9_COMMON *const cm = &cpi->common; VP9_COMMON *const cm = &cpi->common;
SPEED_FEATURES *const sf = &cpi->sf; SPEED_FEATURES *const sf = &cpi->sf;
const SVC *const svc = &cpi->svc;
TileInfo *const tile_info = &tile_data->tile_info; TileInfo *const tile_info = &tile_data->tile_info;
MACROBLOCKD *const xd = &x->e_mbd; MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
@@ -1143,6 +1144,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
int best_pred_sad = INT_MAX; int best_pred_sad = INT_MAX;
int best_early_term = 0; int best_early_term = 0;
int ref_frame_cost[MAX_REF_FRAMES]; int ref_frame_cost[MAX_REF_FRAMES];
int svc_force_zero_mode[3] = {0};
#if CONFIG_VP9_TEMPORAL_DENOISING #if CONFIG_VP9_TEMPORAL_DENOISING
int64_t zero_last_cost_orig = INT64_MAX; int64_t zero_last_cost_orig = INT64_MAX;
#endif #endif
@@ -1196,6 +1198,17 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
} else { } else {
usable_ref_frame = GOLDEN_FRAME; usable_ref_frame = GOLDEN_FRAME;
} }
// If the reference is temporally aligned with current superframe
// (e.g., spatial reference within superframe), constrain the inter mode:
// for now only test zero motion.
if (cpi->use_svc && svc ->force_zero_mode_spatial_ref) {
if (svc->ref_frame_index[cpi->lst_fb_idx] == svc->current_superframe)
svc_force_zero_mode[LAST_FRAME - 1] = 1;
if (svc->ref_frame_index[cpi->gld_fb_idx] == svc->current_superframe)
svc_force_zero_mode[GOLDEN_FRAME - 1] = 1;
}
for (ref_frame = LAST_FRAME; ref_frame <= usable_ref_frame; ++ref_frame) { for (ref_frame = LAST_FRAME; ref_frame <= usable_ref_frame; ++ref_frame) {
const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame); const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
@@ -1248,8 +1261,13 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
continue; continue;
ref_frame = ref_mode_set[idx].ref_frame; ref_frame = ref_mode_set[idx].ref_frame;
if (cpi->use_svc) if (cpi->use_svc) {
ref_frame = ref_mode_set_svc[idx].ref_frame; ref_frame = ref_mode_set_svc[idx].ref_frame;
if (svc_force_zero_mode[ref_frame - 1] &&
frame_mv[this_mode][ref_frame].as_int != 0)
continue;
}
if (!(cpi->ref_frame_flags & flag_list[ref_frame])) if (!(cpi->ref_frame_flags & flag_list[ref_frame]))
continue; continue;
if (const_motion[ref_frame] && this_mode == NEARMV) if (const_motion[ref_frame] && this_mode == NEARMV)

View File

@@ -833,10 +833,16 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi,
ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq); ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq);
if (frame_is_intra_only(cm)) { if (frame_is_intra_only(cm)) {
// Handle the special case for key frames forced when we have reached if (oxcf->rc_mode == VPX_Q) {
// the maximum key frame interval. Here force the Q to a range int qindex = cq_level;
// based on the ambient Q to reduce the risk of popping. double q = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
if (rc->this_key_frame_forced) { int delta_qindex = vp9_compute_qdelta(rc, q, q * 0.25,
cm->bit_depth);
active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality);
} else if (rc->this_key_frame_forced) {
// Handle the special case for key frames forced when we have reached
// the maximum key frame interval. Here force the Q to a range
// based on the ambient Q to reduce the risk of popping.
int qindex = rc->last_boosted_qindex; int qindex = rc->last_boosted_qindex;
double last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth); double last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
int delta_qindex = vp9_compute_qdelta(rc, last_boosted_q, int delta_qindex = vp9_compute_qdelta(rc, last_boosted_q,
@@ -886,17 +892,28 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi,
active_best_quality = active_best_quality * 15 / 16; active_best_quality = active_best_quality * 15 / 16;
} else if (oxcf->rc_mode == VPX_Q) { } else if (oxcf->rc_mode == VPX_Q) {
if (!cpi->refresh_alt_ref_frame) { int qindex = cq_level;
active_best_quality = cq_level; double q = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
} else { int delta_qindex;
active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); if (cpi->refresh_alt_ref_frame)
} delta_qindex = vp9_compute_qdelta(rc, q, q * 0.40, cm->bit_depth);
else
delta_qindex = vp9_compute_qdelta(rc, q, q * 0.50, cm->bit_depth);
active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality);
} else { } else {
active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth);
} }
} else { } else {
if (oxcf->rc_mode == VPX_Q) { if (oxcf->rc_mode == VPX_Q) {
active_best_quality = cq_level; int qindex = cq_level;
double q = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
double delta_rate[FIXED_GF_INTERVAL] =
{0.50, 1.0, 0.85, 1.0, 0.70, 1.0, 0.85, 1.0};
int delta_qindex =
vp9_compute_qdelta(rc, q,
q * delta_rate[cm->current_video_frame %
FIXED_GF_INTERVAL], cm->bit_depth);
active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality);
} else { } else {
// Use the lower of active_worst_quality and recent/average Q. // Use the lower of active_worst_quality and recent/average Q.
if (cm->current_video_frame > 1) if (cm->current_video_frame > 1)
@@ -1313,9 +1330,9 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
} }
} }
} else { } else {
if (rc->is_src_frame_alt_ref || if ((cpi->use_svc && oxcf->rc_mode == VPX_CBR) ||
!(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) || (!rc->is_src_frame_alt_ref &&
(cpi->use_svc && oxcf->rc_mode == VPX_CBR)) { !(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame))) {
rc->last_q[INTER_FRAME] = qindex; rc->last_q[INTER_FRAME] = qindex;
rc->avg_frame_qindex[INTER_FRAME] = rc->avg_frame_qindex[INTER_FRAME] =
ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[INTER_FRAME] + qindex, 2); ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[INTER_FRAME] + qindex, 2);
@@ -1722,29 +1739,36 @@ void vp9_rc_set_gf_interval_range(const VP9_COMP *const cpi,
RATE_CONTROL *const rc) { RATE_CONTROL *const rc) {
const VP9EncoderConfig *const oxcf = &cpi->oxcf; const VP9EncoderConfig *const oxcf = &cpi->oxcf;
// Set Maximum gf/arf interval // Special case code for 1 pass fixed Q mode tests
rc->max_gf_interval = oxcf->max_gf_interval; if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) {
rc->min_gf_interval = oxcf->min_gf_interval; rc->max_gf_interval = FIXED_GF_INTERVAL;
if (rc->min_gf_interval == 0) rc->min_gf_interval = FIXED_GF_INTERVAL;
rc->min_gf_interval = vp9_rc_get_default_min_gf_interval( rc->static_scene_max_gf_interval = FIXED_GF_INTERVAL;
oxcf->width, oxcf->height, cpi->framerate); } else {
if (rc->max_gf_interval == 0) // Set Maximum gf/arf interval
rc->max_gf_interval = vp9_rc_get_default_max_gf_interval( rc->max_gf_interval = oxcf->max_gf_interval;
cpi->framerate, rc->min_gf_interval); rc->min_gf_interval = oxcf->min_gf_interval;
if (rc->min_gf_interval == 0)
rc->min_gf_interval = vp9_rc_get_default_min_gf_interval(
oxcf->width, oxcf->height, cpi->framerate);
if (rc->max_gf_interval == 0)
rc->max_gf_interval = vp9_rc_get_default_max_gf_interval(
cpi->framerate, rc->min_gf_interval);
// Extended interval for genuinely static scenes // Extended interval for genuinely static scenes
rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2; rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2;
if (is_altref_enabled(cpi)) { if (is_altref_enabled(cpi)) {
if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1) if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1)
rc->static_scene_max_gf_interval = oxcf->lag_in_frames - 1; rc->static_scene_max_gf_interval = oxcf->lag_in_frames - 1;
}
if (rc->max_gf_interval > rc->static_scene_max_gf_interval)
rc->max_gf_interval = rc->static_scene_max_gf_interval;
// Clamp min to max
rc->min_gf_interval = VPXMIN(rc->min_gf_interval, rc->max_gf_interval);
} }
if (rc->max_gf_interval > rc->static_scene_max_gf_interval)
rc->max_gf_interval = rc->static_scene_max_gf_interval;
// Clamp min to max
rc->min_gf_interval = VPXMIN(rc->min_gf_interval, rc->max_gf_interval);
} }
void vp9_rc_update_framerate(VP9_COMP *cpi) { void vp9_rc_update_framerate(VP9_COMP *cpi) {

View File

@@ -26,6 +26,7 @@ extern "C" {
#define MIN_GF_INTERVAL 4 #define MIN_GF_INTERVAL 4
#define MAX_GF_INTERVAL 16 #define MAX_GF_INTERVAL 16
#define FIXED_GF_INTERVAL 8 // Used in some testing modes only
#define ONEHALFONLY_RESIZE 0 #define ONEHALFONLY_RESIZE 0
typedef enum { typedef enum {

View File

@@ -25,13 +25,17 @@ void vp9_init_layer_context(VP9_COMP *const cpi) {
const VP9EncoderConfig *const oxcf = &cpi->oxcf; const VP9EncoderConfig *const oxcf = &cpi->oxcf;
int mi_rows = cpi->common.mi_rows; int mi_rows = cpi->common.mi_rows;
int mi_cols = cpi->common.mi_cols; int mi_cols = cpi->common.mi_cols;
int sl, tl; int sl, tl, i;
int alt_ref_idx = svc->number_spatial_layers; int alt_ref_idx = svc->number_spatial_layers;
svc->spatial_layer_id = 0; svc->spatial_layer_id = 0;
svc->temporal_layer_id = 0; svc->temporal_layer_id = 0;
svc->first_spatial_layer_to_encode = 0; svc->first_spatial_layer_to_encode = 0;
svc->rc_drop_superframe = 0; svc->rc_drop_superframe = 0;
svc->force_zero_mode_spatial_ref = 0;
svc->current_superframe = 0;
for (i = 0; i < REF_FRAMES; ++i)
svc->ref_frame_index[i] = -1;
if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) { if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) {
if (vpx_realloc_frame_buffer(&cpi->svc.empty_frame.img, if (vpx_realloc_frame_buffer(&cpi->svc.empty_frame.img,
@@ -353,6 +357,8 @@ void vp9_inc_frame_in_layer(VP9_COMP *const cpi) {
cpi->svc.number_temporal_layers]; cpi->svc.number_temporal_layers];
++lc->current_video_frame_in_layer; ++lc->current_video_frame_in_layer;
++lc->frames_from_key_frame; ++lc->frames_from_key_frame;
if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)
++cpi->svc.current_superframe;
} }
int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) { int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) {
@@ -542,6 +548,7 @@ static void set_flags_and_fb_idx_for_temporal_mode_noLayering(
int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) { int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) {
int width = 0, height = 0; int width = 0, height = 0;
LAYER_CONTEXT *lc = NULL; LAYER_CONTEXT *lc = NULL;
cpi->svc.force_zero_mode_spatial_ref = 1;
if (cpi->svc.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0212) { if (cpi->svc.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0212) {
set_flags_and_fb_idx_for_temporal_mode3(cpi); set_flags_and_fb_idx_for_temporal_mode3(cpi);

View File

@@ -83,6 +83,9 @@ typedef struct {
int ext_lst_fb_idx[VPX_MAX_LAYERS]; int ext_lst_fb_idx[VPX_MAX_LAYERS];
int ext_gld_fb_idx[VPX_MAX_LAYERS]; int ext_gld_fb_idx[VPX_MAX_LAYERS];
int ext_alt_fb_idx[VPX_MAX_LAYERS]; int ext_alt_fb_idx[VPX_MAX_LAYERS];
int ref_frame_index[REF_FRAMES];
int force_zero_mode_spatial_ref;
int current_superframe;
} SVC; } SVC;
struct VP9_COMP; struct VP9_COMP;