diff --git a/vp10/decoder/decodeframe.c b/vp10/decoder/decodeframe.c index e93619f9a..7fed6d53c 100644 --- a/vp10/decoder/decodeframe.c +++ b/vp10/decoder/decodeframe.c @@ -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; } -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) { - int i; - cm->base_qindex = vpx_rb_read_literal(rb, QINDEX_BITS); cm->y_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->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 xd->bd = (int)cm->bit_depth; @@ -2216,11 +2205,25 @@ static size_t read_uncompressed_header(VP10Decoder *pbi, vp10_setup_past_independence(cm); setup_loopfilter(&cm->lf, rb); - setup_quantization(cm, &pbi->mb, rb); + setup_quantization(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); - cm->tx_mode = (!cm->seg.enabled && xd->lossless[0]) ? ONLY_4X4 - : read_tx_mode(rb); + cm->tx_mode = (xd->lossless[0]) ? ONLY_4X4 + : read_tx_mode(rb); cm->reference_mode = read_frame_reference_mode(cm, rb); setup_tile_info(cm, rb); diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c index 1288e5028..434cc99f7 100644 --- a/vp10/encoder/bitstream.c +++ b/vp10/encoder/bitstream.c @@ -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); } + static void update_txfm_probs(VP10_COMMON *cm, vpx_writer *w, FRAME_COUNTS *counts) { 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_quantization(cm, wb); encode_segmentation(cm, xd, wb); - if (!cm->seg.enabled && xd->lossless[0]) + if (xd->lossless[0]) cm->tx_mode = TX_4X4; else write_txfm_mode(cm->tx_mode, wb); diff --git a/vp10/encoder/encoder.c b/vp10/encoder/encoder.c index c5dabceb4..b42e3d6b0 100644 --- a/vp10/encoder/encoder.c +++ b/vp10/encoder/encoder.c @@ -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; #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_last_frame = 1; diff --git a/vp10/encoder/ratectrl.c b/vp10/encoder/ratectrl.c index 3ff24768d..606877594 100644 --- a/vp10/encoder/ratectrl.c +++ b/vp10/encoder/ratectrl.c @@ -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); if (frame_is_intra_only(cm)) { - - // 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. - if (rc->this_key_frame_forced) { + if (oxcf->rc_mode == VPX_Q) { + int qindex = cq_level; + double q = vp10_convert_qindex_to_q(qindex, cm->bit_depth); + int delta_qindex = vp10_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) { int qindex = rc->last_boosted_qindex; double last_boosted_q = vp10_convert_qindex_to_q(qindex, cm->bit_depth); int delta_qindex = vp10_compute_qdelta(rc, last_boosted_q, - last_boosted_q * 0.75, - cm->bit_depth); + last_boosted_q * 0.75, + cm->bit_depth); active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); } else { // 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. q_val = vp10_convert_qindex_to_q(active_best_quality, cm->bit_depth); active_best_quality += vp10_compute_qdelta(rc, q_val, - q_val * q_adj_factor, - cm->bit_depth); + q_val * q_adj_factor, + cm->bit_depth); } } else if (!rc->is_src_frame_alt_ref && (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; } else if (oxcf->rc_mode == VPX_Q) { - if (!cpi->refresh_alt_ref_frame) { - active_best_quality = cq_level; - } else { - active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); - } + int qindex = cq_level; + double q = vp10_convert_qindex_to_q(qindex, cm->bit_depth); + int delta_qindex; + 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 { active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); } } else { 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 { // Use the lower of active_worst_quality and recent/average Q. 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] = ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[KEY_FRAME] + qindex, 2); } else { - if (rc->is_src_frame_alt_ref || + if (!rc->is_src_frame_alt_ref && !(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { rc->last_q[INTER_FRAME] = qindex; 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) { const VP10EncoderConfig *const oxcf = &cpi->oxcf; - // Set Maximum gf/arf interval - rc->max_gf_interval = oxcf->max_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); + // Special case code for 1 pass fixed Q mode tests + if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) { + rc->max_gf_interval = FIXED_GF_INTERVAL; + rc->min_gf_interval = FIXED_GF_INTERVAL; + rc->static_scene_max_gf_interval = FIXED_GF_INTERVAL; + } else { + // Set Maximum gf/arf interval + rc->max_gf_interval = oxcf->max_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 - rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2; + // Extended interval for genuinely static scenes + rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2; - if (is_altref_enabled(cpi)) { - if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1) - rc->static_scene_max_gf_interval = oxcf->lag_in_frames - 1; + if (is_altref_enabled(cpi)) { + if (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) { diff --git a/vp10/encoder/ratectrl.h b/vp10/encoder/ratectrl.h index 8008c1610..0b9fd456d 100644 --- a/vp10/encoder/ratectrl.h +++ b/vp10/encoder/ratectrl.h @@ -26,6 +26,7 @@ extern "C" { #define MIN_GF_INTERVAL 4 #define MAX_GF_INTERVAL 16 +#define FIXED_GF_INTERVAL 8 // Used in some testing modes only typedef enum { INTER_NORMAL = 0, diff --git a/vp10/encoder/rdopt.c b/vp10/encoder/rdopt.c index 18e677953..c65021b4b 100644 --- a/vp10/encoder/rdopt.c +++ b/vp10/encoder/rdopt.c @@ -1050,7 +1050,7 @@ static void super_block_yrd(VP10_COMP *cpi, MACROBLOCK *x, int *rate, 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, ref_best_rd, bs); } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) { diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 5b7761577..437b24e1a 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -496,7 +496,7 @@ static void set_vbp_thresholds(VP9_COMP *cpi, int64_t thresholds[], int q) { threshold_base = 3 * threshold_base; else if (noise_level == kMedium) threshold_base = threshold_base << 1; - else if (noise_level == kLowLow) + else if (noise_level < kLow) threshold_base = (7 * threshold_base) >> 3; } if (cm->width <= 352 && cm->height <= 288) { diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 72fa82835..e4681f601 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -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; #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_last_frame = 1; @@ -2793,6 +2797,22 @@ void vp9_update_reference_frames(VP9_COMP *cpi) { cpi->resize_pending); } #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) { diff --git a/vp9/encoder/vp9_noise_estimate.c b/vp9/encoder/vp9_noise_estimate.c index 6e717e53c..4befbb066 100644 --- a/vp9/encoder/vp9_noise_estimate.c +++ b/vp9/encoder/vp9_noise_estimate.c @@ -25,7 +25,7 @@ void vp9_noise_estimate_init(NOISE_ESTIMATE *const ne, int width, int height) { ne->enabled = 0; - ne->level = kUnknown; + ne->level = kLowLow; ne->value = 0; ne->count = 0; 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) { - int noise_level = kUnknown; + int noise_level = kLowLow; if (ne->value > (ne->thresh << 1)) { noise_level = kHigh; } else { diff --git a/vp9/encoder/vp9_noise_estimate.h b/vp9/encoder/vp9_noise_estimate.h index 266326286..826d125b5 100644 --- a/vp9/encoder/vp9_noise_estimate.h +++ b/vp9/encoder/vp9_noise_estimate.h @@ -24,7 +24,6 @@ extern "C" { #endif typedef enum noise_level { - kUnknown, kLowLow, kLow, kMedium, diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index 0d86518a5..b929758ca 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -1094,6 +1094,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) { VP9_COMMON *const cm = &cpi->common; SPEED_FEATURES *const sf = &cpi->sf; + const SVC *const svc = &cpi->svc; TileInfo *const tile_info = &tile_data->tile_info; MACROBLOCKD *const xd = &x->e_mbd; 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_early_term = 0; int ref_frame_cost[MAX_REF_FRAMES]; + int svc_force_zero_mode[3] = {0}; #if CONFIG_VP9_TEMPORAL_DENOISING int64_t zero_last_cost_orig = INT64_MAX; #endif @@ -1196,6 +1198,17 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, } else { 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) { 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; 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; + 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])) continue; if (const_motion[ref_frame] && this_mode == NEARMV) diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 8ab51cd20..2579c6005 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -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); if (frame_is_intra_only(cm)) { - // 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. - if (rc->this_key_frame_forced) { + if (oxcf->rc_mode == VPX_Q) { + int qindex = cq_level; + double q = vp9_convert_qindex_to_q(qindex, cm->bit_depth); + 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; double last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth); 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; } else if (oxcf->rc_mode == VPX_Q) { - if (!cpi->refresh_alt_ref_frame) { - active_best_quality = cq_level; - } else { - active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); - } + int qindex = cq_level; + double q = vp9_convert_qindex_to_q(qindex, cm->bit_depth); + int delta_qindex; + 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 { active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); } } else { 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 { // Use the lower of active_worst_quality and recent/average Q. if (cm->current_video_frame > 1) @@ -1313,9 +1330,9 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) { } } } else { - if (rc->is_src_frame_alt_ref || - !(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) || - (cpi->use_svc && oxcf->rc_mode == VPX_CBR)) { + if ((cpi->use_svc && oxcf->rc_mode == VPX_CBR) || + (!rc->is_src_frame_alt_ref && + !(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame))) { rc->last_q[INTER_FRAME] = qindex; rc->avg_frame_qindex[INTER_FRAME] = 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) { const VP9EncoderConfig *const oxcf = &cpi->oxcf; - // Set Maximum gf/arf interval - rc->max_gf_interval = oxcf->max_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); + // Special case code for 1 pass fixed Q mode tests + if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) { + rc->max_gf_interval = FIXED_GF_INTERVAL; + rc->min_gf_interval = FIXED_GF_INTERVAL; + rc->static_scene_max_gf_interval = FIXED_GF_INTERVAL; + } else { + // Set Maximum gf/arf interval + rc->max_gf_interval = oxcf->max_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 - rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2; + // Extended interval for genuinely static scenes + rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2; - if (is_altref_enabled(cpi)) { - if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1) - rc->static_scene_max_gf_interval = oxcf->lag_in_frames - 1; + if (is_altref_enabled(cpi)) { + if (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) { diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h index 136fd3e78..3df909cb1 100644 --- a/vp9/encoder/vp9_ratectrl.h +++ b/vp9/encoder/vp9_ratectrl.h @@ -26,6 +26,7 @@ extern "C" { #define MIN_GF_INTERVAL 4 #define MAX_GF_INTERVAL 16 +#define FIXED_GF_INTERVAL 8 // Used in some testing modes only #define ONEHALFONLY_RESIZE 0 typedef enum { diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c index b0617c1ca..a4e7eb19e 100644 --- a/vp9/encoder/vp9_svc_layercontext.c +++ b/vp9/encoder/vp9_svc_layercontext.c @@ -25,13 +25,17 @@ void vp9_init_layer_context(VP9_COMP *const cpi) { const VP9EncoderConfig *const oxcf = &cpi->oxcf; int mi_rows = cpi->common.mi_rows; int mi_cols = cpi->common.mi_cols; - int sl, tl; + int sl, tl, i; int alt_ref_idx = svc->number_spatial_layers; svc->spatial_layer_id = 0; svc->temporal_layer_id = 0; svc->first_spatial_layer_to_encode = 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 (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]; ++lc->current_video_frame_in_layer; ++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) { @@ -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 width = 0, height = 0; LAYER_CONTEXT *lc = NULL; + cpi->svc.force_zero_mode_spatial_ref = 1; if (cpi->svc.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0212) { set_flags_and_fb_idx_for_temporal_mode3(cpi); diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h index 5dbf9b418..1f446d743 100644 --- a/vp9/encoder/vp9_svc_layercontext.h +++ b/vp9/encoder/vp9_svc_layercontext.h @@ -83,6 +83,9 @@ typedef struct { int ext_lst_fb_idx[VPX_MAX_LAYERS]; int ext_gld_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; struct VP9_COMP;