| 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;
|
| }
|
|
|
|
|