Index: source/libvpx/vp9/encoder/vp9_onyx_if.c |
=================================================================== |
--- source/libvpx/vp9/encoder/vp9_onyx_if.c (revision 240950) |
+++ source/libvpx/vp9/encoder/vp9_onyx_if.c (working copy) |
@@ -24,6 +24,8 @@ |
#include "vp9/common/vp9_reconinter.h" |
#include "vp9/common/vp9_systemdependent.h" |
#include "vp9/common/vp9_tile_common.h" |
+ |
+#include "vp9/encoder/vp9_encodemv.h" |
#include "vp9/encoder/vp9_firstpass.h" |
#include "vp9/encoder/vp9_mbgraph.h" |
#include "vp9/encoder/vp9_onyx_int.h" |
@@ -37,9 +39,9 @@ |
#include "vpx_ports/vpx_timer.h" |
+void vp9_entropy_mode_init(); |
+void vp9_coef_tree_initialize(); |
-extern void print_tree_update_probs(); |
- |
static void set_default_lf_deltas(struct loopfilter *lf); |
#define DEFAULT_INTERP_FILTER SWITCHABLE |
@@ -112,14 +114,8 @@ |
extern void vp9_init_quantizer(VP9_COMP *cpi); |
-// Tables relating active max Q to active min Q |
-static int kf_low_motion_minq[QINDEX_RANGE]; |
-static int kf_high_motion_minq[QINDEX_RANGE]; |
-static int gf_low_motion_minq[QINDEX_RANGE]; |
-static int gf_high_motion_minq[QINDEX_RANGE]; |
-static int inter_minq[QINDEX_RANGE]; |
-static int afq_low_motion_minq[QINDEX_RANGE]; |
-static int afq_high_motion_minq[QINDEX_RANGE]; |
+static const double in_frame_q_adj_ratio[MAX_SEGMENTS] = |
+ {1.0, 1.5, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0}; |
static INLINE void Scale2Ratio(int mode, int *hr, int *hs) { |
switch (mode) { |
@@ -147,98 +143,9 @@ |
} |
} |
-// Functions to compute the active minq lookup table entries based on a |
-// formulaic approach to facilitate easier adjustment of the Q tables. |
-// The formulae were derived from computing a 3rd order polynomial best |
-// fit to the original data (after plotting real maxq vs minq (not q index)) |
-static int calculate_minq_index(double maxq, |
- double x3, double x2, double x1, double c) { |
- int i; |
- const double minqtarget = MIN(((x3 * maxq + x2) * maxq + x1) * maxq + c, |
- maxq); |
- |
- // Special case handling to deal with the step from q2.0 |
- // down to lossless mode represented by q 1.0. |
- if (minqtarget <= 2.0) |
- return 0; |
- |
- for (i = 0; i < QINDEX_RANGE; i++) { |
- if (minqtarget <= vp9_convert_qindex_to_q(i)) |
- return i; |
- } |
- |
- return QINDEX_RANGE - 1; |
-} |
- |
-static void init_minq_luts(void) { |
- int i; |
- |
- for (i = 0; i < QINDEX_RANGE; i++) { |
- const double maxq = vp9_convert_qindex_to_q(i); |
- |
- |
- kf_low_motion_minq[i] = calculate_minq_index(maxq, |
- 0.000001, |
- -0.0004, |
- 0.15, |
- 0.0); |
- kf_high_motion_minq[i] = calculate_minq_index(maxq, |
- 0.000002, |
- -0.0012, |
- 0.5, |
- 0.0); |
- |
- gf_low_motion_minq[i] = calculate_minq_index(maxq, |
- 0.0000015, |
- -0.0009, |
- 0.32, |
- 0.0); |
- gf_high_motion_minq[i] = calculate_minq_index(maxq, |
- 0.0000021, |
- -0.00125, |
- 0.50, |
- 0.0); |
- inter_minq[i] = calculate_minq_index(maxq, |
- 0.00000271, |
- -0.00113, |
- 0.75, |
- 0.0); |
- afq_low_motion_minq[i] = calculate_minq_index(maxq, |
- 0.0000015, |
- -0.0009, |
- 0.33, |
- 0.0); |
- afq_high_motion_minq[i] = calculate_minq_index(maxq, |
- 0.0000021, |
- -0.00125, |
- 0.55, |
- 0.0); |
- } |
-} |
- |
-static int get_active_quality(int q, |
- int gfu_boost, |
- int low, |
- int high, |
- int *low_motion_minq, |
- int *high_motion_minq) { |
- int active_best_quality; |
- if (gfu_boost > high) { |
- active_best_quality = low_motion_minq[q]; |
- } else if (gfu_boost < low) { |
- active_best_quality = high_motion_minq[q]; |
- } else { |
- const int gap = high - low; |
- const int offset = high - gfu_boost; |
- const int qdiff = high_motion_minq[q] - low_motion_minq[q]; |
- const int adjustment = ((offset * qdiff) + (gap >> 1)) / gap; |
- active_best_quality = low_motion_minq[q] + adjustment; |
- } |
- return active_best_quality; |
-} |
- |
-static void set_mvcost(VP9_COMP *cpi) { |
+static void set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv) { |
MACROBLOCK *const mb = &cpi->mb; |
+ cpi->common.allow_high_precision_mv = allow_high_precision_mv; |
if (cpi->common.allow_high_precision_mv) { |
mb->mvcost = mb->nmvcost_hp; |
mb->mvsadcost = mb->nmvsadcost_hp; |
@@ -253,11 +160,14 @@ |
if (!init_done) { |
vp9_initialize_common(); |
+ vp9_coef_tree_initialize(); |
vp9_tokenize_initialize(); |
vp9_init_quant_tables(); |
vp9_init_me_luts(); |
- init_minq_luts(); |
+ vp9_rc_init_minq_luts(); |
// init_base_skip_probs(); |
+ vp9_entropy_mv_init(); |
+ vp9_entropy_mode_init(); |
init_done = 1; |
} |
} |
@@ -294,6 +204,8 @@ |
vpx_free(cpi->coding_context.last_frame_seg_map_copy); |
cpi->coding_context.last_frame_seg_map_copy = 0; |
+ vpx_free(cpi->complexity_map); |
+ cpi->complexity_map = 0; |
vpx_free(cpi->active_map); |
cpi->active_map = 0; |
@@ -323,20 +235,20 @@ |
// Computes a q delta (in "q index" terms) to get from a starting q value |
// to a target value |
// target q value |
-int vp9_compute_qdelta(VP9_COMP *cpi, double qstart, double qtarget) { |
+int vp9_compute_qdelta(const VP9_COMP *cpi, double qstart, double qtarget) { |
int i; |
- int start_index = cpi->worst_quality; |
- int target_index = cpi->worst_quality; |
+ int start_index = cpi->rc.worst_quality; |
+ int target_index = cpi->rc.worst_quality; |
// Convert the average q value to an index. |
- for (i = cpi->best_quality; i < cpi->worst_quality; i++) { |
+ for (i = cpi->rc.best_quality; i < cpi->rc.worst_quality; i++) { |
start_index = i; |
if (vp9_convert_qindex_to_q(i) >= qstart) |
break; |
} |
// Convert the q target to an index |
- for (i = cpi->best_quality; i < cpi->worst_quality; i++) { |
+ for (i = cpi->rc.best_quality; i < cpi->rc.worst_quality; i++) { |
target_index = i; |
if (vp9_convert_qindex_to_q(i) >= qtarget) |
break; |
@@ -345,11 +257,84 @@ |
return target_index - start_index; |
} |
+// Computes a q delta (in "q index" terms) to get from a starting q value |
+// to a value that should equate to thegiven rate ratio. |
+ |
+int vp9_compute_qdelta_by_rate(VP9_COMP *cpi, |
+ double base_q_index, double rate_target_ratio) { |
+ int i; |
+ int base_bits_per_mb; |
+ int target_bits_per_mb; |
+ int target_index = cpi->rc.worst_quality; |
+ |
+ // Make SURE use of floating point in this function is safe. |
+ vp9_clear_system_state(); |
+ |
+ // Look up the current projected bits per block for the base index |
+ base_bits_per_mb = vp9_rc_bits_per_mb(cpi->common.frame_type, |
+ base_q_index, 1.0); |
+ |
+ // Find the target bits per mb based on the base value and given ratio. |
+ target_bits_per_mb = rate_target_ratio * base_bits_per_mb; |
+ |
+ // Convert the q target to an index |
+ for (i = cpi->rc.best_quality; i < cpi->rc.worst_quality; i++) { |
+ target_index = i; |
+ if (vp9_rc_bits_per_mb(cpi->common.frame_type, |
+ i, 1.0) <= target_bits_per_mb ) |
+ break; |
+ } |
+ |
+ return target_index - base_q_index; |
+} |
+ |
+// This function sets up a set of segments with delta Q values around |
+// the baseline frame quantizer. |
+static void setup_in_frame_q_adj(VP9_COMP *cpi) { |
+ VP9_COMMON *cm = &cpi->common; |
+ struct segmentation *seg = &cm->seg; |
+ // double q_ratio; |
+ int segment; |
+ int qindex_delta; |
+ |
+ // Make SURE use of floating point in this function is safe. |
+ vp9_clear_system_state(); |
+ |
+ if (cm->frame_type == KEY_FRAME || |
+ cpi->refresh_alt_ref_frame || |
+ (cpi->refresh_golden_frame && !cpi->is_src_frame_alt_ref)) { |
+ // Clear down the segment map |
+ vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols); |
+ |
+ // Clear down the complexity map used for rd |
+ vpx_memset(cpi->complexity_map, 0, cm->mi_rows * cm->mi_cols); |
+ |
+ // Enable segmentation |
+ vp9_enable_segmentation((VP9_PTR)cpi); |
+ vp9_clearall_segfeatures(seg); |
+ |
+ // Select delta coding method |
+ seg->abs_delta = SEGMENT_DELTADATA; |
+ |
+ // Segment 0 "Q" feature is disabled so it defaults to the baseline Q |
+ vp9_disable_segfeature(seg, 0, SEG_LVL_ALT_Q); |
+ |
+ // Use some of the segments for in frame Q adjustment |
+ for (segment = 1; segment < 3; segment++) { |
+ qindex_delta = |
+ vp9_compute_qdelta_by_rate(cpi, cm->base_qindex, |
+ in_frame_q_adj_ratio[segment]); |
+ vp9_enable_segfeature(seg, segment, SEG_LVL_ALT_Q); |
+ vp9_set_segdata(seg, segment, SEG_LVL_ALT_Q, qindex_delta); |
+ } |
+ } |
+} |
+ |
static void configure_static_seg_features(VP9_COMP *cpi) { |
VP9_COMMON *cm = &cpi->common; |
struct segmentation *seg = &cm->seg; |
- int high_q = (int)(cpi->avg_q > 48.0); |
+ int high_q = (int)(cpi->rc.avg_q > 48.0); |
int qi_delta; |
// Disable and clear down for KF |
@@ -387,7 +372,8 @@ |
seg->update_map = 1; |
seg->update_data = 1; |
- qi_delta = vp9_compute_qdelta(cpi, cpi->avg_q, (cpi->avg_q * 0.875)); |
+ qi_delta = vp9_compute_qdelta( |
+ cpi, cpi->rc.avg_q, (cpi->rc.avg_q * 0.875)); |
vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, (qi_delta - 2)); |
vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2); |
@@ -401,15 +387,15 @@ |
// All other frames if segmentation has been enabled |
// First normal frame in a valid gf or alt ref group |
- if (cpi->frames_since_golden == 0) { |
+ if (cpi->rc.frames_since_golden == 0) { |
// Set up segment features for normal frames in an arf group |
if (cpi->source_alt_ref_active) { |
seg->update_map = 0; |
seg->update_data = 1; |
seg->abs_delta = SEGMENT_DELTADATA; |
- qi_delta = vp9_compute_qdelta(cpi, cpi->avg_q, |
- (cpi->avg_q * 1.125)); |
+ qi_delta = vp9_compute_qdelta(cpi, cpi->rc.avg_q, |
+ (cpi->rc.avg_q * 1.125)); |
vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, (qi_delta + 2)); |
vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q); |
@@ -467,69 +453,6 @@ |
} |
} |
-#ifdef ENTROPY_STATS |
-void vp9_update_mode_context_stats(VP9_COMP *cpi) { |
- VP9_COMMON *cm = &cpi->common; |
- int i, j; |
- unsigned int (*inter_mode_counts)[INTER_MODES - 1][2] = |
- cm->fc.inter_mode_counts; |
- int64_t (*mv_ref_stats)[INTER_MODES - 1][2] = cpi->mv_ref_stats; |
- FILE *f; |
- |
- // Read the past stats counters |
- f = fopen("mode_context.bin", "rb"); |
- if (!f) { |
- vpx_memset(cpi->mv_ref_stats, 0, sizeof(cpi->mv_ref_stats)); |
- } else { |
- fread(cpi->mv_ref_stats, sizeof(cpi->mv_ref_stats), 1, f); |
- fclose(f); |
- } |
- |
- // Add in the values for this frame |
- for (i = 0; i < INTER_MODE_CONTEXTS; i++) { |
- for (j = 0; j < INTER_MODES - 1; j++) { |
- mv_ref_stats[i][j][0] += (int64_t)inter_mode_counts[i][j][0]; |
- mv_ref_stats[i][j][1] += (int64_t)inter_mode_counts[i][j][1]; |
- } |
- } |
- |
- // Write back the accumulated stats |
- f = fopen("mode_context.bin", "wb"); |
- fwrite(cpi->mv_ref_stats, sizeof(cpi->mv_ref_stats), 1, f); |
- fclose(f); |
-} |
- |
-void print_mode_context(VP9_COMP *cpi) { |
- FILE *f = fopen("vp9_modecont.c", "a"); |
- int i, j; |
- |
- fprintf(f, "#include \"vp9_entropy.h\"\n"); |
- fprintf( |
- f, |
- "const int inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1] ="); |
- fprintf(f, "{\n"); |
- for (j = 0; j < INTER_MODE_CONTEXTS; j++) { |
- fprintf(f, " {/* %d */ ", j); |
- fprintf(f, " "); |
- for (i = 0; i < INTER_MODES - 1; i++) { |
- int this_prob; |
- int64_t count = cpi->mv_ref_stats[j][i][0] + cpi->mv_ref_stats[j][i][1]; |
- if (count) |
- this_prob = ((cpi->mv_ref_stats[j][i][0] * 256) + (count >> 1)) / count; |
- else |
- this_prob = 128; |
- |
- // context probs |
- fprintf(f, "%5d, ", this_prob); |
- } |
- fprintf(f, " },\n"); |
- } |
- |
- fprintf(f, "};\n"); |
- fclose(f); |
-} |
-#endif // ENTROPY_STATS |
- |
// DEBUG: Print out the segment id of each MB in the current frame. |
static void print_seg_map(VP9_COMP *cpi) { |
VP9_COMMON *cm = &cpi->common; |
@@ -731,6 +654,7 @@ |
sf->tx_size_search_method = USE_FULL_RD; |
sf->use_lp32x32fdct = 0; |
sf->adaptive_motion_search = 0; |
+ sf->adaptive_pred_filter_type = 0; |
sf->use_avoid_tested_higherror = 0; |
sf->reference_masking = 0; |
sf->use_one_partition_size_always = 0; |
@@ -764,10 +688,9 @@ |
sf->static_segmentation = 0; |
#endif |
- sf->variance_adaptive_quantization = 0; |
- |
switch (mode) { |
case 0: // This is the best quality mode. |
+ cpi->diamond_search_sad = vp9_full_range_search; |
break; |
case 1: |
@@ -795,6 +718,7 @@ |
sf->use_rd_breakout = 1; |
sf->adaptive_motion_search = 1; |
+ sf->adaptive_pred_filter_type = 1; |
sf->auto_mv_step_size = 1; |
sf->adaptive_rd_thresh = 2; |
sf->recode_loop = 2; |
@@ -822,9 +746,10 @@ |
sf->use_rd_breakout = 1; |
sf->adaptive_motion_search = 1; |
+ sf->adaptive_pred_filter_type = 2; |
sf->auto_mv_step_size = 1; |
- sf->disable_filter_search_var_thresh = 16; |
+ sf->disable_filter_search_var_thresh = 50; |
sf->comp_inter_joint_search_thresh = BLOCK_SIZES; |
sf->auto_min_max_partition_size = 1; |
@@ -834,6 +759,7 @@ |
sf->adaptive_rd_thresh = 2; |
sf->recode_loop = 2; |
+ sf->use_lp32x32fdct = 1; |
sf->mode_skip_start = 11; |
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V; |
sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V; |
@@ -856,9 +782,10 @@ |
sf->use_rd_breakout = 1; |
sf->adaptive_motion_search = 1; |
+ sf->adaptive_pred_filter_type = 2; |
sf->auto_mv_step_size = 1; |
- sf->disable_filter_search_var_thresh = 16; |
+ sf->disable_filter_search_var_thresh = 100; |
sf->comp_inter_joint_search_thresh = BLOCK_SIZES; |
sf->auto_min_max_partition_size = 1; |
@@ -889,9 +816,10 @@ |
sf->use_rd_breakout = 1; |
sf->adaptive_motion_search = 1; |
+ sf->adaptive_pred_filter_type = 2; |
sf->auto_mv_step_size = 1; |
- sf->disable_filter_search_var_thresh = 16; |
+ sf->disable_filter_search_var_thresh = 200; |
sf->comp_inter_joint_search_thresh = BLOCK_SIZES; |
sf->auto_min_max_partition_size = 1; |
@@ -937,7 +865,7 @@ |
sf->search_method = HEX; |
sf->subpel_iters_per_step = 1; |
sf->disable_split_var_thresh = 64; |
- sf->disable_filter_search_var_thresh = 96; |
+ sf->disable_filter_search_var_thresh = 500; |
for (i = 0; i < TX_SIZES; i++) { |
sf->intra_y_mode_mask[i] = INTRA_DC_ONLY; |
sf->intra_uv_mode_mask[i] = INTRA_DC_ONLY; |
@@ -998,7 +926,7 @@ |
if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer, |
cpi->oxcf.width, cpi->oxcf.height, |
cm->subsampling_x, cm->subsampling_y, |
- VP9BORDERINPIXELS)) |
+ VP9BORDERINPIXELS, NULL, NULL, NULL)) |
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, |
"Failed to allocate altref buffer"); |
} |
@@ -1032,11 +960,6 @@ |
CHECK_MEM_ERROR(cm, cpi->tok, vpx_calloc(tokens, sizeof(*cpi->tok))); |
} |
- // Data used for real time vc mode to see if gf needs refreshing |
- cpi->inter_zz_count = 0; |
- cpi->gf_bad_count = 0; |
- cpi->gf_update_recommended = 0; |
- |
vpx_free(cpi->mb_activity_map); |
CHECK_MEM_ERROR(cm, cpi->mb_activity_map, |
vpx_calloc(sizeof(unsigned int), |
@@ -1071,14 +994,14 @@ |
if (vp9_realloc_frame_buffer(&cpi->last_frame_uf, |
cm->width, cm->height, |
cm->subsampling_x, cm->subsampling_y, |
- VP9BORDERINPIXELS)) |
+ VP9BORDERINPIXELS, NULL, NULL, NULL)) |
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, |
"Failed to reallocate last frame buffer"); |
if (vp9_realloc_frame_buffer(&cpi->scaled_source, |
cm->width, cm->height, |
cm->subsampling_x, cm->subsampling_y, |
- VP9BORDERINPIXELS)) |
+ VP9BORDERINPIXELS, NULL, NULL, NULL)) |
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, |
"Failed to reallocate scaled source buffer"); |
@@ -1131,33 +1054,34 @@ |
cpi->oxcf.framerate = framerate; |
cpi->output_framerate = cpi->oxcf.framerate; |
- cpi->per_frame_bandwidth = (int)(cpi->oxcf.target_bandwidth |
- / cpi->output_framerate); |
- cpi->av_per_frame_bandwidth = (int)(cpi->oxcf.target_bandwidth |
- / cpi->output_framerate); |
- cpi->min_frame_bandwidth = (int)(cpi->av_per_frame_bandwidth * |
- cpi->oxcf.two_pass_vbrmin_section / 100); |
+ 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 * |
+ cpi->oxcf.two_pass_vbrmin_section / 100); |
- cpi->min_frame_bandwidth = MAX(cpi->min_frame_bandwidth, FRAME_OVERHEAD_BITS); |
+ cpi->rc.min_frame_bandwidth = MAX(cpi->rc.min_frame_bandwidth, |
+ FRAME_OVERHEAD_BITS); |
// Set Maximum gf/arf interval |
- cpi->max_gf_interval = 16; |
+ cpi->rc.max_gf_interval = 16; |
// Extended interval for genuinely static scenes |
cpi->twopass.static_scene_max_gf_interval = cpi->key_frame_frequency >> 1; |
// Special conditions when alt ref frame enabled in lagged compress mode |
if (cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames) { |
- if (cpi->max_gf_interval > cpi->oxcf.lag_in_frames - 1) |
- cpi->max_gf_interval = cpi->oxcf.lag_in_frames - 1; |
+ if (cpi->rc.max_gf_interval > cpi->oxcf.lag_in_frames - 1) |
+ cpi->rc.max_gf_interval = cpi->oxcf.lag_in_frames - 1; |
if (cpi->twopass.static_scene_max_gf_interval > cpi->oxcf.lag_in_frames - 1) |
cpi->twopass.static_scene_max_gf_interval = cpi->oxcf.lag_in_frames - 1; |
} |
- if (cpi->max_gf_interval > cpi->twopass.static_scene_max_gf_interval) |
- cpi->max_gf_interval = cpi->twopass.static_scene_max_gf_interval; |
+ if (cpi->rc.max_gf_interval > cpi->twopass.static_scene_max_gf_interval) |
+ cpi->rc.max_gf_interval = cpi->twopass.static_scene_max_gf_interval; |
} |
static int64_t rescale(int val, int64_t num, int denom) { |
@@ -1185,7 +1109,6 @@ |
int i; |
cpi->oxcf = *oxcf; |
- cpi->goldfreq = 7; |
cm->version = oxcf->version; |
@@ -1199,21 +1122,21 @@ |
vp9_change_config(ptr, oxcf); |
// Initialize active best and worst q and average q values. |
- cpi->active_worst_quality = cpi->oxcf.worst_allowed_q; |
- cpi->active_best_quality = cpi->oxcf.best_allowed_q; |
- cpi->avg_frame_qindex = cpi->oxcf.worst_allowed_q; |
+ cpi->rc.active_worst_quality = cpi->oxcf.worst_allowed_q; |
+ cpi->rc.avg_frame_qindex = cpi->oxcf.worst_allowed_q; |
+ |
// Initialise the starting buffer levels |
- cpi->buffer_level = cpi->oxcf.starting_buffer_level; |
- cpi->bits_off_target = cpi->oxcf.starting_buffer_level; |
+ cpi->rc.buffer_level = cpi->oxcf.starting_buffer_level; |
+ cpi->rc.bits_off_target = cpi->oxcf.starting_buffer_level; |
- cpi->rolling_target_bits = cpi->av_per_frame_bandwidth; |
- cpi->rolling_actual_bits = cpi->av_per_frame_bandwidth; |
- cpi->long_rolling_target_bits = cpi->av_per_frame_bandwidth; |
- cpi->long_rolling_actual_bits = cpi->av_per_frame_bandwidth; |
+ cpi->rc.rolling_target_bits = cpi->rc.av_per_frame_bandwidth; |
+ cpi->rc.rolling_actual_bits = cpi->rc.av_per_frame_bandwidth; |
+ cpi->rc.long_rolling_target_bits = cpi->rc.av_per_frame_bandwidth; |
+ cpi->rc.long_rolling_actual_bits = cpi->rc.av_per_frame_bandwidth; |
- cpi->total_actual_bits = 0; |
- cpi->total_target_vs_actual = 0; |
+ cpi->rc.total_actual_bits = 0; |
+ cpi->rc.total_target_vs_actual = 0; |
cpi->static_mb_pct = 0; |
@@ -1277,7 +1200,7 @@ |
cpi->oxcf.lossless = oxcf->lossless; |
cpi->mb.e_mbd.itxm_add = cpi->oxcf.lossless ? vp9_iwht4x4_add |
: vp9_idct4x4_add; |
- cpi->baseline_gf_interval = DEFAULT_GF_INTERVAL; |
+ cpi->rc.baseline_gf_interval = DEFAULT_GF_INTERVAL; |
cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; |
@@ -1289,8 +1212,7 @@ |
cm->reset_frame_context = 0; |
setup_features(cm); |
- cpi->common.allow_high_precision_mv = 0; // Default mv precision |
- set_mvcost(cpi); |
+ set_high_precision_mv(cpi, 0); |
{ |
int i; |
@@ -1332,20 +1254,14 @@ |
vp9_new_framerate(cpi, cpi->oxcf.framerate); |
// Set absolute upper and lower quality limits |
- cpi->worst_quality = cpi->oxcf.worst_allowed_q; |
- cpi->best_quality = cpi->oxcf.best_allowed_q; |
+ cpi->rc.worst_quality = cpi->oxcf.worst_allowed_q; |
+ cpi->rc.best_quality = cpi->oxcf.best_allowed_q; |
// active values should only be modified if out of new range |
- cpi->active_worst_quality = clamp(cpi->active_worst_quality, |
- cpi->oxcf.best_allowed_q, |
- cpi->oxcf.worst_allowed_q); |
+ cpi->rc.active_worst_quality = clamp(cpi->rc.active_worst_quality, |
+ cpi->rc.best_quality, |
+ cpi->rc.worst_quality); |
- cpi->active_best_quality = clamp(cpi->active_best_quality, |
- cpi->oxcf.best_allowed_q, |
- cpi->oxcf.worst_allowed_q); |
- |
- cpi->buffered_mode = cpi->oxcf.optimal_buffer_level > 0; |
- |
cpi->cq_target_quality = cpi->oxcf.cq_level; |
cm->mcomp_filter_type = DEFAULT_INTERP_FILTER; |
@@ -1370,9 +1286,9 @@ |
update_frame_size(cpi); |
if (cpi->oxcf.fixed_q >= 0) { |
- cpi->last_q[0] = cpi->oxcf.fixed_q; |
- cpi->last_q[1] = cpi->oxcf.fixed_q; |
- cpi->last_boosted_qindex = cpi->oxcf.fixed_q; |
+ cpi->rc.last_q[0] = cpi->oxcf.fixed_q; |
+ cpi->rc.last_q[1] = cpi->oxcf.fixed_q; |
+ cpi->rc.last_boosted_qindex = cpi->oxcf.fixed_q; |
} |
cpi->speed = cpi->oxcf.cpu_used; |
@@ -1442,90 +1358,121 @@ |
} while (++i <= MV_MAX); |
} |
+static void alloc_mode_context(VP9_COMMON *cm, int num_4x4_blk, |
+ PICK_MODE_CONTEXT *ctx) { |
+ int num_pix = num_4x4_blk << 4; |
+ int i, k; |
+ ctx->num_4x4_blk = num_4x4_blk; |
+ CHECK_MEM_ERROR(cm, ctx->zcoeff_blk, |
+ vpx_calloc(num_4x4_blk, sizeof(uint8_t))); |
+ for (i = 0; i < MAX_MB_PLANE; ++i) { |
+ for (k = 0; k < 3; ++k) { |
+ CHECK_MEM_ERROR(cm, ctx->coeff[i][k], |
+ vpx_memalign(16, num_pix * sizeof(int16_t))); |
+ CHECK_MEM_ERROR(cm, ctx->qcoeff[i][k], |
+ vpx_memalign(16, num_pix * sizeof(int16_t))); |
+ CHECK_MEM_ERROR(cm, ctx->dqcoeff[i][k], |
+ vpx_memalign(16, num_pix * sizeof(int16_t))); |
+ CHECK_MEM_ERROR(cm, ctx->eobs[i][k], |
+ vpx_memalign(16, num_pix * sizeof(uint16_t))); |
+ ctx->coeff_pbuf[i][k] = ctx->coeff[i][k]; |
+ ctx->qcoeff_pbuf[i][k] = ctx->qcoeff[i][k]; |
+ ctx->dqcoeff_pbuf[i][k] = ctx->dqcoeff[i][k]; |
+ ctx->eobs_pbuf[i][k] = ctx->eobs[i][k]; |
+ } |
+ } |
+} |
+ |
+static void free_mode_context(PICK_MODE_CONTEXT *ctx) { |
+ int i, k; |
+ vpx_free(ctx->zcoeff_blk); |
+ ctx->zcoeff_blk = 0; |
+ for (i = 0; i < MAX_MB_PLANE; ++i) { |
+ for (k = 0; k < 3; ++k) { |
+ vpx_free(ctx->coeff[i][k]); |
+ ctx->coeff[i][k] = 0; |
+ vpx_free(ctx->qcoeff[i][k]); |
+ ctx->qcoeff[i][k] = 0; |
+ vpx_free(ctx->dqcoeff[i][k]); |
+ ctx->dqcoeff[i][k] = 0; |
+ vpx_free(ctx->eobs[i][k]); |
+ ctx->eobs[i][k] = 0; |
+ } |
+ } |
+} |
+ |
static void init_pick_mode_context(VP9_COMP *cpi) { |
int i; |
- MACROBLOCK *x = &cpi->mb; |
- MACROBLOCKD *xd = &x->e_mbd; |
- VP9_COMMON *cm = &cpi->common; |
+ VP9_COMMON *const cm = &cpi->common; |
+ MACROBLOCK *const x = &cpi->mb; |
+ |
for (i = 0; i < BLOCK_SIZES; ++i) { |
const int num_4x4_w = num_4x4_blocks_wide_lookup[i]; |
const int num_4x4_h = num_4x4_blocks_high_lookup[i]; |
const int num_4x4_blk = MAX(4, num_4x4_w * num_4x4_h); |
if (i < BLOCK_16X16) { |
- for (xd->sb_index = 0; xd->sb_index < 4; ++xd->sb_index) { |
- for (xd->mb_index = 0; xd->mb_index < 4; ++xd->mb_index) { |
- for (xd->b_index = 0; xd->b_index < 16 / num_4x4_blk; ++xd->b_index) { |
+ for (x->sb_index = 0; x->sb_index < 4; ++x->sb_index) { |
+ for (x->mb_index = 0; x->mb_index < 4; ++x->mb_index) { |
+ for (x->b_index = 0; x->b_index < 16 / num_4x4_blk; ++x->b_index) { |
PICK_MODE_CONTEXT *ctx = get_block_context(x, i); |
- ctx->num_4x4_blk = num_4x4_blk; |
- CHECK_MEM_ERROR(cm, ctx->zcoeff_blk, |
- vpx_calloc(num_4x4_blk, sizeof(uint8_t))); |
+ alloc_mode_context(cm, num_4x4_blk, ctx); |
} |
} |
} |
} else if (i < BLOCK_32X32) { |
- for (xd->sb_index = 0; xd->sb_index < 4; ++xd->sb_index) { |
- for (xd->mb_index = 0; xd->mb_index < 64 / num_4x4_blk; |
- ++xd->mb_index) { |
+ for (x->sb_index = 0; x->sb_index < 4; ++x->sb_index) { |
+ for (x->mb_index = 0; x->mb_index < 64 / num_4x4_blk; ++x->mb_index) { |
PICK_MODE_CONTEXT *ctx = get_block_context(x, i); |
ctx->num_4x4_blk = num_4x4_blk; |
- CHECK_MEM_ERROR(cm, ctx->zcoeff_blk, |
- vpx_calloc(num_4x4_blk, sizeof(uint8_t))); |
+ alloc_mode_context(cm, num_4x4_blk, ctx); |
} |
} |
} else if (i < BLOCK_64X64) { |
- for (xd->sb_index = 0; xd->sb_index < 256 / num_4x4_blk; ++xd->sb_index) { |
+ for (x->sb_index = 0; x->sb_index < 256 / num_4x4_blk; ++x->sb_index) { |
PICK_MODE_CONTEXT *ctx = get_block_context(x, i); |
ctx->num_4x4_blk = num_4x4_blk; |
- CHECK_MEM_ERROR(cm, ctx->zcoeff_blk, |
- vpx_calloc(num_4x4_blk, sizeof(uint8_t))); |
+ alloc_mode_context(cm, num_4x4_blk, ctx); |
} |
} else { |
PICK_MODE_CONTEXT *ctx = get_block_context(x, i); |
ctx->num_4x4_blk = num_4x4_blk; |
- CHECK_MEM_ERROR(cm, ctx->zcoeff_blk, |
- vpx_calloc(num_4x4_blk, sizeof(uint8_t))); |
+ alloc_mode_context(cm, num_4x4_blk, ctx); |
} |
} |
} |
static void free_pick_mode_context(MACROBLOCK *x) { |
int i; |
- MACROBLOCKD *xd = &x->e_mbd; |
for (i = 0; i < BLOCK_SIZES; ++i) { |
const int num_4x4_w = num_4x4_blocks_wide_lookup[i]; |
const int num_4x4_h = num_4x4_blocks_high_lookup[i]; |
const int num_4x4_blk = MAX(4, num_4x4_w * num_4x4_h); |
if (i < BLOCK_16X16) { |
- for (xd->sb_index = 0; xd->sb_index < 4; ++xd->sb_index) { |
- for (xd->mb_index = 0; xd->mb_index < 4; ++xd->mb_index) { |
- for (xd->b_index = 0; xd->b_index < 16 / num_4x4_blk; ++xd->b_index) { |
+ for (x->sb_index = 0; x->sb_index < 4; ++x->sb_index) { |
+ for (x->mb_index = 0; x->mb_index < 4; ++x->mb_index) { |
+ for (x->b_index = 0; x->b_index < 16 / num_4x4_blk; ++x->b_index) { |
PICK_MODE_CONTEXT *ctx = get_block_context(x, i); |
- vpx_free(ctx->zcoeff_blk); |
- ctx->zcoeff_blk = 0; |
+ free_mode_context(ctx); |
} |
} |
} |
} else if (i < BLOCK_32X32) { |
- for (xd->sb_index = 0; xd->sb_index < 4; ++xd->sb_index) { |
- for (xd->mb_index = 0; xd->mb_index < 64 / num_4x4_blk; |
- ++xd->mb_index) { |
+ for (x->sb_index = 0; x->sb_index < 4; ++x->sb_index) { |
+ for (x->mb_index = 0; x->mb_index < 64 / num_4x4_blk; ++x->mb_index) { |
PICK_MODE_CONTEXT *ctx = get_block_context(x, i); |
- vpx_free(ctx->zcoeff_blk); |
- ctx->zcoeff_blk = 0; |
+ free_mode_context(ctx); |
} |
} |
} else if (i < BLOCK_64X64) { |
- for (xd->sb_index = 0; xd->sb_index < 256 / num_4x4_blk; ++xd->sb_index) { |
+ for (x->sb_index = 0; x->sb_index < 256 / num_4x4_blk; ++x->sb_index) { |
PICK_MODE_CONTEXT *ctx = get_block_context(x, i); |
- vpx_free(ctx->zcoeff_blk); |
- ctx->zcoeff_blk = 0; |
+ free_mode_context(ctx); |
} |
} else { |
PICK_MODE_CONTEXT *ctx = get_block_context(x, i); |
- vpx_free(ctx->zcoeff_blk); |
- ctx->zcoeff_blk = 0; |
+ free_mode_context(ctx); |
} |
} |
} |
@@ -1569,16 +1516,12 @@ |
init_pick_mode_context(cpi); |
cm->current_video_frame = 0; |
- cpi->kf_overspend_bits = 0; |
- cpi->kf_bitrate_adjustment = 0; |
- cpi->frames_till_gf_update_due = 0; |
- cpi->gf_overspend_bits = 0; |
- cpi->non_gf_bitrate_adjustment = 0; |
+ cpi->rc.frames_till_gf_update_due = 0; |
// Set reference frame sign bias for ALTREF frame to 1 (for now) |
cm->ref_frame_sign_bias[ALTREF_FRAME] = 1; |
- cpi->baseline_gf_interval = DEFAULT_GF_INTERVAL; |
+ cpi->rc.baseline_gf_interval = DEFAULT_GF_INTERVAL; |
cpi->gold_is_last = 0; |
cpi->alt_is_last = 0; |
@@ -1591,6 +1534,11 @@ |
CHECK_MEM_ERROR(cm, cpi->segmentation_map, |
vpx_calloc(cm->mi_rows * cm->mi_cols, 1)); |
+ // Create a complexity map used for rd adjustment |
+ CHECK_MEM_ERROR(cm, cpi->complexity_map, |
+ vpx_calloc(cm->mi_rows * cm->mi_cols, 1)); |
+ |
+ |
// And a place holder structure is the coding context |
// for use if we want to save and restore it |
CHECK_MEM_ERROR(cm, cpi->coding_context.last_frame_seg_map_copy, |
@@ -1678,20 +1626,18 @@ |
cpi->first_time_stamp_ever = INT64_MAX; |
- cpi->frames_till_gf_update_due = 0; |
- cpi->key_frame_count = 1; |
+ cpi->rc.frames_till_gf_update_due = 0; |
+ cpi->rc.key_frame_count = 1; |
- cpi->ni_av_qi = cpi->oxcf.worst_allowed_q; |
- cpi->ni_tot_qi = 0; |
- cpi->ni_frames = 0; |
- cpi->tot_q = 0.0; |
- cpi->avg_q = vp9_convert_qindex_to_q(cpi->oxcf.worst_allowed_q); |
- cpi->total_byte_count = 0; |
+ cpi->rc.ni_av_qi = cpi->oxcf.worst_allowed_q; |
+ cpi->rc.ni_tot_qi = 0; |
+ cpi->rc.ni_frames = 0; |
+ cpi->rc.tot_q = 0.0; |
+ cpi->rc.avg_q = vp9_convert_qindex_to_q(cpi->oxcf.worst_allowed_q); |
- cpi->rate_correction_factor = 1.0; |
- cpi->key_frame_rate_correction_factor = 1.0; |
- cpi->gf_rate_correction_factor = 1.0; |
- cpi->twopass.est_max_qcorrection_factor = 1.0; |
+ cpi->rc.rate_correction_factor = 1.0; |
+ cpi->rc.key_frame_rate_correction_factor = 1.0; |
+ cpi->rc.gf_rate_correction_factor = 1.0; |
cal_nmvjointsadcost(cpi->mb.nmvjointsadcost); |
cpi->mb.nmvcost[0] = &cpi->mb.nmvcosts[0][MV_MAX]; |
@@ -1707,7 +1653,7 @@ |
cal_nmvsadcosts_hp(cpi->mb.nmvsadcost_hp); |
for (i = 0; i < KEY_FRAME_CONTEXT; i++) |
- cpi->prior_key_frame_distance[i] = (int)cpi->output_framerate; |
+ cpi->rc.prior_key_frame_distance[i] = (int)cpi->output_framerate; |
#ifdef OUTPUT_YUV_SRC |
yuv_file = fopen("bd.yuv", "ab"); |
@@ -1878,14 +1824,6 @@ |
vp9_end_second_pass(cpi); |
} |
-#ifdef ENTROPY_STATS |
- if (cpi->pass != 1) { |
- print_context_counters(); |
- print_tree_update_probs(); |
- print_mode_context(cpi); |
- } |
-#endif |
- |
#ifdef MODE_STATS |
if (cpi->pass != 1) { |
write_tx_count_stats(); |
@@ -2218,7 +2156,7 @@ |
VP9_COMP *cpi = (VP9_COMP *)(ptr); |
VP9_COMMON *cm = &cpi->common; |
- if (index < 0 || index >= NUM_REF_FRAMES) |
+ if (index < 0 || index >= REF_FRAMES) |
return -1; |
*fb = &cm->yv12_fb[cm->ref_frame_map[index]]; |
@@ -2365,7 +2303,7 @@ |
static void update_alt_ref_frame_stats(VP9_COMP *cpi) { |
// this frame refreshes means next frames don't unless specified by user |
- cpi->frames_since_golden = 0; |
+ cpi->rc.frames_since_golden = 0; |
#if CONFIG_MULTIPLE_ARF |
if (!cpi->multi_arf_enabled) |
@@ -2381,7 +2319,7 @@ |
if (cpi->refresh_golden_frame) { |
// this frame refreshes means next frames don't unless specified by user |
cpi->refresh_golden_frame = 0; |
- cpi->frames_since_golden = 0; |
+ cpi->rc.frames_since_golden = 0; |
// ******** Fixed Q test code only ************ |
// If we are going to use the ALT reference for the next group of frames |
@@ -2389,12 +2327,12 @@ |
if (cpi->oxcf.fixed_q >= 0 && |
cpi->oxcf.play_alternate && !cpi->refresh_alt_ref_frame) { |
cpi->source_alt_ref_pending = 1; |
- cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; |
+ cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval; |
// TODO(ivan): For SVC encoder, GF automatic update is disabled by using |
// a large GF_interval. |
if (cpi->use_svc) { |
- cpi->frames_till_gf_update_due = INT_MAX; |
+ cpi->rc.frames_till_gf_update_due = INT_MAX; |
} |
} |
@@ -2402,18 +2340,18 @@ |
cpi->source_alt_ref_active = 0; |
// Decrement count down till next gf |
- if (cpi->frames_till_gf_update_due > 0) |
- cpi->frames_till_gf_update_due--; |
+ if (cpi->rc.frames_till_gf_update_due > 0) |
+ cpi->rc.frames_till_gf_update_due--; |
} else if (!cpi->refresh_alt_ref_frame) { |
// Decrement count down till next gf |
- if (cpi->frames_till_gf_update_due > 0) |
- cpi->frames_till_gf_update_due--; |
+ if (cpi->rc.frames_till_gf_update_due > 0) |
+ cpi->rc.frames_till_gf_update_due--; |
if (cpi->frames_till_alt_ref_frame) |
cpi->frames_till_alt_ref_frame--; |
- cpi->frames_since_golden++; |
+ cpi->rc.frames_since_golden++; |
} |
} |
@@ -2432,16 +2370,6 @@ |
return i; |
} |
-static void Pass1Encode(VP9_COMP *cpi, unsigned long *size, unsigned char *dest, |
- unsigned int *frame_flags) { |
- (void) size; |
- (void) dest; |
- (void) frame_flags; |
- |
- vp9_set_quantizer(cpi, find_fp_qindex()); |
- vp9_first_pass(cpi); |
-} |
- |
#define WRITE_RECON_BUFFER 0 |
#if WRITE_RECON_BUFFER |
void write_cx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame) { |
@@ -2523,25 +2451,19 @@ |
cpi->refresh_golden_frame || |
cpi->refresh_alt_ref_frame))) { |
// General over and under shoot tests |
- if (((cpi->projected_frame_size > high_limit) && (q < maxq)) || |
- ((cpi->projected_frame_size < low_limit) && (q > minq))) { |
+ if (((cpi->rc.projected_frame_size > high_limit) && (q < maxq)) || |
+ ((cpi->rc.projected_frame_size < low_limit) && (q > minq))) { |
force_recode = 1; |
} else if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { |
// Deal with frame undershoot and whether or not we are |
// below the automatically set cq level. |
if (q > cpi->cq_target_quality && |
- cpi->projected_frame_size < ((cpi->this_frame_target * 7) >> 3)) { |
+ cpi->rc.projected_frame_size < |
+ ((cpi->rc.this_frame_target * 7) >> 3)) { |
force_recode = 1; |
- } else if (q > cpi->oxcf.cq_level && |
- cpi->projected_frame_size < cpi->min_frame_bandwidth && |
- cpi->active_best_quality > cpi->oxcf.cq_level) { |
- // Severe undershoot and between auto and user cq level |
- force_recode = 1; |
- cpi->active_best_quality = cpi->oxcf.cq_level; |
} |
} |
} |
- |
return force_recode; |
} |
@@ -2634,8 +2556,8 @@ |
static void scale_references(VP9_COMP *cpi) { |
VP9_COMMON *cm = &cpi->common; |
int i; |
- int refs[ALLOWED_REFS_PER_FRAME] = {cpi->lst_fb_idx, cpi->gld_fb_idx, |
- cpi->alt_fb_idx}; |
+ int refs[REFS_PER_FRAME] = {cpi->lst_fb_idx, cpi->gld_fb_idx, |
+ cpi->alt_fb_idx}; |
for (i = 0; i < 3; i++) { |
YV12_BUFFER_CONFIG *ref = &cm->yv12_fb[cm->ref_frame_map[refs[i]]]; |
@@ -2647,7 +2569,7 @@ |
vp9_realloc_frame_buffer(&cm->yv12_fb[new_fb], |
cm->width, cm->height, |
cm->subsampling_x, cm->subsampling_y, |
- VP9BORDERINPIXELS); |
+ VP9BORDERINPIXELS, NULL, NULL, NULL); |
scale_and_extend_frame(ref, &cm->yv12_fb[new_fb]); |
cpi->scaled_ref_idx[i] = new_fb; |
} else { |
@@ -2671,22 +2593,20 @@ |
model_count[ZERO_TOKEN] = full_count[ZERO_TOKEN]; |
model_count[ONE_TOKEN] = full_count[ONE_TOKEN]; |
model_count[TWO_TOKEN] = full_count[TWO_TOKEN]; |
- for (n = THREE_TOKEN; n < DCT_EOB_TOKEN; ++n) |
+ for (n = THREE_TOKEN; n < EOB_TOKEN; ++n) |
model_count[TWO_TOKEN] += full_count[n]; |
- model_count[DCT_EOB_MODEL_TOKEN] = full_count[DCT_EOB_TOKEN]; |
+ model_count[EOB_MODEL_TOKEN] = full_count[EOB_TOKEN]; |
} |
-static void full_to_model_counts( |
- vp9_coeff_count_model *model_count, vp9_coeff_count *full_count) { |
+static void full_to_model_counts(vp9_coeff_count_model *model_count, |
+ vp9_coeff_count *full_count) { |
int i, j, k, l; |
- for (i = 0; i < BLOCK_TYPES; ++i) |
+ |
+ for (i = 0; i < PLANE_TYPES; ++i) |
for (j = 0; j < REF_TYPES; ++j) |
for (k = 0; k < COEF_BANDS; ++k) |
- for (l = 0; l < PREV_COEF_CONTEXTS; ++l) { |
- if (l >= 3 && k == 0) |
- continue; |
+ for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) |
full_to_model_count(model_count[i][j][k][l], full_count[i][j][k][l]); |
- } |
} |
#if 0 && CONFIG_INTERNAL_STATS |
@@ -2701,28 +2621,28 @@ |
if (cpi->twopass.total_left_stats.coded_error != 0.0) |
fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d %10d" |
- "%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f" |
- "%6d %6d %5d %5d %5d %8.2f %10d %10.3f" |
+ "%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f" |
+ "%6d %6d %5d %5d %5d %10d %10.3f" |
"%10.3f %8d %10d %10d %10d\n", |
- cpi->common.current_video_frame, cpi->this_frame_target, |
- cpi->projected_frame_size, 0, |
- (cpi->projected_frame_size - cpi->this_frame_target), |
- (int)cpi->total_target_vs_actual, |
- (int)(cpi->oxcf.starting_buffer_level - cpi->bits_off_target), |
- (int)cpi->total_actual_bits, cm->base_qindex, |
+ cpi->common.current_video_frame, cpi->rc.this_frame_target, |
+ cpi->rc.projected_frame_size, 0, |
+ (cpi->rc.projected_frame_size - cpi->rc.this_frame_target), |
+ (int)cpi->rc.total_target_vs_actual, |
+ (int)(cpi->oxcf.starting_buffer_level - cpi->rc.bits_off_target), |
+ (int)cpi->rc.total_actual_bits, cm->base_qindex, |
vp9_convert_qindex_to_q(cm->base_qindex), |
(double)vp9_dc_quant(cm->base_qindex, 0) / 4.0, |
- vp9_convert_qindex_to_q(cpi->active_best_quality), |
- vp9_convert_qindex_to_q(cpi->active_worst_quality), cpi->avg_q, |
- vp9_convert_qindex_to_q(cpi->ni_av_qi), |
+ vp9_convert_qindex_to_q(cpi->rc.active_worst_quality), cpi->rc.avg_q, |
+ vp9_convert_qindex_to_q(cpi->rc.ni_av_qi), |
vp9_convert_qindex_to_q(cpi->cq_target_quality), |
cpi->refresh_last_frame, cpi->refresh_golden_frame, |
- cpi->refresh_alt_ref_frame, cm->frame_type, cpi->gfu_boost, |
- cpi->twopass.est_max_qcorrection_factor, (int)cpi->twopass.bits_left, |
+ cpi->refresh_alt_ref_frame, cm->frame_type, cpi->rc.gfu_boost, |
+ (int)cpi->twopass.bits_left, |
cpi->twopass.total_left_stats.coded_error, |
(double)cpi->twopass.bits_left / |
(1 + cpi->twopass.total_left_stats.coded_error), |
- cpi->tot_recode_hits, recon_err, cpi->kf_boost, cpi->kf_zeromotion_pct); |
+ cpi->tot_recode_hits, recon_err, cpi->rc.kf_boost, |
+ cpi->kf_zeromotion_pct); |
fclose(f); |
@@ -2746,222 +2666,216 @@ |
} |
#endif |
-static int pick_q_and_adjust_q_bounds(VP9_COMP *cpi, |
- int * bottom_index, int * top_index) { |
- // Set an active best quality and if necessary active worst quality |
- int q = cpi->active_worst_quality; |
+static void encode_with_recode_loop(VP9_COMP *cpi, |
+ size_t *size, |
+ uint8_t *dest, |
+ int *q, |
+ int bottom_index, |
+ int top_index, |
+ int frame_over_shoot_limit, |
+ int frame_under_shoot_limit) { |
VP9_COMMON *const cm = &cpi->common; |
+ int loop_count = 0; |
+ int loop = 0; |
+ int overshoot_seen = 0; |
+ int undershoot_seen = 0; |
+ int q_low = bottom_index, q_high = top_index; |
- if (frame_is_intra_only(cm)) { |
-#if !CONFIG_MULTIPLE_ARF |
- // Handle the special case for key frames forced when we have75 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 (cpi->this_key_frame_forced) { |
- int delta_qindex; |
- int qindex = cpi->last_boosted_qindex; |
- double last_boosted_q = vp9_convert_qindex_to_q(qindex); |
+ do { |
+ vp9_clear_system_state(); // __asm emms; |
- delta_qindex = vp9_compute_qdelta(cpi, last_boosted_q, |
- (last_boosted_q * 0.75)); |
+ vp9_set_quantizer(cpi, *q); |
- cpi->active_best_quality = MAX(qindex + delta_qindex, |
- cpi->best_quality); |
- } else { |
- int high = 5000; |
- int low = 400; |
- double q_adj_factor = 1.0; |
- double q_val; |
+ if (loop_count == 0) { |
+ // Set up entropy context depending on frame type. The decoder mandates |
+ // the use of the default context, index 0, for keyframes and inter |
+ // frames where the error_resilient_mode or intra_only flag is set. For |
+ // other inter-frames the encoder currently uses only two contexts; |
+ // context 1 for ALTREF frames and context 0 for the others. |
+ if (cm->frame_type == KEY_FRAME) { |
+ vp9_setup_key_frame(cpi); |
+ } else { |
+ if (!cm->intra_only && !cm->error_resilient_mode) { |
+ cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame; |
+ } |
+ vp9_setup_inter_frame(cpi); |
+ } |
+ } |
- // Baseline value derived from cpi->active_worst_quality and kf boost |
- cpi->active_best_quality = get_active_quality(q, cpi->kf_boost, |
- low, high, |
- kf_low_motion_minq, |
- kf_high_motion_minq); |
+ // Variance adaptive and in frame q adjustment experiments are mutually |
+ // exclusive. |
+ if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
+ vp9_vaq_frame_setup(cpi); |
+ } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) { |
+ setup_in_frame_q_adj(cpi); |
+ } |
- // Allow somewhat lower kf minq with small image formats. |
- if ((cm->width * cm->height) <= (352 * 288)) { |
- q_adj_factor -= 0.25; |
- } |
+ // transform / motion compensation build reconstruction frame |
- // Make a further adjustment based on the kf zero motion measure. |
- q_adj_factor += 0.05 - (0.001 * (double)cpi->kf_zeromotion_pct); |
+ vp9_encode_frame(cpi); |
- // Convert the adjustment factor to a qindex delta |
- // on active_best_quality. |
- q_val = vp9_convert_qindex_to_q(cpi->active_best_quality); |
- cpi->active_best_quality += |
- vp9_compute_qdelta(cpi, q_val, (q_val * q_adj_factor)); |
- } |
-#else |
- double current_q; |
- // Force the KF quantizer to be 30% of the active_worst_quality. |
- current_q = vp9_convert_qindex_to_q(cpi->active_worst_quality); |
- cpi->active_best_quality = cpi->active_worst_quality |
- + vp9_compute_qdelta(cpi, current_q, current_q * 0.3); |
-#endif |
- } else if (!cpi->is_src_frame_alt_ref && |
- (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { |
- int high = 2000; |
- int low = 400; |
+ // Update the skip mb flag probabilities based on the distribution |
+ // seen in the last encoder iteration. |
+ // update_base_skip_probs(cpi); |
- // Use the lower of cpi->active_worst_quality and recent |
- // average Q as basis for GF/ARF best Q limit unless last frame was |
- // a key frame. |
- if (cpi->frames_since_key > 1 && |
- cpi->avg_frame_qindex < cpi->active_worst_quality) { |
- q = cpi->avg_frame_qindex; |
- } |
- // For constrained quality dont allow Q less than the cq level |
- if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { |
- if (q < cpi->cq_target_quality) |
- q = cpi->cq_target_quality; |
- if (cpi->frames_since_key > 1) { |
- cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost, |
- low, high, |
- afq_low_motion_minq, |
- afq_high_motion_minq); |
- } else { |
- cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost, |
- low, high, |
- gf_low_motion_minq, |
- gf_high_motion_minq); |
- } |
- // Constrained quality use slightly lower active best. |
- cpi->active_best_quality = cpi->active_best_quality * 15 / 16; |
+ vp9_clear_system_state(); // __asm emms; |
- } else if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { |
- if (!cpi->refresh_alt_ref_frame) { |
- cpi->active_best_quality = cpi->cq_target_quality; |
- } else { |
- if (cpi->frames_since_key > 1) { |
- cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost, |
- low, high, |
- afq_low_motion_minq, |
- afq_high_motion_minq); |
- } else { |
- cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost, |
- low, high, |
- gf_low_motion_minq, |
- gf_high_motion_minq); |
- } |
- } |
- } else { |
- cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost, |
- low, high, |
- gf_low_motion_minq, |
- gf_high_motion_minq); |
- } |
- } else { |
+ // Dummy pack of the bitstream using up to date stats to get an |
+ // accurate estimate of output frame size to determine if we need |
+ // to recode. |
+ vp9_save_coding_context(cpi); |
+ cpi->dummy_packing = 1; |
+ vp9_pack_bitstream(cpi, dest, size); |
+ cpi->rc.projected_frame_size = (*size) << 3; |
+ vp9_restore_coding_context(cpi); |
+ |
+ if (frame_over_shoot_limit == 0) |
+ frame_over_shoot_limit = 1; |
+ |
if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { |
- cpi->active_best_quality = cpi->cq_target_quality; |
+ loop = 0; |
} else { |
-#ifdef ONE_SHOT_Q_ESTIMATE |
-#ifdef STRICT_ONE_SHOT_Q |
- cpi->active_best_quality = q; |
-#else |
- cpi->active_best_quality = inter_minq[q]; |
-#endif |
-#else |
- cpi->active_best_quality = inter_minq[q]; |
- // 1-pass: for now, use the average Q for the active_best, if its lower |
- // than active_worst. |
- if (cpi->pass == 0 && (cpi->avg_frame_qindex < q)) |
- cpi->active_best_quality = inter_minq[cpi->avg_frame_qindex]; |
-#endif |
+ // Special case handling for forced key frames |
+ if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) { |
+ int last_q = *q; |
+ int kf_err = vp9_calc_ss_err(cpi->Source, get_frame_new_buffer(cm)); |
- // For the constrained quality mode we don't want |
- // q to fall below the cq level. |
- if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && |
- (cpi->active_best_quality < cpi->cq_target_quality)) { |
- // If we are strongly undershooting the target rate in the last |
- // frames then use the user passed in cq value not the auto |
- // cq value. |
- if (cpi->rolling_actual_bits < cpi->min_frame_bandwidth) |
- cpi->active_best_quality = cpi->oxcf.cq_level; |
- else |
- cpi->active_best_quality = cpi->cq_target_quality; |
- } |
- } |
- } |
+ int high_err_target = cpi->ambient_err; |
+ int low_err_target = cpi->ambient_err >> 1; |
- // Clip the active best and worst quality values to limits |
- if (cpi->active_worst_quality > cpi->worst_quality) |
- cpi->active_worst_quality = cpi->worst_quality; |
+ // Prevent possible divide by zero error below for perfect KF |
+ kf_err += !kf_err; |
- if (cpi->active_best_quality < cpi->best_quality) |
- cpi->active_best_quality = cpi->best_quality; |
+ // The key frame is not good enough or we can afford |
+ // to make it better without undue risk of popping. |
+ if ((kf_err > high_err_target && |
+ cpi->rc.projected_frame_size <= frame_over_shoot_limit) || |
+ (kf_err > low_err_target && |
+ cpi->rc.projected_frame_size <= frame_under_shoot_limit)) { |
+ // Lower q_high |
+ q_high = *q > q_low ? *q - 1 : q_low; |
- if (cpi->active_best_quality > cpi->worst_quality) |
- cpi->active_best_quality = cpi->worst_quality; |
+ // Adjust Q |
+ *q = ((*q) * high_err_target) / kf_err; |
+ *q = MIN((*q), (q_high + q_low) >> 1); |
+ } else if (kf_err < low_err_target && |
+ cpi->rc.projected_frame_size >= frame_under_shoot_limit) { |
+ // The key frame is much better than the previous frame |
+ // Raise q_low |
+ q_low = *q < q_high ? *q + 1 : q_high; |
- if (cpi->active_worst_quality < cpi->active_best_quality) |
- cpi->active_worst_quality = cpi->active_best_quality; |
+ // Adjust Q |
+ *q = ((*q) * low_err_target) / kf_err; |
+ *q = MIN((*q), (q_high + q_low + 1) >> 1); |
+ } |
- // Limit Q range for the adaptive loop. |
- if (cm->frame_type == KEY_FRAME && !cpi->this_key_frame_forced) { |
- *top_index = |
- (cpi->active_worst_quality + cpi->active_best_quality * 3) / 4; |
- // If this is the first (key) frame in 1-pass, active best is the user |
- // best-allowed, and leave the top_index to active_worst. |
- if (cpi->pass == 0 && cpi->common.current_video_frame == 0) { |
- cpi->active_best_quality = cpi->oxcf.best_allowed_q; |
- *top_index = cpi->oxcf.worst_allowed_q; |
- } |
- } else if (!cpi->is_src_frame_alt_ref && |
- (cpi->oxcf.end_usage != USAGE_STREAM_FROM_SERVER) && |
- (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { |
- *top_index = |
- (cpi->active_worst_quality + cpi->active_best_quality) / 2; |
- } else { |
- *top_index = cpi->active_worst_quality; |
- } |
- *bottom_index = cpi->active_best_quality; |
+ // Clamp Q to upper and lower limits: |
+ *q = clamp(*q, q_low, q_high); |
- if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { |
- q = cpi->active_best_quality; |
- // Special case code to try and match quality with forced key frames |
- } else if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) { |
- q = cpi->last_boosted_qindex; |
- } else { |
- // Determine initial Q to try. |
- if (cpi->pass == 0) { |
- // 1-pass: for now, use per-frame-bw for target size of frame, scaled |
- // by |x| for key frame. |
- int scale = (cm->frame_type == KEY_FRAME) ? 5 : 1; |
- q = vp9_regulate_q(cpi, scale * cpi->av_per_frame_bandwidth); |
- } else { |
- q = vp9_regulate_q(cpi, cpi->this_frame_target); |
+ loop = *q != last_q; |
+ } else if (recode_loop_test( |
+ cpi, frame_over_shoot_limit, frame_under_shoot_limit, |
+ *q, top_index, bottom_index)) { |
+ // Is the projected frame size out of range and are we allowed |
+ // to attempt to recode. |
+ int last_q = *q; |
+ int retries = 0; |
+ |
+ // Frame size out of permitted range: |
+ // Update correction factor & compute new Q to try... |
+ |
+ // Frame is too large |
+ if (cpi->rc.projected_frame_size > cpi->rc.this_frame_target) { |
+ // Raise Qlow as to at least the current value |
+ q_low = *q < q_high ? *q + 1 : q_high; |
+ |
+ if (undershoot_seen || loop_count > 1) { |
+ // Update rate_correction_factor unless |
+ vp9_rc_update_rate_correction_factors(cpi, 1); |
+ |
+ *q = (q_high + q_low + 1) / 2; |
+ } else { |
+ // Update rate_correction_factor unless |
+ vp9_rc_update_rate_correction_factors(cpi, 0); |
+ |
+ *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target, |
+ bottom_index, top_index); |
+ |
+ while (*q < q_low && retries < 10) { |
+ vp9_rc_update_rate_correction_factors(cpi, 0); |
+ *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target, |
+ bottom_index, top_index); |
+ retries++; |
+ } |
+ } |
+ |
+ overshoot_seen = 1; |
+ } else { |
+ // Frame is too small |
+ q_high = *q > q_low ? *q - 1 : q_low; |
+ |
+ if (overshoot_seen || loop_count > 1) { |
+ vp9_rc_update_rate_correction_factors(cpi, 1); |
+ *q = (q_high + q_low) / 2; |
+ } else { |
+ vp9_rc_update_rate_correction_factors(cpi, 0); |
+ *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target, |
+ bottom_index, top_index); |
+ // Special case reset for qlow for constrained quality. |
+ // This should only trigger where there is very substantial |
+ // undershoot on a frame and the auto cq level is above |
+ // the user passsed in value. |
+ if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY && |
+ *q < q_low) { |
+ q_low = *q; |
+ } |
+ |
+ while (*q > q_high && retries < 10) { |
+ vp9_rc_update_rate_correction_factors(cpi, 0); |
+ *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target, |
+ bottom_index, top_index); |
+ retries++; |
+ } |
+ } |
+ |
+ undershoot_seen = 1; |
+ } |
+ |
+ // Clamp Q to upper and lower limits: |
+ *q = clamp(*q, q_low, q_high); |
+ |
+ loop = *q != last_q; |
+ } else { |
+ loop = 0; |
+ } |
} |
- if (q > *top_index) |
- q = *top_index; |
- } |
- return q; |
+ if (cpi->is_src_frame_alt_ref) |
+ loop = 0; |
+ |
+ if (loop) { |
+ loop_count++; |
+ |
+#if CONFIG_INTERNAL_STATS |
+ cpi->tot_recode_hits++; |
+#endif |
+ } |
+ } while (loop); |
} |
+ |
static void encode_frame_to_data_rate(VP9_COMP *cpi, |
- unsigned long *size, |
- unsigned char *dest, |
+ size_t *size, |
+ uint8_t *dest, |
unsigned int *frame_flags) { |
VP9_COMMON *const cm = &cpi->common; |
TX_SIZE t; |
int q; |
int frame_over_shoot_limit; |
int frame_under_shoot_limit; |
- |
- int loop = 0; |
- int loop_count; |
- |
- int q_low; |
- int q_high; |
- |
int top_index; |
+ int top_index_prop; |
int bottom_index; |
- int active_worst_qchanged = 0; |
- int overshoot_seen = 0; |
- int undershoot_seen = 0; |
- |
SPEED_FEATURES *const sf = &cpi->sf; |
unsigned int max_mv_def = MIN(cpi->common.width, cpi->common.height); |
struct segmentation *const seg = &cm->seg; |
@@ -2983,7 +2897,7 @@ |
// pass function that sets the target bandwidth so we must set it here. |
if (cpi->refresh_alt_ref_frame) { |
// Set a per frame bit target for the alt ref frame. |
- cpi->per_frame_bandwidth = cpi->twopass.gf_bits; |
+ cpi->rc.per_frame_bandwidth = cpi->twopass.gf_bits; |
// Set a per second target bitrate. |
cpi->target_bandwidth = (int)(cpi->twopass.gf_bits * cpi->output_framerate); |
} |
@@ -3071,56 +2985,13 @@ |
configure_static_seg_features(cpi); |
} |
- // Decide how big to make the frame. |
- vp9_pick_frame_size(cpi); |
- |
vp9_clear_system_state(); |
- q = pick_q_and_adjust_q_bounds(cpi, &bottom_index, &top_index); |
- |
- q_high = top_index; |
- q_low = bottom_index; |
- |
- vp9_compute_frame_size_bounds(cpi, &frame_under_shoot_limit, |
- &frame_over_shoot_limit); |
- |
-#if CONFIG_MULTIPLE_ARF |
- // Force the quantizer determined by the coding order pattern. |
- if (cpi->multi_arf_enabled && (cm->frame_type != KEY_FRAME) && |
- cpi->oxcf.end_usage != USAGE_CONSTANT_QUALITY) { |
- double new_q; |
- double current_q = vp9_convert_qindex_to_q(cpi->active_worst_quality); |
- int level = cpi->this_frame_weight; |
- assert(level >= 0); |
- |
- // Set quantizer steps at 10% increments. |
- new_q = current_q * (1.0 - (0.2 * (cpi->max_arf_level - level))); |
- q = cpi->active_worst_quality + vp9_compute_qdelta(cpi, current_q, new_q); |
- |
- bottom_index = q; |
- top_index = q; |
- q_low = q; |
- q_high = q; |
- |
- printf("frame:%d q:%d\n", cm->current_video_frame, q); |
- } |
-#endif |
- |
- loop_count = 0; |
vp9_zero(cpi->rd_tx_select_threshes); |
- if (!frame_is_intra_only(cm)) { |
- cm->mcomp_filter_type = DEFAULT_INTERP_FILTER; |
- /* TODO: Decide this more intelligently */ |
- cm->allow_high_precision_mv = q < HIGH_PRECISION_MV_QTHRESH; |
- set_mvcost(cpi); |
- } |
- |
#if CONFIG_VP9_POSTPROC |
- |
if (cpi->oxcf.noise_sensitivity > 0) { |
int l = 0; |
- |
switch (cpi->oxcf.noise_sensitivity) { |
case 1: |
l = 20; |
@@ -3139,202 +3010,43 @@ |
l = 150; |
break; |
} |
- |
vp9_denoise(cpi->Source, cpi->Source, l); |
} |
- |
#endif |
#ifdef OUTPUT_YUV_SRC |
vp9_write_yuv_frame(cpi->Source); |
#endif |
- do { |
- vp9_clear_system_state(); // __asm emms; |
+ // Decide how big to make the frame. |
+ vp9_rc_pick_frame_size_target(cpi); |
- vp9_set_quantizer(cpi, q); |
+ // Decide frame size bounds |
+ vp9_rc_compute_frame_size_bounds(cpi, cpi->rc.this_frame_target, |
+ &frame_under_shoot_limit, |
+ &frame_over_shoot_limit); |
- if (loop_count == 0) { |
- // Set up entropy context depending on frame type. The decoder mandates |
- // the use of the default context, index 0, for keyframes and inter |
- // frames where the error_resilient_mode or intra_only flag is set. For |
- // other inter-frames the encoder currently uses only two contexts; |
- // context 1 for ALTREF frames and context 0 for the others. |
- if (cm->frame_type == KEY_FRAME) { |
- vp9_setup_key_frame(cpi); |
- } else { |
- if (!cm->intra_only && !cm->error_resilient_mode) { |
- cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame; |
- } |
- vp9_setup_inter_frame(cpi); |
- } |
- } |
+ // Decide q and q bounds |
+ q = vp9_rc_pick_q_and_adjust_q_bounds(cpi, |
+ &bottom_index, |
+ &top_index, |
+ &top_index_prop); |
- if (cpi->sf.variance_adaptive_quantization) { |
- vp9_vaq_frame_setup(cpi); |
- } |
+ if (!frame_is_intra_only(cm)) { |
+ cm->mcomp_filter_type = DEFAULT_INTERP_FILTER; |
+ /* TODO: Decide this more intelligently */ |
+ set_high_precision_mv(cpi, (q < HIGH_PRECISION_MV_QTHRESH)); |
+ } |
- // transform / motion compensation build reconstruction frame |
+ encode_with_recode_loop(cpi, |
+ size, |
+ dest, |
+ &q, |
+ bottom_index, |
+ top_index, |
+ frame_over_shoot_limit, |
+ frame_under_shoot_limit); |
- vp9_encode_frame(cpi); |
- |
- // Update the skip mb flag probabilities based on the distribution |
- // seen in the last encoder iteration. |
- // update_base_skip_probs(cpi); |
- |
- vp9_clear_system_state(); // __asm emms; |
- |
- // Dummy pack of the bitstream using up to date stats to get an |
- // accurate estimate of output frame size to determine if we need |
- // to recode. |
- vp9_save_coding_context(cpi); |
- cpi->dummy_packing = 1; |
- vp9_pack_bitstream(cpi, dest, size); |
- cpi->projected_frame_size = (*size) << 3; |
- vp9_restore_coding_context(cpi); |
- |
- if (frame_over_shoot_limit == 0) |
- frame_over_shoot_limit = 1; |
- active_worst_qchanged = 0; |
- |
- if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { |
- loop = 0; |
- } else { |
- // Special case handling for forced key frames |
- if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) { |
- int last_q = q; |
- int kf_err = vp9_calc_ss_err(cpi->Source, get_frame_new_buffer(cm)); |
- |
- int high_err_target = cpi->ambient_err; |
- int low_err_target = cpi->ambient_err >> 1; |
- |
- // Prevent possible divide by zero error below for perfect KF |
- kf_err += !kf_err; |
- |
- // The key frame is not good enough or we can afford |
- // to make it better without undue risk of popping. |
- if ((kf_err > high_err_target && |
- cpi->projected_frame_size <= frame_over_shoot_limit) || |
- (kf_err > low_err_target && |
- cpi->projected_frame_size <= frame_under_shoot_limit)) { |
- // Lower q_high |
- q_high = q > q_low ? q - 1 : q_low; |
- |
- // Adjust Q |
- q = (q * high_err_target) / kf_err; |
- q = MIN(q, (q_high + q_low) >> 1); |
- } else if (kf_err < low_err_target && |
- cpi->projected_frame_size >= frame_under_shoot_limit) { |
- // The key frame is much better than the previous frame |
- // Raise q_low |
- q_low = q < q_high ? q + 1 : q_high; |
- |
- // Adjust Q |
- q = (q * low_err_target) / kf_err; |
- q = MIN(q, (q_high + q_low + 1) >> 1); |
- } |
- |
- // Clamp Q to upper and lower limits: |
- q = clamp(q, q_low, q_high); |
- |
- loop = q != last_q; |
- } else if (recode_loop_test( |
- cpi, frame_over_shoot_limit, frame_under_shoot_limit, |
- q, top_index, bottom_index)) { |
- // Is the projected frame size out of range and are we allowed |
- // to attempt to recode. |
- int last_q = q; |
- int retries = 0; |
- |
- // Frame size out of permitted range: |
- // Update correction factor & compute new Q to try... |
- |
- // Frame is too large |
- if (cpi->projected_frame_size > cpi->this_frame_target) { |
- // Raise Qlow as to at least the current value |
- q_low = q < q_high ? q + 1 : q_high; |
- |
- if (undershoot_seen || loop_count > 1) { |
- // Update rate_correction_factor unless |
- // cpi->active_worst_quality has changed. |
- if (!active_worst_qchanged) |
- vp9_update_rate_correction_factors(cpi, 1); |
- |
- q = (q_high + q_low + 1) / 2; |
- } else { |
- // Update rate_correction_factor unless |
- // cpi->active_worst_quality has changed. |
- if (!active_worst_qchanged) |
- vp9_update_rate_correction_factors(cpi, 0); |
- |
- q = vp9_regulate_q(cpi, cpi->this_frame_target); |
- |
- while (q < q_low && retries < 10) { |
- vp9_update_rate_correction_factors(cpi, 0); |
- q = vp9_regulate_q(cpi, cpi->this_frame_target); |
- retries++; |
- } |
- } |
- |
- overshoot_seen = 1; |
- } else { |
- // Frame is too small |
- q_high = q > q_low ? q - 1 : q_low; |
- |
- if (overshoot_seen || loop_count > 1) { |
- // Update rate_correction_factor unless |
- // cpi->active_worst_quality has changed. |
- if (!active_worst_qchanged) |
- vp9_update_rate_correction_factors(cpi, 1); |
- |
- q = (q_high + q_low) / 2; |
- } else { |
- // Update rate_correction_factor unless |
- // cpi->active_worst_quality has changed. |
- if (!active_worst_qchanged) |
- vp9_update_rate_correction_factors(cpi, 0); |
- |
- q = vp9_regulate_q(cpi, cpi->this_frame_target); |
- |
- // Special case reset for qlow for constrained quality. |
- // This should only trigger where there is very substantial |
- // undershoot on a frame and the auto cq level is above |
- // the user passsed in value. |
- if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY && q < q_low) { |
- q_low = q; |
- } |
- |
- while (q > q_high && retries < 10) { |
- vp9_update_rate_correction_factors(cpi, 0); |
- q = vp9_regulate_q(cpi, cpi->this_frame_target); |
- retries++; |
- } |
- } |
- |
- undershoot_seen = 1; |
- } |
- |
- // Clamp Q to upper and lower limits: |
- q = clamp(q, q_low, q_high); |
- |
- loop = q != last_q; |
- } else { |
- loop = 0; |
- } |
- } |
- |
- if (cpi->is_src_frame_alt_ref) |
- loop = 0; |
- |
- if (loop) { |
- loop_count++; |
- |
-#if CONFIG_INTERNAL_STATS |
- cpi->tot_recode_hits++; |
-#endif |
- } |
- } while (loop); |
- |
// Special case code to reduce pulsing when key frames are forced at a |
// fixed interval. Note the reconstruction error if it is the frame before |
// the force key frame |
@@ -3391,7 +3103,6 @@ |
vp9_copy(counts->y_mode, cpi->y_mode_count); |
vp9_copy(counts->uv_mode, cpi->y_uv_mode_count); |
- vp9_copy(counts->partition, cpi->partition_count); |
vp9_copy(counts->intra_inter, cpi->intra_inter_count); |
vp9_copy(counts->comp_inter, cpi->comp_inter_count); |
vp9_copy(counts->single_ref, cpi->single_ref_count); |
@@ -3412,103 +3123,8 @@ |
* needed in motion search besides loopfilter */ |
cm->last_frame_type = cm->frame_type; |
- // Update rate control heuristics |
- cpi->total_byte_count += (*size); |
- cpi->projected_frame_size = (*size) << 3; |
+ vp9_rc_postencode_update(cpi, *size, top_index_prop); |
- // Post encode loop adjustment of Q prediction. |
- if (!active_worst_qchanged) |
- vp9_update_rate_correction_factors(cpi, (cpi->sf.recode_loop) ? 2 : 0); |
- |
- cpi->last_q[cm->frame_type] = cm->base_qindex; |
- |
- // Keep record of last boosted (KF/KF/ARF) Q value. |
- // If the current frame is coded at a lower Q then we also update it. |
- // If all mbs in this group are skipped only update if the Q value is |
- // better than that already stored. |
- // This is used to help set quality in forced key frames to reduce popping |
- if ((cm->base_qindex < cpi->last_boosted_qindex) || |
- ((cpi->static_mb_pct < 100) && |
- ((cm->frame_type == KEY_FRAME) || |
- cpi->refresh_alt_ref_frame || |
- (cpi->refresh_golden_frame && !cpi->is_src_frame_alt_ref)))) { |
- cpi->last_boosted_qindex = cm->base_qindex; |
- } |
- |
- if (cm->frame_type == KEY_FRAME) { |
- vp9_adjust_key_frame_context(cpi); |
- } |
- |
- // Keep a record of ambient average Q. |
- if (cm->frame_type != KEY_FRAME) |
- cpi->avg_frame_qindex = (2 + 3 * cpi->avg_frame_qindex + |
- cm->base_qindex) >> 2; |
- |
- // Keep a record from which we can calculate the average Q excluding GF |
- // updates and key frames. |
- if (cm->frame_type != KEY_FRAME && |
- !cpi->refresh_golden_frame && |
- !cpi->refresh_alt_ref_frame) { |
- cpi->ni_frames++; |
- cpi->tot_q += vp9_convert_qindex_to_q(q); |
- cpi->avg_q = cpi->tot_q / (double)cpi->ni_frames; |
- |
- // Calculate the average Q for normal inter frames (not key or GFU frames). |
- cpi->ni_tot_qi += q; |
- cpi->ni_av_qi = cpi->ni_tot_qi / cpi->ni_frames; |
- } |
- |
- // Update the buffer level variable. |
- // Non-viewable frames are a special case and are treated as pure overhead. |
- if (!cm->show_frame) |
- cpi->bits_off_target -= cpi->projected_frame_size; |
- else |
- cpi->bits_off_target += cpi->av_per_frame_bandwidth - |
- cpi->projected_frame_size; |
- |
- // Clip the buffer level at the maximum buffer size |
- if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size) |
- cpi->bits_off_target = cpi->oxcf.maximum_buffer_size; |
- |
- // Rolling monitors of whether we are over or underspending used to help |
- // regulate min and Max Q in two pass. |
- if (cm->frame_type != KEY_FRAME) { |
- cpi->rolling_target_bits = |
- ((cpi->rolling_target_bits * 3) + cpi->this_frame_target + 2) / 4; |
- cpi->rolling_actual_bits = |
- ((cpi->rolling_actual_bits * 3) + cpi->projected_frame_size + 2) / 4; |
- cpi->long_rolling_target_bits = |
- ((cpi->long_rolling_target_bits * 31) + cpi->this_frame_target + 16) / 32; |
- cpi->long_rolling_actual_bits = |
- ((cpi->long_rolling_actual_bits * 31) + |
- cpi->projected_frame_size + 16) / 32; |
- } |
- |
- // Actual bits spent |
- cpi->total_actual_bits += cpi->projected_frame_size; |
- |
- // Debug stats |
- cpi->total_target_vs_actual += (cpi->this_frame_target - |
- cpi->projected_frame_size); |
- |
- cpi->buffer_level = cpi->bits_off_target; |
- |
-#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->this_frame_target - |
- cpi->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->this_frame_target - |
- cpi->projected_frame_size; |
- |
- cpi->twopass.gf_group_bits = MAX(cpi->twopass.gf_group_bits, 0); |
- } |
-#endif |
- |
#if 0 |
output_frame_level_debug_stats(cpi); |
#endif |
@@ -3628,8 +3244,23 @@ |
cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mode_info_stride + 1; |
} |
-static void Pass2Encode(VP9_COMP *cpi, unsigned long *size, |
- unsigned char *dest, unsigned int *frame_flags) { |
+static void Pass0Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, |
+ unsigned int *frame_flags) { |
+ encode_frame_to_data_rate(cpi, size, dest, frame_flags); |
+} |
+ |
+static void Pass1Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, |
+ unsigned int *frame_flags) { |
+ (void) size; |
+ (void) dest; |
+ (void) frame_flags; |
+ |
+ vp9_set_quantizer(cpi, find_fp_qindex()); |
+ vp9_first_pass(cpi); |
+} |
+ |
+static void Pass2Encode(VP9_COMP *cpi, size_t *size, |
+ uint8_t *dest, unsigned int *frame_flags) { |
cpi->enable_encode_breakout = 1; |
if (!cpi->refresh_alt_ref_frame) |
@@ -3637,34 +3268,17 @@ |
encode_frame_to_data_rate(cpi, size, dest, frame_flags); |
// vp9_print_modes_and_motion_vectors(&cpi->common, "encode.stt"); |
-#ifdef DISABLE_RC_LONG_TERM_MEM |
- cpi->twopass.bits_left -= cpi->this_frame_target; |
-#else |
- cpi->twopass.bits_left -= 8 * *size; |
-#endif |
- if (!cpi->refresh_alt_ref_frame) { |
- double lower_bounds_min_rate = FRAME_OVERHEAD_BITS * cpi->oxcf.framerate; |
- double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth |
- * cpi->oxcf.two_pass_vbrmin_section |
- / 100); |
- |
- if (two_pass_min_rate < lower_bounds_min_rate) |
- two_pass_min_rate = lower_bounds_min_rate; |
- |
- cpi->twopass.bits_left += (int64_t)(two_pass_min_rate |
- / cpi->oxcf.framerate); |
- } |
+ vp9_twopass_postencode_update(cpi, *size); |
} |
static void check_initial_width(VP9_COMP *cpi, YV12_BUFFER_CONFIG *sd) { |
- VP9_COMMON *cm = &cpi->common; |
+ VP9_COMMON *const cm = &cpi->common; |
if (!cpi->initial_width) { |
- // TODO(jkoleszar): Support 1/4 subsampling? |
- cm->subsampling_x = (sd != NULL) && sd->uv_width < sd->y_width; |
- cm->subsampling_y = (sd != NULL) && sd->uv_height < sd->y_height; |
+ // TODO(agrange) Subsampling defaults to assuming sampled chroma. |
+ cm->subsampling_x = sd != NULL ? (sd->uv_width < sd->y_width) : 1; |
+ cm->subsampling_y = sd != NULL ? (sd->uv_height < sd->y_height) : 1; |
alloc_raw_frame_buffers(cpi); |
- |
cpi->initial_width = cm->width; |
cpi->initial_height = cm->height; |
} |
@@ -3711,7 +3325,7 @@ |
#endif |
int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, |
- unsigned long *size, unsigned char *dest, |
+ size_t *size, uint8_t *dest, |
int64_t *time_stamp, int64_t *time_end, int flush) { |
VP9_COMP *cpi = (VP9_COMP *) ptr; |
VP9_COMMON *cm = &cpi->common; |
@@ -3727,8 +3341,7 @@ |
cpi->source = NULL; |
- cpi->common.allow_high_precision_mv = ALTREF_HIGH_PRECISION_MV; |
- set_mvcost(cpi); |
+ set_high_precision_mv(cpi, ALTREF_HIGH_PRECISION_MV); |
// Should we code an alternate reference frame. |
if (cpi->oxcf.play_alternate && cpi->source_alt_ref_pending) { |
@@ -3743,7 +3356,7 @@ |
- cpi->next_frame_in_order; |
else |
#endif |
- frames_to_arf = cpi->frames_till_gf_update_due; |
+ frames_to_arf = cpi->rc.frames_till_gf_update_due; |
assert(frames_to_arf < cpi->twopass.frames_to_key); |
@@ -3758,7 +3371,7 @@ |
// Produce the filtered ARF frame. |
// TODO(agrange) merge these two functions. |
configure_arnr_filter(cpi, cm->current_video_frame + frames_to_arf, |
- cpi->gfu_boost); |
+ cpi->rc.gfu_boost); |
vp9_temporal_filter_prepare(cpi, frames_to_arf); |
vp9_extend_frame_borders(&cpi->alt_ref_buffer, |
cm->subsampling_x, cm->subsampling_y); |
@@ -3947,15 +3560,19 @@ |
vp9_realloc_frame_buffer(get_frame_new_buffer(cm), |
cm->width, cm->height, |
cm->subsampling_x, cm->subsampling_y, |
- VP9BORDERINPIXELS); |
+ VP9BORDERINPIXELS, NULL, NULL, NULL); |
// Calculate scaling factors for each of the 3 available references |
- for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) |
+ for (i = 0; i < REFS_PER_FRAME; ++i) { |
vp9_setup_scale_factors(cm, i); |
+ if (vp9_is_scaled(&cm->active_ref_scale_comm[i])) |
+ vp9_extend_frame_borders(&cm->yv12_fb[cm->active_ref_idx[i]], |
+ cm->subsampling_x, cm->subsampling_y); |
+ } |
vp9_setup_interp_filters(&cpi->mb.e_mbd, DEFAULT_INTERP_FILTER, cm); |
- if (cpi->sf.variance_adaptive_quantization) { |
+ if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
vp9_vaq_init(); |
} |
@@ -3964,7 +3581,8 @@ |
} else if (cpi->pass == 2) { |
Pass2Encode(cpi, size, dest, frame_flags); |
} else { |
- encode_frame_to_data_rate(cpi, size, dest, frame_flags); |
+ // One pass encode |
+ Pass0Encode(cpi, size, dest, frame_flags); |
} |
if (cm->refresh_frame_context) |
@@ -4256,37 +3874,9 @@ |
return 0; |
} |
-int vp9_switch_layer(VP9_PTR comp, int layer) { |
- VP9_COMP *cpi = (VP9_COMP *)comp; |
- |
- if (cpi->use_svc) { |
- cpi->current_layer = layer; |
- |
- // Use buffer i for layer i LST |
- cpi->lst_fb_idx = layer; |
- |
- // Use buffer i-1 for layer i Alt (Inter-layer prediction) |
- if (layer != 0) cpi->alt_fb_idx = layer - 1; |
- |
- // Use the rest for Golden |
- if (layer < 2 * cpi->number_spatial_layers - NUM_REF_FRAMES) |
- cpi->gld_fb_idx = cpi->lst_fb_idx; |
- else |
- cpi->gld_fb_idx = 2 * cpi->number_spatial_layers - 1 - layer; |
- |
- printf("Switching to layer %d:\n", layer); |
- printf("Using references: LST/GLD/ALT [%d|%d|%d]\n", cpi->lst_fb_idx, |
- cpi->gld_fb_idx, cpi->alt_fb_idx); |
- } else { |
- printf("Switching layer not supported. Enable SVC first \n"); |
- } |
- return 0; |
-} |
- |
void vp9_set_svc(VP9_PTR comp, int use_svc) { |
VP9_COMP *cpi = (VP9_COMP *)comp; |
cpi->use_svc = use_svc; |
- if (cpi->use_svc) printf("Enabled SVC encoder \n"); |
return; |
} |