Newer
Older
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
#include "vp9/common/vp9_filter.h"
#include "vp9/common/vp9_reconinter.h"
#include "vp9/encoder/vp9_onyx_int.h"
#include "vp9/common/vp9_systemdependent.h"
#include "vp9/encoder/vp9_quantize.h"
#include "vp9/encoder/vp9_mcomp.h"
#include "vp9/encoder/vp9_firstpass.h"
#include "vp9/encoder/vp9_psnr.h"
#include "vp9/encoder/vp9_ratectrl.h"
#include "vp9/common/vp9_quant_common.h"
#include "vp9/common/vp9_tile_common.h"
#include "vp9/encoder/vp9_segmentation.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/vpx_timer.h"
#include "vp9/common/vp9_pred_common.h"
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_bitstream.h"
#include "vp9/encoder/vp9_picklpf.h"
#include "vp9/common/vp9_mvref_common.h"
#include "vp9/encoder/vp9_temporal_filter.h"
#include <math.h>
#include <stdio.h>
#include <limits.h>
extern void print_tree_update_probs();
static void set_default_lf_deltas(VP9_COMP *cpi);
#define SEARCH_BEST_FILTER 0 /* to search exhaustively for
best filter */
#define RESET_FOREACH_FILTER 0 /* whether to reset the encoder state
before trying each new filter */
#define SHARP_FILTER_QTHRESH 0 /* Q threshold for 8-tap sharp filter */
#define ALTREF_HIGH_PRECISION_MV 1 /* whether to use high precision mv
for altref computation */
#define HIGH_PRECISION_MV_QTHRESH 200 /* Q threshold for use of high precision
mv. Choose a very high value for
now so that HIGH_PRECISION is always
chosen */
extern double vp9_calc_ssim(YV12_BUFFER_CONFIG *source,
YV12_BUFFER_CONFIG *dest, int lumamask,
double *weight);
extern double vp9_calc_ssimg(YV12_BUFFER_CONFIG *source,
YV12_BUFFER_CONFIG *dest, double *ssim_y,
double *ssim_u, double *ssim_v);
#ifdef OUTPUT_YUV_SRC
FILE *yuv_file;
#endif
#ifdef OUTPUT_YUV_REC
FILE *yuv_rec_file;
#endif
FILE *keyfile;
#endif
#ifdef ENTROPY_STATS
extern int intra_mode_stats[VP9_INTRA_MODES]
[VP9_INTRA_MODES]
[VP9_INTRA_MODES];
#ifdef NMV_STATS
extern void init_nmvstats();
extern void print_nmvstats();
#endif
#ifdef MODE_STATS
extern void init_tx_count_stats();
extern void write_tx_count_stats();
extern void init_switchable_interp_stats();
extern void write_switchable_interp_stats();
#ifdef SPEEDSTATS
unsigned int frames_at_speed[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
#endif
#if defined(SECTIONBITS_OUTPUT)
extern unsigned __int64 Sectionbits[500];
#endif
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];
// 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,
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;
if (minqtarget <= vp9_convert_qindex_to_q(i))
static void init_minq_luts(void) {
0.0);
kf_high_motion_minq[i] = calculate_minq_index(maxq,
gf_low_motion_minq[i] = calculate_minq_index(maxq,
0.0000015,
-0.0009,
0.33,
0.0);
gf_high_motion_minq[i] = calculate_minq_index(maxq,
0.0000021,
-0.00125,
0.45,
0.0);
inter_minq[i] = calculate_minq_index(maxq,
0.00000271,
-0.00113,
0.697,
0.0);
}
static void set_mvcost(MACROBLOCK *mb) {
if (mb->e_mbd.allow_high_precision_mv) {
mb->mvcost = mb->nmvcost_hp;
mb->mvsadcost = mb->nmvsadcost_hp;
} else {
mb->mvcost = mb->nmvcost;
mb->mvsadcost = mb->nmvsadcost;
}
}
void vp9_initialize_enc() {
vp9_initialize_common();
vp9_tokenize_initialize();
vp9_init_quant_tables();
vp9_init_me_luts();
static void setup_features(VP9_COMP *cpi) {
xd->seg.enabled = 0;
xd->seg.update_map = 0;
xd->seg.update_data = 0;
vpx_memset(xd->seg.tree_probs, 255, sizeof(xd->seg.tree_probs));
vp9_clearall_segfeatures(&xd->seg);
xd->mode_ref_lf_delta_enabled = 0;
xd->mode_ref_lf_delta_update = 0;
vpx_memset(xd->ref_lf_deltas, 0, sizeof(xd->ref_lf_deltas));
vpx_memset(xd->mode_lf_deltas, 0, sizeof(xd->mode_lf_deltas));
vpx_memset(xd->last_ref_lf_deltas, 0, sizeof(xd->ref_lf_deltas));
vpx_memset(xd->last_mode_lf_deltas, 0, sizeof(xd->mode_lf_deltas));
static void dealloc_compressor_data(VP9_COMP *cpi) {
// Delete sementation map
vpx_free(cpi->segmentation_map);
cpi->segmentation_map = 0;
vpx_free(cpi->common.last_frame_seg_map);
cpi->common.last_frame_seg_map = 0;
vpx_free(cpi->coding_context.last_frame_seg_map_copy);
cpi->coding_context.last_frame_seg_map_copy = 0;
vp9_free_frame_buffer(&cpi->last_frame_uf);
vp9_free_frame_buffer(&cpi->scaled_source);
vp9_free_frame_buffer(&cpi->alt_ref_buffer);
vp9_lookahead_destroy(cpi->lookahead);
// Activity mask based per mb zbin adjustments
vpx_free(cpi->mb_activity_map);
cpi->mb_activity_map = 0;
vpx_free(cpi->mb_norm_activity_map);
cpi->mb_norm_activity_map = 0;
// Computes a q delta (in "q index" terms) to get from a starting q value
// to a target value
// target q value
static int compute_qdelta(VP9_COMP *cpi, double qstart, double qtarget) {
int i;
int start_index = cpi->worst_quality;
int target_index = cpi->worst_quality;
// Convert the average q value to an index.
for (i = cpi->best_quality; i < cpi->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++) {
target_index = i;
if (vp9_convert_qindex_to_q(i) >= qtarget)
static void configure_static_seg_features(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
// Disable and clear down for KF
if (cm->frame_type == KEY_FRAME) {
// Clear down the global segmentation map
vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
xd->seg.update_map = 0;
xd->seg.update_data = 0;
vp9_disable_segmentation((VP9_PTR)cpi);
vp9_clearall_segfeatures(&xd->seg);
} else if (cpi->refresh_alt_ref_frame) {
// If this is an alt ref frame
vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
xd->seg.update_map = 0;
xd->seg.update_data = 0;
// Disable segmentation and individual segment features by default
vp9_disable_segmentation((VP9_PTR)cpi);
vp9_clearall_segfeatures(&xd->seg);
// Scan frames from current to arf frame.
// This function re-enables segmentation if appropriate.
vp9_update_mbgraph_stats(cpi);
// If segmentation was enabled set those features needed for the
// arf itself.
if (xd->seg.enabled) {
xd->seg.update_map = 1;
xd->seg.update_data = 1;
qi_delta = compute_qdelta(cpi, cpi->avg_q, (cpi->avg_q * 0.875));
vp9_set_segdata(&xd->seg, 1, SEG_LVL_ALT_Q, (qi_delta - 2));
vp9_set_segdata(&xd->seg, 1, SEG_LVL_ALT_LF, -2);
vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_ALT_Q);
vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_ALT_LF);
xd->seg.abs_delta = SEGMENT_DELTADATA;
} else if (xd->seg.enabled) {
// All other frames if segmentation has been enabled
// First normal frame in a valid gf or alt ref group
if (cpi->common.frames_since_golden == 0) {
// Set up segment features for normal frames in an arf group
xd->seg.update_map = 0;
xd->seg.update_data = 1;
xd->seg.abs_delta = SEGMENT_DELTADATA;
qi_delta = compute_qdelta(cpi, cpi->avg_q,
(cpi->avg_q * 1.125));
vp9_set_segdata(&xd->seg, 1, SEG_LVL_ALT_Q, (qi_delta + 2));
vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_ALT_Q);
vp9_set_segdata(&xd->seg, 1, SEG_LVL_ALT_LF, -2);
vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_ALT_LF);
// Segment coding disabled for compred testing
if (high_q || (cpi->static_mb_pct == 100)) {
vp9_set_segdata(&xd->seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_REF_FRAME);
vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_SKIP);
} else {
// Disable segmentation and clear down features if alt ref
// is not active for this group
vp9_disable_segmentation((VP9_PTR)cpi);
vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
xd->seg.update_map = 0;
xd->seg.update_data = 0;
vp9_clearall_segfeatures(&xd->seg);
} else if (cpi->is_src_frame_alt_ref) {
// Special case where we are coding over the top of a previous
// alt ref frame.
// Segment coding disabled for compred testing
vp9_enable_segfeature(&xd->seg, 0, SEG_LVL_REF_FRAME);
vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_REF_FRAME);
vp9_clear_segdata(&xd->seg, 0, SEG_LVL_REF_FRAME);
vp9_set_segdata(&xd->seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
vp9_clear_segdata(&xd->seg, 1, SEG_LVL_REF_FRAME);
vp9_set_segdata(&xd->seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
vp9_enable_segfeature(&xd->seg, 0, SEG_LVL_SKIP);
vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_SKIP);
xd->seg.update_data = 1;
} else {
// All other frames.
xd->seg.update_map = 0;
xd->seg.update_data = 0;
#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)[VP9_INTER_MODES - 1][2] =
cm->fc.inter_mode_counts;
int64_t (*mv_ref_stats)[VP9_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 < VP9_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][VP9_INTER_MODES - 1] =");
fprintf(f, "{\n");
for (j = 0; j < INTER_MODE_CONTEXTS; j++) {
fprintf(f, " {/* %d */ ", j);
fprintf(f, " ");
for (i = 0; i < VP9_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;
fprintf(statsfile, "%10d\n", cm->current_video_frame);
for (row = 0; row < cpi->common.mi_rows; row++) {
for (col = 0; col < cpi->common.mi_cols; col++) {
fprintf(statsfile, "%10d", cpi->segmentation_map[map_index]);
}
fprintf(statsfile, "\n");
static void update_reference_segmentation_map(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
int row, col;
MODE_INFO *mi, *mi_ptr = cm->mi;
uint8_t *cache_ptr = cm->last_frame_seg_map, *cache;
for (row = 0; row < cm->mi_rows; row++) {
for (col = 0; col < cm->mi_cols; col++, mi++, cache++)
cache[0] = mi->mbmi.segment_id;
mi_ptr += cm->mode_info_stride;
static void set_default_lf_deltas(VP9_COMP *cpi) {
cpi->mb.e_mbd.mode_ref_lf_delta_enabled = 1;
cpi->mb.e_mbd.mode_ref_lf_delta_update = 1;
vpx_memset(cpi->mb.e_mbd.ref_lf_deltas, 0, sizeof(cpi->mb.e_mbd.ref_lf_deltas));
vpx_memset(cpi->mb.e_mbd.mode_lf_deltas, 0, sizeof(cpi->mb.e_mbd.mode_lf_deltas));
// Test of ref frame deltas
cpi->mb.e_mbd.ref_lf_deltas[INTRA_FRAME] = 2;
cpi->mb.e_mbd.ref_lf_deltas[LAST_FRAME] = 0;
cpi->mb.e_mbd.ref_lf_deltas[GOLDEN_FRAME] = -2;
cpi->mb.e_mbd.ref_lf_deltas[ALTREF_FRAME] = -2;
cpi->mb.e_mbd.mode_lf_deltas[0] = 0; // Zero
cpi->mb.e_mbd.mode_lf_deltas[1] = 0; // New mv
static void set_rd_speed_thresholds(VP9_COMP *cpi, int mode, int speed) {
SPEED_FEATURES *sf = &cpi->sf;
int speed_multiplier = speed + 1;
int i;
// Set baseline threshold values
for (i = 0; i < MAX_MODES; ++i)
sf->thresh_mult[i] = mode == 0 ? -500 : 0;
sf->thresh_mult[THR_ZEROMV] = 0;
sf->thresh_mult[THR_ZEROG] = 0;
sf->thresh_mult[THR_ZEROA] = 0;
sf->thresh_mult[THR_NEARESTMV] = 0;
sf->thresh_mult[THR_NEARESTG] = 0;
sf->thresh_mult[THR_NEARESTA] = 0;
sf->thresh_mult[THR_NEARMV] += speed_multiplier * 1000;
sf->thresh_mult[THR_NEARG] += speed_multiplier * 1000;
sf->thresh_mult[THR_NEARA] += speed_multiplier * 1000;
sf->thresh_mult[THR_DC ] = 0;
sf->thresh_mult[THR_TM] += speed_multiplier * 1000;
sf->thresh_mult[THR_V_PRED ] += speed_multiplier * 1000;
sf->thresh_mult[THR_H_PRED ] += speed_multiplier * 1000;
sf->thresh_mult[THR_D45_PRED ] += speed_multiplier * 1500;
sf->thresh_mult[THR_D135_PRED] += speed_multiplier * 1500;
sf->thresh_mult[THR_D117_PRED] += speed_multiplier * 1500;
sf->thresh_mult[THR_D153_PRED] += speed_multiplier * 1500;
sf->thresh_mult[THR_D27_PRED ] += speed_multiplier * 1500;
sf->thresh_mult[THR_D63_PRED ] += speed_multiplier * 1500;
sf->thresh_mult[THR_B_PRED ] += speed_multiplier * 2500;
sf->thresh_mult[THR_NEWMV ] += speed_multiplier * 1000;
sf->thresh_mult[THR_NEWG ] += speed_multiplier * 1000;
sf->thresh_mult[THR_NEWA ] += speed_multiplier * 1000;
sf->thresh_mult[THR_SPLITMV ] += speed_multiplier * 2500;
sf->thresh_mult[THR_SPLITG ] += speed_multiplier * 2500;
sf->thresh_mult[THR_SPLITA ] += speed_multiplier * 2500;
sf->thresh_mult[THR_COMP_ZEROLA] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_ZEROGA] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_NEARESTLA] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_NEARESTGA] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_NEARLA] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_NEARGA] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_NEWLA ] += speed_multiplier * 2000;
sf->thresh_mult[THR_COMP_NEWGA ] += speed_multiplier * 2000;
sf->thresh_mult[THR_COMP_SPLITLA ] += speed_multiplier * 4500;
sf->thresh_mult[THR_COMP_SPLITGA ] += speed_multiplier * 4500;
if (cpi->sf.skip_lots_of_modes) {
for (i = 0; i < MAX_MODES; ++i)
sf->thresh_mult[i] = INT_MAX;
sf->thresh_mult[THR_DC] = 0;
sf->thresh_mult[THR_TM] = 0;
sf->thresh_mult[THR_NEWMV] = 4000;
sf->thresh_mult[THR_NEWG] = 4000;
sf->thresh_mult[THR_NEWA] = 4000;
sf->thresh_mult[THR_NEARESTG] = 0;
sf->thresh_mult[THR_NEARESTA] = 0;
sf->thresh_mult[THR_NEARMV] = 2000;
sf->thresh_mult[THR_NEARG] = 2000;
sf->thresh_mult[THR_NEARA] = 2000;
sf->thresh_mult[THR_SPLITMV] = 2500;
sf->thresh_mult[THR_SPLITG] = 2500;
sf->thresh_mult[THR_SPLITA] = 2500;
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
/* disable frame modes if flags not set */
if (!(cpi->ref_frame_flags & VP9_LAST_FLAG)) {
sf->thresh_mult[THR_NEWMV ] = INT_MAX;
sf->thresh_mult[THR_NEARESTMV] = INT_MAX;
sf->thresh_mult[THR_ZEROMV ] = INT_MAX;
sf->thresh_mult[THR_NEARMV ] = INT_MAX;
sf->thresh_mult[THR_SPLITMV ] = INT_MAX;
}
if (!(cpi->ref_frame_flags & VP9_GOLD_FLAG)) {
sf->thresh_mult[THR_NEARESTG ] = INT_MAX;
sf->thresh_mult[THR_ZEROG ] = INT_MAX;
sf->thresh_mult[THR_NEARG ] = INT_MAX;
sf->thresh_mult[THR_NEWG ] = INT_MAX;
sf->thresh_mult[THR_SPLITG ] = INT_MAX;
}
if (!(cpi->ref_frame_flags & VP9_ALT_FLAG)) {
sf->thresh_mult[THR_NEARESTA ] = INT_MAX;
sf->thresh_mult[THR_ZEROA ] = INT_MAX;
sf->thresh_mult[THR_NEARA ] = INT_MAX;
sf->thresh_mult[THR_NEWA ] = INT_MAX;
sf->thresh_mult[THR_SPLITA ] = INT_MAX;
}
if ((cpi->ref_frame_flags & (VP9_LAST_FLAG | VP9_ALT_FLAG)) !=
(VP9_LAST_FLAG | VP9_ALT_FLAG)) {
sf->thresh_mult[THR_COMP_ZEROLA ] = INT_MAX;
sf->thresh_mult[THR_COMP_NEARESTLA] = INT_MAX;
sf->thresh_mult[THR_COMP_NEARLA ] = INT_MAX;
sf->thresh_mult[THR_COMP_NEWLA ] = INT_MAX;
sf->thresh_mult[THR_COMP_SPLITLA ] = INT_MAX;
}
if ((cpi->ref_frame_flags & (VP9_GOLD_FLAG | VP9_ALT_FLAG)) !=
(VP9_GOLD_FLAG | VP9_ALT_FLAG)) {
sf->thresh_mult[THR_COMP_ZEROGA ] = INT_MAX;
sf->thresh_mult[THR_COMP_NEARESTGA] = INT_MAX;
sf->thresh_mult[THR_COMP_NEARGA ] = INT_MAX;
sf->thresh_mult[THR_COMP_NEWGA ] = INT_MAX;
sf->thresh_mult[THR_COMP_SPLITGA ] = INT_MAX;
}
if (sf->disable_splitmv == 1) {
sf->thresh_mult[THR_SPLITMV ] = INT_MAX;
sf->thresh_mult[THR_SPLITG ] = INT_MAX;
sf->thresh_mult[THR_SPLITA ] = INT_MAX;
sf->thresh_mult[THR_COMP_SPLITLA ] = INT_MAX;
sf->thresh_mult[THR_COMP_SPLITGA ] = INT_MAX;
}
void vp9_set_speed_features(VP9_COMP *cpi) {
int speed = cpi->speed;
// Only modes 0 and 1 supported for now in experimental code basae
// Initialise default mode frequency sampling variables
for (i = 0; i < MAX_MODES; i ++) {
cpi->mode_check_freq[i] = 0;
cpi->mode_test_hit_counts[i] = 0;
cpi->mode_chosen_counts[i] = 0;
}
// Initialize cpi->max_mv_magnitude if appropriate.
if ((cpi->common.frame_type == KEY_FRAME) || cpi->common.intra_only ||
(cpi->common.show_frame == 0)) {
cpi->max_mv_magnitude = 0;
}
// best quality defaults
sf->RD = 1;
sf->search_method = NSTEP;
sf->auto_filter = 1;
sf->recode_loop = 1;
sf->quarter_pixel_search = 1;
sf->half_pixel_search = 1;
sf->iterative_sub_pixel = 1;
sf->optimize_coefficients = !cpi->oxcf.lossless;
sf->reduce_first_step_size = 0;
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_AB4X4;
sf->adaptive_rd_thresh = 0;
sf->use_8tap_always = 0;
sf->use_avoid_tested_higherror = 0;
sf->partition_by_variance = 0;
sf->use_one_partition_size_always = 0;
sf->use_square_partition_only = 0;
sf->use_partitions_less_than = 0;
sf->less_than_block_size = BLOCK_SIZE_MB16X16;
sf->use_partitions_greater_than = 0;
sf->greater_than_block_size = BLOCK_SIZE_SB8X8;
sf->adjust_partitioning_from_last_frame = 0;
sf->last_partitioning_redo_frequency = 4;
sf->mode_search_skip_flags = 0;
sf->last_chroma_intra_mode = TM_PRED;
sf->use_rd_breakout = 0;
sf->use_uv_intra_rd_estimate = 0;
sf->using_small_partition_info = 0;
// Skip any mode not chosen at size < X for all sizes > X
// Hence BLOCK_SIZE_SB64X64 (skip is off)
sf->unused_mode_skip_lvl = BLOCK_SIZE_SB64X64;
#if CONFIG_MULTIPLE_ARF
// Switch segmentation off.
sf->static_segmentation = 0;
#else
sf->search_best_filter = SEARCH_BEST_FILTER;
break;
#if CONFIG_MULTIPLE_ARF
// Switch segmentation off.
sf->static_segmentation = 0;
sf->use_avoid_tested_higherror = 1;
sf->adaptive_rd_thresh = 1;
sf->last_chroma_intra_mode = TM_PRED;
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
sf->tx_size_search_method = ((cpi->common.frame_type == KEY_FRAME ||
cpi->common.intra_only ||
cpi->common.show_frame == 0) ?
USE_FULL_RD :
USE_LARGESTALL);
sf->use_square_partition_only = !(cpi->common.frame_type == KEY_FRAME ||
cpi->common.intra_only ||
cpi->common.show_frame == 0);
sf->disable_splitmv =
(MIN(cpi->common.width, cpi->common.height) >= 720)? 1 : 0;
sf->unused_mode_skip_lvl = BLOCK_SIZE_SB32X32;
sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
FLAG_SKIP_INTRA_BESTINTER |
FLAG_SKIP_COMP_BESTINTRA;
sf->last_chroma_intra_mode = H_PRED;
sf->use_rd_breakout = 1;
sf->use_square_partition_only = 1;
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
sf->adjust_partitioning_from_last_frame = 1;
sf->last_partitioning_redo_frequency = 3;
sf->unused_mode_skip_lvl = BLOCK_SIZE_SB32X32;
sf->tx_size_search_method = ((cpi->common.frame_type == KEY_FRAME ||
cpi->common.intra_only ||
cpi->common.show_frame == 0) ?
USE_FULL_RD :
USE_LARGESTALL);
sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
FLAG_SKIP_INTRA_BESTINTER |
FLAG_SKIP_COMP_BESTINTRA |
FLAG_SKIP_COMP_REFMISMATCH;
sf->last_chroma_intra_mode = DC_PRED;
sf->use_rd_breakout = 1;
sf->use_uv_intra_rd_estimate = 1;
sf->using_small_partition_info = 1;
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
sf->partition_by_variance = 1;
sf->tx_size_search_method = ((cpi->common.frame_type == KEY_FRAME ||
cpi->common.intra_only ||
cpi->common.show_frame == 0) ?
USE_FULL_RD :
USE_LARGESTALL);
sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
FLAG_SKIP_INTRA_BESTINTER |
FLAG_SKIP_COMP_BESTINTRA |
FLAG_SKIP_COMP_REFMISMATCH;
sf->use_rd_breakout = 1;
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
sf->use_one_partition_size_always = 1;
sf->always_this_block_size = BLOCK_SIZE_MB16X16;
sf->tx_size_search_method = ((cpi->common.frame_type == KEY_FRAME ||
cpi->common.intra_only ||
cpi->common.show_frame == 0) ?
USE_FULL_RD :
USE_LARGESTALL);
sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
FLAG_SKIP_INTRA_BESTINTER |
FLAG_SKIP_COMP_BESTINTRA |
FLAG_SKIP_COMP_REFMISMATCH;
sf->use_rd_breakout = 1;
sf->optimize_coefficients = 0;
// sf->reduce_first_step_size = 1;
// sf->reference_masking = 1;
/*
if (speed == 2) {
sf->first_step = 0;
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_SB8X8;
sf->use_partitions_less_than = 1;
sf->less_than_block_size = BLOCK_SIZE_MB16X16;
}
if (speed == 3) {
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_SB8X8;
sf->use_partitions_greater_than = 1;
sf->greater_than_block_size = BLOCK_SIZE_SB8X8;
// Set rd thresholds based on mode and speed setting
if (cpi->sf.adjust_thresholds_by_speed)
set_rd_speed_thresholds(cpi, mode, speed);
else
set_rd_speed_thresholds(cpi, mode, 0);
// Slow quant, dct and trellis not worthwhile for first pass
// so make sure they are always turned off.
if (cpi->pass == 1) {
sf->optimize_coefficients = 0;
}
cpi->mb.fwd_txm16x16 = vp9_short_fdct16x16;
cpi->mb.fwd_txm8x8 = vp9_short_fdct8x8;
cpi->mb.fwd_txm8x4 = vp9_short_fdct8x4;
cpi->mb.fwd_txm4x4 = vp9_short_fdct4x4;
cpi->mb.fwd_txm8x4 = vp9_short_walsh8x4;
cpi->mb.fwd_txm4x4 = vp9_short_walsh4x4;
cpi->mb.quantize_b_4x4 = vp9_regular_quantize_b_4x4;
vp9_init_quantizer(cpi);
cpi->find_fractional_mv_step = vp9_find_best_sub_pixel_step_iteratively;
cpi->find_fractional_mv_step = vp9_find_best_sub_pixel_step;
cpi->find_fractional_mv_step = vp9_find_best_half_pixel_step;
cpi->mb.optimize = cpi->sf.optimize_coefficients == 1 && cpi->pass != 1;
frames_at_speed[cpi->speed]++;
static void alloc_raw_frame_buffers(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
cpi->lookahead = vp9_lookahead_init(cpi->oxcf.width, cpi->oxcf.height,
cm->subsampling_x, cm->subsampling_y,
cpi->oxcf.lag_in_frames);
if (!cpi->lookahead)
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate lag buffers");
if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer,
cpi->oxcf.width, cpi->oxcf.height,
cm->subsampling_x, cm->subsampling_y,
VP9BORDERINPIXELS))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate altref buffer");
static int alloc_partition_data(VP9_COMP *cpi) {
cpi->mb.pip = vpx_calloc(cpi->common.mode_info_stride *
(cpi->common.mi_rows + MI_BLOCK_SIZE),
sizeof(PARTITION_INFO));
if (!cpi->mb.pip)
return 1;
cpi->mb.pi = cpi->mb.pip + cpi->common.mode_info_stride + 1;
void vp9_alloc_compressor_data(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
if (vp9_alloc_frame_buffers(cm, cm->width, cm->height))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate frame buffers");
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate partition data");
if (vp9_alloc_frame_buffer(&cpi->last_frame_uf,
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
VP9BORDERINPIXELS))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate last frame buffer");
if (vp9_alloc_frame_buffer(&cpi->scaled_source,
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
VP9BORDERINPIXELS))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate scaled source buffer");
unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols);
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;
CHECK_MEM_ERROR(cm, cpi->mb_activity_map,
vpx_calloc(sizeof(unsigned int),
cm->mb_rows * cm->mb_cols));
CHECK_MEM_ERROR(cm, cpi->mb_norm_activity_map,
vpx_calloc(sizeof(unsigned int),
cm->mb_rows * cm->mb_cols));
static void update_frame_size(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
// Update size of buffers local to this frame
if (vp9_realloc_frame_buffer(&cpi->last_frame_uf,
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
VP9BORDERINPIXELS))
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))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to reallocate scaled source buffer");
{
int y_stride = cpi->scaled_source.y_stride;
if (cpi->sf.search_method == NSTEP) {
vp9_init3smotion_compensation(&cpi->mb, y_stride);
} else if (cpi->sf.search_method == DIAMOND) {
vp9_init_dsmotion_compensation(&cpi->mb, y_stride);