Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
michael@0 | 3 | * |
michael@0 | 4 | * Use of this source code is governed by a BSD-style license |
michael@0 | 5 | * that can be found in the LICENSE file in the root of the source |
michael@0 | 6 | * tree. An additional intellectual property rights grant can be found |
michael@0 | 7 | * in the file PATENTS. All contributing project authors may |
michael@0 | 8 | * be found in the AUTHORS file in the root of the source tree. |
michael@0 | 9 | */ |
michael@0 | 10 | |
michael@0 | 11 | #include <math.h> |
michael@0 | 12 | #include <limits.h> |
michael@0 | 13 | #include <stdio.h> |
michael@0 | 14 | #include "vp9/encoder/vp9_block.h" |
michael@0 | 15 | #include "vp9/encoder/vp9_onyx_int.h" |
michael@0 | 16 | #include "vp9/encoder/vp9_variance.h" |
michael@0 | 17 | #include "vp9/encoder/vp9_encodeintra.h" |
michael@0 | 18 | #include "vp9/encoder/vp9_mcomp.h" |
michael@0 | 19 | #include "vp9/encoder/vp9_firstpass.h" |
michael@0 | 20 | #include "vpx_scale/vpx_scale.h" |
michael@0 | 21 | #include "vp9/encoder/vp9_encodeframe.h" |
michael@0 | 22 | #include "vp9/encoder/vp9_encodemb.h" |
michael@0 | 23 | #include "vp9/common/vp9_extend.h" |
michael@0 | 24 | #include "vp9/common/vp9_systemdependent.h" |
michael@0 | 25 | #include "vpx_mem/vpx_mem.h" |
michael@0 | 26 | #include "vpx_scale/yv12config.h" |
michael@0 | 27 | #include "vp9/encoder/vp9_quantize.h" |
michael@0 | 28 | #include "vp9/encoder/vp9_rdopt.h" |
michael@0 | 29 | #include "vp9/encoder/vp9_ratectrl.h" |
michael@0 | 30 | #include "vp9/common/vp9_quant_common.h" |
michael@0 | 31 | #include "vp9/common/vp9_entropymv.h" |
michael@0 | 32 | #include "vp9/encoder/vp9_encodemv.h" |
michael@0 | 33 | #include "vp9/encoder/vp9_vaq.h" |
michael@0 | 34 | #include "./vpx_scale_rtcd.h" |
michael@0 | 35 | // TODO(jkoleszar): for setup_dst_planes |
michael@0 | 36 | #include "vp9/common/vp9_reconinter.h" |
michael@0 | 37 | |
michael@0 | 38 | #define OUTPUT_FPF 0 |
michael@0 | 39 | |
michael@0 | 40 | #define IIFACTOR 12.5 |
michael@0 | 41 | #define IIKFACTOR1 12.5 |
michael@0 | 42 | #define IIKFACTOR2 15.0 |
michael@0 | 43 | #define RMAX 512.0 |
michael@0 | 44 | #define GF_RMAX 96.0 |
michael@0 | 45 | #define ERR_DIVISOR 150.0 |
michael@0 | 46 | #define MIN_DECAY_FACTOR 0.1 |
michael@0 | 47 | |
michael@0 | 48 | #define KF_MB_INTRA_MIN 150 |
michael@0 | 49 | #define GF_MB_INTRA_MIN 100 |
michael@0 | 50 | |
michael@0 | 51 | #define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x) - 0.000001 : (x) + 0.000001) |
michael@0 | 52 | |
michael@0 | 53 | #define POW1 (double)cpi->oxcf.two_pass_vbrbias/100.0 |
michael@0 | 54 | #define POW2 (double)cpi->oxcf.two_pass_vbrbias/100.0 |
michael@0 | 55 | |
michael@0 | 56 | static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) { |
michael@0 | 57 | YV12_BUFFER_CONFIG temp = *a; |
michael@0 | 58 | *a = *b; |
michael@0 | 59 | *b = temp; |
michael@0 | 60 | } |
michael@0 | 61 | |
michael@0 | 62 | static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame); |
michael@0 | 63 | |
michael@0 | 64 | static int select_cq_level(int qindex) { |
michael@0 | 65 | int ret_val = QINDEX_RANGE - 1; |
michael@0 | 66 | int i; |
michael@0 | 67 | |
michael@0 | 68 | double target_q = (vp9_convert_qindex_to_q(qindex) * 0.5847) + 1.0; |
michael@0 | 69 | |
michael@0 | 70 | for (i = 0; i < QINDEX_RANGE; i++) { |
michael@0 | 71 | if (target_q <= vp9_convert_qindex_to_q(i)) { |
michael@0 | 72 | ret_val = i; |
michael@0 | 73 | break; |
michael@0 | 74 | } |
michael@0 | 75 | } |
michael@0 | 76 | |
michael@0 | 77 | return ret_val; |
michael@0 | 78 | } |
michael@0 | 79 | |
michael@0 | 80 | |
michael@0 | 81 | // Resets the first pass file to the given position using a relative seek from |
michael@0 | 82 | // the current position. |
michael@0 | 83 | static void reset_fpf_position(VP9_COMP *cpi, FIRSTPASS_STATS *position) { |
michael@0 | 84 | cpi->twopass.stats_in = position; |
michael@0 | 85 | } |
michael@0 | 86 | |
michael@0 | 87 | static int lookup_next_frame_stats(VP9_COMP *cpi, FIRSTPASS_STATS *next_frame) { |
michael@0 | 88 | if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end) |
michael@0 | 89 | return EOF; |
michael@0 | 90 | |
michael@0 | 91 | *next_frame = *cpi->twopass.stats_in; |
michael@0 | 92 | return 1; |
michael@0 | 93 | } |
michael@0 | 94 | |
michael@0 | 95 | // Read frame stats at an offset from the current position |
michael@0 | 96 | static int read_frame_stats(VP9_COMP *cpi, |
michael@0 | 97 | FIRSTPASS_STATS *frame_stats, |
michael@0 | 98 | int offset) { |
michael@0 | 99 | FIRSTPASS_STATS *fps_ptr = cpi->twopass.stats_in; |
michael@0 | 100 | |
michael@0 | 101 | // Check legality of offset |
michael@0 | 102 | if (offset >= 0) { |
michael@0 | 103 | if (&fps_ptr[offset] >= cpi->twopass.stats_in_end) |
michael@0 | 104 | return EOF; |
michael@0 | 105 | } else if (offset < 0) { |
michael@0 | 106 | if (&fps_ptr[offset] < cpi->twopass.stats_in_start) |
michael@0 | 107 | return EOF; |
michael@0 | 108 | } |
michael@0 | 109 | |
michael@0 | 110 | *frame_stats = fps_ptr[offset]; |
michael@0 | 111 | return 1; |
michael@0 | 112 | } |
michael@0 | 113 | |
michael@0 | 114 | static int input_stats(VP9_COMP *cpi, FIRSTPASS_STATS *fps) { |
michael@0 | 115 | if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end) |
michael@0 | 116 | return EOF; |
michael@0 | 117 | |
michael@0 | 118 | *fps = *cpi->twopass.stats_in; |
michael@0 | 119 | cpi->twopass.stats_in = |
michael@0 | 120 | (void *)((char *)cpi->twopass.stats_in + sizeof(FIRSTPASS_STATS)); |
michael@0 | 121 | return 1; |
michael@0 | 122 | } |
michael@0 | 123 | |
michael@0 | 124 | static void output_stats(const VP9_COMP *cpi, |
michael@0 | 125 | struct vpx_codec_pkt_list *pktlist, |
michael@0 | 126 | FIRSTPASS_STATS *stats) { |
michael@0 | 127 | struct vpx_codec_cx_pkt pkt; |
michael@0 | 128 | pkt.kind = VPX_CODEC_STATS_PKT; |
michael@0 | 129 | pkt.data.twopass_stats.buf = stats; |
michael@0 | 130 | pkt.data.twopass_stats.sz = sizeof(FIRSTPASS_STATS); |
michael@0 | 131 | vpx_codec_pkt_list_add(pktlist, &pkt); |
michael@0 | 132 | |
michael@0 | 133 | // TEMP debug code |
michael@0 | 134 | #if OUTPUT_FPF |
michael@0 | 135 | |
michael@0 | 136 | { |
michael@0 | 137 | FILE *fpfile; |
michael@0 | 138 | fpfile = fopen("firstpass.stt", "a"); |
michael@0 | 139 | |
michael@0 | 140 | fprintf(stdout, "%12.0f %12.0f %12.0f %12.0f %12.0f %12.4f %12.4f" |
michael@0 | 141 | "%12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f" |
michael@0 | 142 | "%12.0f %12.0f %12.4f %12.0f %12.0f %12.4f\n", |
michael@0 | 143 | stats->frame, |
michael@0 | 144 | stats->intra_error, |
michael@0 | 145 | stats->coded_error, |
michael@0 | 146 | stats->sr_coded_error, |
michael@0 | 147 | stats->ssim_weighted_pred_err, |
michael@0 | 148 | stats->pcnt_inter, |
michael@0 | 149 | stats->pcnt_motion, |
michael@0 | 150 | stats->pcnt_second_ref, |
michael@0 | 151 | stats->pcnt_neutral, |
michael@0 | 152 | stats->MVr, |
michael@0 | 153 | stats->mvr_abs, |
michael@0 | 154 | stats->MVc, |
michael@0 | 155 | stats->mvc_abs, |
michael@0 | 156 | stats->MVrv, |
michael@0 | 157 | stats->MVcv, |
michael@0 | 158 | stats->mv_in_out_count, |
michael@0 | 159 | stats->new_mv_count, |
michael@0 | 160 | stats->count, |
michael@0 | 161 | stats->duration); |
michael@0 | 162 | fclose(fpfile); |
michael@0 | 163 | } |
michael@0 | 164 | #endif |
michael@0 | 165 | } |
michael@0 | 166 | |
michael@0 | 167 | static void zero_stats(FIRSTPASS_STATS *section) { |
michael@0 | 168 | section->frame = 0.0; |
michael@0 | 169 | section->intra_error = 0.0; |
michael@0 | 170 | section->coded_error = 0.0; |
michael@0 | 171 | section->sr_coded_error = 0.0; |
michael@0 | 172 | section->ssim_weighted_pred_err = 0.0; |
michael@0 | 173 | section->pcnt_inter = 0.0; |
michael@0 | 174 | section->pcnt_motion = 0.0; |
michael@0 | 175 | section->pcnt_second_ref = 0.0; |
michael@0 | 176 | section->pcnt_neutral = 0.0; |
michael@0 | 177 | section->MVr = 0.0; |
michael@0 | 178 | section->mvr_abs = 0.0; |
michael@0 | 179 | section->MVc = 0.0; |
michael@0 | 180 | section->mvc_abs = 0.0; |
michael@0 | 181 | section->MVrv = 0.0; |
michael@0 | 182 | section->MVcv = 0.0; |
michael@0 | 183 | section->mv_in_out_count = 0.0; |
michael@0 | 184 | section->new_mv_count = 0.0; |
michael@0 | 185 | section->count = 0.0; |
michael@0 | 186 | section->duration = 1.0; |
michael@0 | 187 | } |
michael@0 | 188 | |
michael@0 | 189 | static void accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame) { |
michael@0 | 190 | section->frame += frame->frame; |
michael@0 | 191 | section->intra_error += frame->intra_error; |
michael@0 | 192 | section->coded_error += frame->coded_error; |
michael@0 | 193 | section->sr_coded_error += frame->sr_coded_error; |
michael@0 | 194 | section->ssim_weighted_pred_err += frame->ssim_weighted_pred_err; |
michael@0 | 195 | section->pcnt_inter += frame->pcnt_inter; |
michael@0 | 196 | section->pcnt_motion += frame->pcnt_motion; |
michael@0 | 197 | section->pcnt_second_ref += frame->pcnt_second_ref; |
michael@0 | 198 | section->pcnt_neutral += frame->pcnt_neutral; |
michael@0 | 199 | section->MVr += frame->MVr; |
michael@0 | 200 | section->mvr_abs += frame->mvr_abs; |
michael@0 | 201 | section->MVc += frame->MVc; |
michael@0 | 202 | section->mvc_abs += frame->mvc_abs; |
michael@0 | 203 | section->MVrv += frame->MVrv; |
michael@0 | 204 | section->MVcv += frame->MVcv; |
michael@0 | 205 | section->mv_in_out_count += frame->mv_in_out_count; |
michael@0 | 206 | section->new_mv_count += frame->new_mv_count; |
michael@0 | 207 | section->count += frame->count; |
michael@0 | 208 | section->duration += frame->duration; |
michael@0 | 209 | } |
michael@0 | 210 | |
michael@0 | 211 | static void subtract_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame) { |
michael@0 | 212 | section->frame -= frame->frame; |
michael@0 | 213 | section->intra_error -= frame->intra_error; |
michael@0 | 214 | section->coded_error -= frame->coded_error; |
michael@0 | 215 | section->sr_coded_error -= frame->sr_coded_error; |
michael@0 | 216 | section->ssim_weighted_pred_err -= frame->ssim_weighted_pred_err; |
michael@0 | 217 | section->pcnt_inter -= frame->pcnt_inter; |
michael@0 | 218 | section->pcnt_motion -= frame->pcnt_motion; |
michael@0 | 219 | section->pcnt_second_ref -= frame->pcnt_second_ref; |
michael@0 | 220 | section->pcnt_neutral -= frame->pcnt_neutral; |
michael@0 | 221 | section->MVr -= frame->MVr; |
michael@0 | 222 | section->mvr_abs -= frame->mvr_abs; |
michael@0 | 223 | section->MVc -= frame->MVc; |
michael@0 | 224 | section->mvc_abs -= frame->mvc_abs; |
michael@0 | 225 | section->MVrv -= frame->MVrv; |
michael@0 | 226 | section->MVcv -= frame->MVcv; |
michael@0 | 227 | section->mv_in_out_count -= frame->mv_in_out_count; |
michael@0 | 228 | section->new_mv_count -= frame->new_mv_count; |
michael@0 | 229 | section->count -= frame->count; |
michael@0 | 230 | section->duration -= frame->duration; |
michael@0 | 231 | } |
michael@0 | 232 | |
michael@0 | 233 | static void avg_stats(FIRSTPASS_STATS *section) { |
michael@0 | 234 | if (section->count < 1.0) |
michael@0 | 235 | return; |
michael@0 | 236 | |
michael@0 | 237 | section->intra_error /= section->count; |
michael@0 | 238 | section->coded_error /= section->count; |
michael@0 | 239 | section->sr_coded_error /= section->count; |
michael@0 | 240 | section->ssim_weighted_pred_err /= section->count; |
michael@0 | 241 | section->pcnt_inter /= section->count; |
michael@0 | 242 | section->pcnt_second_ref /= section->count; |
michael@0 | 243 | section->pcnt_neutral /= section->count; |
michael@0 | 244 | section->pcnt_motion /= section->count; |
michael@0 | 245 | section->MVr /= section->count; |
michael@0 | 246 | section->mvr_abs /= section->count; |
michael@0 | 247 | section->MVc /= section->count; |
michael@0 | 248 | section->mvc_abs /= section->count; |
michael@0 | 249 | section->MVrv /= section->count; |
michael@0 | 250 | section->MVcv /= section->count; |
michael@0 | 251 | section->mv_in_out_count /= section->count; |
michael@0 | 252 | section->duration /= section->count; |
michael@0 | 253 | } |
michael@0 | 254 | |
michael@0 | 255 | // Calculate a modified Error used in distributing bits between easier and |
michael@0 | 256 | // harder frames. |
michael@0 | 257 | static double calculate_modified_err(VP9_COMP *cpi, |
michael@0 | 258 | FIRSTPASS_STATS *this_frame) { |
michael@0 | 259 | const FIRSTPASS_STATS *const stats = &cpi->twopass.total_stats; |
michael@0 | 260 | const double av_err = stats->ssim_weighted_pred_err / stats->count; |
michael@0 | 261 | const double this_err = this_frame->ssim_weighted_pred_err; |
michael@0 | 262 | return av_err * pow(this_err / DOUBLE_DIVIDE_CHECK(av_err), |
michael@0 | 263 | this_err > av_err ? POW1 : POW2); |
michael@0 | 264 | } |
michael@0 | 265 | |
michael@0 | 266 | static const double weight_table[256] = { |
michael@0 | 267 | 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, |
michael@0 | 268 | 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, |
michael@0 | 269 | 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, |
michael@0 | 270 | 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, |
michael@0 | 271 | 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.031250, 0.062500, |
michael@0 | 272 | 0.093750, 0.125000, 0.156250, 0.187500, 0.218750, 0.250000, 0.281250, |
michael@0 | 273 | 0.312500, 0.343750, 0.375000, 0.406250, 0.437500, 0.468750, 0.500000, |
michael@0 | 274 | 0.531250, 0.562500, 0.593750, 0.625000, 0.656250, 0.687500, 0.718750, |
michael@0 | 275 | 0.750000, 0.781250, 0.812500, 0.843750, 0.875000, 0.906250, 0.937500, |
michael@0 | 276 | 0.968750, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 277 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 278 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 279 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 280 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 281 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 282 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 283 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 284 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 285 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 286 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 287 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 288 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 289 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 290 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 291 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 292 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 293 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 294 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 295 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 296 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 297 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 298 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 299 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 300 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 301 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 302 | 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, |
michael@0 | 303 | 1.000000, 1.000000, 1.000000, 1.000000 |
michael@0 | 304 | }; |
michael@0 | 305 | |
michael@0 | 306 | static double simple_weight(YV12_BUFFER_CONFIG *source) { |
michael@0 | 307 | int i, j; |
michael@0 | 308 | |
michael@0 | 309 | uint8_t *src = source->y_buffer; |
michael@0 | 310 | double sum_weights = 0.0; |
michael@0 | 311 | |
michael@0 | 312 | // Loop through the Y plane examining levels and creating a weight for |
michael@0 | 313 | // the image. |
michael@0 | 314 | i = source->y_height; |
michael@0 | 315 | do { |
michael@0 | 316 | j = source->y_width; |
michael@0 | 317 | do { |
michael@0 | 318 | sum_weights += weight_table[ *src]; |
michael@0 | 319 | src++; |
michael@0 | 320 | } while (--j); |
michael@0 | 321 | src -= source->y_width; |
michael@0 | 322 | src += source->y_stride; |
michael@0 | 323 | } while (--i); |
michael@0 | 324 | |
michael@0 | 325 | sum_weights /= (source->y_height * source->y_width); |
michael@0 | 326 | |
michael@0 | 327 | return sum_weights; |
michael@0 | 328 | } |
michael@0 | 329 | |
michael@0 | 330 | |
michael@0 | 331 | // This function returns the current per frame maximum bitrate target. |
michael@0 | 332 | static int frame_max_bits(VP9_COMP *cpi) { |
michael@0 | 333 | // Max allocation for a single frame based on the max section guidelines |
michael@0 | 334 | // passed in and how many bits are left. |
michael@0 | 335 | // For VBR base this on the bits and frames left plus the |
michael@0 | 336 | // two_pass_vbrmax_section rate passed in by the user. |
michael@0 | 337 | const double max_bits = (1.0 * cpi->twopass.bits_left / |
michael@0 | 338 | (cpi->twopass.total_stats.count - cpi->common.current_video_frame)) * |
michael@0 | 339 | (cpi->oxcf.two_pass_vbrmax_section / 100.0); |
michael@0 | 340 | |
michael@0 | 341 | // Trap case where we are out of bits. |
michael@0 | 342 | return MAX((int)max_bits, 0); |
michael@0 | 343 | } |
michael@0 | 344 | |
michael@0 | 345 | void vp9_init_first_pass(VP9_COMP *cpi) { |
michael@0 | 346 | zero_stats(&cpi->twopass.total_stats); |
michael@0 | 347 | } |
michael@0 | 348 | |
michael@0 | 349 | void vp9_end_first_pass(VP9_COMP *cpi) { |
michael@0 | 350 | output_stats(cpi, cpi->output_pkt_list, &cpi->twopass.total_stats); |
michael@0 | 351 | } |
michael@0 | 352 | |
michael@0 | 353 | static void zz_motion_search(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 354 | YV12_BUFFER_CONFIG *recon_buffer, |
michael@0 | 355 | int *best_motion_err, int recon_yoffset) { |
michael@0 | 356 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 357 | |
michael@0 | 358 | // Set up pointers for this macro block recon buffer |
michael@0 | 359 | xd->plane[0].pre[0].buf = recon_buffer->y_buffer + recon_yoffset; |
michael@0 | 360 | |
michael@0 | 361 | switch (xd->mi_8x8[0]->mbmi.sb_type) { |
michael@0 | 362 | case BLOCK_8X8: |
michael@0 | 363 | vp9_mse8x8(x->plane[0].src.buf, x->plane[0].src.stride, |
michael@0 | 364 | xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride, |
michael@0 | 365 | (unsigned int *)(best_motion_err)); |
michael@0 | 366 | break; |
michael@0 | 367 | case BLOCK_16X8: |
michael@0 | 368 | vp9_mse16x8(x->plane[0].src.buf, x->plane[0].src.stride, |
michael@0 | 369 | xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride, |
michael@0 | 370 | (unsigned int *)(best_motion_err)); |
michael@0 | 371 | break; |
michael@0 | 372 | case BLOCK_8X16: |
michael@0 | 373 | vp9_mse8x16(x->plane[0].src.buf, x->plane[0].src.stride, |
michael@0 | 374 | xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride, |
michael@0 | 375 | (unsigned int *)(best_motion_err)); |
michael@0 | 376 | break; |
michael@0 | 377 | default: |
michael@0 | 378 | vp9_mse16x16(x->plane[0].src.buf, x->plane[0].src.stride, |
michael@0 | 379 | xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride, |
michael@0 | 380 | (unsigned int *)(best_motion_err)); |
michael@0 | 381 | break; |
michael@0 | 382 | } |
michael@0 | 383 | } |
michael@0 | 384 | |
michael@0 | 385 | static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 386 | int_mv *ref_mv, MV *best_mv, |
michael@0 | 387 | YV12_BUFFER_CONFIG *recon_buffer, |
michael@0 | 388 | int *best_motion_err, int recon_yoffset) { |
michael@0 | 389 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 390 | int num00; |
michael@0 | 391 | |
michael@0 | 392 | int_mv tmp_mv; |
michael@0 | 393 | int_mv ref_mv_full; |
michael@0 | 394 | |
michael@0 | 395 | int tmp_err; |
michael@0 | 396 | int step_param = 3; |
michael@0 | 397 | int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; |
michael@0 | 398 | int n; |
michael@0 | 399 | vp9_variance_fn_ptr_t v_fn_ptr = |
michael@0 | 400 | cpi->fn_ptr[xd->mi_8x8[0]->mbmi.sb_type]; |
michael@0 | 401 | int new_mv_mode_penalty = 256; |
michael@0 | 402 | |
michael@0 | 403 | int sr = 0; |
michael@0 | 404 | int quart_frm = MIN(cpi->common.width, cpi->common.height); |
michael@0 | 405 | |
michael@0 | 406 | // refine the motion search range accroding to the frame dimension |
michael@0 | 407 | // for first pass test |
michael@0 | 408 | while ((quart_frm << sr) < MAX_FULL_PEL_VAL) |
michael@0 | 409 | sr++; |
michael@0 | 410 | if (sr) |
michael@0 | 411 | sr--; |
michael@0 | 412 | |
michael@0 | 413 | step_param += sr; |
michael@0 | 414 | further_steps -= sr; |
michael@0 | 415 | |
michael@0 | 416 | // override the default variance function to use MSE |
michael@0 | 417 | switch (xd->mi_8x8[0]->mbmi.sb_type) { |
michael@0 | 418 | case BLOCK_8X8: |
michael@0 | 419 | v_fn_ptr.vf = vp9_mse8x8; |
michael@0 | 420 | break; |
michael@0 | 421 | case BLOCK_16X8: |
michael@0 | 422 | v_fn_ptr.vf = vp9_mse16x8; |
michael@0 | 423 | break; |
michael@0 | 424 | case BLOCK_8X16: |
michael@0 | 425 | v_fn_ptr.vf = vp9_mse8x16; |
michael@0 | 426 | break; |
michael@0 | 427 | default: |
michael@0 | 428 | v_fn_ptr.vf = vp9_mse16x16; |
michael@0 | 429 | break; |
michael@0 | 430 | } |
michael@0 | 431 | |
michael@0 | 432 | // Set up pointers for this macro block recon buffer |
michael@0 | 433 | xd->plane[0].pre[0].buf = recon_buffer->y_buffer + recon_yoffset; |
michael@0 | 434 | |
michael@0 | 435 | // Initial step/diamond search centred on best mv |
michael@0 | 436 | tmp_mv.as_int = 0; |
michael@0 | 437 | ref_mv_full.as_mv.col = ref_mv->as_mv.col >> 3; |
michael@0 | 438 | ref_mv_full.as_mv.row = ref_mv->as_mv.row >> 3; |
michael@0 | 439 | tmp_err = cpi->diamond_search_sad(x, &ref_mv_full, &tmp_mv, step_param, |
michael@0 | 440 | x->sadperbit16, &num00, &v_fn_ptr, |
michael@0 | 441 | x->nmvjointcost, |
michael@0 | 442 | x->mvcost, ref_mv); |
michael@0 | 443 | if (tmp_err < INT_MAX - new_mv_mode_penalty) |
michael@0 | 444 | tmp_err += new_mv_mode_penalty; |
michael@0 | 445 | |
michael@0 | 446 | if (tmp_err < *best_motion_err) { |
michael@0 | 447 | *best_motion_err = tmp_err; |
michael@0 | 448 | best_mv->row = tmp_mv.as_mv.row; |
michael@0 | 449 | best_mv->col = tmp_mv.as_mv.col; |
michael@0 | 450 | } |
michael@0 | 451 | |
michael@0 | 452 | // Further step/diamond searches as necessary |
michael@0 | 453 | n = num00; |
michael@0 | 454 | num00 = 0; |
michael@0 | 455 | |
michael@0 | 456 | while (n < further_steps) { |
michael@0 | 457 | n++; |
michael@0 | 458 | |
michael@0 | 459 | if (num00) { |
michael@0 | 460 | num00--; |
michael@0 | 461 | } else { |
michael@0 | 462 | tmp_err = cpi->diamond_search_sad(x, &ref_mv_full, &tmp_mv, |
michael@0 | 463 | step_param + n, x->sadperbit16, |
michael@0 | 464 | &num00, &v_fn_ptr, |
michael@0 | 465 | x->nmvjointcost, |
michael@0 | 466 | x->mvcost, ref_mv); |
michael@0 | 467 | if (tmp_err < INT_MAX - new_mv_mode_penalty) |
michael@0 | 468 | tmp_err += new_mv_mode_penalty; |
michael@0 | 469 | |
michael@0 | 470 | if (tmp_err < *best_motion_err) { |
michael@0 | 471 | *best_motion_err = tmp_err; |
michael@0 | 472 | best_mv->row = tmp_mv.as_mv.row; |
michael@0 | 473 | best_mv->col = tmp_mv.as_mv.col; |
michael@0 | 474 | } |
michael@0 | 475 | } |
michael@0 | 476 | } |
michael@0 | 477 | } |
michael@0 | 478 | |
michael@0 | 479 | void vp9_first_pass(VP9_COMP *cpi) { |
michael@0 | 480 | int mb_row, mb_col; |
michael@0 | 481 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 482 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 483 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 484 | TileInfo tile; |
michael@0 | 485 | struct macroblock_plane *const p = x->plane; |
michael@0 | 486 | struct macroblockd_plane *const pd = xd->plane; |
michael@0 | 487 | PICK_MODE_CONTEXT *ctx = &x->sb64_context; |
michael@0 | 488 | int i; |
michael@0 | 489 | |
michael@0 | 490 | int recon_yoffset, recon_uvoffset; |
michael@0 | 491 | const int lst_yv12_idx = cm->ref_frame_map[cpi->lst_fb_idx]; |
michael@0 | 492 | const int gld_yv12_idx = cm->ref_frame_map[cpi->gld_fb_idx]; |
michael@0 | 493 | YV12_BUFFER_CONFIG *const lst_yv12 = &cm->yv12_fb[lst_yv12_idx]; |
michael@0 | 494 | YV12_BUFFER_CONFIG *const gld_yv12 = &cm->yv12_fb[gld_yv12_idx]; |
michael@0 | 495 | YV12_BUFFER_CONFIG *const new_yv12 = get_frame_new_buffer(cm); |
michael@0 | 496 | const int recon_y_stride = lst_yv12->y_stride; |
michael@0 | 497 | const int recon_uv_stride = lst_yv12->uv_stride; |
michael@0 | 498 | int64_t intra_error = 0; |
michael@0 | 499 | int64_t coded_error = 0; |
michael@0 | 500 | int64_t sr_coded_error = 0; |
michael@0 | 501 | |
michael@0 | 502 | int sum_mvr = 0, sum_mvc = 0; |
michael@0 | 503 | int sum_mvr_abs = 0, sum_mvc_abs = 0; |
michael@0 | 504 | int sum_mvrs = 0, sum_mvcs = 0; |
michael@0 | 505 | int mvcount = 0; |
michael@0 | 506 | int intercount = 0; |
michael@0 | 507 | int second_ref_count = 0; |
michael@0 | 508 | int intrapenalty = 256; |
michael@0 | 509 | int neutral_count = 0; |
michael@0 | 510 | int new_mv_count = 0; |
michael@0 | 511 | int sum_in_vectors = 0; |
michael@0 | 512 | uint32_t lastmv_as_int = 0; |
michael@0 | 513 | |
michael@0 | 514 | int_mv zero_ref_mv; |
michael@0 | 515 | |
michael@0 | 516 | zero_ref_mv.as_int = 0; |
michael@0 | 517 | |
michael@0 | 518 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 519 | |
michael@0 | 520 | vp9_setup_src_planes(x, cpi->Source, 0, 0); |
michael@0 | 521 | setup_pre_planes(xd, 0, lst_yv12, 0, 0, NULL); |
michael@0 | 522 | setup_dst_planes(xd, new_yv12, 0, 0); |
michael@0 | 523 | |
michael@0 | 524 | xd->mi_8x8 = cm->mi_grid_visible; |
michael@0 | 525 | // required for vp9_frame_init_quantizer |
michael@0 | 526 | xd->mi_8x8[0] = cm->mi; |
michael@0 | 527 | |
michael@0 | 528 | setup_block_dptrs(&x->e_mbd, cm->subsampling_x, cm->subsampling_y); |
michael@0 | 529 | |
michael@0 | 530 | vp9_frame_init_quantizer(cpi); |
michael@0 | 531 | |
michael@0 | 532 | for (i = 0; i < MAX_MB_PLANE; ++i) { |
michael@0 | 533 | p[i].coeff = ctx->coeff_pbuf[i][1]; |
michael@0 | 534 | pd[i].qcoeff = ctx->qcoeff_pbuf[i][1]; |
michael@0 | 535 | pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1]; |
michael@0 | 536 | pd[i].eobs = ctx->eobs_pbuf[i][1]; |
michael@0 | 537 | } |
michael@0 | 538 | x->skip_recode = 0; |
michael@0 | 539 | |
michael@0 | 540 | |
michael@0 | 541 | // Initialise the MV cost table to the defaults |
michael@0 | 542 | // if( cm->current_video_frame == 0) |
michael@0 | 543 | // if ( 0 ) |
michael@0 | 544 | { |
michael@0 | 545 | vp9_init_mv_probs(cm); |
michael@0 | 546 | vp9_initialize_rd_consts(cpi); |
michael@0 | 547 | } |
michael@0 | 548 | |
michael@0 | 549 | // tiling is ignored in the first pass |
michael@0 | 550 | vp9_tile_init(&tile, cm, 0, 0); |
michael@0 | 551 | |
michael@0 | 552 | // for each macroblock row in image |
michael@0 | 553 | for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { |
michael@0 | 554 | int_mv best_ref_mv; |
michael@0 | 555 | |
michael@0 | 556 | best_ref_mv.as_int = 0; |
michael@0 | 557 | |
michael@0 | 558 | // reset above block coeffs |
michael@0 | 559 | xd->up_available = (mb_row != 0); |
michael@0 | 560 | recon_yoffset = (mb_row * recon_y_stride * 16); |
michael@0 | 561 | recon_uvoffset = (mb_row * recon_uv_stride * 8); |
michael@0 | 562 | |
michael@0 | 563 | // Set up limit values for motion vectors to prevent them extending |
michael@0 | 564 | // outside the UMV borders |
michael@0 | 565 | x->mv_row_min = -((mb_row * 16) + BORDER_MV_PIXELS_B16); |
michael@0 | 566 | x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16) |
michael@0 | 567 | + BORDER_MV_PIXELS_B16; |
michael@0 | 568 | |
michael@0 | 569 | // for each macroblock col in image |
michael@0 | 570 | for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { |
michael@0 | 571 | int this_error; |
michael@0 | 572 | int gf_motion_error = INT_MAX; |
michael@0 | 573 | int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row); |
michael@0 | 574 | double error_weight; |
michael@0 | 575 | |
michael@0 | 576 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 577 | error_weight = 1.0; // avoid uninitialized warnings |
michael@0 | 578 | |
michael@0 | 579 | xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset; |
michael@0 | 580 | xd->plane[1].dst.buf = new_yv12->u_buffer + recon_uvoffset; |
michael@0 | 581 | xd->plane[2].dst.buf = new_yv12->v_buffer + recon_uvoffset; |
michael@0 | 582 | xd->left_available = (mb_col != 0); |
michael@0 | 583 | |
michael@0 | 584 | if (mb_col * 2 + 1 < cm->mi_cols) { |
michael@0 | 585 | if (mb_row * 2 + 1 < cm->mi_rows) { |
michael@0 | 586 | xd->mi_8x8[0]->mbmi.sb_type = BLOCK_16X16; |
michael@0 | 587 | } else { |
michael@0 | 588 | xd->mi_8x8[0]->mbmi.sb_type = BLOCK_16X8; |
michael@0 | 589 | } |
michael@0 | 590 | } else { |
michael@0 | 591 | if (mb_row * 2 + 1 < cm->mi_rows) { |
michael@0 | 592 | xd->mi_8x8[0]->mbmi.sb_type = BLOCK_8X16; |
michael@0 | 593 | } else { |
michael@0 | 594 | xd->mi_8x8[0]->mbmi.sb_type = BLOCK_8X8; |
michael@0 | 595 | } |
michael@0 | 596 | } |
michael@0 | 597 | xd->mi_8x8[0]->mbmi.ref_frame[0] = INTRA_FRAME; |
michael@0 | 598 | set_mi_row_col(xd, &tile, |
michael@0 | 599 | mb_row << 1, |
michael@0 | 600 | num_8x8_blocks_high_lookup[xd->mi_8x8[0]->mbmi.sb_type], |
michael@0 | 601 | mb_col << 1, |
michael@0 | 602 | num_8x8_blocks_wide_lookup[xd->mi_8x8[0]->mbmi.sb_type], |
michael@0 | 603 | cm->mi_rows, cm->mi_cols); |
michael@0 | 604 | |
michael@0 | 605 | if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
michael@0 | 606 | int energy = vp9_block_energy(cpi, x, xd->mi_8x8[0]->mbmi.sb_type); |
michael@0 | 607 | error_weight = vp9_vaq_inv_q_ratio(energy); |
michael@0 | 608 | } |
michael@0 | 609 | |
michael@0 | 610 | // do intra 16x16 prediction |
michael@0 | 611 | this_error = vp9_encode_intra(x, use_dc_pred); |
michael@0 | 612 | if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
michael@0 | 613 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 614 | this_error *= error_weight; |
michael@0 | 615 | } |
michael@0 | 616 | |
michael@0 | 617 | // intrapenalty below deals with situations where the intra and inter |
michael@0 | 618 | // error scores are very low (eg a plain black frame). |
michael@0 | 619 | // We do not have special cases in first pass for 0,0 and nearest etc so |
michael@0 | 620 | // all inter modes carry an overhead cost estimate for the mv. |
michael@0 | 621 | // When the error score is very low this causes us to pick all or lots of |
michael@0 | 622 | // INTRA modes and throw lots of key frames. |
michael@0 | 623 | // This penalty adds a cost matching that of a 0,0 mv to the intra case. |
michael@0 | 624 | this_error += intrapenalty; |
michael@0 | 625 | |
michael@0 | 626 | // Cumulative intra error total |
michael@0 | 627 | intra_error += (int64_t)this_error; |
michael@0 | 628 | |
michael@0 | 629 | // Set up limit values for motion vectors to prevent them extending |
michael@0 | 630 | // outside the UMV borders. |
michael@0 | 631 | x->mv_col_min = -((mb_col * 16) + BORDER_MV_PIXELS_B16); |
michael@0 | 632 | x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) |
michael@0 | 633 | + BORDER_MV_PIXELS_B16; |
michael@0 | 634 | |
michael@0 | 635 | // Other than for the first frame do a motion search |
michael@0 | 636 | if (cm->current_video_frame > 0) { |
michael@0 | 637 | int tmp_err; |
michael@0 | 638 | int motion_error = INT_MAX; |
michael@0 | 639 | int_mv mv, tmp_mv; |
michael@0 | 640 | |
michael@0 | 641 | // Simple 0,0 motion with no mv overhead |
michael@0 | 642 | zz_motion_search(cpi, x, lst_yv12, &motion_error, recon_yoffset); |
michael@0 | 643 | mv.as_int = tmp_mv.as_int = 0; |
michael@0 | 644 | |
michael@0 | 645 | // Test last reference frame using the previous best mv as the |
michael@0 | 646 | // starting point (best reference) for the search |
michael@0 | 647 | first_pass_motion_search(cpi, x, &best_ref_mv, |
michael@0 | 648 | &mv.as_mv, lst_yv12, |
michael@0 | 649 | &motion_error, recon_yoffset); |
michael@0 | 650 | if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
michael@0 | 651 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 652 | motion_error *= error_weight; |
michael@0 | 653 | } |
michael@0 | 654 | |
michael@0 | 655 | // If the current best reference mv is not centered on 0,0 then do a 0,0 |
michael@0 | 656 | // based search as well. |
michael@0 | 657 | if (best_ref_mv.as_int) { |
michael@0 | 658 | tmp_err = INT_MAX; |
michael@0 | 659 | first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv.as_mv, |
michael@0 | 660 | lst_yv12, &tmp_err, recon_yoffset); |
michael@0 | 661 | if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
michael@0 | 662 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 663 | tmp_err *= error_weight; |
michael@0 | 664 | } |
michael@0 | 665 | |
michael@0 | 666 | if (tmp_err < motion_error) { |
michael@0 | 667 | motion_error = tmp_err; |
michael@0 | 668 | mv.as_int = tmp_mv.as_int; |
michael@0 | 669 | } |
michael@0 | 670 | } |
michael@0 | 671 | |
michael@0 | 672 | // Experimental search in an older reference frame |
michael@0 | 673 | if (cm->current_video_frame > 1) { |
michael@0 | 674 | // Simple 0,0 motion with no mv overhead |
michael@0 | 675 | zz_motion_search(cpi, x, gld_yv12, |
michael@0 | 676 | &gf_motion_error, recon_yoffset); |
michael@0 | 677 | |
michael@0 | 678 | first_pass_motion_search(cpi, x, &zero_ref_mv, |
michael@0 | 679 | &tmp_mv.as_mv, gld_yv12, |
michael@0 | 680 | &gf_motion_error, recon_yoffset); |
michael@0 | 681 | if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
michael@0 | 682 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 683 | gf_motion_error *= error_weight; |
michael@0 | 684 | } |
michael@0 | 685 | |
michael@0 | 686 | if ((gf_motion_error < motion_error) && |
michael@0 | 687 | (gf_motion_error < this_error)) { |
michael@0 | 688 | second_ref_count++; |
michael@0 | 689 | } |
michael@0 | 690 | |
michael@0 | 691 | // Reset to last frame as reference buffer |
michael@0 | 692 | xd->plane[0].pre[0].buf = lst_yv12->y_buffer + recon_yoffset; |
michael@0 | 693 | xd->plane[1].pre[0].buf = lst_yv12->u_buffer + recon_uvoffset; |
michael@0 | 694 | xd->plane[2].pre[0].buf = lst_yv12->v_buffer + recon_uvoffset; |
michael@0 | 695 | |
michael@0 | 696 | // In accumulating a score for the older reference frame |
michael@0 | 697 | // take the best of the motion predicted score and |
michael@0 | 698 | // the intra coded error (just as will be done for) |
michael@0 | 699 | // accumulation of "coded_error" for the last frame. |
michael@0 | 700 | if (gf_motion_error < this_error) |
michael@0 | 701 | sr_coded_error += gf_motion_error; |
michael@0 | 702 | else |
michael@0 | 703 | sr_coded_error += this_error; |
michael@0 | 704 | } else { |
michael@0 | 705 | sr_coded_error += motion_error; |
michael@0 | 706 | } |
michael@0 | 707 | /* Intra assumed best */ |
michael@0 | 708 | best_ref_mv.as_int = 0; |
michael@0 | 709 | |
michael@0 | 710 | if (motion_error <= this_error) { |
michael@0 | 711 | // Keep a count of cases where the inter and intra were |
michael@0 | 712 | // very close and very low. This helps with scene cut |
michael@0 | 713 | // detection for example in cropped clips with black bars |
michael@0 | 714 | // at the sides or top and bottom. |
michael@0 | 715 | if ((((this_error - intrapenalty) * 9) <= |
michael@0 | 716 | (motion_error * 10)) && |
michael@0 | 717 | (this_error < (2 * intrapenalty))) { |
michael@0 | 718 | neutral_count++; |
michael@0 | 719 | } |
michael@0 | 720 | |
michael@0 | 721 | mv.as_mv.row *= 8; |
michael@0 | 722 | mv.as_mv.col *= 8; |
michael@0 | 723 | this_error = motion_error; |
michael@0 | 724 | vp9_set_mbmode_and_mvs(x, NEWMV, &mv); |
michael@0 | 725 | xd->mi_8x8[0]->mbmi.tx_size = TX_4X4; |
michael@0 | 726 | xd->mi_8x8[0]->mbmi.ref_frame[0] = LAST_FRAME; |
michael@0 | 727 | xd->mi_8x8[0]->mbmi.ref_frame[1] = NONE; |
michael@0 | 728 | vp9_build_inter_predictors_sby(xd, mb_row << 1, |
michael@0 | 729 | mb_col << 1, |
michael@0 | 730 | xd->mi_8x8[0]->mbmi.sb_type); |
michael@0 | 731 | vp9_encode_sby(x, xd->mi_8x8[0]->mbmi.sb_type); |
michael@0 | 732 | sum_mvr += mv.as_mv.row; |
michael@0 | 733 | sum_mvr_abs += abs(mv.as_mv.row); |
michael@0 | 734 | sum_mvc += mv.as_mv.col; |
michael@0 | 735 | sum_mvc_abs += abs(mv.as_mv.col); |
michael@0 | 736 | sum_mvrs += mv.as_mv.row * mv.as_mv.row; |
michael@0 | 737 | sum_mvcs += mv.as_mv.col * mv.as_mv.col; |
michael@0 | 738 | intercount++; |
michael@0 | 739 | |
michael@0 | 740 | best_ref_mv.as_int = mv.as_int; |
michael@0 | 741 | |
michael@0 | 742 | // Was the vector non-zero |
michael@0 | 743 | if (mv.as_int) { |
michael@0 | 744 | mvcount++; |
michael@0 | 745 | |
michael@0 | 746 | // Was it different from the last non zero vector |
michael@0 | 747 | if (mv.as_int != lastmv_as_int) |
michael@0 | 748 | new_mv_count++; |
michael@0 | 749 | lastmv_as_int = mv.as_int; |
michael@0 | 750 | |
michael@0 | 751 | // Does the Row vector point inwards or outwards |
michael@0 | 752 | if (mb_row < cm->mb_rows / 2) { |
michael@0 | 753 | if (mv.as_mv.row > 0) |
michael@0 | 754 | sum_in_vectors--; |
michael@0 | 755 | else if (mv.as_mv.row < 0) |
michael@0 | 756 | sum_in_vectors++; |
michael@0 | 757 | } else if (mb_row > cm->mb_rows / 2) { |
michael@0 | 758 | if (mv.as_mv.row > 0) |
michael@0 | 759 | sum_in_vectors++; |
michael@0 | 760 | else if (mv.as_mv.row < 0) |
michael@0 | 761 | sum_in_vectors--; |
michael@0 | 762 | } |
michael@0 | 763 | |
michael@0 | 764 | // Does the Row vector point inwards or outwards |
michael@0 | 765 | if (mb_col < cm->mb_cols / 2) { |
michael@0 | 766 | if (mv.as_mv.col > 0) |
michael@0 | 767 | sum_in_vectors--; |
michael@0 | 768 | else if (mv.as_mv.col < 0) |
michael@0 | 769 | sum_in_vectors++; |
michael@0 | 770 | } else if (mb_col > cm->mb_cols / 2) { |
michael@0 | 771 | if (mv.as_mv.col > 0) |
michael@0 | 772 | sum_in_vectors++; |
michael@0 | 773 | else if (mv.as_mv.col < 0) |
michael@0 | 774 | sum_in_vectors--; |
michael@0 | 775 | } |
michael@0 | 776 | } |
michael@0 | 777 | } |
michael@0 | 778 | } else { |
michael@0 | 779 | sr_coded_error += (int64_t)this_error; |
michael@0 | 780 | } |
michael@0 | 781 | coded_error += (int64_t)this_error; |
michael@0 | 782 | |
michael@0 | 783 | // adjust to the next column of macroblocks |
michael@0 | 784 | x->plane[0].src.buf += 16; |
michael@0 | 785 | x->plane[1].src.buf += 8; |
michael@0 | 786 | x->plane[2].src.buf += 8; |
michael@0 | 787 | |
michael@0 | 788 | recon_yoffset += 16; |
michael@0 | 789 | recon_uvoffset += 8; |
michael@0 | 790 | } |
michael@0 | 791 | |
michael@0 | 792 | // adjust to the next row of mbs |
michael@0 | 793 | x->plane[0].src.buf += 16 * x->plane[0].src.stride - 16 * cm->mb_cols; |
michael@0 | 794 | x->plane[1].src.buf += 8 * x->plane[1].src.stride - 8 * cm->mb_cols; |
michael@0 | 795 | x->plane[2].src.buf += 8 * x->plane[1].src.stride - 8 * cm->mb_cols; |
michael@0 | 796 | |
michael@0 | 797 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 798 | } |
michael@0 | 799 | |
michael@0 | 800 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 801 | { |
michael@0 | 802 | double weight = 0.0; |
michael@0 | 803 | |
michael@0 | 804 | FIRSTPASS_STATS fps; |
michael@0 | 805 | |
michael@0 | 806 | fps.frame = cm->current_video_frame; |
michael@0 | 807 | fps.intra_error = (double)(intra_error >> 8); |
michael@0 | 808 | fps.coded_error = (double)(coded_error >> 8); |
michael@0 | 809 | fps.sr_coded_error = (double)(sr_coded_error >> 8); |
michael@0 | 810 | weight = simple_weight(cpi->Source); |
michael@0 | 811 | |
michael@0 | 812 | |
michael@0 | 813 | if (weight < 0.1) |
michael@0 | 814 | weight = 0.1; |
michael@0 | 815 | |
michael@0 | 816 | fps.ssim_weighted_pred_err = fps.coded_error * weight; |
michael@0 | 817 | |
michael@0 | 818 | fps.pcnt_inter = 0.0; |
michael@0 | 819 | fps.pcnt_motion = 0.0; |
michael@0 | 820 | fps.MVr = 0.0; |
michael@0 | 821 | fps.mvr_abs = 0.0; |
michael@0 | 822 | fps.MVc = 0.0; |
michael@0 | 823 | fps.mvc_abs = 0.0; |
michael@0 | 824 | fps.MVrv = 0.0; |
michael@0 | 825 | fps.MVcv = 0.0; |
michael@0 | 826 | fps.mv_in_out_count = 0.0; |
michael@0 | 827 | fps.new_mv_count = 0.0; |
michael@0 | 828 | fps.count = 1.0; |
michael@0 | 829 | |
michael@0 | 830 | fps.pcnt_inter = 1.0 * (double)intercount / cm->MBs; |
michael@0 | 831 | fps.pcnt_second_ref = 1.0 * (double)second_ref_count / cm->MBs; |
michael@0 | 832 | fps.pcnt_neutral = 1.0 * (double)neutral_count / cm->MBs; |
michael@0 | 833 | |
michael@0 | 834 | if (mvcount > 0) { |
michael@0 | 835 | fps.MVr = (double)sum_mvr / (double)mvcount; |
michael@0 | 836 | fps.mvr_abs = (double)sum_mvr_abs / (double)mvcount; |
michael@0 | 837 | fps.MVc = (double)sum_mvc / (double)mvcount; |
michael@0 | 838 | fps.mvc_abs = (double)sum_mvc_abs / (double)mvcount; |
michael@0 | 839 | fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / (double)mvcount)) / |
michael@0 | 840 | (double)mvcount; |
michael@0 | 841 | fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / (double)mvcount)) / |
michael@0 | 842 | (double)mvcount; |
michael@0 | 843 | fps.mv_in_out_count = (double)sum_in_vectors / (double)(mvcount * 2); |
michael@0 | 844 | fps.new_mv_count = new_mv_count; |
michael@0 | 845 | |
michael@0 | 846 | fps.pcnt_motion = 1.0 * (double)mvcount / cpi->common.MBs; |
michael@0 | 847 | } |
michael@0 | 848 | |
michael@0 | 849 | // TODO(paulwilkins): Handle the case when duration is set to 0, or |
michael@0 | 850 | // something less than the full time between subsequent values of |
michael@0 | 851 | // cpi->source_time_stamp. |
michael@0 | 852 | fps.duration = (double)(cpi->source->ts_end |
michael@0 | 853 | - cpi->source->ts_start); |
michael@0 | 854 | |
michael@0 | 855 | // don't want to do output stats with a stack variable! |
michael@0 | 856 | cpi->twopass.this_frame_stats = fps; |
michael@0 | 857 | output_stats(cpi, cpi->output_pkt_list, &cpi->twopass.this_frame_stats); |
michael@0 | 858 | accumulate_stats(&cpi->twopass.total_stats, &fps); |
michael@0 | 859 | } |
michael@0 | 860 | |
michael@0 | 861 | // Copy the previous Last Frame back into gf and and arf buffers if |
michael@0 | 862 | // the prediction is good enough... but also dont allow it to lag too far |
michael@0 | 863 | if ((cpi->twopass.sr_update_lag > 3) || |
michael@0 | 864 | ((cm->current_video_frame > 0) && |
michael@0 | 865 | (cpi->twopass.this_frame_stats.pcnt_inter > 0.20) && |
michael@0 | 866 | ((cpi->twopass.this_frame_stats.intra_error / |
michael@0 | 867 | DOUBLE_DIVIDE_CHECK(cpi->twopass.this_frame_stats.coded_error)) > |
michael@0 | 868 | 2.0))) { |
michael@0 | 869 | vp8_yv12_copy_frame(lst_yv12, gld_yv12); |
michael@0 | 870 | cpi->twopass.sr_update_lag = 1; |
michael@0 | 871 | } else { |
michael@0 | 872 | cpi->twopass.sr_update_lag++; |
michael@0 | 873 | } |
michael@0 | 874 | // swap frame pointers so last frame refers to the frame we just compressed |
michael@0 | 875 | swap_yv12(lst_yv12, new_yv12); |
michael@0 | 876 | |
michael@0 | 877 | vp9_extend_frame_borders(lst_yv12, cm->subsampling_x, cm->subsampling_y); |
michael@0 | 878 | |
michael@0 | 879 | // Special case for the first frame. Copy into the GF buffer as a second |
michael@0 | 880 | // reference. |
michael@0 | 881 | if (cm->current_video_frame == 0) |
michael@0 | 882 | vp8_yv12_copy_frame(lst_yv12, gld_yv12); |
michael@0 | 883 | |
michael@0 | 884 | // use this to see what the first pass reconstruction looks like |
michael@0 | 885 | if (0) { |
michael@0 | 886 | char filename[512]; |
michael@0 | 887 | FILE *recon_file; |
michael@0 | 888 | snprintf(filename, sizeof(filename), "enc%04d.yuv", |
michael@0 | 889 | (int)cm->current_video_frame); |
michael@0 | 890 | |
michael@0 | 891 | if (cm->current_video_frame == 0) |
michael@0 | 892 | recon_file = fopen(filename, "wb"); |
michael@0 | 893 | else |
michael@0 | 894 | recon_file = fopen(filename, "ab"); |
michael@0 | 895 | |
michael@0 | 896 | (void)fwrite(lst_yv12->buffer_alloc, lst_yv12->frame_size, 1, recon_file); |
michael@0 | 897 | fclose(recon_file); |
michael@0 | 898 | } |
michael@0 | 899 | |
michael@0 | 900 | cm->current_video_frame++; |
michael@0 | 901 | } |
michael@0 | 902 | |
michael@0 | 903 | // Estimate a cost per mb attributable to overheads such as the coding of |
michael@0 | 904 | // modes and motion vectors. |
michael@0 | 905 | // Currently simplistic in its assumptions for testing. |
michael@0 | 906 | // |
michael@0 | 907 | |
michael@0 | 908 | |
michael@0 | 909 | static double bitcost(double prob) { |
michael@0 | 910 | return -(log(prob) / log(2.0)); |
michael@0 | 911 | } |
michael@0 | 912 | |
michael@0 | 913 | static int64_t estimate_modemvcost(VP9_COMP *cpi, |
michael@0 | 914 | FIRSTPASS_STATS *fpstats) { |
michael@0 | 915 | #if 0 |
michael@0 | 916 | int mv_cost; |
michael@0 | 917 | int mode_cost; |
michael@0 | 918 | |
michael@0 | 919 | double av_pct_inter = fpstats->pcnt_inter / fpstats->count; |
michael@0 | 920 | double av_pct_motion = fpstats->pcnt_motion / fpstats->count; |
michael@0 | 921 | double av_intra = (1.0 - av_pct_inter); |
michael@0 | 922 | |
michael@0 | 923 | double zz_cost; |
michael@0 | 924 | double motion_cost; |
michael@0 | 925 | double intra_cost; |
michael@0 | 926 | |
michael@0 | 927 | zz_cost = bitcost(av_pct_inter - av_pct_motion); |
michael@0 | 928 | motion_cost = bitcost(av_pct_motion); |
michael@0 | 929 | intra_cost = bitcost(av_intra); |
michael@0 | 930 | |
michael@0 | 931 | // Estimate of extra bits per mv overhead for mbs |
michael@0 | 932 | // << 9 is the normalization to the (bits * 512) used in vp9_bits_per_mb |
michael@0 | 933 | mv_cost = ((int)(fpstats->new_mv_count / fpstats->count) * 8) << 9; |
michael@0 | 934 | |
michael@0 | 935 | // Crude estimate of overhead cost from modes |
michael@0 | 936 | // << 9 is the normalization to (bits * 512) used in vp9_bits_per_mb |
michael@0 | 937 | mode_cost = |
michael@0 | 938 | (int)((((av_pct_inter - av_pct_motion) * zz_cost) + |
michael@0 | 939 | (av_pct_motion * motion_cost) + |
michael@0 | 940 | (av_intra * intra_cost)) * cpi->common.MBs) << 9; |
michael@0 | 941 | |
michael@0 | 942 | // return mv_cost + mode_cost; |
michael@0 | 943 | // TODO(paulwilkins): Fix overhead costs for extended Q range. |
michael@0 | 944 | #endif |
michael@0 | 945 | return 0; |
michael@0 | 946 | } |
michael@0 | 947 | |
michael@0 | 948 | static double calc_correction_factor(double err_per_mb, |
michael@0 | 949 | double err_divisor, |
michael@0 | 950 | double pt_low, |
michael@0 | 951 | double pt_high, |
michael@0 | 952 | int q) { |
michael@0 | 953 | const double error_term = err_per_mb / err_divisor; |
michael@0 | 954 | |
michael@0 | 955 | // Adjustment based on actual quantizer to power term. |
michael@0 | 956 | const double power_term = MIN(vp9_convert_qindex_to_q(q) * 0.01 + pt_low, |
michael@0 | 957 | pt_high); |
michael@0 | 958 | |
michael@0 | 959 | // Calculate correction factor |
michael@0 | 960 | if (power_term < 1.0) |
michael@0 | 961 | assert(error_term >= 0.0); |
michael@0 | 962 | |
michael@0 | 963 | return fclamp(pow(error_term, power_term), 0.05, 5.0); |
michael@0 | 964 | } |
michael@0 | 965 | |
michael@0 | 966 | // Given a current maxQ value sets a range for future values. |
michael@0 | 967 | // PGW TODO.. |
michael@0 | 968 | // This code removes direct dependency on QIndex to determine the range |
michael@0 | 969 | // (now uses the actual quantizer) but has not been tuned. |
michael@0 | 970 | static void adjust_maxq_qrange(VP9_COMP *cpi) { |
michael@0 | 971 | int i; |
michael@0 | 972 | // Set the max corresponding to cpi->avg_q * 2.0 |
michael@0 | 973 | double q = cpi->avg_q * 2.0; |
michael@0 | 974 | cpi->twopass.maxq_max_limit = cpi->worst_quality; |
michael@0 | 975 | for (i = cpi->best_quality; i <= cpi->worst_quality; i++) { |
michael@0 | 976 | cpi->twopass.maxq_max_limit = i; |
michael@0 | 977 | if (vp9_convert_qindex_to_q(i) >= q) |
michael@0 | 978 | break; |
michael@0 | 979 | } |
michael@0 | 980 | |
michael@0 | 981 | // Set the min corresponding to cpi->avg_q * 0.5 |
michael@0 | 982 | q = cpi->avg_q * 0.5; |
michael@0 | 983 | cpi->twopass.maxq_min_limit = cpi->best_quality; |
michael@0 | 984 | for (i = cpi->worst_quality; i >= cpi->best_quality; i--) { |
michael@0 | 985 | cpi->twopass.maxq_min_limit = i; |
michael@0 | 986 | if (vp9_convert_qindex_to_q(i) <= q) |
michael@0 | 987 | break; |
michael@0 | 988 | } |
michael@0 | 989 | } |
michael@0 | 990 | |
michael@0 | 991 | static int estimate_max_q(VP9_COMP *cpi, |
michael@0 | 992 | FIRSTPASS_STATS *fpstats, |
michael@0 | 993 | int section_target_bandwitdh) { |
michael@0 | 994 | int q; |
michael@0 | 995 | int num_mbs = cpi->common.MBs; |
michael@0 | 996 | int target_norm_bits_per_mb; |
michael@0 | 997 | |
michael@0 | 998 | double section_err = fpstats->coded_error / fpstats->count; |
michael@0 | 999 | double sr_correction; |
michael@0 | 1000 | double err_per_mb = section_err / num_mbs; |
michael@0 | 1001 | double err_correction_factor; |
michael@0 | 1002 | double speed_correction = 1.0; |
michael@0 | 1003 | |
michael@0 | 1004 | if (section_target_bandwitdh <= 0) |
michael@0 | 1005 | return cpi->twopass.maxq_max_limit; // Highest value allowed |
michael@0 | 1006 | |
michael@0 | 1007 | target_norm_bits_per_mb = section_target_bandwitdh < (1 << 20) |
michael@0 | 1008 | ? (512 * section_target_bandwitdh) / num_mbs |
michael@0 | 1009 | : 512 * (section_target_bandwitdh / num_mbs); |
michael@0 | 1010 | |
michael@0 | 1011 | // Look at the drop in prediction quality between the last frame |
michael@0 | 1012 | // and the GF buffer (which contained an older frame). |
michael@0 | 1013 | if (fpstats->sr_coded_error > fpstats->coded_error) { |
michael@0 | 1014 | double sr_err_diff = (fpstats->sr_coded_error - fpstats->coded_error) / |
michael@0 | 1015 | (fpstats->count * cpi->common.MBs); |
michael@0 | 1016 | sr_correction = fclamp(pow(sr_err_diff / 32.0, 0.25), 0.75, 1.25); |
michael@0 | 1017 | } else { |
michael@0 | 1018 | sr_correction = 0.75; |
michael@0 | 1019 | } |
michael@0 | 1020 | |
michael@0 | 1021 | // Calculate a corrective factor based on a rolling ratio of bits spent |
michael@0 | 1022 | // vs target bits |
michael@0 | 1023 | if (cpi->rolling_target_bits > 0 && |
michael@0 | 1024 | cpi->active_worst_quality < cpi->worst_quality) { |
michael@0 | 1025 | double rolling_ratio = (double)cpi->rolling_actual_bits / |
michael@0 | 1026 | (double)cpi->rolling_target_bits; |
michael@0 | 1027 | |
michael@0 | 1028 | if (rolling_ratio < 0.95) |
michael@0 | 1029 | cpi->twopass.est_max_qcorrection_factor -= 0.005; |
michael@0 | 1030 | else if (rolling_ratio > 1.05) |
michael@0 | 1031 | cpi->twopass.est_max_qcorrection_factor += 0.005; |
michael@0 | 1032 | |
michael@0 | 1033 | cpi->twopass.est_max_qcorrection_factor = fclamp( |
michael@0 | 1034 | cpi->twopass.est_max_qcorrection_factor, 0.1, 10.0); |
michael@0 | 1035 | } |
michael@0 | 1036 | |
michael@0 | 1037 | // Corrections for higher compression speed settings |
michael@0 | 1038 | // (reduced compression expected) |
michael@0 | 1039 | // FIXME(jimbankoski): Once we settle on vp9 speed features we need to |
michael@0 | 1040 | // change this code. |
michael@0 | 1041 | if (cpi->compressor_speed == 1) |
michael@0 | 1042 | speed_correction = cpi->oxcf.cpu_used <= 5 ? |
michael@0 | 1043 | 1.04 + (/*cpi->oxcf.cpu_used*/0 * 0.04) : |
michael@0 | 1044 | 1.25; |
michael@0 | 1045 | |
michael@0 | 1046 | // Try and pick a max Q that will be high enough to encode the |
michael@0 | 1047 | // content at the given rate. |
michael@0 | 1048 | for (q = cpi->twopass.maxq_min_limit; q < cpi->twopass.maxq_max_limit; q++) { |
michael@0 | 1049 | int bits_per_mb_at_this_q; |
michael@0 | 1050 | |
michael@0 | 1051 | err_correction_factor = calc_correction_factor(err_per_mb, |
michael@0 | 1052 | ERR_DIVISOR, 0.4, 0.90, q) * |
michael@0 | 1053 | sr_correction * speed_correction * |
michael@0 | 1054 | cpi->twopass.est_max_qcorrection_factor; |
michael@0 | 1055 | |
michael@0 | 1056 | bits_per_mb_at_this_q = vp9_bits_per_mb(INTER_FRAME, q, |
michael@0 | 1057 | err_correction_factor); |
michael@0 | 1058 | |
michael@0 | 1059 | if (bits_per_mb_at_this_q <= target_norm_bits_per_mb) |
michael@0 | 1060 | break; |
michael@0 | 1061 | } |
michael@0 | 1062 | |
michael@0 | 1063 | // Restriction on active max q for constrained quality mode. |
michael@0 | 1064 | if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY && |
michael@0 | 1065 | q < cpi->cq_target_quality) |
michael@0 | 1066 | q = cpi->cq_target_quality; |
michael@0 | 1067 | |
michael@0 | 1068 | // Adjust maxq_min_limit and maxq_max_limit limits based on |
michael@0 | 1069 | // average q observed in clip for non kf/gf/arf frames |
michael@0 | 1070 | // Give average a chance to settle though. |
michael@0 | 1071 | // PGW TODO.. This code is broken for the extended Q range |
michael@0 | 1072 | if (cpi->ni_frames > ((int)cpi->twopass.total_stats.count >> 8) && |
michael@0 | 1073 | cpi->ni_frames > 25) |
michael@0 | 1074 | adjust_maxq_qrange(cpi); |
michael@0 | 1075 | |
michael@0 | 1076 | return q; |
michael@0 | 1077 | } |
michael@0 | 1078 | |
michael@0 | 1079 | // For cq mode estimate a cq level that matches the observed |
michael@0 | 1080 | // complexity and data rate. |
michael@0 | 1081 | static int estimate_cq(VP9_COMP *cpi, |
michael@0 | 1082 | FIRSTPASS_STATS *fpstats, |
michael@0 | 1083 | int section_target_bandwitdh) { |
michael@0 | 1084 | int q; |
michael@0 | 1085 | int num_mbs = cpi->common.MBs; |
michael@0 | 1086 | int target_norm_bits_per_mb; |
michael@0 | 1087 | |
michael@0 | 1088 | double section_err = (fpstats->coded_error / fpstats->count); |
michael@0 | 1089 | double err_per_mb = section_err / num_mbs; |
michael@0 | 1090 | double err_correction_factor; |
michael@0 | 1091 | double sr_err_diff; |
michael@0 | 1092 | double sr_correction; |
michael@0 | 1093 | double speed_correction = 1.0; |
michael@0 | 1094 | double clip_iiratio; |
michael@0 | 1095 | double clip_iifactor; |
michael@0 | 1096 | |
michael@0 | 1097 | target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) |
michael@0 | 1098 | ? (512 * section_target_bandwitdh) / num_mbs |
michael@0 | 1099 | : 512 * (section_target_bandwitdh / num_mbs); |
michael@0 | 1100 | |
michael@0 | 1101 | |
michael@0 | 1102 | // Corrections for higher compression speed settings |
michael@0 | 1103 | // (reduced compression expected) |
michael@0 | 1104 | if (cpi->compressor_speed == 1) { |
michael@0 | 1105 | if (cpi->oxcf.cpu_used <= 5) |
michael@0 | 1106 | speed_correction = 1.04 + (/*cpi->oxcf.cpu_used*/ 0 * 0.04); |
michael@0 | 1107 | else |
michael@0 | 1108 | speed_correction = 1.25; |
michael@0 | 1109 | } |
michael@0 | 1110 | |
michael@0 | 1111 | // Look at the drop in prediction quality between the last frame |
michael@0 | 1112 | // and the GF buffer (which contained an older frame). |
michael@0 | 1113 | if (fpstats->sr_coded_error > fpstats->coded_error) { |
michael@0 | 1114 | sr_err_diff = |
michael@0 | 1115 | (fpstats->sr_coded_error - fpstats->coded_error) / |
michael@0 | 1116 | (fpstats->count * cpi->common.MBs); |
michael@0 | 1117 | sr_correction = (sr_err_diff / 32.0); |
michael@0 | 1118 | sr_correction = pow(sr_correction, 0.25); |
michael@0 | 1119 | if (sr_correction < 0.75) |
michael@0 | 1120 | sr_correction = 0.75; |
michael@0 | 1121 | else if (sr_correction > 1.25) |
michael@0 | 1122 | sr_correction = 1.25; |
michael@0 | 1123 | } else { |
michael@0 | 1124 | sr_correction = 0.75; |
michael@0 | 1125 | } |
michael@0 | 1126 | |
michael@0 | 1127 | // II ratio correction factor for clip as a whole |
michael@0 | 1128 | clip_iiratio = cpi->twopass.total_stats.intra_error / |
michael@0 | 1129 | DOUBLE_DIVIDE_CHECK(cpi->twopass.total_stats.coded_error); |
michael@0 | 1130 | clip_iifactor = 1.0 - ((clip_iiratio - 10.0) * 0.025); |
michael@0 | 1131 | if (clip_iifactor < 0.80) |
michael@0 | 1132 | clip_iifactor = 0.80; |
michael@0 | 1133 | |
michael@0 | 1134 | // Try and pick a Q that can encode the content at the given rate. |
michael@0 | 1135 | for (q = 0; q < MAXQ; q++) { |
michael@0 | 1136 | int bits_per_mb_at_this_q; |
michael@0 | 1137 | |
michael@0 | 1138 | // Error per MB based correction factor |
michael@0 | 1139 | err_correction_factor = |
michael@0 | 1140 | calc_correction_factor(err_per_mb, 100.0, 0.4, 0.90, q) * |
michael@0 | 1141 | sr_correction * speed_correction * clip_iifactor; |
michael@0 | 1142 | |
michael@0 | 1143 | bits_per_mb_at_this_q = |
michael@0 | 1144 | vp9_bits_per_mb(INTER_FRAME, q, err_correction_factor); |
michael@0 | 1145 | |
michael@0 | 1146 | if (bits_per_mb_at_this_q <= target_norm_bits_per_mb) |
michael@0 | 1147 | break; |
michael@0 | 1148 | } |
michael@0 | 1149 | |
michael@0 | 1150 | // Clip value to range "best allowed to (worst allowed - 1)" |
michael@0 | 1151 | q = select_cq_level(q); |
michael@0 | 1152 | if (q >= cpi->worst_quality) |
michael@0 | 1153 | q = cpi->worst_quality - 1; |
michael@0 | 1154 | if (q < cpi->best_quality) |
michael@0 | 1155 | q = cpi->best_quality; |
michael@0 | 1156 | |
michael@0 | 1157 | return q; |
michael@0 | 1158 | } |
michael@0 | 1159 | |
michael@0 | 1160 | extern void vp9_new_framerate(VP9_COMP *cpi, double framerate); |
michael@0 | 1161 | |
michael@0 | 1162 | void vp9_init_second_pass(VP9_COMP *cpi) { |
michael@0 | 1163 | FIRSTPASS_STATS this_frame; |
michael@0 | 1164 | FIRSTPASS_STATS *start_pos; |
michael@0 | 1165 | |
michael@0 | 1166 | double lower_bounds_min_rate = FRAME_OVERHEAD_BITS * cpi->oxcf.framerate; |
michael@0 | 1167 | double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth * |
michael@0 | 1168 | cpi->oxcf.two_pass_vbrmin_section / 100); |
michael@0 | 1169 | |
michael@0 | 1170 | if (two_pass_min_rate < lower_bounds_min_rate) |
michael@0 | 1171 | two_pass_min_rate = lower_bounds_min_rate; |
michael@0 | 1172 | |
michael@0 | 1173 | zero_stats(&cpi->twopass.total_stats); |
michael@0 | 1174 | zero_stats(&cpi->twopass.total_left_stats); |
michael@0 | 1175 | |
michael@0 | 1176 | if (!cpi->twopass.stats_in_end) |
michael@0 | 1177 | return; |
michael@0 | 1178 | |
michael@0 | 1179 | cpi->twopass.total_stats = *cpi->twopass.stats_in_end; |
michael@0 | 1180 | cpi->twopass.total_left_stats = cpi->twopass.total_stats; |
michael@0 | 1181 | |
michael@0 | 1182 | // each frame can have a different duration, as the frame rate in the source |
michael@0 | 1183 | // isn't guaranteed to be constant. The frame rate prior to the first frame |
michael@0 | 1184 | // encoded in the second pass is a guess. However the sum duration is not. |
michael@0 | 1185 | // Its calculated based on the actual durations of all frames from the first |
michael@0 | 1186 | // pass. |
michael@0 | 1187 | vp9_new_framerate(cpi, 10000000.0 * cpi->twopass.total_stats.count / |
michael@0 | 1188 | cpi->twopass.total_stats.duration); |
michael@0 | 1189 | |
michael@0 | 1190 | cpi->output_framerate = cpi->oxcf.framerate; |
michael@0 | 1191 | cpi->twopass.bits_left = (int64_t)(cpi->twopass.total_stats.duration * |
michael@0 | 1192 | cpi->oxcf.target_bandwidth / 10000000.0); |
michael@0 | 1193 | cpi->twopass.bits_left -= (int64_t)(cpi->twopass.total_stats.duration * |
michael@0 | 1194 | two_pass_min_rate / 10000000.0); |
michael@0 | 1195 | |
michael@0 | 1196 | // Calculate a minimum intra value to be used in determining the IIratio |
michael@0 | 1197 | // scores used in the second pass. We have this minimum to make sure |
michael@0 | 1198 | // that clips that are static but "low complexity" in the intra domain |
michael@0 | 1199 | // are still boosted appropriately for KF/GF/ARF |
michael@0 | 1200 | cpi->twopass.kf_intra_err_min = KF_MB_INTRA_MIN * cpi->common.MBs; |
michael@0 | 1201 | cpi->twopass.gf_intra_err_min = GF_MB_INTRA_MIN * cpi->common.MBs; |
michael@0 | 1202 | |
michael@0 | 1203 | // This variable monitors how far behind the second ref update is lagging |
michael@0 | 1204 | cpi->twopass.sr_update_lag = 1; |
michael@0 | 1205 | |
michael@0 | 1206 | // Scan the first pass file and calculate an average Intra / Inter error score |
michael@0 | 1207 | // ratio for the sequence. |
michael@0 | 1208 | { |
michael@0 | 1209 | double sum_iiratio = 0.0; |
michael@0 | 1210 | double IIRatio; |
michael@0 | 1211 | |
michael@0 | 1212 | start_pos = cpi->twopass.stats_in; // Note the starting "file" position. |
michael@0 | 1213 | |
michael@0 | 1214 | while (input_stats(cpi, &this_frame) != EOF) { |
michael@0 | 1215 | IIRatio = this_frame.intra_error |
michael@0 | 1216 | / DOUBLE_DIVIDE_CHECK(this_frame.coded_error); |
michael@0 | 1217 | IIRatio = (IIRatio < 1.0) ? 1.0 : (IIRatio > 20.0) ? 20.0 : IIRatio; |
michael@0 | 1218 | sum_iiratio += IIRatio; |
michael@0 | 1219 | } |
michael@0 | 1220 | |
michael@0 | 1221 | cpi->twopass.avg_iiratio = sum_iiratio / |
michael@0 | 1222 | DOUBLE_DIVIDE_CHECK((double)cpi->twopass.total_stats.count); |
michael@0 | 1223 | |
michael@0 | 1224 | // Reset file position |
michael@0 | 1225 | reset_fpf_position(cpi, start_pos); |
michael@0 | 1226 | } |
michael@0 | 1227 | |
michael@0 | 1228 | // Scan the first pass file and calculate a modified total error based upon |
michael@0 | 1229 | // the bias/power function used to allocate bits. |
michael@0 | 1230 | { |
michael@0 | 1231 | start_pos = cpi->twopass.stats_in; // Note starting "file" position |
michael@0 | 1232 | |
michael@0 | 1233 | cpi->twopass.modified_error_total = 0.0; |
michael@0 | 1234 | cpi->twopass.modified_error_used = 0.0; |
michael@0 | 1235 | |
michael@0 | 1236 | while (input_stats(cpi, &this_frame) != EOF) { |
michael@0 | 1237 | cpi->twopass.modified_error_total += |
michael@0 | 1238 | calculate_modified_err(cpi, &this_frame); |
michael@0 | 1239 | } |
michael@0 | 1240 | cpi->twopass.modified_error_left = cpi->twopass.modified_error_total; |
michael@0 | 1241 | |
michael@0 | 1242 | reset_fpf_position(cpi, start_pos); // Reset file position |
michael@0 | 1243 | } |
michael@0 | 1244 | } |
michael@0 | 1245 | |
michael@0 | 1246 | void vp9_end_second_pass(VP9_COMP *cpi) { |
michael@0 | 1247 | } |
michael@0 | 1248 | |
michael@0 | 1249 | // This function gives and estimate of how badly we believe |
michael@0 | 1250 | // the prediction quality is decaying from frame to frame. |
michael@0 | 1251 | static double get_prediction_decay_rate(VP9_COMP *cpi, |
michael@0 | 1252 | FIRSTPASS_STATS *next_frame) { |
michael@0 | 1253 | double prediction_decay_rate; |
michael@0 | 1254 | double second_ref_decay; |
michael@0 | 1255 | double mb_sr_err_diff; |
michael@0 | 1256 | |
michael@0 | 1257 | // Initial basis is the % mbs inter coded |
michael@0 | 1258 | prediction_decay_rate = next_frame->pcnt_inter; |
michael@0 | 1259 | |
michael@0 | 1260 | // Look at the observed drop in prediction quality between the last frame |
michael@0 | 1261 | // and the GF buffer (which contains an older frame). |
michael@0 | 1262 | mb_sr_err_diff = (next_frame->sr_coded_error - next_frame->coded_error) / |
michael@0 | 1263 | cpi->common.MBs; |
michael@0 | 1264 | if (mb_sr_err_diff <= 512.0) { |
michael@0 | 1265 | second_ref_decay = 1.0 - (mb_sr_err_diff / 512.0); |
michael@0 | 1266 | second_ref_decay = pow(second_ref_decay, 0.5); |
michael@0 | 1267 | if (second_ref_decay < 0.85) |
michael@0 | 1268 | second_ref_decay = 0.85; |
michael@0 | 1269 | else if (second_ref_decay > 1.0) |
michael@0 | 1270 | second_ref_decay = 1.0; |
michael@0 | 1271 | } else { |
michael@0 | 1272 | second_ref_decay = 0.85; |
michael@0 | 1273 | } |
michael@0 | 1274 | |
michael@0 | 1275 | if (second_ref_decay < prediction_decay_rate) |
michael@0 | 1276 | prediction_decay_rate = second_ref_decay; |
michael@0 | 1277 | |
michael@0 | 1278 | return prediction_decay_rate; |
michael@0 | 1279 | } |
michael@0 | 1280 | |
michael@0 | 1281 | // Function to test for a condition where a complex transition is followed |
michael@0 | 1282 | // by a static section. For example in slide shows where there is a fade |
michael@0 | 1283 | // between slides. This is to help with more optimal kf and gf positioning. |
michael@0 | 1284 | static int detect_transition_to_still( |
michael@0 | 1285 | VP9_COMP *cpi, |
michael@0 | 1286 | int frame_interval, |
michael@0 | 1287 | int still_interval, |
michael@0 | 1288 | double loop_decay_rate, |
michael@0 | 1289 | double last_decay_rate) { |
michael@0 | 1290 | int trans_to_still = 0; |
michael@0 | 1291 | |
michael@0 | 1292 | // Break clause to detect very still sections after motion |
michael@0 | 1293 | // For example a static image after a fade or other transition |
michael@0 | 1294 | // instead of a clean scene cut. |
michael@0 | 1295 | if (frame_interval > MIN_GF_INTERVAL && |
michael@0 | 1296 | loop_decay_rate >= 0.999 && |
michael@0 | 1297 | last_decay_rate < 0.9) { |
michael@0 | 1298 | int j; |
michael@0 | 1299 | FIRSTPASS_STATS *position = cpi->twopass.stats_in; |
michael@0 | 1300 | FIRSTPASS_STATS tmp_next_frame; |
michael@0 | 1301 | double zz_inter; |
michael@0 | 1302 | |
michael@0 | 1303 | // Look ahead a few frames to see if static condition |
michael@0 | 1304 | // persists... |
michael@0 | 1305 | for (j = 0; j < still_interval; j++) { |
michael@0 | 1306 | if (EOF == input_stats(cpi, &tmp_next_frame)) |
michael@0 | 1307 | break; |
michael@0 | 1308 | |
michael@0 | 1309 | zz_inter = |
michael@0 | 1310 | (tmp_next_frame.pcnt_inter - tmp_next_frame.pcnt_motion); |
michael@0 | 1311 | if (zz_inter < 0.999) |
michael@0 | 1312 | break; |
michael@0 | 1313 | } |
michael@0 | 1314 | // Reset file position |
michael@0 | 1315 | reset_fpf_position(cpi, position); |
michael@0 | 1316 | |
michael@0 | 1317 | // Only if it does do we signal a transition to still |
michael@0 | 1318 | if (j == still_interval) |
michael@0 | 1319 | trans_to_still = 1; |
michael@0 | 1320 | } |
michael@0 | 1321 | |
michael@0 | 1322 | return trans_to_still; |
michael@0 | 1323 | } |
michael@0 | 1324 | |
michael@0 | 1325 | // This function detects a flash through the high relative pcnt_second_ref |
michael@0 | 1326 | // score in the frame following a flash frame. The offset passed in should |
michael@0 | 1327 | // reflect this |
michael@0 | 1328 | static int detect_flash(VP9_COMP *cpi, int offset) { |
michael@0 | 1329 | FIRSTPASS_STATS next_frame; |
michael@0 | 1330 | |
michael@0 | 1331 | int flash_detected = 0; |
michael@0 | 1332 | |
michael@0 | 1333 | // Read the frame data. |
michael@0 | 1334 | // The return is FALSE (no flash detected) if not a valid frame |
michael@0 | 1335 | if (read_frame_stats(cpi, &next_frame, offset) != EOF) { |
michael@0 | 1336 | // What we are looking for here is a situation where there is a |
michael@0 | 1337 | // brief break in prediction (such as a flash) but subsequent frames |
michael@0 | 1338 | // are reasonably well predicted by an earlier (pre flash) frame. |
michael@0 | 1339 | // The recovery after a flash is indicated by a high pcnt_second_ref |
michael@0 | 1340 | // comapred to pcnt_inter. |
michael@0 | 1341 | if (next_frame.pcnt_second_ref > next_frame.pcnt_inter && |
michael@0 | 1342 | next_frame.pcnt_second_ref >= 0.5) |
michael@0 | 1343 | flash_detected = 1; |
michael@0 | 1344 | } |
michael@0 | 1345 | |
michael@0 | 1346 | return flash_detected; |
michael@0 | 1347 | } |
michael@0 | 1348 | |
michael@0 | 1349 | // Update the motion related elements to the GF arf boost calculation |
michael@0 | 1350 | static void accumulate_frame_motion_stats( |
michael@0 | 1351 | FIRSTPASS_STATS *this_frame, |
michael@0 | 1352 | double *this_frame_mv_in_out, |
michael@0 | 1353 | double *mv_in_out_accumulator, |
michael@0 | 1354 | double *abs_mv_in_out_accumulator, |
michael@0 | 1355 | double *mv_ratio_accumulator) { |
michael@0 | 1356 | // double this_frame_mv_in_out; |
michael@0 | 1357 | double this_frame_mvr_ratio; |
michael@0 | 1358 | double this_frame_mvc_ratio; |
michael@0 | 1359 | double motion_pct; |
michael@0 | 1360 | |
michael@0 | 1361 | // Accumulate motion stats. |
michael@0 | 1362 | motion_pct = this_frame->pcnt_motion; |
michael@0 | 1363 | |
michael@0 | 1364 | // Accumulate Motion In/Out of frame stats |
michael@0 | 1365 | *this_frame_mv_in_out = this_frame->mv_in_out_count * motion_pct; |
michael@0 | 1366 | *mv_in_out_accumulator += this_frame->mv_in_out_count * motion_pct; |
michael@0 | 1367 | *abs_mv_in_out_accumulator += |
michael@0 | 1368 | fabs(this_frame->mv_in_out_count * motion_pct); |
michael@0 | 1369 | |
michael@0 | 1370 | // Accumulate a measure of how uniform (or conversely how random) |
michael@0 | 1371 | // the motion field is. (A ratio of absmv / mv) |
michael@0 | 1372 | if (motion_pct > 0.05) { |
michael@0 | 1373 | this_frame_mvr_ratio = fabs(this_frame->mvr_abs) / |
michael@0 | 1374 | DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVr)); |
michael@0 | 1375 | |
michael@0 | 1376 | this_frame_mvc_ratio = fabs(this_frame->mvc_abs) / |
michael@0 | 1377 | DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVc)); |
michael@0 | 1378 | |
michael@0 | 1379 | *mv_ratio_accumulator += |
michael@0 | 1380 | (this_frame_mvr_ratio < this_frame->mvr_abs) |
michael@0 | 1381 | ? (this_frame_mvr_ratio * motion_pct) |
michael@0 | 1382 | : this_frame->mvr_abs * motion_pct; |
michael@0 | 1383 | |
michael@0 | 1384 | *mv_ratio_accumulator += |
michael@0 | 1385 | (this_frame_mvc_ratio < this_frame->mvc_abs) |
michael@0 | 1386 | ? (this_frame_mvc_ratio * motion_pct) |
michael@0 | 1387 | : this_frame->mvc_abs * motion_pct; |
michael@0 | 1388 | } |
michael@0 | 1389 | } |
michael@0 | 1390 | |
michael@0 | 1391 | // Calculate a baseline boost number for the current frame. |
michael@0 | 1392 | static double calc_frame_boost( |
michael@0 | 1393 | VP9_COMP *cpi, |
michael@0 | 1394 | FIRSTPASS_STATS *this_frame, |
michael@0 | 1395 | double this_frame_mv_in_out) { |
michael@0 | 1396 | double frame_boost; |
michael@0 | 1397 | |
michael@0 | 1398 | // Underlying boost factor is based on inter intra error ratio |
michael@0 | 1399 | if (this_frame->intra_error > cpi->twopass.gf_intra_err_min) |
michael@0 | 1400 | frame_boost = (IIFACTOR * this_frame->intra_error / |
michael@0 | 1401 | DOUBLE_DIVIDE_CHECK(this_frame->coded_error)); |
michael@0 | 1402 | else |
michael@0 | 1403 | frame_boost = (IIFACTOR * cpi->twopass.gf_intra_err_min / |
michael@0 | 1404 | DOUBLE_DIVIDE_CHECK(this_frame->coded_error)); |
michael@0 | 1405 | |
michael@0 | 1406 | // Increase boost for frames where new data coming into frame |
michael@0 | 1407 | // (eg zoom out). Slightly reduce boost if there is a net balance |
michael@0 | 1408 | // of motion out of the frame (zoom in). |
michael@0 | 1409 | // The range for this_frame_mv_in_out is -1.0 to +1.0 |
michael@0 | 1410 | if (this_frame_mv_in_out > 0.0) |
michael@0 | 1411 | frame_boost += frame_boost * (this_frame_mv_in_out * 2.0); |
michael@0 | 1412 | // In extreme case boost is halved |
michael@0 | 1413 | else |
michael@0 | 1414 | frame_boost += frame_boost * (this_frame_mv_in_out / 2.0); |
michael@0 | 1415 | |
michael@0 | 1416 | // Clip to maximum |
michael@0 | 1417 | if (frame_boost > GF_RMAX) |
michael@0 | 1418 | frame_boost = GF_RMAX; |
michael@0 | 1419 | |
michael@0 | 1420 | return frame_boost; |
michael@0 | 1421 | } |
michael@0 | 1422 | |
michael@0 | 1423 | static int calc_arf_boost(VP9_COMP *cpi, int offset, |
michael@0 | 1424 | int f_frames, int b_frames, |
michael@0 | 1425 | int *f_boost, int *b_boost) { |
michael@0 | 1426 | FIRSTPASS_STATS this_frame; |
michael@0 | 1427 | |
michael@0 | 1428 | int i; |
michael@0 | 1429 | double boost_score = 0.0; |
michael@0 | 1430 | double mv_ratio_accumulator = 0.0; |
michael@0 | 1431 | double decay_accumulator = 1.0; |
michael@0 | 1432 | double this_frame_mv_in_out = 0.0; |
michael@0 | 1433 | double mv_in_out_accumulator = 0.0; |
michael@0 | 1434 | double abs_mv_in_out_accumulator = 0.0; |
michael@0 | 1435 | int arf_boost; |
michael@0 | 1436 | int flash_detected = 0; |
michael@0 | 1437 | |
michael@0 | 1438 | // Search forward from the proposed arf/next gf position |
michael@0 | 1439 | for (i = 0; i < f_frames; i++) { |
michael@0 | 1440 | if (read_frame_stats(cpi, &this_frame, (i + offset)) == EOF) |
michael@0 | 1441 | break; |
michael@0 | 1442 | |
michael@0 | 1443 | // Update the motion related elements to the boost calculation |
michael@0 | 1444 | accumulate_frame_motion_stats(&this_frame, |
michael@0 | 1445 | &this_frame_mv_in_out, &mv_in_out_accumulator, |
michael@0 | 1446 | &abs_mv_in_out_accumulator, |
michael@0 | 1447 | &mv_ratio_accumulator); |
michael@0 | 1448 | |
michael@0 | 1449 | // We want to discount the flash frame itself and the recovery |
michael@0 | 1450 | // frame that follows as both will have poor scores. |
michael@0 | 1451 | flash_detected = detect_flash(cpi, (i + offset)) || |
michael@0 | 1452 | detect_flash(cpi, (i + offset + 1)); |
michael@0 | 1453 | |
michael@0 | 1454 | // Cumulative effect of prediction quality decay |
michael@0 | 1455 | if (!flash_detected) { |
michael@0 | 1456 | decay_accumulator *= get_prediction_decay_rate(cpi, &this_frame); |
michael@0 | 1457 | decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR |
michael@0 | 1458 | ? MIN_DECAY_FACTOR : decay_accumulator; |
michael@0 | 1459 | } |
michael@0 | 1460 | |
michael@0 | 1461 | boost_score += (decay_accumulator * |
michael@0 | 1462 | calc_frame_boost(cpi, &this_frame, this_frame_mv_in_out)); |
michael@0 | 1463 | } |
michael@0 | 1464 | |
michael@0 | 1465 | *f_boost = (int)boost_score; |
michael@0 | 1466 | |
michael@0 | 1467 | // Reset for backward looking loop |
michael@0 | 1468 | boost_score = 0.0; |
michael@0 | 1469 | mv_ratio_accumulator = 0.0; |
michael@0 | 1470 | decay_accumulator = 1.0; |
michael@0 | 1471 | this_frame_mv_in_out = 0.0; |
michael@0 | 1472 | mv_in_out_accumulator = 0.0; |
michael@0 | 1473 | abs_mv_in_out_accumulator = 0.0; |
michael@0 | 1474 | |
michael@0 | 1475 | // Search backward towards last gf position |
michael@0 | 1476 | for (i = -1; i >= -b_frames; i--) { |
michael@0 | 1477 | if (read_frame_stats(cpi, &this_frame, (i + offset)) == EOF) |
michael@0 | 1478 | break; |
michael@0 | 1479 | |
michael@0 | 1480 | // Update the motion related elements to the boost calculation |
michael@0 | 1481 | accumulate_frame_motion_stats(&this_frame, |
michael@0 | 1482 | &this_frame_mv_in_out, &mv_in_out_accumulator, |
michael@0 | 1483 | &abs_mv_in_out_accumulator, |
michael@0 | 1484 | &mv_ratio_accumulator); |
michael@0 | 1485 | |
michael@0 | 1486 | // We want to discount the the flash frame itself and the recovery |
michael@0 | 1487 | // frame that follows as both will have poor scores. |
michael@0 | 1488 | flash_detected = detect_flash(cpi, (i + offset)) || |
michael@0 | 1489 | detect_flash(cpi, (i + offset + 1)); |
michael@0 | 1490 | |
michael@0 | 1491 | // Cumulative effect of prediction quality decay |
michael@0 | 1492 | if (!flash_detected) { |
michael@0 | 1493 | decay_accumulator *= get_prediction_decay_rate(cpi, &this_frame); |
michael@0 | 1494 | decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR |
michael@0 | 1495 | ? MIN_DECAY_FACTOR : decay_accumulator; |
michael@0 | 1496 | } |
michael@0 | 1497 | |
michael@0 | 1498 | boost_score += (decay_accumulator * |
michael@0 | 1499 | calc_frame_boost(cpi, &this_frame, this_frame_mv_in_out)); |
michael@0 | 1500 | } |
michael@0 | 1501 | *b_boost = (int)boost_score; |
michael@0 | 1502 | |
michael@0 | 1503 | arf_boost = (*f_boost + *b_boost); |
michael@0 | 1504 | if (arf_boost < ((b_frames + f_frames) * 20)) |
michael@0 | 1505 | arf_boost = ((b_frames + f_frames) * 20); |
michael@0 | 1506 | |
michael@0 | 1507 | return arf_boost; |
michael@0 | 1508 | } |
michael@0 | 1509 | |
michael@0 | 1510 | #if CONFIG_MULTIPLE_ARF |
michael@0 | 1511 | // Work out the frame coding order for a GF or an ARF group. |
michael@0 | 1512 | // The current implementation codes frames in their natural order for a |
michael@0 | 1513 | // GF group, and inserts additional ARFs into an ARF group using a |
michael@0 | 1514 | // binary split approach. |
michael@0 | 1515 | // NOTE: this function is currently implemented recursively. |
michael@0 | 1516 | static void schedule_frames(VP9_COMP *cpi, const int start, const int end, |
michael@0 | 1517 | const int arf_idx, const int gf_or_arf_group, |
michael@0 | 1518 | const int level) { |
michael@0 | 1519 | int i, abs_end, half_range; |
michael@0 | 1520 | int *cfo = cpi->frame_coding_order; |
michael@0 | 1521 | int idx = cpi->new_frame_coding_order_period; |
michael@0 | 1522 | |
michael@0 | 1523 | // If (end < 0) an ARF should be coded at position (-end). |
michael@0 | 1524 | assert(start >= 0); |
michael@0 | 1525 | |
michael@0 | 1526 | // printf("start:%d end:%d\n", start, end); |
michael@0 | 1527 | |
michael@0 | 1528 | // GF Group: code frames in logical order. |
michael@0 | 1529 | if (gf_or_arf_group == 0) { |
michael@0 | 1530 | assert(end >= start); |
michael@0 | 1531 | for (i = start; i <= end; ++i) { |
michael@0 | 1532 | cfo[idx] = i; |
michael@0 | 1533 | cpi->arf_buffer_idx[idx] = arf_idx; |
michael@0 | 1534 | cpi->arf_weight[idx] = -1; |
michael@0 | 1535 | ++idx; |
michael@0 | 1536 | } |
michael@0 | 1537 | cpi->new_frame_coding_order_period = idx; |
michael@0 | 1538 | return; |
michael@0 | 1539 | } |
michael@0 | 1540 | |
michael@0 | 1541 | // ARF Group: work out the ARF schedule. |
michael@0 | 1542 | // Mark ARF frames as negative. |
michael@0 | 1543 | if (end < 0) { |
michael@0 | 1544 | // printf("start:%d end:%d\n", -end, -end); |
michael@0 | 1545 | // ARF frame is at the end of the range. |
michael@0 | 1546 | cfo[idx] = end; |
michael@0 | 1547 | // What ARF buffer does this ARF use as predictor. |
michael@0 | 1548 | cpi->arf_buffer_idx[idx] = (arf_idx > 2) ? (arf_idx - 1) : 2; |
michael@0 | 1549 | cpi->arf_weight[idx] = level; |
michael@0 | 1550 | ++idx; |
michael@0 | 1551 | abs_end = -end; |
michael@0 | 1552 | } else { |
michael@0 | 1553 | abs_end = end; |
michael@0 | 1554 | } |
michael@0 | 1555 | |
michael@0 | 1556 | half_range = (abs_end - start) >> 1; |
michael@0 | 1557 | |
michael@0 | 1558 | // ARFs may not be adjacent, they must be separated by at least |
michael@0 | 1559 | // MIN_GF_INTERVAL non-ARF frames. |
michael@0 | 1560 | if ((start + MIN_GF_INTERVAL) >= (abs_end - MIN_GF_INTERVAL)) { |
michael@0 | 1561 | // printf("start:%d end:%d\n", start, abs_end); |
michael@0 | 1562 | // Update the coding order and active ARF. |
michael@0 | 1563 | for (i = start; i <= abs_end; ++i) { |
michael@0 | 1564 | cfo[idx] = i; |
michael@0 | 1565 | cpi->arf_buffer_idx[idx] = arf_idx; |
michael@0 | 1566 | cpi->arf_weight[idx] = -1; |
michael@0 | 1567 | ++idx; |
michael@0 | 1568 | } |
michael@0 | 1569 | cpi->new_frame_coding_order_period = idx; |
michael@0 | 1570 | } else { |
michael@0 | 1571 | // Place a new ARF at the mid-point of the range. |
michael@0 | 1572 | cpi->new_frame_coding_order_period = idx; |
michael@0 | 1573 | schedule_frames(cpi, start, -(start + half_range), arf_idx + 1, |
michael@0 | 1574 | gf_or_arf_group, level + 1); |
michael@0 | 1575 | schedule_frames(cpi, start + half_range + 1, abs_end, arf_idx, |
michael@0 | 1576 | gf_or_arf_group, level + 1); |
michael@0 | 1577 | } |
michael@0 | 1578 | } |
michael@0 | 1579 | |
michael@0 | 1580 | #define FIXED_ARF_GROUP_SIZE 16 |
michael@0 | 1581 | |
michael@0 | 1582 | void define_fixed_arf_period(VP9_COMP *cpi) { |
michael@0 | 1583 | int i; |
michael@0 | 1584 | int max_level = INT_MIN; |
michael@0 | 1585 | |
michael@0 | 1586 | assert(cpi->multi_arf_enabled); |
michael@0 | 1587 | assert(cpi->oxcf.lag_in_frames >= FIXED_ARF_GROUP_SIZE); |
michael@0 | 1588 | |
michael@0 | 1589 | // Save the weight of the last frame in the sequence before next |
michael@0 | 1590 | // sequence pattern overwrites it. |
michael@0 | 1591 | cpi->this_frame_weight = cpi->arf_weight[cpi->sequence_number]; |
michael@0 | 1592 | assert(cpi->this_frame_weight >= 0); |
michael@0 | 1593 | |
michael@0 | 1594 | // Initialize frame coding order variables. |
michael@0 | 1595 | cpi->new_frame_coding_order_period = 0; |
michael@0 | 1596 | cpi->next_frame_in_order = 0; |
michael@0 | 1597 | cpi->arf_buffered = 0; |
michael@0 | 1598 | vp9_zero(cpi->frame_coding_order); |
michael@0 | 1599 | vp9_zero(cpi->arf_buffer_idx); |
michael@0 | 1600 | vpx_memset(cpi->arf_weight, -1, sizeof(cpi->arf_weight)); |
michael@0 | 1601 | |
michael@0 | 1602 | if (cpi->twopass.frames_to_key <= (FIXED_ARF_GROUP_SIZE + 8)) { |
michael@0 | 1603 | // Setup a GF group close to the keyframe. |
michael@0 | 1604 | cpi->source_alt_ref_pending = 0; |
michael@0 | 1605 | cpi->baseline_gf_interval = cpi->twopass.frames_to_key; |
michael@0 | 1606 | schedule_frames(cpi, 0, (cpi->baseline_gf_interval - 1), 2, 0, 0); |
michael@0 | 1607 | } else { |
michael@0 | 1608 | // Setup a fixed period ARF group. |
michael@0 | 1609 | cpi->source_alt_ref_pending = 1; |
michael@0 | 1610 | cpi->baseline_gf_interval = FIXED_ARF_GROUP_SIZE; |
michael@0 | 1611 | schedule_frames(cpi, 0, -(cpi->baseline_gf_interval - 1), 2, 1, 0); |
michael@0 | 1612 | } |
michael@0 | 1613 | |
michael@0 | 1614 | // Replace level indicator of -1 with correct level. |
michael@0 | 1615 | for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { |
michael@0 | 1616 | if (cpi->arf_weight[i] > max_level) { |
michael@0 | 1617 | max_level = cpi->arf_weight[i]; |
michael@0 | 1618 | } |
michael@0 | 1619 | } |
michael@0 | 1620 | ++max_level; |
michael@0 | 1621 | for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { |
michael@0 | 1622 | if (cpi->arf_weight[i] == -1) { |
michael@0 | 1623 | cpi->arf_weight[i] = max_level; |
michael@0 | 1624 | } |
michael@0 | 1625 | } |
michael@0 | 1626 | cpi->max_arf_level = max_level; |
michael@0 | 1627 | #if 0 |
michael@0 | 1628 | printf("\nSchedule: "); |
michael@0 | 1629 | for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { |
michael@0 | 1630 | printf("%4d ", cpi->frame_coding_order[i]); |
michael@0 | 1631 | } |
michael@0 | 1632 | printf("\n"); |
michael@0 | 1633 | printf("ARFref: "); |
michael@0 | 1634 | for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { |
michael@0 | 1635 | printf("%4d ", cpi->arf_buffer_idx[i]); |
michael@0 | 1636 | } |
michael@0 | 1637 | printf("\n"); |
michael@0 | 1638 | printf("Weight: "); |
michael@0 | 1639 | for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { |
michael@0 | 1640 | printf("%4d ", cpi->arf_weight[i]); |
michael@0 | 1641 | } |
michael@0 | 1642 | printf("\n"); |
michael@0 | 1643 | #endif |
michael@0 | 1644 | } |
michael@0 | 1645 | #endif |
michael@0 | 1646 | |
michael@0 | 1647 | // Analyse and define a gf/arf group. |
michael@0 | 1648 | static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { |
michael@0 | 1649 | FIRSTPASS_STATS next_frame = { 0 }; |
michael@0 | 1650 | FIRSTPASS_STATS *start_pos; |
michael@0 | 1651 | int i; |
michael@0 | 1652 | double boost_score = 0.0; |
michael@0 | 1653 | double old_boost_score = 0.0; |
michael@0 | 1654 | double gf_group_err = 0.0; |
michael@0 | 1655 | double gf_first_frame_err = 0.0; |
michael@0 | 1656 | double mod_frame_err = 0.0; |
michael@0 | 1657 | |
michael@0 | 1658 | double mv_ratio_accumulator = 0.0; |
michael@0 | 1659 | double decay_accumulator = 1.0; |
michael@0 | 1660 | double zero_motion_accumulator = 1.0; |
michael@0 | 1661 | |
michael@0 | 1662 | double loop_decay_rate = 1.00; // Starting decay rate |
michael@0 | 1663 | double last_loop_decay_rate = 1.00; |
michael@0 | 1664 | |
michael@0 | 1665 | double this_frame_mv_in_out = 0.0; |
michael@0 | 1666 | double mv_in_out_accumulator = 0.0; |
michael@0 | 1667 | double abs_mv_in_out_accumulator = 0.0; |
michael@0 | 1668 | double mv_ratio_accumulator_thresh; |
michael@0 | 1669 | int max_bits = frame_max_bits(cpi); // Max for a single frame |
michael@0 | 1670 | |
michael@0 | 1671 | unsigned int allow_alt_ref = |
michael@0 | 1672 | cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames; |
michael@0 | 1673 | |
michael@0 | 1674 | int f_boost = 0; |
michael@0 | 1675 | int b_boost = 0; |
michael@0 | 1676 | int flash_detected; |
michael@0 | 1677 | int active_max_gf_interval; |
michael@0 | 1678 | |
michael@0 | 1679 | cpi->twopass.gf_group_bits = 0; |
michael@0 | 1680 | |
michael@0 | 1681 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 1682 | |
michael@0 | 1683 | start_pos = cpi->twopass.stats_in; |
michael@0 | 1684 | |
michael@0 | 1685 | // Load stats for the current frame. |
michael@0 | 1686 | mod_frame_err = calculate_modified_err(cpi, this_frame); |
michael@0 | 1687 | |
michael@0 | 1688 | // Note the error of the frame at the start of the group (this will be |
michael@0 | 1689 | // the GF frame error if we code a normal gf |
michael@0 | 1690 | gf_first_frame_err = mod_frame_err; |
michael@0 | 1691 | |
michael@0 | 1692 | // Special treatment if the current frame is a key frame (which is also |
michael@0 | 1693 | // a gf). If it is then its error score (and hence bit allocation) need |
michael@0 | 1694 | // to be subtracted out from the calculation for the GF group |
michael@0 | 1695 | if (cpi->common.frame_type == KEY_FRAME) |
michael@0 | 1696 | gf_group_err -= gf_first_frame_err; |
michael@0 | 1697 | |
michael@0 | 1698 | // Motion breakout threshold for loop below depends on image size. |
michael@0 | 1699 | mv_ratio_accumulator_thresh = (cpi->common.width + cpi->common.height) / 10.0; |
michael@0 | 1700 | |
michael@0 | 1701 | // Work out a maximum interval for the GF. |
michael@0 | 1702 | // If the image appears completely static we can extend beyond this. |
michael@0 | 1703 | // The value chosen depends on the active Q range. At low Q we have |
michael@0 | 1704 | // bits to spare and are better with a smaller interval and smaller boost. |
michael@0 | 1705 | // At high Q when there are few bits to spare we are better with a longer |
michael@0 | 1706 | // interval to spread the cost of the GF. |
michael@0 | 1707 | active_max_gf_interval = |
michael@0 | 1708 | 12 + ((int)vp9_convert_qindex_to_q(cpi->active_worst_quality) >> 5); |
michael@0 | 1709 | |
michael@0 | 1710 | if (active_max_gf_interval > cpi->max_gf_interval) |
michael@0 | 1711 | active_max_gf_interval = cpi->max_gf_interval; |
michael@0 | 1712 | |
michael@0 | 1713 | i = 0; |
michael@0 | 1714 | while (((i < cpi->twopass.static_scene_max_gf_interval) || |
michael@0 | 1715 | ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL)) && |
michael@0 | 1716 | (i < cpi->twopass.frames_to_key)) { |
michael@0 | 1717 | i++; // Increment the loop counter |
michael@0 | 1718 | |
michael@0 | 1719 | // Accumulate error score of frames in this gf group |
michael@0 | 1720 | mod_frame_err = calculate_modified_err(cpi, this_frame); |
michael@0 | 1721 | gf_group_err += mod_frame_err; |
michael@0 | 1722 | |
michael@0 | 1723 | if (EOF == input_stats(cpi, &next_frame)) |
michael@0 | 1724 | break; |
michael@0 | 1725 | |
michael@0 | 1726 | // Test for the case where there is a brief flash but the prediction |
michael@0 | 1727 | // quality back to an earlier frame is then restored. |
michael@0 | 1728 | flash_detected = detect_flash(cpi, 0); |
michael@0 | 1729 | |
michael@0 | 1730 | // Update the motion related elements to the boost calculation |
michael@0 | 1731 | accumulate_frame_motion_stats(&next_frame, |
michael@0 | 1732 | &this_frame_mv_in_out, &mv_in_out_accumulator, |
michael@0 | 1733 | &abs_mv_in_out_accumulator, |
michael@0 | 1734 | &mv_ratio_accumulator); |
michael@0 | 1735 | |
michael@0 | 1736 | // Cumulative effect of prediction quality decay |
michael@0 | 1737 | if (!flash_detected) { |
michael@0 | 1738 | last_loop_decay_rate = loop_decay_rate; |
michael@0 | 1739 | loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame); |
michael@0 | 1740 | decay_accumulator = decay_accumulator * loop_decay_rate; |
michael@0 | 1741 | |
michael@0 | 1742 | // Monitor for static sections. |
michael@0 | 1743 | if ((next_frame.pcnt_inter - next_frame.pcnt_motion) < |
michael@0 | 1744 | zero_motion_accumulator) { |
michael@0 | 1745 | zero_motion_accumulator = |
michael@0 | 1746 | (next_frame.pcnt_inter - next_frame.pcnt_motion); |
michael@0 | 1747 | } |
michael@0 | 1748 | |
michael@0 | 1749 | // Break clause to detect very still sections after motion |
michael@0 | 1750 | // (for example a static image after a fade or other transition). |
michael@0 | 1751 | if (detect_transition_to_still(cpi, i, 5, loop_decay_rate, |
michael@0 | 1752 | last_loop_decay_rate)) { |
michael@0 | 1753 | allow_alt_ref = 0; |
michael@0 | 1754 | break; |
michael@0 | 1755 | } |
michael@0 | 1756 | } |
michael@0 | 1757 | |
michael@0 | 1758 | // Calculate a boost number for this frame |
michael@0 | 1759 | boost_score += |
michael@0 | 1760 | (decay_accumulator * |
michael@0 | 1761 | calc_frame_boost(cpi, &next_frame, this_frame_mv_in_out)); |
michael@0 | 1762 | |
michael@0 | 1763 | // Break out conditions. |
michael@0 | 1764 | if ( |
michael@0 | 1765 | // Break at cpi->max_gf_interval unless almost totally static |
michael@0 | 1766 | (i >= active_max_gf_interval && (zero_motion_accumulator < 0.995)) || |
michael@0 | 1767 | ( |
michael@0 | 1768 | // Don't break out with a very short interval |
michael@0 | 1769 | (i > MIN_GF_INTERVAL) && |
michael@0 | 1770 | // Don't break out very close to a key frame |
michael@0 | 1771 | ((cpi->twopass.frames_to_key - i) >= MIN_GF_INTERVAL) && |
michael@0 | 1772 | ((boost_score > 125.0) || (next_frame.pcnt_inter < 0.75)) && |
michael@0 | 1773 | (!flash_detected) && |
michael@0 | 1774 | ((mv_ratio_accumulator > mv_ratio_accumulator_thresh) || |
michael@0 | 1775 | (abs_mv_in_out_accumulator > 3.0) || |
michael@0 | 1776 | (mv_in_out_accumulator < -2.0) || |
michael@0 | 1777 | ((boost_score - old_boost_score) < IIFACTOR)))) { |
michael@0 | 1778 | boost_score = old_boost_score; |
michael@0 | 1779 | break; |
michael@0 | 1780 | } |
michael@0 | 1781 | |
michael@0 | 1782 | *this_frame = next_frame; |
michael@0 | 1783 | |
michael@0 | 1784 | old_boost_score = boost_score; |
michael@0 | 1785 | } |
michael@0 | 1786 | |
michael@0 | 1787 | cpi->gf_zeromotion_pct = (int)(zero_motion_accumulator * 1000.0); |
michael@0 | 1788 | |
michael@0 | 1789 | // Don't allow a gf too near the next kf |
michael@0 | 1790 | if ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL) { |
michael@0 | 1791 | while (i < cpi->twopass.frames_to_key) { |
michael@0 | 1792 | i++; |
michael@0 | 1793 | |
michael@0 | 1794 | if (EOF == input_stats(cpi, this_frame)) |
michael@0 | 1795 | break; |
michael@0 | 1796 | |
michael@0 | 1797 | if (i < cpi->twopass.frames_to_key) { |
michael@0 | 1798 | mod_frame_err = calculate_modified_err(cpi, this_frame); |
michael@0 | 1799 | gf_group_err += mod_frame_err; |
michael@0 | 1800 | } |
michael@0 | 1801 | } |
michael@0 | 1802 | } |
michael@0 | 1803 | |
michael@0 | 1804 | // Set the interval until the next gf or arf. |
michael@0 | 1805 | cpi->baseline_gf_interval = i; |
michael@0 | 1806 | |
michael@0 | 1807 | #if CONFIG_MULTIPLE_ARF |
michael@0 | 1808 | if (cpi->multi_arf_enabled) { |
michael@0 | 1809 | // Initialize frame coding order variables. |
michael@0 | 1810 | cpi->new_frame_coding_order_period = 0; |
michael@0 | 1811 | cpi->next_frame_in_order = 0; |
michael@0 | 1812 | cpi->arf_buffered = 0; |
michael@0 | 1813 | vp9_zero(cpi->frame_coding_order); |
michael@0 | 1814 | vp9_zero(cpi->arf_buffer_idx); |
michael@0 | 1815 | vpx_memset(cpi->arf_weight, -1, sizeof(cpi->arf_weight)); |
michael@0 | 1816 | } |
michael@0 | 1817 | #endif |
michael@0 | 1818 | |
michael@0 | 1819 | // Should we use the alternate reference frame |
michael@0 | 1820 | if (allow_alt_ref && |
michael@0 | 1821 | (i < cpi->oxcf.lag_in_frames) && |
michael@0 | 1822 | (i >= MIN_GF_INTERVAL) && |
michael@0 | 1823 | // dont use ARF very near next kf |
michael@0 | 1824 | (i <= (cpi->twopass.frames_to_key - MIN_GF_INTERVAL)) && |
michael@0 | 1825 | ((next_frame.pcnt_inter > 0.75) || |
michael@0 | 1826 | (next_frame.pcnt_second_ref > 0.5)) && |
michael@0 | 1827 | ((mv_in_out_accumulator / (double)i > -0.2) || |
michael@0 | 1828 | (mv_in_out_accumulator > -2.0)) && |
michael@0 | 1829 | (boost_score > 100)) { |
michael@0 | 1830 | // Alternative boost calculation for alt ref |
michael@0 | 1831 | cpi->gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost, |
michael@0 | 1832 | &b_boost); |
michael@0 | 1833 | cpi->source_alt_ref_pending = 1; |
michael@0 | 1834 | |
michael@0 | 1835 | #if CONFIG_MULTIPLE_ARF |
michael@0 | 1836 | // Set the ARF schedule. |
michael@0 | 1837 | if (cpi->multi_arf_enabled) { |
michael@0 | 1838 | schedule_frames(cpi, 0, -(cpi->baseline_gf_interval - 1), 2, 1, 0); |
michael@0 | 1839 | } |
michael@0 | 1840 | #endif |
michael@0 | 1841 | } else { |
michael@0 | 1842 | cpi->gfu_boost = (int)boost_score; |
michael@0 | 1843 | cpi->source_alt_ref_pending = 0; |
michael@0 | 1844 | #if CONFIG_MULTIPLE_ARF |
michael@0 | 1845 | // Set the GF schedule. |
michael@0 | 1846 | if (cpi->multi_arf_enabled) { |
michael@0 | 1847 | schedule_frames(cpi, 0, cpi->baseline_gf_interval - 1, 2, 0, 0); |
michael@0 | 1848 | assert(cpi->new_frame_coding_order_period == cpi->baseline_gf_interval); |
michael@0 | 1849 | } |
michael@0 | 1850 | #endif |
michael@0 | 1851 | } |
michael@0 | 1852 | |
michael@0 | 1853 | #if CONFIG_MULTIPLE_ARF |
michael@0 | 1854 | if (cpi->multi_arf_enabled && (cpi->common.frame_type != KEY_FRAME)) { |
michael@0 | 1855 | int max_level = INT_MIN; |
michael@0 | 1856 | // Replace level indicator of -1 with correct level. |
michael@0 | 1857 | for (i = 0; i < cpi->frame_coding_order_period; ++i) { |
michael@0 | 1858 | if (cpi->arf_weight[i] > max_level) { |
michael@0 | 1859 | max_level = cpi->arf_weight[i]; |
michael@0 | 1860 | } |
michael@0 | 1861 | } |
michael@0 | 1862 | ++max_level; |
michael@0 | 1863 | for (i = 0; i < cpi->frame_coding_order_period; ++i) { |
michael@0 | 1864 | if (cpi->arf_weight[i] == -1) { |
michael@0 | 1865 | cpi->arf_weight[i] = max_level; |
michael@0 | 1866 | } |
michael@0 | 1867 | } |
michael@0 | 1868 | cpi->max_arf_level = max_level; |
michael@0 | 1869 | } |
michael@0 | 1870 | #if 0 |
michael@0 | 1871 | if (cpi->multi_arf_enabled) { |
michael@0 | 1872 | printf("\nSchedule: "); |
michael@0 | 1873 | for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { |
michael@0 | 1874 | printf("%4d ", cpi->frame_coding_order[i]); |
michael@0 | 1875 | } |
michael@0 | 1876 | printf("\n"); |
michael@0 | 1877 | printf("ARFref: "); |
michael@0 | 1878 | for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { |
michael@0 | 1879 | printf("%4d ", cpi->arf_buffer_idx[i]); |
michael@0 | 1880 | } |
michael@0 | 1881 | printf("\n"); |
michael@0 | 1882 | printf("Weight: "); |
michael@0 | 1883 | for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { |
michael@0 | 1884 | printf("%4d ", cpi->arf_weight[i]); |
michael@0 | 1885 | } |
michael@0 | 1886 | printf("\n"); |
michael@0 | 1887 | } |
michael@0 | 1888 | #endif |
michael@0 | 1889 | #endif |
michael@0 | 1890 | |
michael@0 | 1891 | // Now decide how many bits should be allocated to the GF group as a |
michael@0 | 1892 | // proportion of those remaining in the kf group. |
michael@0 | 1893 | // The final key frame group in the clip is treated as a special case |
michael@0 | 1894 | // where cpi->twopass.kf_group_bits is tied to cpi->twopass.bits_left. |
michael@0 | 1895 | // This is also important for short clips where there may only be one |
michael@0 | 1896 | // key frame. |
michael@0 | 1897 | if (cpi->twopass.frames_to_key >= (int)(cpi->twopass.total_stats.count - |
michael@0 | 1898 | cpi->common.current_video_frame)) { |
michael@0 | 1899 | cpi->twopass.kf_group_bits = |
michael@0 | 1900 | (cpi->twopass.bits_left > 0) ? cpi->twopass.bits_left : 0; |
michael@0 | 1901 | } |
michael@0 | 1902 | |
michael@0 | 1903 | // Calculate the bits to be allocated to the group as a whole |
michael@0 | 1904 | if ((cpi->twopass.kf_group_bits > 0) && |
michael@0 | 1905 | (cpi->twopass.kf_group_error_left > 0)) { |
michael@0 | 1906 | cpi->twopass.gf_group_bits = |
michael@0 | 1907 | (int64_t)(cpi->twopass.kf_group_bits * |
michael@0 | 1908 | (gf_group_err / cpi->twopass.kf_group_error_left)); |
michael@0 | 1909 | } else { |
michael@0 | 1910 | cpi->twopass.gf_group_bits = 0; |
michael@0 | 1911 | } |
michael@0 | 1912 | cpi->twopass.gf_group_bits = |
michael@0 | 1913 | (cpi->twopass.gf_group_bits < 0) |
michael@0 | 1914 | ? 0 |
michael@0 | 1915 | : (cpi->twopass.gf_group_bits > cpi->twopass.kf_group_bits) |
michael@0 | 1916 | ? cpi->twopass.kf_group_bits : cpi->twopass.gf_group_bits; |
michael@0 | 1917 | |
michael@0 | 1918 | // Clip cpi->twopass.gf_group_bits based on user supplied data rate |
michael@0 | 1919 | // variability limit (cpi->oxcf.two_pass_vbrmax_section) |
michael@0 | 1920 | if (cpi->twopass.gf_group_bits > |
michael@0 | 1921 | (int64_t)max_bits * cpi->baseline_gf_interval) |
michael@0 | 1922 | cpi->twopass.gf_group_bits = (int64_t)max_bits * cpi->baseline_gf_interval; |
michael@0 | 1923 | |
michael@0 | 1924 | // Reset the file position |
michael@0 | 1925 | reset_fpf_position(cpi, start_pos); |
michael@0 | 1926 | |
michael@0 | 1927 | // Update the record of error used so far (only done once per gf group) |
michael@0 | 1928 | cpi->twopass.modified_error_used += gf_group_err; |
michael@0 | 1929 | |
michael@0 | 1930 | // Assign bits to the arf or gf. |
michael@0 | 1931 | for (i = 0; |
michael@0 | 1932 | i <= (cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME); |
michael@0 | 1933 | ++i) { |
michael@0 | 1934 | int allocation_chunks; |
michael@0 | 1935 | int q = cpi->oxcf.fixed_q < 0 ? cpi->last_q[INTER_FRAME] |
michael@0 | 1936 | : cpi->oxcf.fixed_q; |
michael@0 | 1937 | int gf_bits; |
michael@0 | 1938 | |
michael@0 | 1939 | int boost = (cpi->gfu_boost * vp9_gfboost_qadjust(q)) / 100; |
michael@0 | 1940 | |
michael@0 | 1941 | // Set max and minimum boost and hence minimum allocation |
michael@0 | 1942 | boost = clamp(boost, 125, (cpi->baseline_gf_interval + 1) * 200); |
michael@0 | 1943 | |
michael@0 | 1944 | if (cpi->source_alt_ref_pending && i == 0) |
michael@0 | 1945 | allocation_chunks = ((cpi->baseline_gf_interval + 1) * 100) + boost; |
michael@0 | 1946 | else |
michael@0 | 1947 | allocation_chunks = (cpi->baseline_gf_interval * 100) + (boost - 100); |
michael@0 | 1948 | |
michael@0 | 1949 | // Prevent overflow |
michael@0 | 1950 | if (boost > 1023) { |
michael@0 | 1951 | int divisor = boost >> 10; |
michael@0 | 1952 | boost /= divisor; |
michael@0 | 1953 | allocation_chunks /= divisor; |
michael@0 | 1954 | } |
michael@0 | 1955 | |
michael@0 | 1956 | // Calculate the number of bits to be spent on the gf or arf based on |
michael@0 | 1957 | // the boost number |
michael@0 | 1958 | gf_bits = (int)((double)boost * (cpi->twopass.gf_group_bits / |
michael@0 | 1959 | (double)allocation_chunks)); |
michael@0 | 1960 | |
michael@0 | 1961 | // If the frame that is to be boosted is simpler than the average for |
michael@0 | 1962 | // the gf/arf group then use an alternative calculation |
michael@0 | 1963 | // based on the error score of the frame itself |
michael@0 | 1964 | if (mod_frame_err < gf_group_err / (double)cpi->baseline_gf_interval) { |
michael@0 | 1965 | double alt_gf_grp_bits = |
michael@0 | 1966 | (double)cpi->twopass.kf_group_bits * |
michael@0 | 1967 | (mod_frame_err * (double)cpi->baseline_gf_interval) / |
michael@0 | 1968 | DOUBLE_DIVIDE_CHECK(cpi->twopass.kf_group_error_left); |
michael@0 | 1969 | |
michael@0 | 1970 | int alt_gf_bits = (int)((double)boost * (alt_gf_grp_bits / |
michael@0 | 1971 | (double)allocation_chunks)); |
michael@0 | 1972 | |
michael@0 | 1973 | if (gf_bits > alt_gf_bits) |
michael@0 | 1974 | gf_bits = alt_gf_bits; |
michael@0 | 1975 | } else { |
michael@0 | 1976 | // If it is harder than other frames in the group make sure it at |
michael@0 | 1977 | // least receives an allocation in keeping with its relative error |
michael@0 | 1978 | // score, otherwise it may be worse off than an "un-boosted" frame. |
michael@0 | 1979 | int alt_gf_bits = (int)((double)cpi->twopass.kf_group_bits * |
michael@0 | 1980 | mod_frame_err / |
michael@0 | 1981 | DOUBLE_DIVIDE_CHECK(cpi->twopass.kf_group_error_left)); |
michael@0 | 1982 | |
michael@0 | 1983 | if (alt_gf_bits > gf_bits) |
michael@0 | 1984 | gf_bits = alt_gf_bits; |
michael@0 | 1985 | } |
michael@0 | 1986 | |
michael@0 | 1987 | // Dont allow a negative value for gf_bits |
michael@0 | 1988 | if (gf_bits < 0) |
michael@0 | 1989 | gf_bits = 0; |
michael@0 | 1990 | |
michael@0 | 1991 | // Add in minimum for a frame |
michael@0 | 1992 | gf_bits += cpi->min_frame_bandwidth; |
michael@0 | 1993 | |
michael@0 | 1994 | if (i == 0) { |
michael@0 | 1995 | cpi->twopass.gf_bits = gf_bits; |
michael@0 | 1996 | } |
michael@0 | 1997 | if (i == 1 || (!cpi->source_alt_ref_pending |
michael@0 | 1998 | && (cpi->common.frame_type != KEY_FRAME))) { |
michael@0 | 1999 | // Per frame bit target for this frame |
michael@0 | 2000 | cpi->per_frame_bandwidth = gf_bits; |
michael@0 | 2001 | } |
michael@0 | 2002 | } |
michael@0 | 2003 | |
michael@0 | 2004 | { |
michael@0 | 2005 | // Adjust KF group bits and error remaining |
michael@0 | 2006 | cpi->twopass.kf_group_error_left -= (int64_t)gf_group_err; |
michael@0 | 2007 | cpi->twopass.kf_group_bits -= cpi->twopass.gf_group_bits; |
michael@0 | 2008 | |
michael@0 | 2009 | if (cpi->twopass.kf_group_bits < 0) |
michael@0 | 2010 | cpi->twopass.kf_group_bits = 0; |
michael@0 | 2011 | |
michael@0 | 2012 | // Note the error score left in the remaining frames of the group. |
michael@0 | 2013 | // For normal GFs we want to remove the error score for the first frame |
michael@0 | 2014 | // of the group (except in Key frame case where this has already |
michael@0 | 2015 | // happened) |
michael@0 | 2016 | if (!cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME) |
michael@0 | 2017 | cpi->twopass.gf_group_error_left = (int64_t)(gf_group_err |
michael@0 | 2018 | - gf_first_frame_err); |
michael@0 | 2019 | else |
michael@0 | 2020 | cpi->twopass.gf_group_error_left = (int64_t)gf_group_err; |
michael@0 | 2021 | |
michael@0 | 2022 | cpi->twopass.gf_group_bits -= cpi->twopass.gf_bits |
michael@0 | 2023 | - cpi->min_frame_bandwidth; |
michael@0 | 2024 | |
michael@0 | 2025 | if (cpi->twopass.gf_group_bits < 0) |
michael@0 | 2026 | cpi->twopass.gf_group_bits = 0; |
michael@0 | 2027 | |
michael@0 | 2028 | // This condition could fail if there are two kfs very close together |
michael@0 | 2029 | // despite (MIN_GF_INTERVAL) and would cause a divide by 0 in the |
michael@0 | 2030 | // calculation of alt_extra_bits. |
michael@0 | 2031 | if (cpi->baseline_gf_interval >= 3) { |
michael@0 | 2032 | const int boost = cpi->source_alt_ref_pending ? b_boost : cpi->gfu_boost; |
michael@0 | 2033 | |
michael@0 | 2034 | if (boost >= 150) { |
michael@0 | 2035 | int alt_extra_bits; |
michael@0 | 2036 | int pct_extra = (boost - 100) / 50; |
michael@0 | 2037 | pct_extra = (pct_extra > 20) ? 20 : pct_extra; |
michael@0 | 2038 | |
michael@0 | 2039 | alt_extra_bits = (int)((cpi->twopass.gf_group_bits * pct_extra) / 100); |
michael@0 | 2040 | cpi->twopass.gf_group_bits -= alt_extra_bits; |
michael@0 | 2041 | } |
michael@0 | 2042 | } |
michael@0 | 2043 | } |
michael@0 | 2044 | |
michael@0 | 2045 | if (cpi->common.frame_type != KEY_FRAME) { |
michael@0 | 2046 | FIRSTPASS_STATS sectionstats; |
michael@0 | 2047 | |
michael@0 | 2048 | zero_stats(§ionstats); |
michael@0 | 2049 | reset_fpf_position(cpi, start_pos); |
michael@0 | 2050 | |
michael@0 | 2051 | for (i = 0; i < cpi->baseline_gf_interval; i++) { |
michael@0 | 2052 | input_stats(cpi, &next_frame); |
michael@0 | 2053 | accumulate_stats(§ionstats, &next_frame); |
michael@0 | 2054 | } |
michael@0 | 2055 | |
michael@0 | 2056 | avg_stats(§ionstats); |
michael@0 | 2057 | |
michael@0 | 2058 | cpi->twopass.section_intra_rating = (int) |
michael@0 | 2059 | (sectionstats.intra_error / |
michael@0 | 2060 | DOUBLE_DIVIDE_CHECK(sectionstats.coded_error)); |
michael@0 | 2061 | |
michael@0 | 2062 | reset_fpf_position(cpi, start_pos); |
michael@0 | 2063 | } |
michael@0 | 2064 | } |
michael@0 | 2065 | |
michael@0 | 2066 | // Allocate bits to a normal frame that is neither a gf an arf or a key frame. |
michael@0 | 2067 | static void assign_std_frame_bits(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { |
michael@0 | 2068 | int target_frame_size; |
michael@0 | 2069 | |
michael@0 | 2070 | double modified_err; |
michael@0 | 2071 | double err_fraction; |
michael@0 | 2072 | |
michael@0 | 2073 | // Max for a single frame. |
michael@0 | 2074 | int max_bits = frame_max_bits(cpi); |
michael@0 | 2075 | |
michael@0 | 2076 | // Calculate modified prediction error used in bit allocation. |
michael@0 | 2077 | modified_err = calculate_modified_err(cpi, this_frame); |
michael@0 | 2078 | |
michael@0 | 2079 | if (cpi->twopass.gf_group_error_left > 0) |
michael@0 | 2080 | // What portion of the remaining GF group error is used by this frame. |
michael@0 | 2081 | err_fraction = modified_err / cpi->twopass.gf_group_error_left; |
michael@0 | 2082 | else |
michael@0 | 2083 | err_fraction = 0.0; |
michael@0 | 2084 | |
michael@0 | 2085 | // How many of those bits available for allocation should we give it? |
michael@0 | 2086 | target_frame_size = (int)((double)cpi->twopass.gf_group_bits * err_fraction); |
michael@0 | 2087 | |
michael@0 | 2088 | // Clip target size to 0 - max_bits (or cpi->twopass.gf_group_bits) at |
michael@0 | 2089 | // the top end. |
michael@0 | 2090 | if (target_frame_size < 0) { |
michael@0 | 2091 | target_frame_size = 0; |
michael@0 | 2092 | } else { |
michael@0 | 2093 | if (target_frame_size > max_bits) |
michael@0 | 2094 | target_frame_size = max_bits; |
michael@0 | 2095 | |
michael@0 | 2096 | if (target_frame_size > cpi->twopass.gf_group_bits) |
michael@0 | 2097 | target_frame_size = (int)cpi->twopass.gf_group_bits; |
michael@0 | 2098 | } |
michael@0 | 2099 | |
michael@0 | 2100 | // Adjust error and bits remaining. |
michael@0 | 2101 | cpi->twopass.gf_group_error_left -= (int64_t)modified_err; |
michael@0 | 2102 | cpi->twopass.gf_group_bits -= target_frame_size; |
michael@0 | 2103 | |
michael@0 | 2104 | if (cpi->twopass.gf_group_bits < 0) |
michael@0 | 2105 | cpi->twopass.gf_group_bits = 0; |
michael@0 | 2106 | |
michael@0 | 2107 | // Add in the minimum number of bits that is set aside for every frame. |
michael@0 | 2108 | target_frame_size += cpi->min_frame_bandwidth; |
michael@0 | 2109 | |
michael@0 | 2110 | // Per frame bit target for this frame. |
michael@0 | 2111 | cpi->per_frame_bandwidth = target_frame_size; |
michael@0 | 2112 | } |
michael@0 | 2113 | |
michael@0 | 2114 | // Make a damped adjustment to the active max q. |
michael@0 | 2115 | static int adjust_active_maxq(int old_maxqi, int new_maxqi) { |
michael@0 | 2116 | int i; |
michael@0 | 2117 | const double old_q = vp9_convert_qindex_to_q(old_maxqi); |
michael@0 | 2118 | const double new_q = vp9_convert_qindex_to_q(new_maxqi); |
michael@0 | 2119 | const double target_q = ((old_q * 7.0) + new_q) / 8.0; |
michael@0 | 2120 | |
michael@0 | 2121 | if (target_q > old_q) { |
michael@0 | 2122 | for (i = old_maxqi; i <= new_maxqi; i++) |
michael@0 | 2123 | if (vp9_convert_qindex_to_q(i) >= target_q) |
michael@0 | 2124 | return i; |
michael@0 | 2125 | } else { |
michael@0 | 2126 | for (i = old_maxqi; i >= new_maxqi; i--) |
michael@0 | 2127 | if (vp9_convert_qindex_to_q(i) <= target_q) |
michael@0 | 2128 | return i; |
michael@0 | 2129 | } |
michael@0 | 2130 | |
michael@0 | 2131 | return new_maxqi; |
michael@0 | 2132 | } |
michael@0 | 2133 | |
michael@0 | 2134 | void vp9_second_pass(VP9_COMP *cpi) { |
michael@0 | 2135 | int tmp_q; |
michael@0 | 2136 | int frames_left = (int)(cpi->twopass.total_stats.count - |
michael@0 | 2137 | cpi->common.current_video_frame); |
michael@0 | 2138 | |
michael@0 | 2139 | FIRSTPASS_STATS this_frame; |
michael@0 | 2140 | FIRSTPASS_STATS this_frame_copy; |
michael@0 | 2141 | |
michael@0 | 2142 | double this_frame_intra_error; |
michael@0 | 2143 | double this_frame_coded_error; |
michael@0 | 2144 | |
michael@0 | 2145 | if (!cpi->twopass.stats_in) |
michael@0 | 2146 | return; |
michael@0 | 2147 | |
michael@0 | 2148 | vp9_clear_system_state(); |
michael@0 | 2149 | |
michael@0 | 2150 | if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { |
michael@0 | 2151 | cpi->active_worst_quality = cpi->oxcf.cq_level; |
michael@0 | 2152 | } else { |
michael@0 | 2153 | // Special case code for first frame. |
michael@0 | 2154 | if (cpi->common.current_video_frame == 0) { |
michael@0 | 2155 | int section_target_bandwidth = |
michael@0 | 2156 | (int)(cpi->twopass.bits_left / frames_left); |
michael@0 | 2157 | cpi->twopass.est_max_qcorrection_factor = 1.0; |
michael@0 | 2158 | |
michael@0 | 2159 | // Set a cq_level in constrained quality mode. |
michael@0 | 2160 | // Commenting this code out for now since it does not seem to be |
michael@0 | 2161 | // working well. |
michael@0 | 2162 | /* |
michael@0 | 2163 | if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { |
michael@0 | 2164 | int est_cq = estimate_cq(cpi, &cpi->twopass.total_left_stats, |
michael@0 | 2165 | section_target_bandwidth); |
michael@0 | 2166 | |
michael@0 | 2167 | if (est_cq > cpi->cq_target_quality) |
michael@0 | 2168 | cpi->cq_target_quality = est_cq; |
michael@0 | 2169 | else |
michael@0 | 2170 | cpi->cq_target_quality = cpi->oxcf.cq_level; |
michael@0 | 2171 | } |
michael@0 | 2172 | */ |
michael@0 | 2173 | |
michael@0 | 2174 | // guess at maxq needed in 2nd pass |
michael@0 | 2175 | cpi->twopass.maxq_max_limit = cpi->worst_quality; |
michael@0 | 2176 | cpi->twopass.maxq_min_limit = cpi->best_quality; |
michael@0 | 2177 | |
michael@0 | 2178 | tmp_q = estimate_max_q(cpi, &cpi->twopass.total_left_stats, |
michael@0 | 2179 | section_target_bandwidth); |
michael@0 | 2180 | |
michael@0 | 2181 | cpi->active_worst_quality = tmp_q; |
michael@0 | 2182 | cpi->ni_av_qi = tmp_q; |
michael@0 | 2183 | cpi->avg_q = vp9_convert_qindex_to_q(tmp_q); |
michael@0 | 2184 | |
michael@0 | 2185 | // Limit the maxq value returned subsequently. |
michael@0 | 2186 | // This increases the risk of overspend or underspend if the initial |
michael@0 | 2187 | // estimate for the clip is bad, but helps prevent excessive |
michael@0 | 2188 | // variation in Q, especially near the end of a clip |
michael@0 | 2189 | // where for example a small overspend may cause Q to crash |
michael@0 | 2190 | adjust_maxq_qrange(cpi); |
michael@0 | 2191 | } |
michael@0 | 2192 | |
michael@0 | 2193 | // The last few frames of a clip almost always have to few or too many |
michael@0 | 2194 | // bits and for the sake of over exact rate control we dont want to make |
michael@0 | 2195 | // radical adjustments to the allowed quantizer range just to use up a |
michael@0 | 2196 | // few surplus bits or get beneath the target rate. |
michael@0 | 2197 | else if ((cpi->common.current_video_frame < |
michael@0 | 2198 | (((unsigned int)cpi->twopass.total_stats.count * 255) >> 8)) && |
michael@0 | 2199 | ((cpi->common.current_video_frame + cpi->baseline_gf_interval) < |
michael@0 | 2200 | (unsigned int)cpi->twopass.total_stats.count)) { |
michael@0 | 2201 | int section_target_bandwidth = |
michael@0 | 2202 | (int)(cpi->twopass.bits_left / frames_left); |
michael@0 | 2203 | if (frames_left < 1) |
michael@0 | 2204 | frames_left = 1; |
michael@0 | 2205 | |
michael@0 | 2206 | tmp_q = estimate_max_q( |
michael@0 | 2207 | cpi, |
michael@0 | 2208 | &cpi->twopass.total_left_stats, |
michael@0 | 2209 | section_target_bandwidth); |
michael@0 | 2210 | |
michael@0 | 2211 | // Make a damped adjustment to active max Q |
michael@0 | 2212 | cpi->active_worst_quality = |
michael@0 | 2213 | adjust_active_maxq(cpi->active_worst_quality, tmp_q); |
michael@0 | 2214 | } |
michael@0 | 2215 | } |
michael@0 | 2216 | vp9_zero(this_frame); |
michael@0 | 2217 | if (EOF == input_stats(cpi, &this_frame)) |
michael@0 | 2218 | return; |
michael@0 | 2219 | |
michael@0 | 2220 | this_frame_intra_error = this_frame.intra_error; |
michael@0 | 2221 | this_frame_coded_error = this_frame.coded_error; |
michael@0 | 2222 | |
michael@0 | 2223 | // keyframe and section processing ! |
michael@0 | 2224 | if (cpi->twopass.frames_to_key == 0) { |
michael@0 | 2225 | // Define next KF group and assign bits to it |
michael@0 | 2226 | this_frame_copy = this_frame; |
michael@0 | 2227 | find_next_key_frame(cpi, &this_frame_copy); |
michael@0 | 2228 | } |
michael@0 | 2229 | |
michael@0 | 2230 | // Is this a GF / ARF (Note that a KF is always also a GF) |
michael@0 | 2231 | if (cpi->frames_till_gf_update_due == 0) { |
michael@0 | 2232 | // Define next gf group and assign bits to it |
michael@0 | 2233 | this_frame_copy = this_frame; |
michael@0 | 2234 | |
michael@0 | 2235 | cpi->gf_zeromotion_pct = 0; |
michael@0 | 2236 | |
michael@0 | 2237 | #if CONFIG_MULTIPLE_ARF |
michael@0 | 2238 | if (cpi->multi_arf_enabled) { |
michael@0 | 2239 | define_fixed_arf_period(cpi); |
michael@0 | 2240 | } else { |
michael@0 | 2241 | #endif |
michael@0 | 2242 | define_gf_group(cpi, &this_frame_copy); |
michael@0 | 2243 | #if CONFIG_MULTIPLE_ARF |
michael@0 | 2244 | } |
michael@0 | 2245 | #endif |
michael@0 | 2246 | |
michael@0 | 2247 | if (cpi->gf_zeromotion_pct > 995) { |
michael@0 | 2248 | // As long as max_thresh for encode breakout is small enough, it is ok |
michael@0 | 2249 | // to enable it for no-show frame, i.e. set enable_encode_breakout to 2. |
michael@0 | 2250 | if (!cpi->common.show_frame) |
michael@0 | 2251 | cpi->enable_encode_breakout = 0; |
michael@0 | 2252 | else |
michael@0 | 2253 | cpi->enable_encode_breakout = 2; |
michael@0 | 2254 | } |
michael@0 | 2255 | |
michael@0 | 2256 | // If we are going to code an altref frame at the end of the group |
michael@0 | 2257 | // and the current frame is not a key frame.... |
michael@0 | 2258 | // If the previous group used an arf this frame has already benefited |
michael@0 | 2259 | // from that arf boost and it should not be given extra bits |
michael@0 | 2260 | // If the previous group was NOT coded using arf we may want to apply |
michael@0 | 2261 | // some boost to this GF as well |
michael@0 | 2262 | if (cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME)) { |
michael@0 | 2263 | // Assign a standard frames worth of bits from those allocated |
michael@0 | 2264 | // to the GF group |
michael@0 | 2265 | int bak = cpi->per_frame_bandwidth; |
michael@0 | 2266 | this_frame_copy = this_frame; |
michael@0 | 2267 | assign_std_frame_bits(cpi, &this_frame_copy); |
michael@0 | 2268 | cpi->per_frame_bandwidth = bak; |
michael@0 | 2269 | } |
michael@0 | 2270 | } else { |
michael@0 | 2271 | // Otherwise this is an ordinary frame |
michael@0 | 2272 | // Assign bits from those allocated to the GF group |
michael@0 | 2273 | this_frame_copy = this_frame; |
michael@0 | 2274 | assign_std_frame_bits(cpi, &this_frame_copy); |
michael@0 | 2275 | } |
michael@0 | 2276 | |
michael@0 | 2277 | // Keep a globally available copy of this and the next frame's iiratio. |
michael@0 | 2278 | cpi->twopass.this_iiratio = (int)(this_frame_intra_error / |
michael@0 | 2279 | DOUBLE_DIVIDE_CHECK(this_frame_coded_error)); |
michael@0 | 2280 | { |
michael@0 | 2281 | FIRSTPASS_STATS next_frame; |
michael@0 | 2282 | if (lookup_next_frame_stats(cpi, &next_frame) != EOF) { |
michael@0 | 2283 | cpi->twopass.next_iiratio = (int)(next_frame.intra_error / |
michael@0 | 2284 | DOUBLE_DIVIDE_CHECK(next_frame.coded_error)); |
michael@0 | 2285 | } |
michael@0 | 2286 | } |
michael@0 | 2287 | |
michael@0 | 2288 | // Set nominal per second bandwidth for this frame |
michael@0 | 2289 | cpi->target_bandwidth = (int)(cpi->per_frame_bandwidth |
michael@0 | 2290 | * cpi->output_framerate); |
michael@0 | 2291 | if (cpi->target_bandwidth < 0) |
michael@0 | 2292 | cpi->target_bandwidth = 0; |
michael@0 | 2293 | |
michael@0 | 2294 | cpi->twopass.frames_to_key--; |
michael@0 | 2295 | |
michael@0 | 2296 | // Update the total stats remaining structure |
michael@0 | 2297 | subtract_stats(&cpi->twopass.total_left_stats, &this_frame); |
michael@0 | 2298 | } |
michael@0 | 2299 | |
michael@0 | 2300 | static int test_candidate_kf(VP9_COMP *cpi, |
michael@0 | 2301 | FIRSTPASS_STATS *last_frame, |
michael@0 | 2302 | FIRSTPASS_STATS *this_frame, |
michael@0 | 2303 | FIRSTPASS_STATS *next_frame) { |
michael@0 | 2304 | int is_viable_kf = 0; |
michael@0 | 2305 | |
michael@0 | 2306 | // Does the frame satisfy the primary criteria of a key frame |
michael@0 | 2307 | // If so, then examine how well it predicts subsequent frames |
michael@0 | 2308 | if ((this_frame->pcnt_second_ref < 0.10) && |
michael@0 | 2309 | (next_frame->pcnt_second_ref < 0.10) && |
michael@0 | 2310 | ((this_frame->pcnt_inter < 0.05) || |
michael@0 | 2311 | (((this_frame->pcnt_inter - this_frame->pcnt_neutral) < .35) && |
michael@0 | 2312 | ((this_frame->intra_error / |
michael@0 | 2313 | DOUBLE_DIVIDE_CHECK(this_frame->coded_error)) < 2.5) && |
michael@0 | 2314 | ((fabs(last_frame->coded_error - this_frame->coded_error) / |
michael@0 | 2315 | DOUBLE_DIVIDE_CHECK(this_frame->coded_error) > |
michael@0 | 2316 | .40) || |
michael@0 | 2317 | (fabs(last_frame->intra_error - this_frame->intra_error) / |
michael@0 | 2318 | DOUBLE_DIVIDE_CHECK(this_frame->intra_error) > |
michael@0 | 2319 | .40) || |
michael@0 | 2320 | ((next_frame->intra_error / |
michael@0 | 2321 | DOUBLE_DIVIDE_CHECK(next_frame->coded_error)) > 3.5))))) { |
michael@0 | 2322 | int i; |
michael@0 | 2323 | FIRSTPASS_STATS *start_pos; |
michael@0 | 2324 | |
michael@0 | 2325 | FIRSTPASS_STATS local_next_frame; |
michael@0 | 2326 | |
michael@0 | 2327 | double boost_score = 0.0; |
michael@0 | 2328 | double old_boost_score = 0.0; |
michael@0 | 2329 | double decay_accumulator = 1.0; |
michael@0 | 2330 | double next_iiratio; |
michael@0 | 2331 | |
michael@0 | 2332 | local_next_frame = *next_frame; |
michael@0 | 2333 | |
michael@0 | 2334 | // Note the starting file position so we can reset to it |
michael@0 | 2335 | start_pos = cpi->twopass.stats_in; |
michael@0 | 2336 | |
michael@0 | 2337 | // Examine how well the key frame predicts subsequent frames |
michael@0 | 2338 | for (i = 0; i < 16; i++) { |
michael@0 | 2339 | next_iiratio = (IIKFACTOR1 * local_next_frame.intra_error / |
michael@0 | 2340 | DOUBLE_DIVIDE_CHECK(local_next_frame.coded_error)); |
michael@0 | 2341 | |
michael@0 | 2342 | if (next_iiratio > RMAX) |
michael@0 | 2343 | next_iiratio = RMAX; |
michael@0 | 2344 | |
michael@0 | 2345 | // Cumulative effect of decay in prediction quality |
michael@0 | 2346 | if (local_next_frame.pcnt_inter > 0.85) |
michael@0 | 2347 | decay_accumulator = decay_accumulator * local_next_frame.pcnt_inter; |
michael@0 | 2348 | else |
michael@0 | 2349 | decay_accumulator = |
michael@0 | 2350 | decay_accumulator * ((0.85 + local_next_frame.pcnt_inter) / 2.0); |
michael@0 | 2351 | |
michael@0 | 2352 | // decay_accumulator = decay_accumulator * local_next_frame.pcnt_inter; |
michael@0 | 2353 | |
michael@0 | 2354 | // Keep a running total |
michael@0 | 2355 | boost_score += (decay_accumulator * next_iiratio); |
michael@0 | 2356 | |
michael@0 | 2357 | // Test various breakout clauses |
michael@0 | 2358 | if ((local_next_frame.pcnt_inter < 0.05) || |
michael@0 | 2359 | (next_iiratio < 1.5) || |
michael@0 | 2360 | (((local_next_frame.pcnt_inter - |
michael@0 | 2361 | local_next_frame.pcnt_neutral) < 0.20) && |
michael@0 | 2362 | (next_iiratio < 3.0)) || |
michael@0 | 2363 | ((boost_score - old_boost_score) < 3.0) || |
michael@0 | 2364 | (local_next_frame.intra_error < 200) |
michael@0 | 2365 | ) { |
michael@0 | 2366 | break; |
michael@0 | 2367 | } |
michael@0 | 2368 | |
michael@0 | 2369 | old_boost_score = boost_score; |
michael@0 | 2370 | |
michael@0 | 2371 | // Get the next frame details |
michael@0 | 2372 | if (EOF == input_stats(cpi, &local_next_frame)) |
michael@0 | 2373 | break; |
michael@0 | 2374 | } |
michael@0 | 2375 | |
michael@0 | 2376 | // If there is tolerable prediction for at least the next 3 frames then |
michael@0 | 2377 | // break out else discard this potential key frame and move on |
michael@0 | 2378 | if (boost_score > 30.0 && (i > 3)) { |
michael@0 | 2379 | is_viable_kf = 1; |
michael@0 | 2380 | } else { |
michael@0 | 2381 | // Reset the file position |
michael@0 | 2382 | reset_fpf_position(cpi, start_pos); |
michael@0 | 2383 | |
michael@0 | 2384 | is_viable_kf = 0; |
michael@0 | 2385 | } |
michael@0 | 2386 | } |
michael@0 | 2387 | |
michael@0 | 2388 | return is_viable_kf; |
michael@0 | 2389 | } |
michael@0 | 2390 | static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { |
michael@0 | 2391 | int i, j; |
michael@0 | 2392 | FIRSTPASS_STATS last_frame; |
michael@0 | 2393 | FIRSTPASS_STATS first_frame; |
michael@0 | 2394 | FIRSTPASS_STATS next_frame; |
michael@0 | 2395 | FIRSTPASS_STATS *start_position; |
michael@0 | 2396 | |
michael@0 | 2397 | double decay_accumulator = 1.0; |
michael@0 | 2398 | double zero_motion_accumulator = 1.0; |
michael@0 | 2399 | double boost_score = 0; |
michael@0 | 2400 | double loop_decay_rate; |
michael@0 | 2401 | |
michael@0 | 2402 | double kf_mod_err = 0.0; |
michael@0 | 2403 | double kf_group_err = 0.0; |
michael@0 | 2404 | double kf_group_intra_err = 0.0; |
michael@0 | 2405 | double kf_group_coded_err = 0.0; |
michael@0 | 2406 | double recent_loop_decay[8] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; |
michael@0 | 2407 | |
michael@0 | 2408 | vp9_zero(next_frame); |
michael@0 | 2409 | |
michael@0 | 2410 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 2411 | start_position = cpi->twopass.stats_in; |
michael@0 | 2412 | |
michael@0 | 2413 | cpi->common.frame_type = KEY_FRAME; |
michael@0 | 2414 | |
michael@0 | 2415 | // is this a forced key frame by interval |
michael@0 | 2416 | cpi->this_key_frame_forced = cpi->next_key_frame_forced; |
michael@0 | 2417 | |
michael@0 | 2418 | // Clear the alt ref active flag as this can never be active on a key frame |
michael@0 | 2419 | cpi->source_alt_ref_active = 0; |
michael@0 | 2420 | |
michael@0 | 2421 | // Kf is always a gf so clear frames till next gf counter |
michael@0 | 2422 | cpi->frames_till_gf_update_due = 0; |
michael@0 | 2423 | |
michael@0 | 2424 | cpi->twopass.frames_to_key = 1; |
michael@0 | 2425 | |
michael@0 | 2426 | // Take a copy of the initial frame details |
michael@0 | 2427 | first_frame = *this_frame; |
michael@0 | 2428 | |
michael@0 | 2429 | cpi->twopass.kf_group_bits = 0; // Total bits available to kf group |
michael@0 | 2430 | cpi->twopass.kf_group_error_left = 0; // Group modified error score. |
michael@0 | 2431 | |
michael@0 | 2432 | kf_mod_err = calculate_modified_err(cpi, this_frame); |
michael@0 | 2433 | |
michael@0 | 2434 | // find the next keyframe |
michael@0 | 2435 | i = 0; |
michael@0 | 2436 | while (cpi->twopass.stats_in < cpi->twopass.stats_in_end) { |
michael@0 | 2437 | // Accumulate kf group error |
michael@0 | 2438 | kf_group_err += calculate_modified_err(cpi, this_frame); |
michael@0 | 2439 | |
michael@0 | 2440 | // These figures keep intra and coded error counts for all frames including |
michael@0 | 2441 | // key frames in the group. The effect of the key frame itself can be |
michael@0 | 2442 | // subtracted out using the first_frame data collected above. |
michael@0 | 2443 | kf_group_intra_err += this_frame->intra_error; |
michael@0 | 2444 | kf_group_coded_err += this_frame->coded_error; |
michael@0 | 2445 | |
michael@0 | 2446 | // load a the next frame's stats |
michael@0 | 2447 | last_frame = *this_frame; |
michael@0 | 2448 | input_stats(cpi, this_frame); |
michael@0 | 2449 | |
michael@0 | 2450 | // Provided that we are not at the end of the file... |
michael@0 | 2451 | if (cpi->oxcf.auto_key |
michael@0 | 2452 | && lookup_next_frame_stats(cpi, &next_frame) != EOF) { |
michael@0 | 2453 | // Normal scene cut check |
michael@0 | 2454 | if (test_candidate_kf(cpi, &last_frame, this_frame, &next_frame)) |
michael@0 | 2455 | break; |
michael@0 | 2456 | |
michael@0 | 2457 | |
michael@0 | 2458 | // How fast is prediction quality decaying |
michael@0 | 2459 | loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame); |
michael@0 | 2460 | |
michael@0 | 2461 | // We want to know something about the recent past... rather than |
michael@0 | 2462 | // as used elsewhere where we are concened with decay in prediction |
michael@0 | 2463 | // quality since the last GF or KF. |
michael@0 | 2464 | recent_loop_decay[i % 8] = loop_decay_rate; |
michael@0 | 2465 | decay_accumulator = 1.0; |
michael@0 | 2466 | for (j = 0; j < 8; j++) |
michael@0 | 2467 | decay_accumulator *= recent_loop_decay[j]; |
michael@0 | 2468 | |
michael@0 | 2469 | // Special check for transition or high motion followed by a |
michael@0 | 2470 | // to a static scene. |
michael@0 | 2471 | if (detect_transition_to_still(cpi, i, cpi->key_frame_frequency - i, |
michael@0 | 2472 | loop_decay_rate, decay_accumulator)) |
michael@0 | 2473 | break; |
michael@0 | 2474 | |
michael@0 | 2475 | // Step on to the next frame |
michael@0 | 2476 | cpi->twopass.frames_to_key++; |
michael@0 | 2477 | |
michael@0 | 2478 | // If we don't have a real key frame within the next two |
michael@0 | 2479 | // forcekeyframeevery intervals then break out of the loop. |
michael@0 | 2480 | if (cpi->twopass.frames_to_key >= 2 * (int)cpi->key_frame_frequency) |
michael@0 | 2481 | break; |
michael@0 | 2482 | } else { |
michael@0 | 2483 | cpi->twopass.frames_to_key++; |
michael@0 | 2484 | } |
michael@0 | 2485 | i++; |
michael@0 | 2486 | } |
michael@0 | 2487 | |
michael@0 | 2488 | // If there is a max kf interval set by the user we must obey it. |
michael@0 | 2489 | // We already breakout of the loop above at 2x max. |
michael@0 | 2490 | // This code centers the extra kf if the actual natural |
michael@0 | 2491 | // interval is between 1x and 2x |
michael@0 | 2492 | if (cpi->oxcf.auto_key |
michael@0 | 2493 | && cpi->twopass.frames_to_key > (int)cpi->key_frame_frequency) { |
michael@0 | 2494 | FIRSTPASS_STATS *current_pos = cpi->twopass.stats_in; |
michael@0 | 2495 | FIRSTPASS_STATS tmp_frame; |
michael@0 | 2496 | |
michael@0 | 2497 | cpi->twopass.frames_to_key /= 2; |
michael@0 | 2498 | |
michael@0 | 2499 | // Copy first frame details |
michael@0 | 2500 | tmp_frame = first_frame; |
michael@0 | 2501 | |
michael@0 | 2502 | // Reset to the start of the group |
michael@0 | 2503 | reset_fpf_position(cpi, start_position); |
michael@0 | 2504 | |
michael@0 | 2505 | kf_group_err = 0; |
michael@0 | 2506 | kf_group_intra_err = 0; |
michael@0 | 2507 | kf_group_coded_err = 0; |
michael@0 | 2508 | |
michael@0 | 2509 | // Rescan to get the correct error data for the forced kf group |
michael@0 | 2510 | for (i = 0; i < cpi->twopass.frames_to_key; i++) { |
michael@0 | 2511 | // Accumulate kf group errors |
michael@0 | 2512 | kf_group_err += calculate_modified_err(cpi, &tmp_frame); |
michael@0 | 2513 | kf_group_intra_err += tmp_frame.intra_error; |
michael@0 | 2514 | kf_group_coded_err += tmp_frame.coded_error; |
michael@0 | 2515 | |
michael@0 | 2516 | // Load a the next frame's stats |
michael@0 | 2517 | input_stats(cpi, &tmp_frame); |
michael@0 | 2518 | } |
michael@0 | 2519 | |
michael@0 | 2520 | // Reset to the start of the group |
michael@0 | 2521 | reset_fpf_position(cpi, current_pos); |
michael@0 | 2522 | |
michael@0 | 2523 | cpi->next_key_frame_forced = 1; |
michael@0 | 2524 | } else { |
michael@0 | 2525 | cpi->next_key_frame_forced = 0; |
michael@0 | 2526 | } |
michael@0 | 2527 | // Special case for the last frame of the file |
michael@0 | 2528 | if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end) { |
michael@0 | 2529 | // Accumulate kf group error |
michael@0 | 2530 | kf_group_err += calculate_modified_err(cpi, this_frame); |
michael@0 | 2531 | |
michael@0 | 2532 | // These figures keep intra and coded error counts for all frames including |
michael@0 | 2533 | // key frames in the group. The effect of the key frame itself can be |
michael@0 | 2534 | // subtracted out using the first_frame data collected above. |
michael@0 | 2535 | kf_group_intra_err += this_frame->intra_error; |
michael@0 | 2536 | kf_group_coded_err += this_frame->coded_error; |
michael@0 | 2537 | } |
michael@0 | 2538 | |
michael@0 | 2539 | // Calculate the number of bits that should be assigned to the kf group. |
michael@0 | 2540 | if ((cpi->twopass.bits_left > 0) && |
michael@0 | 2541 | (cpi->twopass.modified_error_left > 0.0)) { |
michael@0 | 2542 | // Max for a single normal frame (not key frame) |
michael@0 | 2543 | int max_bits = frame_max_bits(cpi); |
michael@0 | 2544 | |
michael@0 | 2545 | // Maximum bits for the kf group |
michael@0 | 2546 | int64_t max_grp_bits; |
michael@0 | 2547 | |
michael@0 | 2548 | // Default allocation based on bits left and relative |
michael@0 | 2549 | // complexity of the section |
michael@0 | 2550 | cpi->twopass.kf_group_bits = (int64_t)(cpi->twopass.bits_left * |
michael@0 | 2551 | (kf_group_err / |
michael@0 | 2552 | cpi->twopass.modified_error_left)); |
michael@0 | 2553 | |
michael@0 | 2554 | // Clip based on maximum per frame rate defined by the user. |
michael@0 | 2555 | max_grp_bits = (int64_t)max_bits * (int64_t)cpi->twopass.frames_to_key; |
michael@0 | 2556 | if (cpi->twopass.kf_group_bits > max_grp_bits) |
michael@0 | 2557 | cpi->twopass.kf_group_bits = max_grp_bits; |
michael@0 | 2558 | } else { |
michael@0 | 2559 | cpi->twopass.kf_group_bits = 0; |
michael@0 | 2560 | } |
michael@0 | 2561 | // Reset the first pass file position |
michael@0 | 2562 | reset_fpf_position(cpi, start_position); |
michael@0 | 2563 | |
michael@0 | 2564 | // Determine how big to make this keyframe based on how well the subsequent |
michael@0 | 2565 | // frames use inter blocks. |
michael@0 | 2566 | decay_accumulator = 1.0; |
michael@0 | 2567 | boost_score = 0.0; |
michael@0 | 2568 | loop_decay_rate = 1.00; // Starting decay rate |
michael@0 | 2569 | |
michael@0 | 2570 | // Scan through the kf group collating various stats. |
michael@0 | 2571 | for (i = 0; i < cpi->twopass.frames_to_key; i++) { |
michael@0 | 2572 | double r; |
michael@0 | 2573 | |
michael@0 | 2574 | if (EOF == input_stats(cpi, &next_frame)) |
michael@0 | 2575 | break; |
michael@0 | 2576 | |
michael@0 | 2577 | // Monitor for static sections. |
michael@0 | 2578 | if ((next_frame.pcnt_inter - next_frame.pcnt_motion) < |
michael@0 | 2579 | zero_motion_accumulator) { |
michael@0 | 2580 | zero_motion_accumulator = |
michael@0 | 2581 | (next_frame.pcnt_inter - next_frame.pcnt_motion); |
michael@0 | 2582 | } |
michael@0 | 2583 | |
michael@0 | 2584 | // For the first few frames collect data to decide kf boost. |
michael@0 | 2585 | if (i <= (cpi->max_gf_interval * 2)) { |
michael@0 | 2586 | if (next_frame.intra_error > cpi->twopass.kf_intra_err_min) |
michael@0 | 2587 | r = (IIKFACTOR2 * next_frame.intra_error / |
michael@0 | 2588 | DOUBLE_DIVIDE_CHECK(next_frame.coded_error)); |
michael@0 | 2589 | else |
michael@0 | 2590 | r = (IIKFACTOR2 * cpi->twopass.kf_intra_err_min / |
michael@0 | 2591 | DOUBLE_DIVIDE_CHECK(next_frame.coded_error)); |
michael@0 | 2592 | |
michael@0 | 2593 | if (r > RMAX) |
michael@0 | 2594 | r = RMAX; |
michael@0 | 2595 | |
michael@0 | 2596 | // How fast is prediction quality decaying |
michael@0 | 2597 | if (!detect_flash(cpi, 0)) { |
michael@0 | 2598 | loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame); |
michael@0 | 2599 | decay_accumulator = decay_accumulator * loop_decay_rate; |
michael@0 | 2600 | decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR |
michael@0 | 2601 | ? MIN_DECAY_FACTOR : decay_accumulator; |
michael@0 | 2602 | } |
michael@0 | 2603 | |
michael@0 | 2604 | boost_score += (decay_accumulator * r); |
michael@0 | 2605 | } |
michael@0 | 2606 | } |
michael@0 | 2607 | |
michael@0 | 2608 | { |
michael@0 | 2609 | FIRSTPASS_STATS sectionstats; |
michael@0 | 2610 | |
michael@0 | 2611 | zero_stats(§ionstats); |
michael@0 | 2612 | reset_fpf_position(cpi, start_position); |
michael@0 | 2613 | |
michael@0 | 2614 | for (i = 0; i < cpi->twopass.frames_to_key; i++) { |
michael@0 | 2615 | input_stats(cpi, &next_frame); |
michael@0 | 2616 | accumulate_stats(§ionstats, &next_frame); |
michael@0 | 2617 | } |
michael@0 | 2618 | |
michael@0 | 2619 | avg_stats(§ionstats); |
michael@0 | 2620 | |
michael@0 | 2621 | cpi->twopass.section_intra_rating = (int) |
michael@0 | 2622 | (sectionstats.intra_error |
michael@0 | 2623 | / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error)); |
michael@0 | 2624 | } |
michael@0 | 2625 | |
michael@0 | 2626 | // Reset the first pass file position |
michael@0 | 2627 | reset_fpf_position(cpi, start_position); |
michael@0 | 2628 | |
michael@0 | 2629 | // Work out how many bits to allocate for the key frame itself |
michael@0 | 2630 | if (1) { |
michael@0 | 2631 | int kf_boost = (int)boost_score; |
michael@0 | 2632 | int allocation_chunks; |
michael@0 | 2633 | int alt_kf_bits; |
michael@0 | 2634 | |
michael@0 | 2635 | if (kf_boost < (cpi->twopass.frames_to_key * 3)) |
michael@0 | 2636 | kf_boost = (cpi->twopass.frames_to_key * 3); |
michael@0 | 2637 | |
michael@0 | 2638 | if (kf_boost < 300) // Min KF boost |
michael@0 | 2639 | kf_boost = 300; |
michael@0 | 2640 | |
michael@0 | 2641 | // Make a note of baseline boost and the zero motion |
michael@0 | 2642 | // accumulator value for use elsewhere. |
michael@0 | 2643 | cpi->kf_boost = kf_boost; |
michael@0 | 2644 | cpi->kf_zeromotion_pct = (int)(zero_motion_accumulator * 100.0); |
michael@0 | 2645 | |
michael@0 | 2646 | // We do three calculations for kf size. |
michael@0 | 2647 | // The first is based on the error score for the whole kf group. |
michael@0 | 2648 | // The second (optionaly) on the key frames own error if this is |
michael@0 | 2649 | // smaller than the average for the group. |
michael@0 | 2650 | // The final one insures that the frame receives at least the |
michael@0 | 2651 | // allocation it would have received based on its own error score vs |
michael@0 | 2652 | // the error score remaining |
michael@0 | 2653 | // Special case if the sequence appears almost totaly static |
michael@0 | 2654 | // In this case we want to spend almost all of the bits on the |
michael@0 | 2655 | // key frame. |
michael@0 | 2656 | // cpi->twopass.frames_to_key-1 because key frame itself is taken |
michael@0 | 2657 | // care of by kf_boost. |
michael@0 | 2658 | if (zero_motion_accumulator >= 0.99) { |
michael@0 | 2659 | allocation_chunks = |
michael@0 | 2660 | ((cpi->twopass.frames_to_key - 1) * 10) + kf_boost; |
michael@0 | 2661 | } else { |
michael@0 | 2662 | allocation_chunks = |
michael@0 | 2663 | ((cpi->twopass.frames_to_key - 1) * 100) + kf_boost; |
michael@0 | 2664 | } |
michael@0 | 2665 | |
michael@0 | 2666 | // Prevent overflow |
michael@0 | 2667 | if (kf_boost > 1028) { |
michael@0 | 2668 | int divisor = kf_boost >> 10; |
michael@0 | 2669 | kf_boost /= divisor; |
michael@0 | 2670 | allocation_chunks /= divisor; |
michael@0 | 2671 | } |
michael@0 | 2672 | |
michael@0 | 2673 | cpi->twopass.kf_group_bits = |
michael@0 | 2674 | (cpi->twopass.kf_group_bits < 0) ? 0 : cpi->twopass.kf_group_bits; |
michael@0 | 2675 | |
michael@0 | 2676 | // Calculate the number of bits to be spent on the key frame |
michael@0 | 2677 | cpi->twopass.kf_bits = |
michael@0 | 2678 | (int)((double)kf_boost * |
michael@0 | 2679 | ((double)cpi->twopass.kf_group_bits / (double)allocation_chunks)); |
michael@0 | 2680 | |
michael@0 | 2681 | // If the key frame is actually easier than the average for the |
michael@0 | 2682 | // kf group (which does sometimes happen... eg a blank intro frame) |
michael@0 | 2683 | // Then use an alternate calculation based on the kf error score |
michael@0 | 2684 | // which should give a smaller key frame. |
michael@0 | 2685 | if (kf_mod_err < kf_group_err / cpi->twopass.frames_to_key) { |
michael@0 | 2686 | double alt_kf_grp_bits = |
michael@0 | 2687 | ((double)cpi->twopass.bits_left * |
michael@0 | 2688 | (kf_mod_err * (double)cpi->twopass.frames_to_key) / |
michael@0 | 2689 | DOUBLE_DIVIDE_CHECK(cpi->twopass.modified_error_left)); |
michael@0 | 2690 | |
michael@0 | 2691 | alt_kf_bits = (int)((double)kf_boost * |
michael@0 | 2692 | (alt_kf_grp_bits / (double)allocation_chunks)); |
michael@0 | 2693 | |
michael@0 | 2694 | if (cpi->twopass.kf_bits > alt_kf_bits) { |
michael@0 | 2695 | cpi->twopass.kf_bits = alt_kf_bits; |
michael@0 | 2696 | } |
michael@0 | 2697 | } else { |
michael@0 | 2698 | // Else if it is much harder than other frames in the group make sure |
michael@0 | 2699 | // it at least receives an allocation in keeping with its relative |
michael@0 | 2700 | // error score |
michael@0 | 2701 | alt_kf_bits = |
michael@0 | 2702 | (int)((double)cpi->twopass.bits_left * |
michael@0 | 2703 | (kf_mod_err / |
michael@0 | 2704 | DOUBLE_DIVIDE_CHECK(cpi->twopass.modified_error_left))); |
michael@0 | 2705 | |
michael@0 | 2706 | if (alt_kf_bits > cpi->twopass.kf_bits) { |
michael@0 | 2707 | cpi->twopass.kf_bits = alt_kf_bits; |
michael@0 | 2708 | } |
michael@0 | 2709 | } |
michael@0 | 2710 | |
michael@0 | 2711 | cpi->twopass.kf_group_bits -= cpi->twopass.kf_bits; |
michael@0 | 2712 | // Add in the minimum frame allowance |
michael@0 | 2713 | cpi->twopass.kf_bits += cpi->min_frame_bandwidth; |
michael@0 | 2714 | |
michael@0 | 2715 | // Peer frame bit target for this frame |
michael@0 | 2716 | cpi->per_frame_bandwidth = cpi->twopass.kf_bits; |
michael@0 | 2717 | // Convert to a per second bitrate |
michael@0 | 2718 | cpi->target_bandwidth = (int)(cpi->twopass.kf_bits * |
michael@0 | 2719 | cpi->output_framerate); |
michael@0 | 2720 | } |
michael@0 | 2721 | |
michael@0 | 2722 | // Note the total error score of the kf group minus the key frame itself |
michael@0 | 2723 | cpi->twopass.kf_group_error_left = (int)(kf_group_err - kf_mod_err); |
michael@0 | 2724 | |
michael@0 | 2725 | // Adjust the count of total modified error left. |
michael@0 | 2726 | // The count of bits left is adjusted elsewhere based on real coded frame |
michael@0 | 2727 | // sizes. |
michael@0 | 2728 | cpi->twopass.modified_error_left -= kf_group_err; |
michael@0 | 2729 | } |