/* * 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 <limits.h>#include <math.h>#include <stdio.h>#include <stdlib.h> #include "./vp9_rtcd.h"#include "./vpx_config.h"#include "./vpx_dsp_rtcd.h"#include "./vpx_scale_rtcd.h"#include "vpx_dsp/psnr.h"#include "vpx_dsp/vpx_dsp_common.h"#include "vpx_dsp/vpx_filter.h"#if CONFIG_INTERNAL_STATS#include "vpx_dsp/ssim.h"#endif#include "vpx_ports/mem.h"#include "vpx_ports/system_state.h"#include "vpx_ports/vpx_timer.h"#if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG#include "vpx_util/vpx_debug_util.h"#endif // CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG #include "vp9/common/vp9_alloccommon.h"#include "vp9/common/vp9_filter.h"#include "vp9/common/vp9_idct.h"#if CONFIG_NON_GREEDY_MV#include "vp9/common/vp9_mvref_common.h"#endif#if CONFIG_VP9_POSTPROC#include "vp9/common/vp9_postproc.h"#endif#include "vp9/common/vp9_reconinter.h"#include "vp9/common/vp9_reconintra.h"#include "vp9/common/vp9_tile_common.h"#include "vp9/common/vp9_scan.h" #if !CONFIG_REALTIME_ONLY#include "vp9/encoder/vp9_alt_ref_aq.h"#include "vp9/encoder/vp9_aq_360.h"#include "vp9/encoder/vp9_aq_complexity.h"#endif#include "vp9/encoder/vp9_aq_cyclicrefresh.h"#if !CONFIG_REALTIME_ONLY#include "vp9/encoder/vp9_aq_variance.h"#endif#include "vp9/encoder/vp9_bitstream.h"#if CONFIG_INTERNAL_STATS#include "vp9/encoder/vp9_blockiness.h"#endif#include "vp9/encoder/vp9_context_tree.h"#include "vp9/encoder/vp9_encodeframe.h"#include "vp9/encoder/vp9_encodemb.h"#include "vp9/encoder/vp9_encodemv.h"#include "vp9/encoder/vp9_encoder.h"#include "vp9/encoder/vp9_ethread.h"#include "vp9/encoder/vp9_extend.h"#include "vp9/encoder/vp9_firstpass.h"#include "vp9/encoder/vp9_mbgraph.h"#if CONFIG_NON_GREEDY_MV#include "vp9/encoder/vp9_mcomp.h"#endif#include "vp9/encoder/vp9_multi_thread.h"#include "vp9/encoder/vp9_noise_estimate.h"#include "vp9/encoder/vp9_picklpf.h"#include "vp9/encoder/vp9_ratectrl.h"#include "vp9/encoder/vp9_rd.h"#include "vp9/encoder/vp9_resize.h"#include "vp9/encoder/vp9_segmentation.h"#include "vp9/encoder/vp9_skin_detection.h"#include "vp9/encoder/vp9_speed_features.h"#include "vp9/encoder/vp9_svc_layercontext.h"#include "vp9/encoder/vp9_temporal_filter.h"#include "vp9/vp9_cx_iface.h" #define AM_SEGMENT_ID_INACTIVE 7#define AM_SEGMENT_ID_ACTIVE 0 // Whether to use high precision mv for altref computation.#define ALTREF_HIGH_PRECISION_MV 1 // Q threshold for high precision mv. Choose a very high value for now so that// HIGH_PRECISION is always chosen.#define HIGH_PRECISION_MV_QTHRESH 200 #define FRAME_SIZE_FACTOR 128 // empirical params for context model threshold#define FRAME_RATE_FACTOR 8 #ifdef OUTPUT_YUV_DENOISEDFILE *yuv_denoised_file = NULL;#endif#ifdef OUTPUT_YUV_SKINMAPstatic FILE *yuv_skinmap_file = NULL;#endif#ifdef OUTPUT_YUV_RECFILE *yuv_rec_file;#endif#ifdef OUTPUT_YUV_SVC_SRCFILE *yuv_svc_src[3] = { NULL, NULL, NULL };#endif #if 0FILE *framepsnr;FILE *kf_list;FILE *keyfile;#endif #ifdef ENABLE_KF_DENOISE// Test condition for spatial denoise of source.static int is_spatial_denoise_enabled(VP9_COMP *cpi) { VP9_COMMON *const cm = &cpi->common; const VP9EncoderConfig *const oxcf = &cpi->oxcf; return (oxcf->pass != 1) && !is_lossless_requested(&cpi->oxcf) && frame_is_intra_only(cm);}#endif #if CONFIG_VP9_HIGHBITDEPTHvoid highbd_wht_fwd_txfm(int16_t *src_diff, int bw, tran_low_t *coeff, TX_SIZE tx_size);#endifvoid wht_fwd_txfm(int16_t *src_diff, int bw, tran_low_t *coeff, TX_SIZE tx_size); #if !CONFIG_REALTIME_ONLY// compute adaptive threshold for skip recodingstatic int compute_context_model_thresh(const VP9_COMP *const cpi) { const VP9_COMMON *const cm = &cpi->common; const VP9EncoderConfig *const oxcf = &cpi->oxcf; const int frame_size = (cm->width * cm->height) >> 10; const int bitrate = (int)(oxcf->target_bandwidth >> 10); const int qindex_factor = cm->base_qindex + (MAXQ >> 1); // This equation makes the threshold adaptive to frame size. // Coding gain obtained by recoding comes from alternate frames of large // content change. We skip recoding if the difference of previous and current // frame context probability model is less than a certain threshold. // The first component is the most critical part to guarantee adaptivity. // Other parameters are estimated based on normal setting of hd resolution // parameters. e.g frame_size = 1920x1080, bitrate = 8000, qindex_factor < 50 const int thresh = ((FRAME_SIZE_FACTOR * frame_size - FRAME_RATE_FACTOR * bitrate) * qindex_factor) >> 9; return thresh;} // compute the total cost difference between current// and previous frame context prob model.static int compute_context_model_diff(const VP9_COMMON *const cm) { const FRAME_CONTEXT *const pre_fc = &cm->frame_contexts[cm->frame_context_idx]; const FRAME_CONTEXT *const cur_fc = cm->fc; const FRAME_COUNTS *counts = &cm->counts; vpx_prob pre_last_prob, cur_last_prob; int diff = 0; int i, j, k, l, m, n; // y_mode_prob for (i = 0; i < BLOCK_SIZE_GROUPS; ++i) { for (j = 0; j < INTRA_MODES - 1; ++j) { diff += (int)counts->y_mode[i][j] * (pre_fc->y_mode_prob[i][j] - cur_fc->y_mode_prob[i][j]); } pre_last_prob = MAX_PROB - pre_fc->y_mode_prob[i][INTRA_MODES - 2]; cur_last_prob = MAX_PROB - cur_fc->y_mode_prob[i][INTRA_MODES - 2]; diff += (int)counts->y_mode[i][INTRA_MODES - 1] * (pre_last_prob - cur_last_prob); } // uv_mode_prob for (i = 0; i < INTRA_MODES; ++i) { for (j = 0; j < INTRA_MODES - 1; ++j) { diff += (int)counts->uv_mode[i][j] * (pre_fc->uv_mode_prob[i][j] - cur_fc->uv_mode_prob[i][j]); } pre_last_prob = MAX_PROB - pre_fc->uv_mode_prob[i][INTRA_MODES - 2]; cur_last_prob = MAX_PROB - cur_fc->uv_mode_prob[i][INTRA_MODES - 2]; diff += (int)counts->uv_mode[i][INTRA_MODES - 1] * (pre_last_prob - cur_last_prob); } // partition_prob for (i = 0; i < PARTITION_CONTEXTS; ++i) { for (j = 0; j < PARTITION_TYPES - 1; ++j) { diff += (int)counts->partition[i][j] * (pre_fc->partition_prob[i][j] - cur_fc->partition_prob[i][j]); } pre_last_prob = MAX_PROB - pre_fc->partition_prob[i][PARTITION_TYPES - 2]; cur_last_prob = MAX_PROB - cur_fc->partition_prob[i][PARTITION_TYPES - 2]; diff += (int)counts->partition[i][PARTITION_TYPES - 1] * (pre_last_prob - cur_last_prob); } // coef_probs for (i = 0; i < TX_SIZES; ++i) { for (j = 0; j < PLANE_TYPES; ++j) { for (k = 0; k < REF_TYPES; ++k) { for (l = 0; l < COEF_BANDS; ++l) { for (m = 0; m < BAND_COEFF_CONTEXTS(l); ++m) { for (n = 0; n < UNCONSTRAINED_NODES; ++n) { diff += (int)counts->coef[i][j][k][l][m][n] * (pre_fc->coef_probs[i][j][k][l][m][n] - cur_fc->coef_probs[i][j][k][l][m][n]); } pre_last_prob = MAX_PROB - pre_fc->coef_probs[i][j][k][l][m][UNCONSTRAINED_NODES - 1]; cur_last_prob = MAX_PROB - cur_fc->coef_probs[i][j][k][l][m][UNCONSTRAINED_NODES - 1]; diff += (int)counts->coef[i][j][k][l][m][UNCONSTRAINED_NODES] * (pre_last_prob - cur_last_prob); } } } } } // switchable_interp_prob for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) { for (j = 0; j < SWITCHABLE_FILTERS - 1; ++j) { diff += (int)counts->switchable_interp[i][j] * (pre_fc->switchable_interp_prob[i][j] - cur_fc->switchable_interp_prob[i][j]); } pre_last_prob = MAX_PROB - pre_fc->switchable_interp_prob[i][SWITCHABLE_FILTERS - 2]; cur_last_prob = MAX_PROB - cur_fc->switchable_interp_prob[i][SWITCHABLE_FILTERS - 2]; diff += (int)counts->switchable_interp[i][SWITCHABLE_FILTERS - 1] * (pre_last_prob - cur_last_prob); } // inter_mode_probs for (i = 0; i < INTER_MODE_CONTEXTS; ++i) { for (j = 0; j < INTER_MODES - 1; ++j) { diff += (int)counts->inter_mode[i][j] * (pre_fc->inter_mode_probs[i][j] - cur_fc->inter_mode_probs[i][j]); } pre_last_prob = MAX_PROB - pre_fc->inter_mode_probs[i][INTER_MODES - 2]; cur_last_prob = MAX_PROB - cur_fc->inter_mode_probs[i][INTER_MODES - 2]; diff += (int)counts->inter_mode[i][INTER_MODES - 1] * (pre_last_prob - cur_last_prob); } // intra_inter_prob for (i = 0; i < INTRA_INTER_CONTEXTS; ++i) { diff += (int)counts->intra_inter[i][0] * (pre_fc->intra_inter_prob[i] - cur_fc->intra_inter_prob[i]); pre_last_prob = MAX_PROB - pre_fc->intra_inter_prob[i]; cur_last_prob = MAX_PROB - cur_fc->intra_inter_prob[i]; diff += (int)counts->intra_inter[i][1] * (pre_last_prob - cur_last_prob); } // comp_inter_prob for (i = 0; i < COMP_INTER_CONTEXTS; ++i) { diff += (int)counts->comp_inter[i][0] * (pre_fc->comp_inter_prob[i] - cur_fc->comp_inter_prob[i]); pre_last_prob = MAX_PROB - pre_fc->comp_inter_prob[i]; cur_last_prob = MAX_PROB - cur_fc->comp_inter_prob[i]; diff += (int)counts->comp_inter[i][1] * (pre_last_prob - cur_last_prob); } // single_ref_prob for (i = 0; i < REF_CONTEXTS; ++i) { for (j = 0; j < 2; ++j) { diff += (int)counts->single_ref[i][j][0] * (pre_fc->single_ref_prob[i][j] - cur_fc->single_ref_prob[i][j]); pre_last_prob = MAX_PROB - pre_fc->single_ref_prob[i][j]; cur_last_prob = MAX_PROB - cur_fc->single_ref_prob[i][j]; diff += (int)counts->single_ref[i][j][1] * (pre_last_prob - cur_last_prob); } } // comp_ref_prob for (i = 0; i < REF_CONTEXTS; ++i) { diff += (int)counts->comp_ref[i][0] * (pre_fc->comp_ref_prob[i] - cur_fc->comp_ref_prob[i]); pre_last_prob = MAX_PROB - pre_fc->comp_ref_prob[i]; cur_last_prob = MAX_PROB - cur_fc->comp_ref_prob[i]; diff += (int)counts->comp_ref[i][1] * (pre_last_prob - cur_last_prob); } // tx_probs for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { // p32x32 for (j = 0; j < TX_SIZES - 1; ++j) { diff += (int)counts->tx.p32x32[i][j] * (pre_fc->tx_probs.p32x32[i][j] - cur_fc->tx_probs.p32x32[i][j]); } pre_last_prob = MAX_PROB - pre_fc->tx_probs.p32x32[i][TX_SIZES - 2]; cur_last_prob = MAX_PROB - cur_fc->tx_probs.p32x32[i][TX_SIZES - 2]; diff += (int)counts->tx.p32x32[i][TX_SIZES - 1] * (pre_last_prob - cur_last_prob); // p16x16 for (j = 0; j < TX_SIZES - 2; ++j) { diff += (int)counts->tx.p16x16[i][j] * (pre_fc->tx_probs.p16x16[i][j] - cur_fc->tx_probs.p16x16[i][j]); } pre_last_prob = MAX_PROB - pre_fc->tx_probs.p16x16[i][TX_SIZES - 3]; cur_last_prob = MAX_PROB - cur_fc->tx_probs.p16x16[i][TX_SIZES - 3]; diff += (int)counts->tx.p16x16[i][TX_SIZES - 2] * (pre_last_prob - cur_last_prob); // p8x8 for (j = 0; j < TX_SIZES - 3; ++j) { diff += (int)counts->tx.p8x8[i][j] * (pre_fc->tx_probs.p8x8[i][j] - cur_fc->tx_probs.p8x8[i][j]); } pre_last_prob = MAX_PROB - pre_fc->tx_probs.p8x8[i][TX_SIZES - 4]; cur_last_prob = MAX_PROB - cur_fc->tx_probs.p8x8[i][TX_SIZES - 4]; diff += (int)counts->tx.p8x8[i][TX_SIZES - 3] * (pre_last_prob - cur_last_prob); } // skip_probs for (i = 0; i < SKIP_CONTEXTS; ++i) { diff += (int)counts->skip[i][0] * (pre_fc->skip_probs[i] - cur_fc->skip_probs[i]); pre_last_prob = MAX_PROB - pre_fc->skip_probs[i]; cur_last_prob = MAX_PROB - cur_fc->skip_probs[i]; diff += (int)counts->skip[i][1] * (pre_last_prob - cur_last_prob); } // mv for (i = 0; i < MV_JOINTS - 1; ++i) { diff += (int)counts->mv.joints[i] * (pre_fc->nmvc.joints[i] - cur_fc->nmvc.joints[i]); } pre_last_prob = MAX_PROB - pre_fc->nmvc.joints[MV_JOINTS - 2]; cur_last_prob = MAX_PROB - cur_fc->nmvc.joints[MV_JOINTS - 2]; diff += (int)counts->mv.joints[MV_JOINTS - 1] * (pre_last_prob - cur_last_prob); for (i = 0; i < 2; ++i) { const nmv_component_counts *nmv_count = &counts->mv.comps[i]; const nmv_component *pre_nmv_prob = &pre_fc->nmvc.comps[i]; const nmv_component *cur_nmv_prob = &cur_fc->nmvc.comps[i]; // sign diff += (int)nmv_count->sign[0] * (pre_nmv_prob->sign - cur_nmv_prob->sign); pre_last_prob = MAX_PROB - pre_nmv_prob->sign; cur_last_prob = MAX_PROB - cur_nmv_prob->sign; diff += (int)nmv_count->sign[1] * (pre_last_prob - cur_last_prob); // classes for (j = 0; j < MV_CLASSES - 1; ++j) { diff += (int)nmv_count->classes[j] * (pre_nmv_prob->classes[j] - cur_nmv_prob->classes[j]); } pre_last_prob = MAX_PROB - pre_nmv_prob->classes[MV_CLASSES - 2]; cur_last_prob = MAX_PROB - cur_nmv_prob->classes[MV_CLASSES - 2]; diff += (int)nmv_count->classes[MV_CLASSES - 1] * (pre_last_prob - cur_last_prob); // class0 for (j = 0; j < CLASS0_SIZE - 1; ++j) { diff += (int)nmv_count->class0[j] * (pre_nmv_prob->class0[j] - cur_nmv_prob->class0[j]); } pre_last_prob = MAX_PROB - pre_nmv_prob->class0[CLASS0_SIZE - 2]; cur_last_prob = MAX_PROB - cur_nmv_prob->class0[CLASS0_SIZE - 2]; diff += (int)nmv_count->class0[CLASS0_SIZE - 1] * (pre_last_prob - cur_last_prob); // bits for (j = 0; j < MV_OFFSET_BITS; ++j) { diff += (int)nmv_count->bits[j][0] * (pre_nmv_prob->bits[j] - cur_nmv_prob->bits[j]); pre_last_prob = MAX_PROB - pre_nmv_prob->bits[j]; cur_last_prob = MAX_PROB - cur_nmv_prob->bits[j]; diff += (int)nmv_count->bits[j][1] * (pre_last_prob - cur_last_prob); } // class0_fp for (j = 0; j < CLASS0_SIZE; ++j) { for (k = 0; k < MV_FP_SIZE - 1; ++k) { diff += (int)nmv_count->class0_fp[j][k] * (pre_nmv_prob->class0_fp[j][k] - cur_nmv_prob->class0_fp[j][k]); } pre_last_prob = MAX_PROB - pre_nmv_prob->class0_fp[j][MV_FP_SIZE - 2]; cur_last_prob = MAX_PROB - cur_nmv_prob->class0_fp[j][MV_FP_SIZE - 2]; diff += (int)nmv_count->class0_fp[j][MV_FP_SIZE - 1] * (pre_last_prob - cur_last_prob); } // fp for (j = 0; j < MV_FP_SIZE - 1; ++j) { diff += (int)nmv_count->fp[j] * (pre_nmv_prob->fp[j] - cur_nmv_prob->fp[j]); } pre_last_prob = MAX_PROB - pre_nmv_prob->fp[MV_FP_SIZE - 2]; cur_last_prob = MAX_PROB - cur_nmv_prob->fp[MV_FP_SIZE - 2]; diff += (int)nmv_count->fp[MV_FP_SIZE - 1] * (pre_last_prob - cur_last_prob); // class0_hp diff += (int)nmv_count->class0_hp[0] * (pre_nmv_prob->class0_hp - cur_nmv_prob->class0_hp); pre_last_prob = MAX_PROB - pre_nmv_prob->class0_hp; cur_last_prob = MAX_PROB - cur_nmv_prob->class0_hp; diff += (int)nmv_count->class0_hp[1] * (pre_last_prob - cur_last_prob); // hp diff += (int)nmv_count->hp[0] * (pre_nmv_prob->hp - cur_nmv_prob->hp); pre_last_prob = MAX_PROB - pre_nmv_prob->hp; cur_last_prob = MAX_PROB - cur_nmv_prob->hp; diff += (int)nmv_count->hp[1] * (pre_last_prob - cur_last_prob); } return -diff;}#endif // !CONFIG_REALTIME_ONLY // Test for whether to calculate metrics for the frame.static int is_psnr_calc_enabled(const VP9_COMP *cpi) { const VP9_COMMON *const cm = &cpi->common; const VP9EncoderConfig *const oxcf = &cpi->oxcf; return cpi->b_calculate_psnr && (oxcf->pass != 1) && cm->show_frame;} /* clang-format off */const Vp9LevelSpec vp9_level_defs[VP9_LEVELS] = { // sample rate size breadth bitrate cpb { LEVEL_1, 829440, 36864, 512, 200, 400, 2, 1, 4, 8 }, { LEVEL_1_1, 2764800, 73728, 768, 800, 1000, 2, 1, 4, 8 }, { LEVEL_2, 4608000, 122880, 960, 1800, 1500, 2, 1, 4, 8 }, { LEVEL_2_1, 9216000, 245760, 1344, 3600, 2800, 2, 2, 4, 8 }, { LEVEL_3, 20736000, 552960, 2048, 7200, 6000, 2, 4, 4, 8 }, { LEVEL_3_1, 36864000, 983040, 2752, 12000, 10000, 2, 4, 4, 8 }, { LEVEL_4, 83558400, 2228224, 4160, 18000, 16000, 4, 4, 4, 8 }, { LEVEL_4_1, 160432128, 2228224, 4160, 30000, 18000, 4, 4, 5, 6 }, { LEVEL_5, 311951360, 8912896, 8384, 60000, 36000, 6, 8, 6, 4 }, { LEVEL_5_1, 588251136, 8912896, 8384, 120000, 46000, 8, 8, 10, 4 }, // TODO(huisu): update max_cpb_size for level 5_2 ~ 6_2 when // they are finalized (currently tentative). { LEVEL_5_2, 1176502272, 8912896, 8384, 180000, 90000, 8, 8, 10, 4 }, { LEVEL_6, 1176502272, 35651584, 16832, 180000, 90000, 8, 16, 10, 4 }, { LEVEL_6_1, 2353004544u, 35651584, 16832, 240000, 180000, 8, 16, 10, 4 }, { LEVEL_6_2, 4706009088u, 35651584, 16832, 480000, 360000, 8, 16, 10, 4 },};/* clang-format on */ static const char *level_fail_messages[TARGET_LEVEL_FAIL_IDS] = { "The average bit-rate is too high.", "The picture size is too large.", "The picture width/height is too large.", "The luma sample rate is too large.", "The CPB size is too large.", "The compression ratio is too small", "Too many column tiles are used.", "The alt-ref distance is too small.",Lines 1–500 of 8268. Load more
/* * 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 <limits.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #include "./vp9_rtcd.h" #include "./vpx_config.h" #include "./vpx_dsp_rtcd.h" #include "./vpx_scale_rtcd.h" #include "vpx_dsp/psnr.h" #include "vpx_dsp/vpx_dsp_common.h" #include "vpx_dsp/vpx_filter.h" #if CONFIG_INTERNAL_STATS #include "vpx_dsp/ssim.h" #endif #include "vpx_ports/mem.h" #include "vpx_ports/system_state.h" #include "vpx_ports/vpx_timer.h" #if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG #include "vpx_util/vpx_debug_util.h" #endif // CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG #include "vp9/common/vp9_alloccommon.h" #include "vp9/common/vp9_filter.h" #include "vp9/common/vp9_idct.h" #if CONFIG_NON_GREEDY_MV #include "vp9/common/vp9_mvref_common.h" #endif #if CONFIG_VP9_POSTPROC #include "vp9/common/vp9_postproc.h" #endif #include "vp9/common/vp9_reconinter.h" #include "vp9/common/vp9_reconintra.h" #include "vp9/common/vp9_tile_common.h" #include "vp9/common/vp9_scan.h" #if !CONFIG_REALTIME_ONLY #include "vp9/encoder/vp9_alt_ref_aq.h" #include "vp9/encoder/vp9_aq_360.h" #include "vp9/encoder/vp9_aq_complexity.h" #endif #include "vp9/encoder/vp9_aq_cyclicrefresh.h" #if !CONFIG_REALTIME_ONLY #include "vp9/encoder/vp9_aq_variance.h" #endif #include "vp9/encoder/vp9_bitstream.h" #if CONFIG_INTERNAL_STATS #include "vp9/encoder/vp9_blockiness.h" #endif #include "vp9/encoder/vp9_context_tree.h" #include "vp9/encoder/vp9_encodeframe.h" #include "vp9/encoder/vp9_encodemb.h" #include "vp9/encoder/vp9_encodemv.h" #include "vp9/encoder/vp9_encoder.h" #include "vp9/encoder/vp9_ethread.h" #include "vp9/encoder/vp9_extend.h" #include "vp9/encoder/vp9_firstpass.h" #include "vp9/encoder/vp9_mbgraph.h" #if CONFIG_NON_GREEDY_MV #include "vp9/encoder/vp9_mcomp.h" #endif #include "vp9/encoder/vp9_multi_thread.h" #include "vp9/encoder/vp9_noise_estimate.h" #include "vp9/encoder/vp9_picklpf.h" #include "vp9/encoder/vp9_ratectrl.h" #include "vp9/encoder/vp9_rd.h" #include "vp9/encoder/vp9_resize.h" #include "vp9/encoder/vp9_segmentation.h" #include "vp9/encoder/vp9_skin_detection.h" #include "vp9/encoder/vp9_speed_features.h" #include "vp9/encoder/vp9_svc_layercontext.h" #include "vp9/encoder/vp9_temporal_filter.h" #include "vp9/vp9_cx_iface.h" #define AM_SEGMENT_ID_INACTIVE 7 #define AM_SEGMENT_ID_ACTIVE 0 // Whether to use high precision mv for altref computation. #define ALTREF_HIGH_PRECISION_MV 1 // Q threshold for high precision mv. Choose a very high value for now so that // HIGH_PRECISION is always chosen. #define HIGH_PRECISION_MV_QTHRESH 200 #define FRAME_SIZE_FACTOR 128 // empirical params for context model threshold #define FRAME_RATE_FACTOR 8 #ifdef OUTPUT_YUV_DENOISED FILE *yuv_denoised_file = NULL; #endif #ifdef OUTPUT_YUV_SKINMAP static FILE *yuv_skinmap_file = NULL; #endif #ifdef OUTPUT_YUV_REC FILE *yuv_rec_file; #endif #ifdef OUTPUT_YUV_SVC_SRC FILE *yuv_svc_src[3] = { NULL, NULL, NULL }; #endif #if 0 FILE *framepsnr; FILE *kf_list; FILE *keyfile; #endif #ifdef ENABLE_KF_DENOISE // Test condition for spatial denoise of source. static int is_spatial_denoise_enabled(VP9_COMP *cpi) { VP9_COMMON *const cm = &cpi->common; const VP9EncoderConfig *const oxcf = &cpi->oxcf; return (oxcf->pass != 1) && !is_lossless_requested(&cpi->oxcf) && frame_is_intra_only(cm); } #endif #if CONFIG_VP9_HIGHBITDEPTH void highbd_wht_fwd_txfm(int16_t *src_diff, int bw, tran_low_t *coeff, TX_SIZE tx_size); #endif void wht_fwd_txfm(int16_t *src_diff, int bw, tran_low_t *coeff, TX_SIZE tx_size); #if !CONFIG_REALTIME_ONLY // compute adaptive threshold for skip recoding static int compute_context_model_thresh(const VP9_COMP *const cpi) { const VP9_COMMON *const cm = &cpi->common; const VP9EncoderConfig *const oxcf = &cpi->oxcf; const int frame_size = (cm->width * cm->height) >> 10; const int bitrate = (int)(oxcf->target_bandwidth >> 10); const int qindex_factor = cm->base_qindex + (MAXQ >> 1); // This equation makes the threshold adaptive to frame size. // Coding gain obtained by recoding comes from alternate frames of large // content change. We skip recoding if the difference of previous and current // frame context probability model is less than a certain threshold. // The first component is the most critical part to guarantee adaptivity. // Other parameters are estimated based on normal setting of hd resolution // parameters. e.g frame_size = 1920x1080, bitrate = 8000, qindex_factor < 50 const int thresh = ((FRAME_SIZE_FACTOR * frame_size - FRAME_RATE_FACTOR * bitrate) * qindex_factor) >> 9; return thresh; } // compute the total cost difference between current // and previous frame context prob model. static int compute_context_model_diff(const VP9_COMMON *const cm) { const FRAME_CONTEXT *const pre_fc = &cm->frame_contexts[cm->frame_context_idx]; const FRAME_CONTEXT *const cur_fc = cm->fc; const FRAME_COUNTS *counts = &cm->counts; vpx_prob pre_last_prob, cur_last_prob; int diff = 0; int i, j, k, l, m, n; // y_mode_prob for (i = 0; i < BLOCK_SIZE_GROUPS; ++i) { for (j = 0; j < INTRA_MODES - 1; ++j) { diff += (int)counts->y_mode[i][j] * (pre_fc->y_mode_prob[i][j] - cur_fc->y_mode_prob[i][j]); } pre_last_prob = MAX_PROB - pre_fc->y_mode_prob[i][INTRA_MODES - 2]; cur_last_prob = MAX_PROB - cur_fc->y_mode_prob[i][INTRA_MODES - 2]; diff += (int)counts->y_mode[i][INTRA_MODES - 1] * (pre_last_prob - cur_last_prob); } // uv_mode_prob for (i = 0; i < INTRA_MODES; ++i) { for (j = 0; j < INTRA_MODES - 1; ++j) { diff += (int)counts->uv_mode[i][j] * (pre_fc->uv_mode_prob[i][j] - cur_fc->uv_mode_prob[i][j]); } pre_last_prob = MAX_PROB - pre_fc->uv_mode_prob[i][INTRA_MODES - 2]; cur_last_prob = MAX_PROB - cur_fc->uv_mode_prob[i][INTRA_MODES - 2]; diff += (int)counts->uv_mode[i][INTRA_MODES - 1] * (pre_last_prob - cur_last_prob); } // partition_prob for (i = 0; i < PARTITION_CONTEXTS; ++i) { for (j = 0; j < PARTITION_TYPES - 1; ++j) { diff += (int)counts->partition[i][j] * (pre_fc->partition_prob[i][j] - cur_fc->partition_prob[i][j]); } pre_last_prob = MAX_PROB - pre_fc->partition_prob[i][PARTITION_TYPES - 2]; cur_last_prob = MAX_PROB - cur_fc->partition_prob[i][PARTITION_TYPES - 2]; diff += (int)counts->partition[i][PARTITION_TYPES - 1] * (pre_last_prob - cur_last_prob); } // coef_probs for (i = 0; i < TX_SIZES; ++i) { for (j = 0; j < PLANE_TYPES; ++j) { for (k = 0; k < REF_TYPES; ++k) { for (l = 0; l < COEF_BANDS; ++l) { for (m = 0; m < BAND_COEFF_CONTEXTS(l); ++m) { for (n = 0; n < UNCONSTRAINED_NODES; ++n) { diff += (int)counts->coef[i][j][k][l][m][n] * (pre_fc->coef_probs[i][j][k][l][m][n] - cur_fc->coef_probs[i][j][k][l][m][n]); } pre_last_prob = MAX_PROB - pre_fc->coef_probs[i][j][k][l][m][UNCONSTRAINED_NODES - 1]; cur_last_prob = MAX_PROB - cur_fc->coef_probs[i][j][k][l][m][UNCONSTRAINED_NODES - 1]; diff += (int)counts->coef[i][j][k][l][m][UNCONSTRAINED_NODES] * (pre_last_prob - cur_last_prob); } } } } } // switchable_interp_prob for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) { for (j = 0; j < SWITCHABLE_FILTERS - 1; ++j) { diff += (int)counts->switchable_interp[i][j] * (pre_fc->switchable_interp_prob[i][j] - cur_fc->switchable_interp_prob[i][j]); } pre_last_prob = MAX_PROB - pre_fc->switchable_interp_prob[i][SWITCHABLE_FILTERS - 2]; cur_last_prob = MAX_PROB - cur_fc->switchable_interp_prob[i][SWITCHABLE_FILTERS - 2]; diff += (int)counts->switchable_interp[i][SWITCHABLE_FILTERS - 1] * (pre_last_prob - cur_last_prob); } // inter_mode_probs for (i = 0; i < INTER_MODE_CONTEXTS; ++i) { for (j = 0; j < INTER_MODES - 1; ++j) { diff += (int)counts->inter_mode[i][j] * (pre_fc->inter_mode_probs[i][j] - cur_fc->inter_mode_probs[i][j]); } pre_last_prob = MAX_PROB - pre_fc->inter_mode_probs[i][INTER_MODES - 2]; cur_last_prob = MAX_PROB - cur_fc->inter_mode_probs[i][INTER_MODES - 2]; diff += (int)counts->inter_mode[i][INTER_MODES - 1] * (pre_last_prob - cur_last_prob); } // intra_inter_prob for (i = 0; i < INTRA_INTER_CONTEXTS; ++i) { diff += (int)counts->intra_inter[i][0] * (pre_fc->intra_inter_prob[i] - cur_fc->intra_inter_prob[i]); pre_last_prob = MAX_PROB - pre_fc->intra_inter_prob[i]; cur_last_prob = MAX_PROB - cur_fc->intra_inter_prob[i]; diff += (int)counts->intra_inter[i][1] * (pre_last_prob - cur_last_prob); } // comp_inter_prob for (i = 0; i < COMP_INTER_CONTEXTS; ++i) { diff += (int)counts->comp_inter[i][0] * (pre_fc->comp_inter_prob[i] - cur_fc->comp_inter_prob[i]); pre_last_prob = MAX_PROB - pre_fc->comp_inter_prob[i]; cur_last_prob = MAX_PROB - cur_fc->comp_inter_prob[i]; diff += (int)counts->comp_inter[i][1] * (pre_last_prob - cur_last_prob); } // single_ref_prob for (i = 0; i < REF_CONTEXTS; ++i) { for (j = 0; j < 2; ++j) { diff += (int)counts->single_ref[i][j][0] * (pre_fc->single_ref_prob[i][j] - cur_fc->single_ref_prob[i][j]); pre_last_prob = MAX_PROB - pre_fc->single_ref_prob[i][j]; cur_last_prob = MAX_PROB - cur_fc->single_ref_prob[i][j]; diff += (int)counts->single_ref[i][j][1] * (pre_last_prob - cur_last_prob); } } // comp_ref_prob for (i = 0; i < REF_CONTEXTS; ++i) { diff += (int)counts->comp_ref[i][0] * (pre_fc->comp_ref_prob[i] - cur_fc->comp_ref_prob[i]); pre_last_prob = MAX_PROB - pre_fc->comp_ref_prob[i]; cur_last_prob = MAX_PROB - cur_fc->comp_ref_prob[i]; diff += (int)counts->comp_ref[i][1] * (pre_last_prob - cur_last_prob); } // tx_probs for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { // p32x32 for (j = 0; j < TX_SIZES - 1; ++j) { diff += (int)counts->tx.p32x32[i][j] * (pre_fc->tx_probs.p32x32[i][j] - cur_fc->tx_probs.p32x32[i][j]); } pre_last_prob = MAX_PROB - pre_fc->tx_probs.p32x32[i][TX_SIZES - 2]; cur_last_prob = MAX_PROB - cur_fc->tx_probs.p32x32[i][TX_SIZES - 2]; diff += (int)counts->tx.p32x32[i][TX_SIZES - 1] * (pre_last_prob - cur_last_prob); // p16x16 for (j = 0; j < TX_SIZES - 2; ++j) { diff += (int)counts->tx.p16x16[i][j] * (pre_fc->tx_probs.p16x16[i][j] - cur_fc->tx_probs.p16x16[i][j]); } pre_last_prob = MAX_PROB - pre_fc->tx_probs.p16x16[i][TX_SIZES - 3]; cur_last_prob = MAX_PROB - cur_fc->tx_probs.p16x16[i][TX_SIZES - 3]; diff += (int)counts->tx.p16x16[i][TX_SIZES - 2] * (pre_last_prob - cur_last_prob); // p8x8 for (j = 0; j < TX_SIZES - 3; ++j) { diff += (int)counts->tx.p8x8[i][j] * (pre_fc->tx_probs.p8x8[i][j] - cur_fc->tx_probs.p8x8[i][j]); } pre_last_prob = MAX_PROB - pre_fc->tx_probs.p8x8[i][TX_SIZES - 4]; cur_last_prob = MAX_PROB - cur_fc->tx_probs.p8x8[i][TX_SIZES - 4]; diff += (int)counts->tx.p8x8[i][TX_SIZES - 3] * (pre_last_prob - cur_last_prob); } // skip_probs for (i = 0; i < SKIP_CONTEXTS; ++i) { diff += (int)counts->skip[i][0] * (pre_fc->skip_probs[i] - cur_fc->skip_probs[i]); pre_last_prob = MAX_PROB - pre_fc->skip_probs[i]; cur_last_prob = MAX_PROB - cur_fc->skip_probs[i]; diff += (int)counts->skip[i][1] * (pre_last_prob - cur_last_prob); } // mv for (i = 0; i < MV_JOINTS - 1; ++i) { diff += (int)counts->mv.joints[i] * (pre_fc->nmvc.joints[i] - cur_fc->nmvc.joints[i]); } pre_last_prob = MAX_PROB - pre_fc->nmvc.joints[MV_JOINTS - 2]; cur_last_prob = MAX_PROB - cur_fc->nmvc.joints[MV_JOINTS - 2]; diff += (int)counts->mv.joints[MV_JOINTS - 1] * (pre_last_prob - cur_last_prob); for (i = 0; i < 2; ++i) { const nmv_component_counts *nmv_count = &counts->mv.comps[i]; const nmv_component *pre_nmv_prob = &pre_fc->nmvc.comps[i]; const nmv_component *cur_nmv_prob = &cur_fc->nmvc.comps[i]; // sign diff += (int)nmv_count->sign[0] * (pre_nmv_prob->sign - cur_nmv_prob->sign); pre_last_prob = MAX_PROB - pre_nmv_prob->sign; cur_last_prob = MAX_PROB - cur_nmv_prob->sign; diff += (int)nmv_count->sign[1] * (pre_last_prob - cur_last_prob); // classes for (j = 0; j < MV_CLASSES - 1; ++j) { diff += (int)nmv_count->classes[j] * (pre_nmv_prob->classes[j] - cur_nmv_prob->classes[j]); } pre_last_prob = MAX_PROB - pre_nmv_prob->classes[MV_CLASSES - 2]; cur_last_prob = MAX_PROB - cur_nmv_prob->classes[MV_CLASSES - 2]; diff += (int)nmv_count->classes[MV_CLASSES - 1] * (pre_last_prob - cur_last_prob); // class0 for (j = 0; j < CLASS0_SIZE - 1; ++j) { diff += (int)nmv_count->class0[j] * (pre_nmv_prob->class0[j] - cur_nmv_prob->class0[j]); } pre_last_prob = MAX_PROB - pre_nmv_prob->class0[CLASS0_SIZE - 2]; cur_last_prob = MAX_PROB - cur_nmv_prob->class0[CLASS0_SIZE - 2]; diff += (int)nmv_count->class0[CLASS0_SIZE - 1] * (pre_last_prob - cur_last_prob); // bits for (j = 0; j < MV_OFFSET_BITS; ++j) { diff += (int)nmv_count->bits[j][0] * (pre_nmv_prob->bits[j] - cur_nmv_prob->bits[j]); pre_last_prob = MAX_PROB - pre_nmv_prob->bits[j]; cur_last_prob = MAX_PROB - cur_nmv_prob->bits[j]; diff += (int)nmv_count->bits[j][1] * (pre_last_prob - cur_last_prob); } // class0_fp for (j = 0; j < CLASS0_SIZE; ++j) { for (k = 0; k < MV_FP_SIZE - 1; ++k) { diff += (int)nmv_count->class0_fp[j][k] * (pre_nmv_prob->class0_fp[j][k] - cur_nmv_prob->class0_fp[j][k]); } pre_last_prob = MAX_PROB - pre_nmv_prob->class0_fp[j][MV_FP_SIZE - 2]; cur_last_prob = MAX_PROB - cur_nmv_prob->class0_fp[j][MV_FP_SIZE - 2]; diff += (int)nmv_count->class0_fp[j][MV_FP_SIZE - 1] * (pre_last_prob - cur_last_prob); } // fp for (j = 0; j < MV_FP_SIZE - 1; ++j) { diff += (int)nmv_count->fp[j] * (pre_nmv_prob->fp[j] - cur_nmv_prob->fp[j]); } pre_last_prob = MAX_PROB - pre_nmv_prob->fp[MV_FP_SIZE - 2]; cur_last_prob = MAX_PROB - cur_nmv_prob->fp[MV_FP_SIZE - 2]; diff += (int)nmv_count->fp[MV_FP_SIZE - 1] * (pre_last_prob - cur_last_prob); // class0_hp diff += (int)nmv_count->class0_hp[0] * (pre_nmv_prob->class0_hp - cur_nmv_prob->class0_hp); pre_last_prob = MAX_PROB - pre_nmv_prob->class0_hp; cur_last_prob = MAX_PROB - cur_nmv_prob->class0_hp; diff += (int)nmv_count->class0_hp[1] * (pre_last_prob - cur_last_prob); // hp diff += (int)nmv_count->hp[0] * (pre_nmv_prob->hp - cur_nmv_prob->hp); pre_last_prob = MAX_PROB - pre_nmv_prob->hp; cur_last_prob = MAX_PROB - cur_nmv_prob->hp; diff += (int)nmv_count->hp[1] * (pre_last_prob - cur_last_prob); } return -diff; } #endif // !CONFIG_REALTIME_ONLY // Test for whether to calculate metrics for the frame. static int is_psnr_calc_enabled(const VP9_COMP *cpi) { const VP9_COMMON *const cm = &cpi->common; const VP9EncoderConfig *const oxcf = &cpi->oxcf; return cpi->b_calculate_psnr && (oxcf->pass != 1) && cm->show_frame; } /* clang-format off */ const Vp9LevelSpec vp9_level_defs[VP9_LEVELS] = { // sample rate size breadth bitrate cpb { LEVEL_1, 829440, 36864, 512, 200, 400, 2, 1, 4, 8 }, { LEVEL_1_1, 2764800, 73728, 768, 800, 1000, 2, 1, 4, 8 }, { LEVEL_2, 4608000, 122880, 960, 1800, 1500, 2, 1, 4, 8 }, { LEVEL_2_1, 9216000, 245760, 1344, 3600, 2800, 2, 2, 4, 8 }, { LEVEL_3, 20736000, 552960, 2048, 7200, 6000, 2, 4, 4, 8 }, { LEVEL_3_1, 36864000, 983040, 2752, 12000, 10000, 2, 4, 4, 8 }, { LEVEL_4, 83558400, 2228224, 4160, 18000, 16000, 4, 4, 4, 8 }, { LEVEL_4_1, 160432128, 2228224, 4160, 30000, 18000, 4, 4, 5, 6 }, { LEVEL_5, 311951360, 8912896, 8384, 60000, 36000, 6, 8, 6, 4 }, { LEVEL_5_1, 588251136, 8912896, 8384, 120000, 46000, 8, 8, 10, 4 }, // TODO(huisu): update max_cpb_size for level 5_2 ~ 6_2 when // they are finalized (currently tentative). { LEVEL_5_2, 1176502272, 8912896, 8384, 180000, 90000, 8, 8, 10, 4 }, { LEVEL_6, 1176502272, 35651584, 16832, 180000, 90000, 8, 16, 10, 4 }, { LEVEL_6_1, 2353004544u, 35651584, 16832, 240000, 180000, 8, 16, 10, 4 }, { LEVEL_6_2, 4706009088u, 35651584, 16832, 480000, 360000, 8, 16, 10, 4 }, }; /* clang-format on */ static const char *level_fail_messages[TARGET_LEVEL_FAIL_IDS] = { "The average bit-rate is too high.", "The picture size is too large.", "The picture width/height is too large.", "The luma sample rate is too large.", "The CPB size is too large.", "The compression ratio is too small", "Too many column tiles are used.", "The alt-ref distance is too small.",