1559 lines · 56.2 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 <stdlib.h>#include <stdio.h>#include <string.h>#include <limits.h>#include <assert.h> #include "math.h"#include "vp8/common/common.h"#include "ratectrl.h"#include "vp8/common/entropymode.h"#include "vpx_mem/vpx_mem.h"#include "vp8/common/systemdependent.h"#include "encodemv.h"#include "vpx_dsp/vpx_dsp_common.h"#include "vpx_ports/system_state.h" #define MIN_BPB_FACTOR 0.01#define MAX_BPB_FACTOR 50 extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES]; #ifdef MODE_STATSextern int y_modes[5];extern int uv_modes[4];extern int b_modes[10]; extern int inter_y_modes[10];extern int inter_uv_modes[4];extern int inter_b_modes[10];#endif /* Bits Per MB at different Q (Multiplied by 512) */#define BPER_MB_NORMBITS 9 /* Work in progress recalibration of baseline rate tables based on * the assumption that bits per mb is inversely proportional to the * quantizer value. */const int vp8_bits_per_mb[2][QINDEX_RANGE] = {  /* Intra case 450000/Qintra */  {      1125000, 900000, 750000, 642857, 562500, 500000, 450000, 450000, 409090,      375000,  346153, 321428, 300000, 281250, 264705, 264705, 250000, 236842,      225000,  225000, 214285, 214285, 204545, 204545, 195652, 195652, 187500,      180000,  180000, 173076, 166666, 160714, 155172, 150000, 145161, 140625,      136363,  132352, 128571, 125000, 121621, 121621, 118421, 115384, 112500,      109756,  107142, 104651, 102272, 100000, 97826,  97826,  95744,  93750,      91836,   90000,  88235,  86538,  84905,  83333,  81818,  80357,  78947,      77586,   76271,  75000,  73770,  72580,  71428,  70312,  69230,  68181,      67164,   66176,  65217,  64285,  63380,  62500,  61643,  60810,  60000,      59210,   59210,  58441,  57692,  56962,  56250,  55555,  54878,  54216,      53571,   52941,  52325,  51724,  51136,  50561,  49450,  48387,  47368,      46875,   45918,  45000,  44554,  44117,  43269,  42452,  41666,  40909,      40178,   39473,  38793,  38135,  36885,  36290,  35714,  35156,  34615,      34090,   33582,  33088,  32608,  32142,  31468,  31034,  30405,  29801,      29220,   28662,  },  /* Inter case 285000/Qinter */  {      712500, 570000, 475000, 407142, 356250, 316666, 285000, 259090, 237500,      219230, 203571, 190000, 178125, 167647, 158333, 150000, 142500, 135714,      129545, 123913, 118750, 114000, 109615, 105555, 101785, 98275,  95000,      91935,  89062,  86363,  83823,  81428,  79166,  77027,  75000,  73076,      71250,  69512,  67857,  66279,  64772,  63333,  61956,  60638,  59375,      58163,  57000,  55882,  54807,  53773,  52777,  51818,  50892,  50000,      49137,  47500,  45967,  44531,  43181,  41911,  40714,  39583,  38513,      37500,  36538,  35625,  34756,  33928,  33139,  32386,  31666,  30978,      30319,  29687,  29081,  28500,  27941,  27403,  26886,  26388,  25909,      25446,  25000,  24568,  23949,  23360,  22800,  22265,  21755,  21268,      20802,  20357,  19930,  19520,  19127,  18750,  18387,  18037,  17701,      17378,  17065,  16764,  16473,  16101,  15745,  15405,  15079,  14766,      14467,  14179,  13902,  13636,  13380,  13133,  12895,  12666,  12445,      12179,  11924,  11632,  11445,  11220,  11003,  10795,  10594,  10401,      10215,  10035,  }}; static const int kf_boost_qadjustment[QINDEX_RANGE] = {  128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,  143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,  158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,  173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187,  188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 200, 201,  201, 202, 203, 203, 203, 204, 204, 205, 205, 206, 206, 207, 207, 208, 208,  209, 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216,  216, 217, 217, 218, 218, 219, 219, 220, 220, 220, 220, 220, 220, 220, 220,  220, 220, 220, 220, 220, 220, 220, 220,}; /* #define GFQ_ADJUSTMENT (Q+100) */#define GFQ_ADJUSTMENT vp8_gf_boost_qadjustment[Q]const int vp8_gf_boost_qadjustment[QINDEX_RANGE] = {  80,  82,  84,  86,  88,  90,  92,  94,  96,  97,  98,  99,  100, 101, 102,  103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,  118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,  133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147,  148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162,  163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177,  178, 179, 180, 181, 182, 183, 184, 184, 185, 185, 186, 186, 187, 187, 188,  188, 189, 189, 190, 190, 191, 191, 192, 192, 193, 193, 194, 194, 194, 194,  195, 195, 196, 196, 197, 197, 198, 198}; /*const int vp8_gf_boost_qadjustment[QINDEX_RANGE] ={    100,101,102,103,104,105,105,106,    106,107,107,108,109,109,110,111,    112,113,114,115,116,117,118,119,    120,121,122,123,124,125,126,127,    128,129,130,131,132,133,134,135,    136,137,138,139,140,141,142,143,    144,145,146,147,148,149,150,151,    152,153,154,155,156,157,158,159,    160,161,162,163,164,165,166,167,    168,169,170,170,171,171,172,172,    173,173,173,174,174,174,175,175,    175,176,176,176,177,177,177,177,    178,178,179,179,180,180,181,181,    182,182,183,183,184,184,185,185,    186,186,187,187,188,188,189,189,    190,190,191,191,192,192,193,193,};*/ static const int kf_gf_boost_qlimits[QINDEX_RANGE] = {  150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 205, 210, 215, 220,  225, 230, 235, 240, 245, 250, 255, 260, 265, 270, 275, 280, 285, 290, 295,  300, 305, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430,  440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570, 580,  590, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,  600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,  600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,  600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,  600, 600, 600, 600, 600, 600, 600, 600,}; static const int gf_adjust_table[101] = {  100, 115, 130, 145, 160, 175, 190, 200, 210, 220, 230, 240, 260, 270, 280,  290, 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 400, 400, 400,  400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,  400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,  400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,  400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,  400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,}; static const int gf_intra_usage_adjustment[20] = {  125, 120, 115, 110, 105, 100, 95, 85, 80, 75,  70,  65,  60,  55,  50,  50,  50, 50, 50, 50,}; static const int gf_interval_table[101] = {  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,  10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,}; static const unsigned int prior_key_frame_weight[KEY_FRAME_CONTEXT] = { 1, 2, 3,                                                                        4, 5 }; void vp8_save_coding_context(VP8_COMP *cpi) {  CODING_CONTEXT *const cc = &cpi->coding_context;   /* Stores a snapshot of key state variables which can subsequently be   * restored with a call to vp8_restore_coding_context. These functions are   * intended for use in a re-code loop in vp8_compress_frame where the   * quantizer value is adjusted between loop iterations.   */   cc->frames_since_key = cpi->frames_since_key;  cc->filter_level = cpi->common.filter_level;  cc->frames_till_gf_update_due = cpi->frames_till_gf_update_due;  cc->frames_since_golden = cpi->frames_since_golden;   vp8_copy(cc->mvc, cpi->common.fc.mvc);  vp8_copy(cc->mvcosts, cpi->rd_costs.mvcosts);   vp8_copy(cc->ymode_prob, cpi->common.fc.ymode_prob);  vp8_copy(cc->uv_mode_prob, cpi->common.fc.uv_mode_prob);   vp8_copy(cc->ymode_count, cpi->mb.ymode_count);  vp8_copy(cc->uv_mode_count, cpi->mb.uv_mode_count); /* Stats */#ifdef MODE_STATS  vp8_copy(cc->y_modes, y_modes);  vp8_copy(cc->uv_modes, uv_modes);  vp8_copy(cc->b_modes, b_modes);  vp8_copy(cc->inter_y_modes, inter_y_modes);  vp8_copy(cc->inter_uv_modes, inter_uv_modes);  vp8_copy(cc->inter_b_modes, inter_b_modes);#endif   cc->this_frame_percent_intra = cpi->this_frame_percent_intra;} void vp8_restore_coding_context(VP8_COMP *cpi) {  CODING_CONTEXT *const cc = &cpi->coding_context;   /* Restore key state variables to the snapshot state stored in the   * previous call to vp8_save_coding_context.   */   cpi->frames_since_key = cc->frames_since_key;  cpi->common.filter_level = cc->filter_level;  cpi->frames_till_gf_update_due = cc->frames_till_gf_update_due;  cpi->frames_since_golden = cc->frames_since_golden;   vp8_copy(cpi->common.fc.mvc, cc->mvc);   vp8_copy(cpi->rd_costs.mvcosts, cc->mvcosts);   vp8_copy(cpi->common.fc.ymode_prob, cc->ymode_prob);  vp8_copy(cpi->common.fc.uv_mode_prob, cc->uv_mode_prob);   vp8_copy(cpi->mb.ymode_count, cc->ymode_count);  vp8_copy(cpi->mb.uv_mode_count, cc->uv_mode_count); /* Stats */#ifdef MODE_STATS  vp8_copy(y_modes, cc->y_modes);  vp8_copy(uv_modes, cc->uv_modes);  vp8_copy(b_modes, cc->b_modes);  vp8_copy(inter_y_modes, cc->inter_y_modes);  vp8_copy(inter_uv_modes, cc->inter_uv_modes);  vp8_copy(inter_b_modes, cc->inter_b_modes);#endif   cpi->this_frame_percent_intra = cc->this_frame_percent_intra;} void vp8_setup_key_frame(VP8_COMP *cpi) {  /* Setup for Key frame: */   vp8_default_coef_probs(&cpi->common);   memcpy(cpi->common.fc.mvc, vp8_default_mv_context,         sizeof(vp8_default_mv_context));  {    int flag[2] = { 1, 1 };    vp8_build_component_cost_table(        cpi->mb.mvcost, (const MV_CONTEXT *)cpi->common.fc.mvc, flag);  }   /* Make sure we initialize separate contexts for altref,gold, and normal.   * TODO shouldn't need 3 different copies of structure to do this!   */  memcpy(&cpi->lfc_a, &cpi->common.fc, sizeof(cpi->common.fc));  memcpy(&cpi->lfc_g, &cpi->common.fc, sizeof(cpi->common.fc));  memcpy(&cpi->lfc_n, &cpi->common.fc, sizeof(cpi->common.fc));   cpi->common.filter_level = cpi->common.base_qindex * 3 / 8;   /* Provisional interval before next GF */  if (cpi->auto_gold) {    cpi->frames_till_gf_update_due = cpi->baseline_gf_interval;  } else {    cpi->frames_till_gf_update_due = DEFAULT_GF_INTERVAL;  }   cpi->common.refresh_golden_frame = 1;  cpi->common.refresh_alt_ref_frame = 1;} static int estimate_bits_at_q(int frame_kind, int Q, int MBs,                              double correction_factor) {  int Bpm = (int)(.5 + correction_factor * vp8_bits_per_mb[frame_kind][Q]);   /* Attempt to retain reasonable accuracy without overflow. The cutoff is   * chosen such that the maximum product of Bpm and MBs fits 31 bits. The   * largest Bpm takes 20 bits.   */  if (MBs > (1 << 11)) {    return (Bpm >> BPER_MB_NORMBITS) * MBs;  } else {    return (Bpm * MBs) >> BPER_MB_NORMBITS;  }} static void calc_iframe_target_size(VP8_COMP *cpi) {  /* boost defaults to half second */  int kf_boost;  uint64_t target;   /* Clear down mmx registers to allow floating point in what follows */  vpx_clear_system_state();   if (cpi->oxcf.fixed_q >= 0) {    int Q = cpi->oxcf.key_q;     target = estimate_bits_at_q(INTRA_FRAME, Q, cpi->common.MBs,                                cpi->key_frame_rate_correction_factor);  } else if (cpi->pass == 2) {    /* New Two pass RC */    target = cpi->per_frame_bandwidth;  }  /* First Frame is a special case */  else if (cpi->common.current_video_frame == 0) {    /* 1 Pass there is no information on which to base size so use     * bandwidth per second * fraction of the initial buffer     * level     */    target = cpi->oxcf.starting_buffer_level / 2;     if (target > cpi->oxcf.target_bandwidth * 3 / 2) {      target = cpi->oxcf.target_bandwidth * 3 / 2;    }  } else {    /* if this keyframe was forced, use a more recent Q estimate */    int Q = (cpi->common.frame_flags & FRAMEFLAGS_KEY) ? cpi->avg_frame_qindex                                                       : cpi->ni_av_qi;     int initial_boost = 32; /* |3.0 * per_frame_bandwidth| */    /* Boost depends somewhat on frame rate: only used for 1 layer case. */    if (cpi->oxcf.number_of_layers == 1) {      kf_boost = VPXMAX(initial_boost, (int)(2 * cpi->output_framerate - 16));    } else {      /* Initial factor: set target size to: |3.0 * per_frame_bandwidth|. */      kf_boost = initial_boost;    }     /* adjustment up based on q: this factor ranges from ~1.2 to 2.2. */    kf_boost = kf_boost * kf_boost_qadjustment[Q] / 100;     /* frame separation adjustment ( down) */    if (cpi->frames_since_key < cpi->output_framerate / 2) {      kf_boost =          (int)(kf_boost * cpi->frames_since_key / (cpi->output_framerate / 2));    }     /* Minimal target size is |2* per_frame_bandwidth|. */    if (kf_boost < 16) kf_boost = 16;     target = ((16 + kf_boost) * cpi->per_frame_bandwidth) >> 4;  }   if (cpi->oxcf.rc_max_intra_bitrate_pct) {    unsigned int max_rate =        cpi->per_frame_bandwidth * cpi->oxcf.rc_max_intra_bitrate_pct / 100;     if (target > max_rate) target = max_rate;  }   cpi->this_frame_target = (int)target;   /* TODO: if we separate rate targeting from Q targetting, move this.   * Reset the active worst quality to the baseline value for key frames.   */  if (cpi->pass != 2) cpi->active_worst_quality = cpi->worst_quality; #if 0    {        FILE *f;         f = fopen("kf_boost.stt", "a");        fprintf(f, " %8u %10d %10d %10d\n",                cpi->common.current_video_frame,  cpi->gfu_boost, cpi->baseline_gf_interval, cpi->source_alt_ref_pending);         fclose(f);    }#endif} /* Do the best we can to define the parameters for the next GF based on what * information we have available. */static void calc_gf_params(VP8_COMP *cpi) {  int Q =      (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;  int Boost = 0;   int gf_frame_useage = 0; /* Golden frame useage since last GF */  int tot_mbs = cpi->recent_ref_frame_usage[INTRA_FRAME] +                cpi->recent_ref_frame_usage[LAST_FRAME] +                cpi->recent_ref_frame_usage[GOLDEN_FRAME] +                cpi->recent_ref_frame_usage[ALTREF_FRAME];   int pct_gf_active = (100 * cpi->gf_active_count) /                      (cpi->common.mb_rows * cpi->common.mb_cols);   if (tot_mbs) {    gf_frame_useage = (cpi->recent_ref_frame_usage[GOLDEN_FRAME] +                       cpi->recent_ref_frame_usage[ALTREF_FRAME]) *                      100 / tot_mbs;  }   if (pct_gf_active > gf_frame_useage) gf_frame_useage = pct_gf_active;   /* Not two pass */  if (cpi->pass != 2) {    /* Single Pass lagged mode: TBD */    if (0) {    }     /* Single Pass compression: Has to use current and historical data */    else {#if 0            /* Experimental code */            int index = cpi->one_pass_frame_index;            int frames_to_scan = (cpi->max_gf_interval <= MAX_LAG_BUFFERS) ? cpi->max_gf_interval : MAX_LAG_BUFFERS;             /* ************** Experimental code - incomplete */            /*            double decay_val = 1.0;            double IIAccumulator = 0.0;            double last_iiaccumulator = 0.0;            double IIRatio;             cpi->one_pass_frame_index = cpi->common.current_video_frame%MAX_LAG_BUFFERS;             for ( i = 0; i < (frames_to_scan - 1); i++ )            {                if ( index < 0 )                    index = MAX_LAG_BUFFERS;                index --;                 if ( cpi->one_pass_frame_stats[index].frame_coded_error > 0.0 )                {                    IIRatio = cpi->one_pass_frame_stats[index].frame_intra_error / cpi->one_pass_frame_stats[index].frame_coded_error;                     if ( IIRatio > 30.0 )                        IIRatio = 30.0;                }                else                    IIRatio = 30.0;                 IIAccumulator += IIRatio * decay_val;                 decay_val = decay_val * cpi->one_pass_frame_stats[index].frame_pcnt_inter;                 if (    (i > MIN_GF_INTERVAL) &&                        ((IIAccumulator - last_iiaccumulator) < 2.0) )                {                    break;                }                last_iiaccumulator = IIAccumulator;            }             Boost = IIAccumulator*100.0/16.0;            cpi->baseline_gf_interval = i;             */#else       /*************************************************************/      /* OLD code */       /* Adjust boost based upon ambient Q */      Boost = GFQ_ADJUSTMENT;       /* Adjust based upon most recently measure intra useage */      Boost = Boost *              gf_intra_usage_adjustment[(cpi->this_frame_percent_intra < 15)                                            ? cpi->this_frame_percent_intra                                            : 14] /              100;       /* Adjust gf boost based upon GF usage since last GF */      Boost = Boost * gf_adjust_table[gf_frame_useage] / 100;#endif    }     /* golden frame boost without recode loop often goes awry.  be     * safe by keeping numbers down.     */    if (!cpi->sf.recode_loop) {      if (cpi->compressor_speed == 2) Boost = Boost / 2;    }     /* Apply an upper limit based on Q for 1 pass encodes */    if (Boost > kf_gf_boost_qlimits[Q] && (cpi->pass == 0)) {      Boost = kf_gf_boost_qlimits[Q];       /* Apply lower limits to boost. */    } else if (Boost < 110) {      Boost = 110;    }     /* Note the boost used */    cpi->last_boost = Boost;  }   /* Estimate next interval   * This is updated once the real frame size/boost is known.   */  if (cpi->oxcf.fixed_q == -1) {

Lines 1–500 of 1559.

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