8268 lines · 294.4 KB · C
RawDownload
/* * 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.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t