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 <limits.h> |
michael@0 | 12 | #include <math.h> |
michael@0 | 13 | #include <stdio.h> |
michael@0 | 14 | |
michael@0 | 15 | #include "./vp9_rtcd.h" |
michael@0 | 16 | #include "./vpx_config.h" |
michael@0 | 17 | |
michael@0 | 18 | #include "vpx_ports/vpx_timer.h" |
michael@0 | 19 | |
michael@0 | 20 | #include "vp9/common/vp9_common.h" |
michael@0 | 21 | #include "vp9/common/vp9_entropy.h" |
michael@0 | 22 | #include "vp9/common/vp9_entropymode.h" |
michael@0 | 23 | #include "vp9/common/vp9_extend.h" |
michael@0 | 24 | #include "vp9/common/vp9_findnearmv.h" |
michael@0 | 25 | #include "vp9/common/vp9_idct.h" |
michael@0 | 26 | #include "vp9/common/vp9_mvref_common.h" |
michael@0 | 27 | #include "vp9/common/vp9_pred_common.h" |
michael@0 | 28 | #include "vp9/common/vp9_quant_common.h" |
michael@0 | 29 | #include "vp9/common/vp9_reconintra.h" |
michael@0 | 30 | #include "vp9/common/vp9_reconinter.h" |
michael@0 | 31 | #include "vp9/common/vp9_seg_common.h" |
michael@0 | 32 | #include "vp9/common/vp9_tile_common.h" |
michael@0 | 33 | #include "vp9/encoder/vp9_encodeframe.h" |
michael@0 | 34 | #include "vp9/encoder/vp9_encodeintra.h" |
michael@0 | 35 | #include "vp9/encoder/vp9_encodemb.h" |
michael@0 | 36 | #include "vp9/encoder/vp9_encodemv.h" |
michael@0 | 37 | #include "vp9/encoder/vp9_onyx_int.h" |
michael@0 | 38 | #include "vp9/encoder/vp9_rdopt.h" |
michael@0 | 39 | #include "vp9/encoder/vp9_segmentation.h" |
michael@0 | 40 | #include "vp9/common/vp9_systemdependent.h" |
michael@0 | 41 | #include "vp9/encoder/vp9_tokenize.h" |
michael@0 | 42 | #include "vp9/encoder/vp9_vaq.h" |
michael@0 | 43 | |
michael@0 | 44 | |
michael@0 | 45 | #define DBG_PRNT_SEGMAP 0 |
michael@0 | 46 | |
michael@0 | 47 | |
michael@0 | 48 | // #define ENC_DEBUG |
michael@0 | 49 | #ifdef ENC_DEBUG |
michael@0 | 50 | int enc_debug = 0; |
michael@0 | 51 | #endif |
michael@0 | 52 | |
michael@0 | 53 | static INLINE uint8_t *get_sb_index(MACROBLOCK *x, BLOCK_SIZE subsize) { |
michael@0 | 54 | switch (subsize) { |
michael@0 | 55 | case BLOCK_64X64: |
michael@0 | 56 | case BLOCK_64X32: |
michael@0 | 57 | case BLOCK_32X64: |
michael@0 | 58 | case BLOCK_32X32: |
michael@0 | 59 | return &x->sb_index; |
michael@0 | 60 | case BLOCK_32X16: |
michael@0 | 61 | case BLOCK_16X32: |
michael@0 | 62 | case BLOCK_16X16: |
michael@0 | 63 | return &x->mb_index; |
michael@0 | 64 | case BLOCK_16X8: |
michael@0 | 65 | case BLOCK_8X16: |
michael@0 | 66 | case BLOCK_8X8: |
michael@0 | 67 | return &x->b_index; |
michael@0 | 68 | case BLOCK_8X4: |
michael@0 | 69 | case BLOCK_4X8: |
michael@0 | 70 | case BLOCK_4X4: |
michael@0 | 71 | return &x->ab_index; |
michael@0 | 72 | default: |
michael@0 | 73 | assert(0); |
michael@0 | 74 | return NULL; |
michael@0 | 75 | } |
michael@0 | 76 | } |
michael@0 | 77 | |
michael@0 | 78 | static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled, |
michael@0 | 79 | int mi_row, int mi_col, BLOCK_SIZE bsize); |
michael@0 | 80 | |
michael@0 | 81 | static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x); |
michael@0 | 82 | |
michael@0 | 83 | /* activity_avg must be positive, or flat regions could get a zero weight |
michael@0 | 84 | * (infinite lambda), which confounds analysis. |
michael@0 | 85 | * This also avoids the need for divide by zero checks in |
michael@0 | 86 | * vp9_activity_masking(). |
michael@0 | 87 | */ |
michael@0 | 88 | #define ACTIVITY_AVG_MIN (64) |
michael@0 | 89 | |
michael@0 | 90 | /* Motion vector component magnitude threshold for defining fast motion. */ |
michael@0 | 91 | #define FAST_MOTION_MV_THRESH (24) |
michael@0 | 92 | |
michael@0 | 93 | /* This is used as a reference when computing the source variance for the |
michael@0 | 94 | * purposes of activity masking. |
michael@0 | 95 | * Eventually this should be replaced by custom no-reference routines, |
michael@0 | 96 | * which will be faster. |
michael@0 | 97 | */ |
michael@0 | 98 | static const uint8_t VP9_VAR_OFFS[64] = { |
michael@0 | 99 | 128, 128, 128, 128, 128, 128, 128, 128, |
michael@0 | 100 | 128, 128, 128, 128, 128, 128, 128, 128, |
michael@0 | 101 | 128, 128, 128, 128, 128, 128, 128, 128, |
michael@0 | 102 | 128, 128, 128, 128, 128, 128, 128, 128, |
michael@0 | 103 | 128, 128, 128, 128, 128, 128, 128, 128, |
michael@0 | 104 | 128, 128, 128, 128, 128, 128, 128, 128, |
michael@0 | 105 | 128, 128, 128, 128, 128, 128, 128, 128, |
michael@0 | 106 | 128, 128, 128, 128, 128, 128, 128, 128 |
michael@0 | 107 | }; |
michael@0 | 108 | |
michael@0 | 109 | static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi, MACROBLOCK *x, |
michael@0 | 110 | BLOCK_SIZE bs) { |
michael@0 | 111 | unsigned int var, sse; |
michael@0 | 112 | var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, |
michael@0 | 113 | x->plane[0].src.stride, |
michael@0 | 114 | VP9_VAR_OFFS, 0, &sse); |
michael@0 | 115 | return (var + (1 << (num_pels_log2_lookup[bs] - 1))) >> |
michael@0 | 116 | num_pels_log2_lookup[bs]; |
michael@0 | 117 | } |
michael@0 | 118 | |
michael@0 | 119 | // Original activity measure from Tim T's code. |
michael@0 | 120 | static unsigned int tt_activity_measure(MACROBLOCK *x) { |
michael@0 | 121 | unsigned int act; |
michael@0 | 122 | unsigned int sse; |
michael@0 | 123 | /* TODO: This could also be done over smaller areas (8x8), but that would |
michael@0 | 124 | * require extensive changes elsewhere, as lambda is assumed to be fixed |
michael@0 | 125 | * over an entire MB in most of the code. |
michael@0 | 126 | * Another option is to compute four 8x8 variances, and pick a single |
michael@0 | 127 | * lambda using a non-linear combination (e.g., the smallest, or second |
michael@0 | 128 | * smallest, etc.). |
michael@0 | 129 | */ |
michael@0 | 130 | act = vp9_variance16x16(x->plane[0].src.buf, x->plane[0].src.stride, |
michael@0 | 131 | VP9_VAR_OFFS, 0, &sse); |
michael@0 | 132 | act <<= 4; |
michael@0 | 133 | |
michael@0 | 134 | /* If the region is flat, lower the activity some more. */ |
michael@0 | 135 | if (act < 8 << 12) |
michael@0 | 136 | act = act < 5 << 12 ? act : 5 << 12; |
michael@0 | 137 | |
michael@0 | 138 | return act; |
michael@0 | 139 | } |
michael@0 | 140 | |
michael@0 | 141 | // Stub for alternative experimental activity measures. |
michael@0 | 142 | static unsigned int alt_activity_measure(MACROBLOCK *x, int use_dc_pred) { |
michael@0 | 143 | return vp9_encode_intra(x, use_dc_pred); |
michael@0 | 144 | } |
michael@0 | 145 | |
michael@0 | 146 | // Measure the activity of the current macroblock |
michael@0 | 147 | // What we measure here is TBD so abstracted to this function |
michael@0 | 148 | #define ALT_ACT_MEASURE 1 |
michael@0 | 149 | static unsigned int mb_activity_measure(MACROBLOCK *x, int mb_row, int mb_col) { |
michael@0 | 150 | unsigned int mb_activity; |
michael@0 | 151 | |
michael@0 | 152 | if (ALT_ACT_MEASURE) { |
michael@0 | 153 | int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row); |
michael@0 | 154 | |
michael@0 | 155 | // Or use and alternative. |
michael@0 | 156 | mb_activity = alt_activity_measure(x, use_dc_pred); |
michael@0 | 157 | } else { |
michael@0 | 158 | // Original activity measure from Tim T's code. |
michael@0 | 159 | mb_activity = tt_activity_measure(x); |
michael@0 | 160 | } |
michael@0 | 161 | |
michael@0 | 162 | if (mb_activity < ACTIVITY_AVG_MIN) |
michael@0 | 163 | mb_activity = ACTIVITY_AVG_MIN; |
michael@0 | 164 | |
michael@0 | 165 | return mb_activity; |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | // Calculate an "average" mb activity value for the frame |
michael@0 | 169 | #define ACT_MEDIAN 0 |
michael@0 | 170 | static void calc_av_activity(VP9_COMP *cpi, int64_t activity_sum) { |
michael@0 | 171 | #if ACT_MEDIAN |
michael@0 | 172 | // Find median: Simple n^2 algorithm for experimentation |
michael@0 | 173 | { |
michael@0 | 174 | unsigned int median; |
michael@0 | 175 | unsigned int i, j; |
michael@0 | 176 | unsigned int *sortlist; |
michael@0 | 177 | unsigned int tmp; |
michael@0 | 178 | |
michael@0 | 179 | // Create a list to sort to |
michael@0 | 180 | CHECK_MEM_ERROR(&cpi->common, sortlist, vpx_calloc(sizeof(unsigned int), |
michael@0 | 181 | cpi->common.MBs)); |
michael@0 | 182 | |
michael@0 | 183 | // Copy map to sort list |
michael@0 | 184 | vpx_memcpy(sortlist, cpi->mb_activity_map, |
michael@0 | 185 | sizeof(unsigned int) * cpi->common.MBs); |
michael@0 | 186 | |
michael@0 | 187 | // Ripple each value down to its correct position |
michael@0 | 188 | for (i = 1; i < cpi->common.MBs; i ++) { |
michael@0 | 189 | for (j = i; j > 0; j --) { |
michael@0 | 190 | if (sortlist[j] < sortlist[j - 1]) { |
michael@0 | 191 | // Swap values |
michael@0 | 192 | tmp = sortlist[j - 1]; |
michael@0 | 193 | sortlist[j - 1] = sortlist[j]; |
michael@0 | 194 | sortlist[j] = tmp; |
michael@0 | 195 | } else { |
michael@0 | 196 | break; |
michael@0 | 197 | } |
michael@0 | 198 | } |
michael@0 | 199 | } |
michael@0 | 200 | |
michael@0 | 201 | // Even number MBs so estimate median as mean of two either side. |
michael@0 | 202 | median = (1 + sortlist[cpi->common.MBs >> 1] + |
michael@0 | 203 | sortlist[(cpi->common.MBs >> 1) + 1]) >> 1; |
michael@0 | 204 | |
michael@0 | 205 | cpi->activity_avg = median; |
michael@0 | 206 | |
michael@0 | 207 | vpx_free(sortlist); |
michael@0 | 208 | } |
michael@0 | 209 | #else |
michael@0 | 210 | // Simple mean for now |
michael@0 | 211 | cpi->activity_avg = (unsigned int) (activity_sum / cpi->common.MBs); |
michael@0 | 212 | #endif // ACT_MEDIAN |
michael@0 | 213 | |
michael@0 | 214 | if (cpi->activity_avg < ACTIVITY_AVG_MIN) |
michael@0 | 215 | cpi->activity_avg = ACTIVITY_AVG_MIN; |
michael@0 | 216 | |
michael@0 | 217 | // Experimental code: return fixed value normalized for several clips |
michael@0 | 218 | if (ALT_ACT_MEASURE) |
michael@0 | 219 | cpi->activity_avg = 100000; |
michael@0 | 220 | } |
michael@0 | 221 | |
michael@0 | 222 | #define USE_ACT_INDEX 0 |
michael@0 | 223 | #define OUTPUT_NORM_ACT_STATS 0 |
michael@0 | 224 | |
michael@0 | 225 | #if USE_ACT_INDEX |
michael@0 | 226 | // Calculate an activity index for each mb |
michael@0 | 227 | static void calc_activity_index(VP9_COMP *cpi, MACROBLOCK *x) { |
michael@0 | 228 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 229 | int mb_row, mb_col; |
michael@0 | 230 | |
michael@0 | 231 | int64_t act; |
michael@0 | 232 | int64_t a; |
michael@0 | 233 | int64_t b; |
michael@0 | 234 | |
michael@0 | 235 | #if OUTPUT_NORM_ACT_STATS |
michael@0 | 236 | FILE *f = fopen("norm_act.stt", "a"); |
michael@0 | 237 | fprintf(f, "\n%12d\n", cpi->activity_avg); |
michael@0 | 238 | #endif |
michael@0 | 239 | |
michael@0 | 240 | // Reset pointers to start of activity map |
michael@0 | 241 | x->mb_activity_ptr = cpi->mb_activity_map; |
michael@0 | 242 | |
michael@0 | 243 | // Calculate normalized mb activity number. |
michael@0 | 244 | for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { |
michael@0 | 245 | // for each macroblock col in image |
michael@0 | 246 | for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { |
michael@0 | 247 | // Read activity from the map |
michael@0 | 248 | act = *(x->mb_activity_ptr); |
michael@0 | 249 | |
michael@0 | 250 | // Calculate a normalized activity number |
michael@0 | 251 | a = act + 4 * cpi->activity_avg; |
michael@0 | 252 | b = 4 * act + cpi->activity_avg; |
michael@0 | 253 | |
michael@0 | 254 | if (b >= a) |
michael@0 | 255 | *(x->activity_ptr) = (int)((b + (a >> 1)) / a) - 1; |
michael@0 | 256 | else |
michael@0 | 257 | *(x->activity_ptr) = 1 - (int)((a + (b >> 1)) / b); |
michael@0 | 258 | |
michael@0 | 259 | #if OUTPUT_NORM_ACT_STATS |
michael@0 | 260 | fprintf(f, " %6d", *(x->mb_activity_ptr)); |
michael@0 | 261 | #endif |
michael@0 | 262 | // Increment activity map pointers |
michael@0 | 263 | x->mb_activity_ptr++; |
michael@0 | 264 | } |
michael@0 | 265 | |
michael@0 | 266 | #if OUTPUT_NORM_ACT_STATS |
michael@0 | 267 | fprintf(f, "\n"); |
michael@0 | 268 | #endif |
michael@0 | 269 | } |
michael@0 | 270 | |
michael@0 | 271 | #if OUTPUT_NORM_ACT_STATS |
michael@0 | 272 | fclose(f); |
michael@0 | 273 | #endif |
michael@0 | 274 | } |
michael@0 | 275 | #endif // USE_ACT_INDEX |
michael@0 | 276 | |
michael@0 | 277 | // Loop through all MBs. Note activity of each, average activity and |
michael@0 | 278 | // calculate a normalized activity for each |
michael@0 | 279 | static void build_activity_map(VP9_COMP *cpi) { |
michael@0 | 280 | MACROBLOCK * const x = &cpi->mb; |
michael@0 | 281 | MACROBLOCKD *xd = &x->e_mbd; |
michael@0 | 282 | VP9_COMMON * const cm = &cpi->common; |
michael@0 | 283 | |
michael@0 | 284 | #if ALT_ACT_MEASURE |
michael@0 | 285 | YV12_BUFFER_CONFIG *new_yv12 = get_frame_new_buffer(cm); |
michael@0 | 286 | int recon_yoffset; |
michael@0 | 287 | int recon_y_stride = new_yv12->y_stride; |
michael@0 | 288 | #endif |
michael@0 | 289 | |
michael@0 | 290 | int mb_row, mb_col; |
michael@0 | 291 | unsigned int mb_activity; |
michael@0 | 292 | int64_t activity_sum = 0; |
michael@0 | 293 | |
michael@0 | 294 | x->mb_activity_ptr = cpi->mb_activity_map; |
michael@0 | 295 | |
michael@0 | 296 | // for each macroblock row in image |
michael@0 | 297 | for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { |
michael@0 | 298 | #if ALT_ACT_MEASURE |
michael@0 | 299 | // reset above block coeffs |
michael@0 | 300 | xd->up_available = (mb_row != 0); |
michael@0 | 301 | recon_yoffset = (mb_row * recon_y_stride * 16); |
michael@0 | 302 | #endif |
michael@0 | 303 | // for each macroblock col in image |
michael@0 | 304 | for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { |
michael@0 | 305 | #if ALT_ACT_MEASURE |
michael@0 | 306 | xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset; |
michael@0 | 307 | xd->left_available = (mb_col != 0); |
michael@0 | 308 | recon_yoffset += 16; |
michael@0 | 309 | #endif |
michael@0 | 310 | |
michael@0 | 311 | // measure activity |
michael@0 | 312 | mb_activity = mb_activity_measure(x, mb_row, mb_col); |
michael@0 | 313 | |
michael@0 | 314 | // Keep frame sum |
michael@0 | 315 | activity_sum += mb_activity; |
michael@0 | 316 | |
michael@0 | 317 | // Store MB level activity details. |
michael@0 | 318 | *x->mb_activity_ptr = mb_activity; |
michael@0 | 319 | |
michael@0 | 320 | // Increment activity map pointer |
michael@0 | 321 | x->mb_activity_ptr++; |
michael@0 | 322 | |
michael@0 | 323 | // adjust to the next column of source macroblocks |
michael@0 | 324 | x->plane[0].src.buf += 16; |
michael@0 | 325 | } |
michael@0 | 326 | |
michael@0 | 327 | // adjust to the next row of mbs |
michael@0 | 328 | x->plane[0].src.buf += 16 * x->plane[0].src.stride - 16 * cm->mb_cols; |
michael@0 | 329 | } |
michael@0 | 330 | |
michael@0 | 331 | // Calculate an "average" MB activity |
michael@0 | 332 | calc_av_activity(cpi, activity_sum); |
michael@0 | 333 | |
michael@0 | 334 | #if USE_ACT_INDEX |
michael@0 | 335 | // Calculate an activity index number of each mb |
michael@0 | 336 | calc_activity_index(cpi, x); |
michael@0 | 337 | #endif |
michael@0 | 338 | } |
michael@0 | 339 | |
michael@0 | 340 | // Macroblock activity masking |
michael@0 | 341 | void vp9_activity_masking(VP9_COMP *cpi, MACROBLOCK *x) { |
michael@0 | 342 | #if USE_ACT_INDEX |
michael@0 | 343 | x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2); |
michael@0 | 344 | x->errorperbit = x->rdmult * 100 / (110 * x->rddiv); |
michael@0 | 345 | x->errorperbit += (x->errorperbit == 0); |
michael@0 | 346 | #else |
michael@0 | 347 | int64_t a; |
michael@0 | 348 | int64_t b; |
michael@0 | 349 | int64_t act = *(x->mb_activity_ptr); |
michael@0 | 350 | |
michael@0 | 351 | // Apply the masking to the RD multiplier. |
michael@0 | 352 | a = act + (2 * cpi->activity_avg); |
michael@0 | 353 | b = (2 * act) + cpi->activity_avg; |
michael@0 | 354 | |
michael@0 | 355 | x->rdmult = (unsigned int) (((int64_t) x->rdmult * b + (a >> 1)) / a); |
michael@0 | 356 | x->errorperbit = x->rdmult * 100 / (110 * x->rddiv); |
michael@0 | 357 | x->errorperbit += (x->errorperbit == 0); |
michael@0 | 358 | #endif |
michael@0 | 359 | |
michael@0 | 360 | // Activity based Zbin adjustment |
michael@0 | 361 | adjust_act_zbin(cpi, x); |
michael@0 | 362 | } |
michael@0 | 363 | |
michael@0 | 364 | static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, |
michael@0 | 365 | BLOCK_SIZE bsize, int output_enabled) { |
michael@0 | 366 | int i, x_idx, y; |
michael@0 | 367 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 368 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 369 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 370 | struct macroblock_plane *const p = x->plane; |
michael@0 | 371 | struct macroblockd_plane *const pd = xd->plane; |
michael@0 | 372 | MODE_INFO *mi = &ctx->mic; |
michael@0 | 373 | MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 374 | MODE_INFO *mi_addr = xd->mi_8x8[0]; |
michael@0 | 375 | |
michael@0 | 376 | int mb_mode_index = ctx->best_mode_index; |
michael@0 | 377 | const int mis = cm->mode_info_stride; |
michael@0 | 378 | const int mi_width = num_8x8_blocks_wide_lookup[bsize]; |
michael@0 | 379 | const int mi_height = num_8x8_blocks_high_lookup[bsize]; |
michael@0 | 380 | int max_plane; |
michael@0 | 381 | |
michael@0 | 382 | assert(mi->mbmi.mode < MB_MODE_COUNT); |
michael@0 | 383 | assert(mi->mbmi.ref_frame[0] < MAX_REF_FRAMES); |
michael@0 | 384 | assert(mi->mbmi.ref_frame[1] < MAX_REF_FRAMES); |
michael@0 | 385 | assert(mi->mbmi.sb_type == bsize); |
michael@0 | 386 | |
michael@0 | 387 | *mi_addr = *mi; |
michael@0 | 388 | |
michael@0 | 389 | max_plane = is_inter_block(mbmi) ? MAX_MB_PLANE : 1; |
michael@0 | 390 | for (i = 0; i < max_plane; ++i) { |
michael@0 | 391 | p[i].coeff = ctx->coeff_pbuf[i][1]; |
michael@0 | 392 | pd[i].qcoeff = ctx->qcoeff_pbuf[i][1]; |
michael@0 | 393 | pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1]; |
michael@0 | 394 | pd[i].eobs = ctx->eobs_pbuf[i][1]; |
michael@0 | 395 | } |
michael@0 | 396 | |
michael@0 | 397 | for (i = max_plane; i < MAX_MB_PLANE; ++i) { |
michael@0 | 398 | p[i].coeff = ctx->coeff_pbuf[i][2]; |
michael@0 | 399 | pd[i].qcoeff = ctx->qcoeff_pbuf[i][2]; |
michael@0 | 400 | pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][2]; |
michael@0 | 401 | pd[i].eobs = ctx->eobs_pbuf[i][2]; |
michael@0 | 402 | } |
michael@0 | 403 | |
michael@0 | 404 | // Restore the coding context of the MB to that that was in place |
michael@0 | 405 | // when the mode was picked for it |
michael@0 | 406 | for (y = 0; y < mi_height; y++) |
michael@0 | 407 | for (x_idx = 0; x_idx < mi_width; x_idx++) |
michael@0 | 408 | if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx |
michael@0 | 409 | && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) |
michael@0 | 410 | xd->mi_8x8[x_idx + y * mis] = mi_addr; |
michael@0 | 411 | |
michael@0 | 412 | if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
michael@0 | 413 | vp9_mb_init_quantizer(cpi, x); |
michael@0 | 414 | } |
michael@0 | 415 | |
michael@0 | 416 | // FIXME(rbultje) I'm pretty sure this should go to the end of this block |
michael@0 | 417 | // (i.e. after the output_enabled) |
michael@0 | 418 | if (bsize < BLOCK_32X32) { |
michael@0 | 419 | if (bsize < BLOCK_16X16) |
michael@0 | 420 | ctx->tx_rd_diff[ALLOW_16X16] = ctx->tx_rd_diff[ALLOW_8X8]; |
michael@0 | 421 | ctx->tx_rd_diff[ALLOW_32X32] = ctx->tx_rd_diff[ALLOW_16X16]; |
michael@0 | 422 | } |
michael@0 | 423 | |
michael@0 | 424 | if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) { |
michael@0 | 425 | mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int; |
michael@0 | 426 | mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int; |
michael@0 | 427 | } |
michael@0 | 428 | |
michael@0 | 429 | x->skip = ctx->skip; |
michael@0 | 430 | vpx_memcpy(x->zcoeff_blk[mbmi->tx_size], ctx->zcoeff_blk, |
michael@0 | 431 | sizeof(uint8_t) * ctx->num_4x4_blk); |
michael@0 | 432 | |
michael@0 | 433 | if (!output_enabled) |
michael@0 | 434 | return; |
michael@0 | 435 | |
michael@0 | 436 | if (!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) { |
michael@0 | 437 | for (i = 0; i < TX_MODES; i++) |
michael@0 | 438 | cpi->rd_tx_select_diff[i] += ctx->tx_rd_diff[i]; |
michael@0 | 439 | } |
michael@0 | 440 | |
michael@0 | 441 | if (frame_is_intra_only(cm)) { |
michael@0 | 442 | #if CONFIG_INTERNAL_STATS |
michael@0 | 443 | static const int kf_mode_index[] = { |
michael@0 | 444 | THR_DC /*DC_PRED*/, |
michael@0 | 445 | THR_V_PRED /*V_PRED*/, |
michael@0 | 446 | THR_H_PRED /*H_PRED*/, |
michael@0 | 447 | THR_D45_PRED /*D45_PRED*/, |
michael@0 | 448 | THR_D135_PRED /*D135_PRED*/, |
michael@0 | 449 | THR_D117_PRED /*D117_PRED*/, |
michael@0 | 450 | THR_D153_PRED /*D153_PRED*/, |
michael@0 | 451 | THR_D207_PRED /*D207_PRED*/, |
michael@0 | 452 | THR_D63_PRED /*D63_PRED*/, |
michael@0 | 453 | THR_TM /*TM_PRED*/, |
michael@0 | 454 | }; |
michael@0 | 455 | cpi->mode_chosen_counts[kf_mode_index[mi->mbmi.mode]]++; |
michael@0 | 456 | #endif |
michael@0 | 457 | } else { |
michael@0 | 458 | // Note how often each mode chosen as best |
michael@0 | 459 | cpi->mode_chosen_counts[mb_mode_index]++; |
michael@0 | 460 | if (is_inter_block(mbmi) |
michael@0 | 461 | && (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV)) { |
michael@0 | 462 | int_mv best_mv[2]; |
michael@0 | 463 | const MV_REFERENCE_FRAME rf1 = mbmi->ref_frame[0]; |
michael@0 | 464 | const MV_REFERENCE_FRAME rf2 = mbmi->ref_frame[1]; |
michael@0 | 465 | best_mv[0].as_int = ctx->best_ref_mv.as_int; |
michael@0 | 466 | best_mv[1].as_int = ctx->second_best_ref_mv.as_int; |
michael@0 | 467 | if (mbmi->mode == NEWMV) { |
michael@0 | 468 | best_mv[0].as_int = mbmi->ref_mvs[rf1][0].as_int; |
michael@0 | 469 | if (rf2 > 0) |
michael@0 | 470 | best_mv[1].as_int = mbmi->ref_mvs[rf2][0].as_int; |
michael@0 | 471 | } |
michael@0 | 472 | mbmi->best_mv[0].as_int = best_mv[0].as_int; |
michael@0 | 473 | mbmi->best_mv[1].as_int = best_mv[1].as_int; |
michael@0 | 474 | vp9_update_mv_count(cpi, x, best_mv); |
michael@0 | 475 | } |
michael@0 | 476 | |
michael@0 | 477 | if (cm->mcomp_filter_type == SWITCHABLE && is_inter_mode(mbmi->mode)) { |
michael@0 | 478 | const int ctx = vp9_get_pred_context_switchable_interp(xd); |
michael@0 | 479 | ++cm->counts.switchable_interp[ctx][mbmi->interp_filter]; |
michael@0 | 480 | } |
michael@0 | 481 | |
michael@0 | 482 | cpi->rd_comp_pred_diff[SINGLE_PREDICTION_ONLY] += ctx->single_pred_diff; |
michael@0 | 483 | cpi->rd_comp_pred_diff[COMP_PREDICTION_ONLY] += ctx->comp_pred_diff; |
michael@0 | 484 | cpi->rd_comp_pred_diff[HYBRID_PREDICTION] += ctx->hybrid_pred_diff; |
michael@0 | 485 | |
michael@0 | 486 | for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) |
michael@0 | 487 | cpi->rd_filter_diff[i] += ctx->best_filter_diff[i]; |
michael@0 | 488 | } |
michael@0 | 489 | } |
michael@0 | 490 | |
michael@0 | 491 | void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src, |
michael@0 | 492 | int mi_row, int mi_col) { |
michael@0 | 493 | uint8_t *const buffers[4] = {src->y_buffer, src->u_buffer, src->v_buffer, |
michael@0 | 494 | src->alpha_buffer}; |
michael@0 | 495 | const int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride, |
michael@0 | 496 | src->alpha_stride}; |
michael@0 | 497 | int i; |
michael@0 | 498 | |
michael@0 | 499 | for (i = 0; i < MAX_MB_PLANE; i++) |
michael@0 | 500 | setup_pred_plane(&x->plane[i].src, buffers[i], strides[i], mi_row, mi_col, |
michael@0 | 501 | NULL, x->e_mbd.plane[i].subsampling_x, |
michael@0 | 502 | x->e_mbd.plane[i].subsampling_y); |
michael@0 | 503 | } |
michael@0 | 504 | |
michael@0 | 505 | static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile, |
michael@0 | 506 | int mi_row, int mi_col, BLOCK_SIZE bsize) { |
michael@0 | 507 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 508 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 509 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 510 | MB_MODE_INFO *mbmi; |
michael@0 | 511 | const int dst_fb_idx = cm->new_fb_idx; |
michael@0 | 512 | const int idx_str = xd->mode_info_stride * mi_row + mi_col; |
michael@0 | 513 | const int mi_width = num_8x8_blocks_wide_lookup[bsize]; |
michael@0 | 514 | const int mi_height = num_8x8_blocks_high_lookup[bsize]; |
michael@0 | 515 | const int mb_row = mi_row >> 1; |
michael@0 | 516 | const int mb_col = mi_col >> 1; |
michael@0 | 517 | const int idx_map = mb_row * cm->mb_cols + mb_col; |
michael@0 | 518 | const struct segmentation *const seg = &cm->seg; |
michael@0 | 519 | |
michael@0 | 520 | set_skip_context(xd, cpi->above_context, cpi->left_context, mi_row, mi_col); |
michael@0 | 521 | |
michael@0 | 522 | // Activity map pointer |
michael@0 | 523 | x->mb_activity_ptr = &cpi->mb_activity_map[idx_map]; |
michael@0 | 524 | x->active_ptr = cpi->active_map + idx_map; |
michael@0 | 525 | |
michael@0 | 526 | xd->mi_8x8 = cm->mi_grid_visible + idx_str; |
michael@0 | 527 | xd->prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str; |
michael@0 | 528 | |
michael@0 | 529 | // Special case: if prev_mi is NULL, the previous mode info context |
michael@0 | 530 | // cannot be used. |
michael@0 | 531 | xd->last_mi = cm->prev_mi ? xd->prev_mi_8x8[0] : NULL; |
michael@0 | 532 | |
michael@0 | 533 | xd->mi_8x8[0] = cm->mi + idx_str; |
michael@0 | 534 | |
michael@0 | 535 | mbmi = &xd->mi_8x8[0]->mbmi; |
michael@0 | 536 | |
michael@0 | 537 | // Set up destination pointers |
michael@0 | 538 | setup_dst_planes(xd, &cm->yv12_fb[dst_fb_idx], mi_row, mi_col); |
michael@0 | 539 | |
michael@0 | 540 | // Set up limit values for MV components |
michael@0 | 541 | // mv beyond the range do not produce new/different prediction block |
michael@0 | 542 | x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + VP9_INTERP_EXTEND); |
michael@0 | 543 | x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + VP9_INTERP_EXTEND); |
michael@0 | 544 | x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + VP9_INTERP_EXTEND; |
michael@0 | 545 | x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + VP9_INTERP_EXTEND; |
michael@0 | 546 | |
michael@0 | 547 | // Set up distance of MB to edge of frame in 1/8th pel units |
michael@0 | 548 | assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1))); |
michael@0 | 549 | set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, |
michael@0 | 550 | cm->mi_rows, cm->mi_cols); |
michael@0 | 551 | |
michael@0 | 552 | /* set up source buffers */ |
michael@0 | 553 | vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col); |
michael@0 | 554 | |
michael@0 | 555 | /* R/D setup */ |
michael@0 | 556 | x->rddiv = cpi->RDDIV; |
michael@0 | 557 | x->rdmult = cpi->RDMULT; |
michael@0 | 558 | |
michael@0 | 559 | /* segment ID */ |
michael@0 | 560 | if (seg->enabled) { |
michael@0 | 561 | if (!cpi->oxcf.aq_mode == VARIANCE_AQ) { |
michael@0 | 562 | uint8_t *map = seg->update_map ? cpi->segmentation_map |
michael@0 | 563 | : cm->last_frame_seg_map; |
michael@0 | 564 | mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col); |
michael@0 | 565 | } |
michael@0 | 566 | vp9_mb_init_quantizer(cpi, x); |
michael@0 | 567 | |
michael@0 | 568 | if (seg->enabled && cpi->seg0_cnt > 0 |
michael@0 | 569 | && !vp9_segfeature_active(seg, 0, SEG_LVL_REF_FRAME) |
michael@0 | 570 | && vp9_segfeature_active(seg, 1, SEG_LVL_REF_FRAME)) { |
michael@0 | 571 | cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt; |
michael@0 | 572 | } else { |
michael@0 | 573 | const int y = mb_row & ~3; |
michael@0 | 574 | const int x = mb_col & ~3; |
michael@0 | 575 | const int p16 = ((mb_row & 1) << 1) + (mb_col & 1); |
michael@0 | 576 | const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1); |
michael@0 | 577 | const int tile_progress = tile->mi_col_start * cm->mb_rows >> 1; |
michael@0 | 578 | const int mb_cols = (tile->mi_col_end - tile->mi_col_start) >> 1; |
michael@0 | 579 | |
michael@0 | 580 | cpi->seg0_progress = ((y * mb_cols + x * 4 + p32 + p16 + tile_progress) |
michael@0 | 581 | << 16) / cm->MBs; |
michael@0 | 582 | } |
michael@0 | 583 | |
michael@0 | 584 | x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id]; |
michael@0 | 585 | } else { |
michael@0 | 586 | mbmi->segment_id = 0; |
michael@0 | 587 | x->encode_breakout = cpi->oxcf.encode_breakout; |
michael@0 | 588 | } |
michael@0 | 589 | } |
michael@0 | 590 | |
michael@0 | 591 | static void pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, |
michael@0 | 592 | int mi_row, int mi_col, |
michael@0 | 593 | int *totalrate, int64_t *totaldist, |
michael@0 | 594 | BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, |
michael@0 | 595 | int64_t best_rd) { |
michael@0 | 596 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 597 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 598 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 599 | struct macroblock_plane *const p = x->plane; |
michael@0 | 600 | struct macroblockd_plane *const pd = xd->plane; |
michael@0 | 601 | int i; |
michael@0 | 602 | int orig_rdmult = x->rdmult; |
michael@0 | 603 | double rdmult_ratio; |
michael@0 | 604 | |
michael@0 | 605 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 606 | rdmult_ratio = 1.0; // avoid uninitialized warnings |
michael@0 | 607 | |
michael@0 | 608 | // Use the lower precision, but faster, 32x32 fdct for mode selection. |
michael@0 | 609 | x->use_lp32x32fdct = 1; |
michael@0 | 610 | |
michael@0 | 611 | if (bsize < BLOCK_8X8) { |
michael@0 | 612 | // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0 |
michael@0 | 613 | // there is nothing to be done. |
michael@0 | 614 | if (x->ab_index != 0) { |
michael@0 | 615 | *totalrate = 0; |
michael@0 | 616 | *totaldist = 0; |
michael@0 | 617 | return; |
michael@0 | 618 | } |
michael@0 | 619 | } |
michael@0 | 620 | |
michael@0 | 621 | set_offsets(cpi, tile, mi_row, mi_col, bsize); |
michael@0 | 622 | xd->mi_8x8[0]->mbmi.sb_type = bsize; |
michael@0 | 623 | |
michael@0 | 624 | for (i = 0; i < MAX_MB_PLANE; ++i) { |
michael@0 | 625 | p[i].coeff = ctx->coeff_pbuf[i][0]; |
michael@0 | 626 | pd[i].qcoeff = ctx->qcoeff_pbuf[i][0]; |
michael@0 | 627 | pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0]; |
michael@0 | 628 | pd[i].eobs = ctx->eobs_pbuf[i][0]; |
michael@0 | 629 | } |
michael@0 | 630 | ctx->is_coded = 0; |
michael@0 | 631 | x->skip_recode = 0; |
michael@0 | 632 | |
michael@0 | 633 | // Set to zero to make sure we do not use the previous encoded frame stats |
michael@0 | 634 | xd->mi_8x8[0]->mbmi.skip_coeff = 0; |
michael@0 | 635 | |
michael@0 | 636 | x->source_variance = get_sby_perpixel_variance(cpi, x, bsize); |
michael@0 | 637 | |
michael@0 | 638 | if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
michael@0 | 639 | int energy; |
michael@0 | 640 | if (bsize <= BLOCK_16X16) { |
michael@0 | 641 | energy = x->mb_energy; |
michael@0 | 642 | } else { |
michael@0 | 643 | energy = vp9_block_energy(cpi, x, bsize); |
michael@0 | 644 | } |
michael@0 | 645 | |
michael@0 | 646 | xd->mi_8x8[0]->mbmi.segment_id = vp9_vaq_segment_id(energy); |
michael@0 | 647 | rdmult_ratio = vp9_vaq_rdmult_ratio(energy); |
michael@0 | 648 | vp9_mb_init_quantizer(cpi, x); |
michael@0 | 649 | } |
michael@0 | 650 | |
michael@0 | 651 | if (cpi->oxcf.tuning == VP8_TUNE_SSIM) |
michael@0 | 652 | vp9_activity_masking(cpi, x); |
michael@0 | 653 | |
michael@0 | 654 | if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
michael@0 | 655 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 656 | x->rdmult = round(x->rdmult * rdmult_ratio); |
michael@0 | 657 | } |
michael@0 | 658 | |
michael@0 | 659 | // Find best coding mode & reconstruct the MB so it is available |
michael@0 | 660 | // as a predictor for MBs that follow in the SB |
michael@0 | 661 | if (frame_is_intra_only(cm)) { |
michael@0 | 662 | vp9_rd_pick_intra_mode_sb(cpi, x, totalrate, totaldist, bsize, ctx, |
michael@0 | 663 | best_rd); |
michael@0 | 664 | } else { |
michael@0 | 665 | if (bsize >= BLOCK_8X8) |
michael@0 | 666 | vp9_rd_pick_inter_mode_sb(cpi, x, tile, mi_row, mi_col, |
michael@0 | 667 | totalrate, totaldist, bsize, ctx, best_rd); |
michael@0 | 668 | else |
michael@0 | 669 | vp9_rd_pick_inter_mode_sub8x8(cpi, x, tile, mi_row, mi_col, totalrate, |
michael@0 | 670 | totaldist, bsize, ctx, best_rd); |
michael@0 | 671 | } |
michael@0 | 672 | |
michael@0 | 673 | if (cpi->oxcf.aq_mode == VARIANCE_AQ) { |
michael@0 | 674 | x->rdmult = orig_rdmult; |
michael@0 | 675 | if (*totalrate != INT_MAX) { |
michael@0 | 676 | vp9_clear_system_state(); // __asm emms; |
michael@0 | 677 | *totalrate = round(*totalrate * rdmult_ratio); |
michael@0 | 678 | } |
michael@0 | 679 | } |
michael@0 | 680 | } |
michael@0 | 681 | |
michael@0 | 682 | static void update_stats(VP9_COMP *cpi) { |
michael@0 | 683 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 684 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 685 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 686 | MODE_INFO *mi = xd->mi_8x8[0]; |
michael@0 | 687 | MB_MODE_INFO *const mbmi = &mi->mbmi; |
michael@0 | 688 | |
michael@0 | 689 | if (!frame_is_intra_only(cm)) { |
michael@0 | 690 | const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id, |
michael@0 | 691 | SEG_LVL_REF_FRAME); |
michael@0 | 692 | |
michael@0 | 693 | if (!seg_ref_active) |
michael@0 | 694 | cpi->intra_inter_count[vp9_get_pred_context_intra_inter(xd)] |
michael@0 | 695 | [is_inter_block(mbmi)]++; |
michael@0 | 696 | |
michael@0 | 697 | // If the segment reference feature is enabled we have only a single |
michael@0 | 698 | // reference frame allowed for the segment so exclude it from |
michael@0 | 699 | // the reference frame counts used to work out probabilities. |
michael@0 | 700 | if (is_inter_block(mbmi) && !seg_ref_active) { |
michael@0 | 701 | if (cm->comp_pred_mode == HYBRID_PREDICTION) |
michael@0 | 702 | cpi->comp_inter_count[vp9_get_pred_context_comp_inter_inter(cm, xd)] |
michael@0 | 703 | [has_second_ref(mbmi)]++; |
michael@0 | 704 | |
michael@0 | 705 | if (has_second_ref(mbmi)) { |
michael@0 | 706 | cpi->comp_ref_count[vp9_get_pred_context_comp_ref_p(cm, xd)] |
michael@0 | 707 | [mbmi->ref_frame[0] == GOLDEN_FRAME]++; |
michael@0 | 708 | } else { |
michael@0 | 709 | cpi->single_ref_count[vp9_get_pred_context_single_ref_p1(xd)][0] |
michael@0 | 710 | [mbmi->ref_frame[0] != LAST_FRAME]++; |
michael@0 | 711 | if (mbmi->ref_frame[0] != LAST_FRAME) |
michael@0 | 712 | cpi->single_ref_count[vp9_get_pred_context_single_ref_p2(xd)][1] |
michael@0 | 713 | [mbmi->ref_frame[0] != GOLDEN_FRAME]++; |
michael@0 | 714 | } |
michael@0 | 715 | } |
michael@0 | 716 | } |
michael@0 | 717 | } |
michael@0 | 718 | |
michael@0 | 719 | static BLOCK_SIZE *get_sb_partitioning(MACROBLOCK *x, BLOCK_SIZE bsize) { |
michael@0 | 720 | switch (bsize) { |
michael@0 | 721 | case BLOCK_64X64: |
michael@0 | 722 | return &x->sb64_partitioning; |
michael@0 | 723 | case BLOCK_32X32: |
michael@0 | 724 | return &x->sb_partitioning[x->sb_index]; |
michael@0 | 725 | case BLOCK_16X16: |
michael@0 | 726 | return &x->mb_partitioning[x->sb_index][x->mb_index]; |
michael@0 | 727 | case BLOCK_8X8: |
michael@0 | 728 | return &x->b_partitioning[x->sb_index][x->mb_index][x->b_index]; |
michael@0 | 729 | default: |
michael@0 | 730 | assert(0); |
michael@0 | 731 | return NULL; |
michael@0 | 732 | } |
michael@0 | 733 | } |
michael@0 | 734 | |
michael@0 | 735 | static void restore_context(VP9_COMP *cpi, int mi_row, int mi_col, |
michael@0 | 736 | ENTROPY_CONTEXT a[16 * MAX_MB_PLANE], |
michael@0 | 737 | ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], |
michael@0 | 738 | PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8], |
michael@0 | 739 | BLOCK_SIZE bsize) { |
michael@0 | 740 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 741 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 742 | int p; |
michael@0 | 743 | const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; |
michael@0 | 744 | const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; |
michael@0 | 745 | int mi_width = num_8x8_blocks_wide_lookup[bsize]; |
michael@0 | 746 | int mi_height = num_8x8_blocks_high_lookup[bsize]; |
michael@0 | 747 | for (p = 0; p < MAX_MB_PLANE; p++) { |
michael@0 | 748 | vpx_memcpy( |
michael@0 | 749 | cpi->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x), |
michael@0 | 750 | a + num_4x4_blocks_wide * p, |
michael@0 | 751 | (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >> |
michael@0 | 752 | xd->plane[p].subsampling_x); |
michael@0 | 753 | vpx_memcpy( |
michael@0 | 754 | cpi->left_context[p] |
michael@0 | 755 | + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y), |
michael@0 | 756 | l + num_4x4_blocks_high * p, |
michael@0 | 757 | (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >> |
michael@0 | 758 | xd->plane[p].subsampling_y); |
michael@0 | 759 | } |
michael@0 | 760 | vpx_memcpy(cpi->above_seg_context + mi_col, sa, |
michael@0 | 761 | sizeof(*cpi->above_seg_context) * mi_width); |
michael@0 | 762 | vpx_memcpy(cpi->left_seg_context + (mi_row & MI_MASK), sl, |
michael@0 | 763 | sizeof(cpi->left_seg_context[0]) * mi_height); |
michael@0 | 764 | } |
michael@0 | 765 | static void save_context(VP9_COMP *cpi, int mi_row, int mi_col, |
michael@0 | 766 | ENTROPY_CONTEXT a[16 * MAX_MB_PLANE], |
michael@0 | 767 | ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], |
michael@0 | 768 | PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8], |
michael@0 | 769 | BLOCK_SIZE bsize) { |
michael@0 | 770 | const MACROBLOCK *const x = &cpi->mb; |
michael@0 | 771 | const MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 772 | int p; |
michael@0 | 773 | const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; |
michael@0 | 774 | const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; |
michael@0 | 775 | int mi_width = num_8x8_blocks_wide_lookup[bsize]; |
michael@0 | 776 | int mi_height = num_8x8_blocks_high_lookup[bsize]; |
michael@0 | 777 | |
michael@0 | 778 | // buffer the above/left context information of the block in search. |
michael@0 | 779 | for (p = 0; p < MAX_MB_PLANE; ++p) { |
michael@0 | 780 | vpx_memcpy( |
michael@0 | 781 | a + num_4x4_blocks_wide * p, |
michael@0 | 782 | cpi->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x), |
michael@0 | 783 | (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >> |
michael@0 | 784 | xd->plane[p].subsampling_x); |
michael@0 | 785 | vpx_memcpy( |
michael@0 | 786 | l + num_4x4_blocks_high * p, |
michael@0 | 787 | cpi->left_context[p] |
michael@0 | 788 | + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y), |
michael@0 | 789 | (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >> |
michael@0 | 790 | xd->plane[p].subsampling_y); |
michael@0 | 791 | } |
michael@0 | 792 | vpx_memcpy(sa, cpi->above_seg_context + mi_col, |
michael@0 | 793 | sizeof(*cpi->above_seg_context) * mi_width); |
michael@0 | 794 | vpx_memcpy(sl, cpi->left_seg_context + (mi_row & MI_MASK), |
michael@0 | 795 | sizeof(cpi->left_seg_context[0]) * mi_height); |
michael@0 | 796 | } |
michael@0 | 797 | |
michael@0 | 798 | static void encode_b(VP9_COMP *cpi, const TileInfo *const tile, |
michael@0 | 799 | TOKENEXTRA **tp, int mi_row, int mi_col, |
michael@0 | 800 | int output_enabled, BLOCK_SIZE bsize, int sub_index) { |
michael@0 | 801 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 802 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 803 | |
michael@0 | 804 | if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
michael@0 | 805 | return; |
michael@0 | 806 | |
michael@0 | 807 | if (sub_index != -1) |
michael@0 | 808 | *get_sb_index(x, bsize) = sub_index; |
michael@0 | 809 | |
michael@0 | 810 | if (bsize < BLOCK_8X8) { |
michael@0 | 811 | // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0 |
michael@0 | 812 | // there is nothing to be done. |
michael@0 | 813 | if (x->ab_index > 0) |
michael@0 | 814 | return; |
michael@0 | 815 | } |
michael@0 | 816 | set_offsets(cpi, tile, mi_row, mi_col, bsize); |
michael@0 | 817 | update_state(cpi, get_block_context(x, bsize), bsize, output_enabled); |
michael@0 | 818 | encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize); |
michael@0 | 819 | |
michael@0 | 820 | if (output_enabled) { |
michael@0 | 821 | update_stats(cpi); |
michael@0 | 822 | |
michael@0 | 823 | (*tp)->token = EOSB_TOKEN; |
michael@0 | 824 | (*tp)++; |
michael@0 | 825 | } |
michael@0 | 826 | } |
michael@0 | 827 | |
michael@0 | 828 | static void encode_sb(VP9_COMP *cpi, const TileInfo *const tile, |
michael@0 | 829 | TOKENEXTRA **tp, int mi_row, int mi_col, |
michael@0 | 830 | int output_enabled, BLOCK_SIZE bsize) { |
michael@0 | 831 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 832 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 833 | BLOCK_SIZE c1 = BLOCK_8X8; |
michael@0 | 834 | const int bsl = b_width_log2(bsize), bs = (1 << bsl) / 4; |
michael@0 | 835 | int pl = 0; |
michael@0 | 836 | PARTITION_TYPE partition; |
michael@0 | 837 | BLOCK_SIZE subsize; |
michael@0 | 838 | int i; |
michael@0 | 839 | |
michael@0 | 840 | if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
michael@0 | 841 | return; |
michael@0 | 842 | |
michael@0 | 843 | c1 = BLOCK_4X4; |
michael@0 | 844 | if (bsize >= BLOCK_8X8) { |
michael@0 | 845 | pl = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context, |
michael@0 | 846 | mi_row, mi_col, bsize); |
michael@0 | 847 | c1 = *(get_sb_partitioning(x, bsize)); |
michael@0 | 848 | } |
michael@0 | 849 | partition = partition_lookup[bsl][c1]; |
michael@0 | 850 | |
michael@0 | 851 | switch (partition) { |
michael@0 | 852 | case PARTITION_NONE: |
michael@0 | 853 | if (output_enabled && bsize >= BLOCK_8X8) |
michael@0 | 854 | cpi->partition_count[pl][PARTITION_NONE]++; |
michael@0 | 855 | encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, c1, -1); |
michael@0 | 856 | break; |
michael@0 | 857 | case PARTITION_VERT: |
michael@0 | 858 | if (output_enabled) |
michael@0 | 859 | cpi->partition_count[pl][PARTITION_VERT]++; |
michael@0 | 860 | encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, c1, 0); |
michael@0 | 861 | encode_b(cpi, tile, tp, mi_row, mi_col + bs, output_enabled, c1, 1); |
michael@0 | 862 | break; |
michael@0 | 863 | case PARTITION_HORZ: |
michael@0 | 864 | if (output_enabled) |
michael@0 | 865 | cpi->partition_count[pl][PARTITION_HORZ]++; |
michael@0 | 866 | encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, c1, 0); |
michael@0 | 867 | encode_b(cpi, tile, tp, mi_row + bs, mi_col, output_enabled, c1, 1); |
michael@0 | 868 | break; |
michael@0 | 869 | case PARTITION_SPLIT: |
michael@0 | 870 | subsize = get_subsize(bsize, PARTITION_SPLIT); |
michael@0 | 871 | |
michael@0 | 872 | if (output_enabled) |
michael@0 | 873 | cpi->partition_count[pl][PARTITION_SPLIT]++; |
michael@0 | 874 | |
michael@0 | 875 | for (i = 0; i < 4; i++) { |
michael@0 | 876 | const int x_idx = i & 1, y_idx = i >> 1; |
michael@0 | 877 | |
michael@0 | 878 | *get_sb_index(x, subsize) = i; |
michael@0 | 879 | encode_sb(cpi, tile, tp, mi_row + y_idx * bs, mi_col + x_idx * bs, |
michael@0 | 880 | output_enabled, subsize); |
michael@0 | 881 | } |
michael@0 | 882 | break; |
michael@0 | 883 | default: |
michael@0 | 884 | assert(0); |
michael@0 | 885 | break; |
michael@0 | 886 | } |
michael@0 | 887 | |
michael@0 | 888 | if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8) |
michael@0 | 889 | update_partition_context(cpi->above_seg_context, cpi->left_seg_context, |
michael@0 | 890 | mi_row, mi_col, c1, bsize); |
michael@0 | 891 | } |
michael@0 | 892 | |
michael@0 | 893 | // Check to see if the given partition size is allowed for a specified number |
michael@0 | 894 | // of 8x8 block rows and columns remaining in the image. |
michael@0 | 895 | // If not then return the largest allowed partition size |
michael@0 | 896 | static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, |
michael@0 | 897 | int rows_left, int cols_left, |
michael@0 | 898 | int *bh, int *bw) { |
michael@0 | 899 | if ((rows_left <= 0) || (cols_left <= 0)) { |
michael@0 | 900 | return MIN(bsize, BLOCK_8X8); |
michael@0 | 901 | } else { |
michael@0 | 902 | for (; bsize > 0; --bsize) { |
michael@0 | 903 | *bh = num_8x8_blocks_high_lookup[bsize]; |
michael@0 | 904 | *bw = num_8x8_blocks_wide_lookup[bsize]; |
michael@0 | 905 | if ((*bh <= rows_left) && (*bw <= cols_left)) { |
michael@0 | 906 | break; |
michael@0 | 907 | } |
michael@0 | 908 | } |
michael@0 | 909 | } |
michael@0 | 910 | return bsize; |
michael@0 | 911 | } |
michael@0 | 912 | |
michael@0 | 913 | // This function attempts to set all mode info entries in a given SB64 |
michael@0 | 914 | // to the same block partition size. |
michael@0 | 915 | // However, at the bottom and right borders of the image the requested size |
michael@0 | 916 | // may not be allowed in which case this code attempts to choose the largest |
michael@0 | 917 | // allowable partition. |
michael@0 | 918 | static void set_partitioning(VP9_COMP *cpi, const TileInfo *const tile, |
michael@0 | 919 | MODE_INFO **mi_8x8, int mi_row, int mi_col) { |
michael@0 | 920 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 921 | BLOCK_SIZE bsize = cpi->sf.always_this_block_size; |
michael@0 | 922 | const int mis = cm->mode_info_stride; |
michael@0 | 923 | int row8x8_remaining = tile->mi_row_end - mi_row; |
michael@0 | 924 | int col8x8_remaining = tile->mi_col_end - mi_col; |
michael@0 | 925 | int block_row, block_col; |
michael@0 | 926 | MODE_INFO * mi_upper_left = cm->mi + mi_row * mis + mi_col; |
michael@0 | 927 | int bh = num_8x8_blocks_high_lookup[bsize]; |
michael@0 | 928 | int bw = num_8x8_blocks_wide_lookup[bsize]; |
michael@0 | 929 | |
michael@0 | 930 | assert((row8x8_remaining > 0) && (col8x8_remaining > 0)); |
michael@0 | 931 | |
michael@0 | 932 | // Apply the requested partition size to the SB64 if it is all "in image" |
michael@0 | 933 | if ((col8x8_remaining >= MI_BLOCK_SIZE) && |
michael@0 | 934 | (row8x8_remaining >= MI_BLOCK_SIZE)) { |
michael@0 | 935 | for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) { |
michael@0 | 936 | for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) { |
michael@0 | 937 | int index = block_row * mis + block_col; |
michael@0 | 938 | mi_8x8[index] = mi_upper_left + index; |
michael@0 | 939 | mi_8x8[index]->mbmi.sb_type = bsize; |
michael@0 | 940 | } |
michael@0 | 941 | } |
michael@0 | 942 | } else { |
michael@0 | 943 | // Else this is a partial SB64. |
michael@0 | 944 | for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) { |
michael@0 | 945 | for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) { |
michael@0 | 946 | int index = block_row * mis + block_col; |
michael@0 | 947 | // Find a partition size that fits |
michael@0 | 948 | bsize = find_partition_size(cpi->sf.always_this_block_size, |
michael@0 | 949 | (row8x8_remaining - block_row), |
michael@0 | 950 | (col8x8_remaining - block_col), &bh, &bw); |
michael@0 | 951 | mi_8x8[index] = mi_upper_left + index; |
michael@0 | 952 | mi_8x8[index]->mbmi.sb_type = bsize; |
michael@0 | 953 | } |
michael@0 | 954 | } |
michael@0 | 955 | } |
michael@0 | 956 | } |
michael@0 | 957 | |
michael@0 | 958 | static void copy_partitioning(VP9_COMP *cpi, MODE_INFO **mi_8x8, |
michael@0 | 959 | MODE_INFO **prev_mi_8x8) { |
michael@0 | 960 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 961 | const int mis = cm->mode_info_stride; |
michael@0 | 962 | int block_row, block_col; |
michael@0 | 963 | |
michael@0 | 964 | for (block_row = 0; block_row < 8; ++block_row) { |
michael@0 | 965 | for (block_col = 0; block_col < 8; ++block_col) { |
michael@0 | 966 | MODE_INFO * prev_mi = prev_mi_8x8[block_row * mis + block_col]; |
michael@0 | 967 | BLOCK_SIZE sb_type = prev_mi ? prev_mi->mbmi.sb_type : 0; |
michael@0 | 968 | ptrdiff_t offset; |
michael@0 | 969 | |
michael@0 | 970 | if (prev_mi) { |
michael@0 | 971 | offset = prev_mi - cm->prev_mi; |
michael@0 | 972 | mi_8x8[block_row * mis + block_col] = cm->mi + offset; |
michael@0 | 973 | mi_8x8[block_row * mis + block_col]->mbmi.sb_type = sb_type; |
michael@0 | 974 | } |
michael@0 | 975 | } |
michael@0 | 976 | } |
michael@0 | 977 | } |
michael@0 | 978 | |
michael@0 | 979 | static int sb_has_motion(VP9_COMP *cpi, MODE_INFO **prev_mi_8x8) { |
michael@0 | 980 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 981 | const int mis = cm->mode_info_stride; |
michael@0 | 982 | int block_row, block_col; |
michael@0 | 983 | |
michael@0 | 984 | if (cm->prev_mi) { |
michael@0 | 985 | for (block_row = 0; block_row < 8; ++block_row) { |
michael@0 | 986 | for (block_col = 0; block_col < 8; ++block_col) { |
michael@0 | 987 | MODE_INFO * prev_mi = prev_mi_8x8[block_row * mis + block_col]; |
michael@0 | 988 | if (prev_mi) { |
michael@0 | 989 | if (abs(prev_mi->mbmi.mv[0].as_mv.row) >= 8 || |
michael@0 | 990 | abs(prev_mi->mbmi.mv[0].as_mv.col) >= 8) |
michael@0 | 991 | return 1; |
michael@0 | 992 | } |
michael@0 | 993 | } |
michael@0 | 994 | } |
michael@0 | 995 | } |
michael@0 | 996 | return 0; |
michael@0 | 997 | } |
michael@0 | 998 | |
michael@0 | 999 | static void rd_use_partition(VP9_COMP *cpi, |
michael@0 | 1000 | const TileInfo *const tile, |
michael@0 | 1001 | MODE_INFO **mi_8x8, |
michael@0 | 1002 | TOKENEXTRA **tp, int mi_row, int mi_col, |
michael@0 | 1003 | BLOCK_SIZE bsize, int *rate, int64_t *dist, |
michael@0 | 1004 | int do_recon) { |
michael@0 | 1005 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 1006 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 1007 | const int mis = cm->mode_info_stride; |
michael@0 | 1008 | int bsl = b_width_log2(bsize); |
michael@0 | 1009 | const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; |
michael@0 | 1010 | const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; |
michael@0 | 1011 | int ms = num_4x4_blocks_wide / 2; |
michael@0 | 1012 | int mh = num_4x4_blocks_high / 2; |
michael@0 | 1013 | int bss = (1 << bsl) / 4; |
michael@0 | 1014 | int i, pl; |
michael@0 | 1015 | PARTITION_TYPE partition = PARTITION_NONE; |
michael@0 | 1016 | BLOCK_SIZE subsize; |
michael@0 | 1017 | ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE]; |
michael@0 | 1018 | PARTITION_CONTEXT sl[8], sa[8]; |
michael@0 | 1019 | int last_part_rate = INT_MAX; |
michael@0 | 1020 | int64_t last_part_dist = INT_MAX; |
michael@0 | 1021 | int split_rate = INT_MAX; |
michael@0 | 1022 | int64_t split_dist = INT_MAX; |
michael@0 | 1023 | int none_rate = INT_MAX; |
michael@0 | 1024 | int64_t none_dist = INT_MAX; |
michael@0 | 1025 | int chosen_rate = INT_MAX; |
michael@0 | 1026 | int64_t chosen_dist = INT_MAX; |
michael@0 | 1027 | BLOCK_SIZE sub_subsize = BLOCK_4X4; |
michael@0 | 1028 | int splits_below = 0; |
michael@0 | 1029 | BLOCK_SIZE bs_type = mi_8x8[0]->mbmi.sb_type; |
michael@0 | 1030 | |
michael@0 | 1031 | if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
michael@0 | 1032 | return; |
michael@0 | 1033 | |
michael@0 | 1034 | partition = partition_lookup[bsl][bs_type]; |
michael@0 | 1035 | |
michael@0 | 1036 | subsize = get_subsize(bsize, partition); |
michael@0 | 1037 | |
michael@0 | 1038 | if (bsize < BLOCK_8X8) { |
michael@0 | 1039 | // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0 |
michael@0 | 1040 | // there is nothing to be done. |
michael@0 | 1041 | if (x->ab_index != 0) { |
michael@0 | 1042 | *rate = 0; |
michael@0 | 1043 | *dist = 0; |
michael@0 | 1044 | return; |
michael@0 | 1045 | } |
michael@0 | 1046 | } else { |
michael@0 | 1047 | *(get_sb_partitioning(x, bsize)) = subsize; |
michael@0 | 1048 | } |
michael@0 | 1049 | save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
michael@0 | 1050 | |
michael@0 | 1051 | if (bsize == BLOCK_16X16) { |
michael@0 | 1052 | set_offsets(cpi, tile, mi_row, mi_col, bsize); |
michael@0 | 1053 | x->mb_energy = vp9_block_energy(cpi, x, bsize); |
michael@0 | 1054 | } |
michael@0 | 1055 | |
michael@0 | 1056 | x->fast_ms = 0; |
michael@0 | 1057 | x->subblock_ref = 0; |
michael@0 | 1058 | |
michael@0 | 1059 | if (cpi->sf.adjust_partitioning_from_last_frame) { |
michael@0 | 1060 | // Check if any of the sub blocks are further split. |
michael@0 | 1061 | if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) { |
michael@0 | 1062 | sub_subsize = get_subsize(subsize, PARTITION_SPLIT); |
michael@0 | 1063 | splits_below = 1; |
michael@0 | 1064 | for (i = 0; i < 4; i++) { |
michael@0 | 1065 | int jj = i >> 1, ii = i & 0x01; |
michael@0 | 1066 | MODE_INFO * this_mi = mi_8x8[jj * bss * mis + ii * bss]; |
michael@0 | 1067 | if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) { |
michael@0 | 1068 | splits_below = 0; |
michael@0 | 1069 | } |
michael@0 | 1070 | } |
michael@0 | 1071 | } |
michael@0 | 1072 | |
michael@0 | 1073 | // If partition is not none try none unless each of the 4 splits are split |
michael@0 | 1074 | // even further.. |
michael@0 | 1075 | if (partition != PARTITION_NONE && !splits_below && |
michael@0 | 1076 | mi_row + (ms >> 1) < cm->mi_rows && |
michael@0 | 1077 | mi_col + (ms >> 1) < cm->mi_cols) { |
michael@0 | 1078 | *(get_sb_partitioning(x, bsize)) = bsize; |
michael@0 | 1079 | pick_sb_modes(cpi, tile, mi_row, mi_col, &none_rate, &none_dist, bsize, |
michael@0 | 1080 | get_block_context(x, bsize), INT64_MAX); |
michael@0 | 1081 | |
michael@0 | 1082 | pl = partition_plane_context(cpi->above_seg_context, |
michael@0 | 1083 | cpi->left_seg_context, |
michael@0 | 1084 | mi_row, mi_col, bsize); |
michael@0 | 1085 | none_rate += x->partition_cost[pl][PARTITION_NONE]; |
michael@0 | 1086 | |
michael@0 | 1087 | restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
michael@0 | 1088 | mi_8x8[0]->mbmi.sb_type = bs_type; |
michael@0 | 1089 | *(get_sb_partitioning(x, bsize)) = subsize; |
michael@0 | 1090 | } |
michael@0 | 1091 | } |
michael@0 | 1092 | |
michael@0 | 1093 | switch (partition) { |
michael@0 | 1094 | case PARTITION_NONE: |
michael@0 | 1095 | pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate, &last_part_dist, |
michael@0 | 1096 | bsize, get_block_context(x, bsize), INT64_MAX); |
michael@0 | 1097 | break; |
michael@0 | 1098 | case PARTITION_HORZ: |
michael@0 | 1099 | *get_sb_index(x, subsize) = 0; |
michael@0 | 1100 | pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate, &last_part_dist, |
michael@0 | 1101 | subsize, get_block_context(x, subsize), INT64_MAX); |
michael@0 | 1102 | if (last_part_rate != INT_MAX && |
michael@0 | 1103 | bsize >= BLOCK_8X8 && mi_row + (mh >> 1) < cm->mi_rows) { |
michael@0 | 1104 | int rt = 0; |
michael@0 | 1105 | int64_t dt = 0; |
michael@0 | 1106 | update_state(cpi, get_block_context(x, subsize), subsize, 0); |
michael@0 | 1107 | encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); |
michael@0 | 1108 | *get_sb_index(x, subsize) = 1; |
michael@0 | 1109 | pick_sb_modes(cpi, tile, mi_row + (ms >> 1), mi_col, &rt, &dt, subsize, |
michael@0 | 1110 | get_block_context(x, subsize), INT64_MAX); |
michael@0 | 1111 | if (rt == INT_MAX || dt == INT_MAX) { |
michael@0 | 1112 | last_part_rate = INT_MAX; |
michael@0 | 1113 | last_part_dist = INT_MAX; |
michael@0 | 1114 | break; |
michael@0 | 1115 | } |
michael@0 | 1116 | |
michael@0 | 1117 | last_part_rate += rt; |
michael@0 | 1118 | last_part_dist += dt; |
michael@0 | 1119 | } |
michael@0 | 1120 | break; |
michael@0 | 1121 | case PARTITION_VERT: |
michael@0 | 1122 | *get_sb_index(x, subsize) = 0; |
michael@0 | 1123 | pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate, &last_part_dist, |
michael@0 | 1124 | subsize, get_block_context(x, subsize), INT64_MAX); |
michael@0 | 1125 | if (last_part_rate != INT_MAX && |
michael@0 | 1126 | bsize >= BLOCK_8X8 && mi_col + (ms >> 1) < cm->mi_cols) { |
michael@0 | 1127 | int rt = 0; |
michael@0 | 1128 | int64_t dt = 0; |
michael@0 | 1129 | update_state(cpi, get_block_context(x, subsize), subsize, 0); |
michael@0 | 1130 | encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); |
michael@0 | 1131 | *get_sb_index(x, subsize) = 1; |
michael@0 | 1132 | pick_sb_modes(cpi, tile, mi_row, mi_col + (ms >> 1), &rt, &dt, subsize, |
michael@0 | 1133 | get_block_context(x, subsize), INT64_MAX); |
michael@0 | 1134 | if (rt == INT_MAX || dt == INT_MAX) { |
michael@0 | 1135 | last_part_rate = INT_MAX; |
michael@0 | 1136 | last_part_dist = INT_MAX; |
michael@0 | 1137 | break; |
michael@0 | 1138 | } |
michael@0 | 1139 | last_part_rate += rt; |
michael@0 | 1140 | last_part_dist += dt; |
michael@0 | 1141 | } |
michael@0 | 1142 | break; |
michael@0 | 1143 | case PARTITION_SPLIT: |
michael@0 | 1144 | // Split partition. |
michael@0 | 1145 | last_part_rate = 0; |
michael@0 | 1146 | last_part_dist = 0; |
michael@0 | 1147 | for (i = 0; i < 4; i++) { |
michael@0 | 1148 | int x_idx = (i & 1) * (ms >> 1); |
michael@0 | 1149 | int y_idx = (i >> 1) * (ms >> 1); |
michael@0 | 1150 | int jj = i >> 1, ii = i & 0x01; |
michael@0 | 1151 | int rt; |
michael@0 | 1152 | int64_t dt; |
michael@0 | 1153 | |
michael@0 | 1154 | if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols)) |
michael@0 | 1155 | continue; |
michael@0 | 1156 | |
michael@0 | 1157 | *get_sb_index(x, subsize) = i; |
michael@0 | 1158 | |
michael@0 | 1159 | rd_use_partition(cpi, tile, mi_8x8 + jj * bss * mis + ii * bss, tp, |
michael@0 | 1160 | mi_row + y_idx, mi_col + x_idx, subsize, &rt, &dt, |
michael@0 | 1161 | i != 3); |
michael@0 | 1162 | if (rt == INT_MAX || dt == INT_MAX) { |
michael@0 | 1163 | last_part_rate = INT_MAX; |
michael@0 | 1164 | last_part_dist = INT_MAX; |
michael@0 | 1165 | break; |
michael@0 | 1166 | } |
michael@0 | 1167 | last_part_rate += rt; |
michael@0 | 1168 | last_part_dist += dt; |
michael@0 | 1169 | } |
michael@0 | 1170 | break; |
michael@0 | 1171 | default: |
michael@0 | 1172 | assert(0); |
michael@0 | 1173 | } |
michael@0 | 1174 | |
michael@0 | 1175 | pl = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context, |
michael@0 | 1176 | mi_row, mi_col, bsize); |
michael@0 | 1177 | if (last_part_rate < INT_MAX) |
michael@0 | 1178 | last_part_rate += x->partition_cost[pl][partition]; |
michael@0 | 1179 | |
michael@0 | 1180 | if (cpi->sf.adjust_partitioning_from_last_frame |
michael@0 | 1181 | && partition != PARTITION_SPLIT && bsize > BLOCK_8X8 |
michael@0 | 1182 | && (mi_row + ms < cm->mi_rows || mi_row + (ms >> 1) == cm->mi_rows) |
michael@0 | 1183 | && (mi_col + ms < cm->mi_cols || mi_col + (ms >> 1) == cm->mi_cols)) { |
michael@0 | 1184 | BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT); |
michael@0 | 1185 | split_rate = 0; |
michael@0 | 1186 | split_dist = 0; |
michael@0 | 1187 | restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
michael@0 | 1188 | |
michael@0 | 1189 | // Split partition. |
michael@0 | 1190 | for (i = 0; i < 4; i++) { |
michael@0 | 1191 | int x_idx = (i & 1) * (num_4x4_blocks_wide >> 2); |
michael@0 | 1192 | int y_idx = (i >> 1) * (num_4x4_blocks_wide >> 2); |
michael@0 | 1193 | int rt = 0; |
michael@0 | 1194 | int64_t dt = 0; |
michael@0 | 1195 | ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE]; |
michael@0 | 1196 | PARTITION_CONTEXT sl[8], sa[8]; |
michael@0 | 1197 | |
michael@0 | 1198 | if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols)) |
michael@0 | 1199 | continue; |
michael@0 | 1200 | |
michael@0 | 1201 | *get_sb_index(x, split_subsize) = i; |
michael@0 | 1202 | *get_sb_partitioning(x, bsize) = split_subsize; |
michael@0 | 1203 | *get_sb_partitioning(x, split_subsize) = split_subsize; |
michael@0 | 1204 | |
michael@0 | 1205 | save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
michael@0 | 1206 | |
michael@0 | 1207 | pick_sb_modes(cpi, tile, mi_row + y_idx, mi_col + x_idx, &rt, &dt, |
michael@0 | 1208 | split_subsize, get_block_context(x, split_subsize), |
michael@0 | 1209 | INT64_MAX); |
michael@0 | 1210 | |
michael@0 | 1211 | restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
michael@0 | 1212 | |
michael@0 | 1213 | if (rt == INT_MAX || dt == INT_MAX) { |
michael@0 | 1214 | split_rate = INT_MAX; |
michael@0 | 1215 | split_dist = INT_MAX; |
michael@0 | 1216 | break; |
michael@0 | 1217 | } |
michael@0 | 1218 | |
michael@0 | 1219 | if (i != 3) |
michael@0 | 1220 | encode_sb(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, 0, |
michael@0 | 1221 | split_subsize); |
michael@0 | 1222 | |
michael@0 | 1223 | split_rate += rt; |
michael@0 | 1224 | split_dist += dt; |
michael@0 | 1225 | pl = partition_plane_context(cpi->above_seg_context, |
michael@0 | 1226 | cpi->left_seg_context, |
michael@0 | 1227 | mi_row + y_idx, mi_col + x_idx, bsize); |
michael@0 | 1228 | split_rate += x->partition_cost[pl][PARTITION_NONE]; |
michael@0 | 1229 | } |
michael@0 | 1230 | pl = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context, |
michael@0 | 1231 | mi_row, mi_col, bsize); |
michael@0 | 1232 | if (split_rate < INT_MAX) { |
michael@0 | 1233 | split_rate += x->partition_cost[pl][PARTITION_SPLIT]; |
michael@0 | 1234 | |
michael@0 | 1235 | chosen_rate = split_rate; |
michael@0 | 1236 | chosen_dist = split_dist; |
michael@0 | 1237 | } |
michael@0 | 1238 | } |
michael@0 | 1239 | |
michael@0 | 1240 | // If last_part is better set the partitioning to that... |
michael@0 | 1241 | if (RDCOST(x->rdmult, x->rddiv, last_part_rate, last_part_dist) |
michael@0 | 1242 | < RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist)) { |
michael@0 | 1243 | mi_8x8[0]->mbmi.sb_type = bsize; |
michael@0 | 1244 | if (bsize >= BLOCK_8X8) |
michael@0 | 1245 | *(get_sb_partitioning(x, bsize)) = subsize; |
michael@0 | 1246 | chosen_rate = last_part_rate; |
michael@0 | 1247 | chosen_dist = last_part_dist; |
michael@0 | 1248 | } |
michael@0 | 1249 | // If none was better set the partitioning to that... |
michael@0 | 1250 | if (RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist) |
michael@0 | 1251 | > RDCOST(x->rdmult, x->rddiv, none_rate, none_dist)) { |
michael@0 | 1252 | if (bsize >= BLOCK_8X8) |
michael@0 | 1253 | *(get_sb_partitioning(x, bsize)) = bsize; |
michael@0 | 1254 | chosen_rate = none_rate; |
michael@0 | 1255 | chosen_dist = none_dist; |
michael@0 | 1256 | } |
michael@0 | 1257 | |
michael@0 | 1258 | restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
michael@0 | 1259 | |
michael@0 | 1260 | // We must have chosen a partitioning and encoding or we'll fail later on. |
michael@0 | 1261 | // No other opportunities for success. |
michael@0 | 1262 | if ( bsize == BLOCK_64X64) |
michael@0 | 1263 | assert(chosen_rate < INT_MAX && chosen_dist < INT_MAX); |
michael@0 | 1264 | |
michael@0 | 1265 | if (do_recon) |
michael@0 | 1266 | encode_sb(cpi, tile, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize); |
michael@0 | 1267 | |
michael@0 | 1268 | *rate = chosen_rate; |
michael@0 | 1269 | *dist = chosen_dist; |
michael@0 | 1270 | } |
michael@0 | 1271 | |
michael@0 | 1272 | static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = { |
michael@0 | 1273 | BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, |
michael@0 | 1274 | BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, BLOCK_8X8, |
michael@0 | 1275 | BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16 |
michael@0 | 1276 | }; |
michael@0 | 1277 | |
michael@0 | 1278 | static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = { |
michael@0 | 1279 | BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, |
michael@0 | 1280 | BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, BLOCK_64X64, |
michael@0 | 1281 | BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, BLOCK_64X64 |
michael@0 | 1282 | }; |
michael@0 | 1283 | |
michael@0 | 1284 | // Look at all the mode_info entries for blocks that are part of this |
michael@0 | 1285 | // partition and find the min and max values for sb_type. |
michael@0 | 1286 | // At the moment this is designed to work on a 64x64 SB but could be |
michael@0 | 1287 | // adjusted to use a size parameter. |
michael@0 | 1288 | // |
michael@0 | 1289 | // The min and max are assumed to have been initialized prior to calling this |
michael@0 | 1290 | // function so repeat calls can accumulate a min and max of more than one sb64. |
michael@0 | 1291 | static void get_sb_partition_size_range(VP9_COMP *cpi, MODE_INFO ** mi_8x8, |
michael@0 | 1292 | BLOCK_SIZE * min_block_size, |
michael@0 | 1293 | BLOCK_SIZE * max_block_size ) { |
michael@0 | 1294 | MACROBLOCKD *const xd = &cpi->mb.e_mbd; |
michael@0 | 1295 | int sb_width_in_blocks = MI_BLOCK_SIZE; |
michael@0 | 1296 | int sb_height_in_blocks = MI_BLOCK_SIZE; |
michael@0 | 1297 | int i, j; |
michael@0 | 1298 | int index = 0; |
michael@0 | 1299 | |
michael@0 | 1300 | // Check the sb_type for each block that belongs to this region. |
michael@0 | 1301 | for (i = 0; i < sb_height_in_blocks; ++i) { |
michael@0 | 1302 | for (j = 0; j < sb_width_in_blocks; ++j) { |
michael@0 | 1303 | MODE_INFO * mi = mi_8x8[index+j]; |
michael@0 | 1304 | BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : 0; |
michael@0 | 1305 | *min_block_size = MIN(*min_block_size, sb_type); |
michael@0 | 1306 | *max_block_size = MAX(*max_block_size, sb_type); |
michael@0 | 1307 | } |
michael@0 | 1308 | index += xd->mode_info_stride; |
michael@0 | 1309 | } |
michael@0 | 1310 | } |
michael@0 | 1311 | |
michael@0 | 1312 | // Look at neighboring blocks and set a min and max partition size based on |
michael@0 | 1313 | // what they chose. |
michael@0 | 1314 | static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile, |
michael@0 | 1315 | int row, int col, |
michael@0 | 1316 | BLOCK_SIZE *min_block_size, |
michael@0 | 1317 | BLOCK_SIZE *max_block_size) { |
michael@0 | 1318 | VP9_COMMON * const cm = &cpi->common; |
michael@0 | 1319 | MACROBLOCKD *const xd = &cpi->mb.e_mbd; |
michael@0 | 1320 | MODE_INFO ** mi_8x8 = xd->mi_8x8; |
michael@0 | 1321 | MODE_INFO ** prev_mi_8x8 = xd->prev_mi_8x8; |
michael@0 | 1322 | |
michael@0 | 1323 | const int left_in_image = xd->left_available && mi_8x8[-1]; |
michael@0 | 1324 | const int above_in_image = xd->up_available && |
michael@0 | 1325 | mi_8x8[-xd->mode_info_stride]; |
michael@0 | 1326 | MODE_INFO ** above_sb64_mi_8x8; |
michael@0 | 1327 | MODE_INFO ** left_sb64_mi_8x8; |
michael@0 | 1328 | |
michael@0 | 1329 | int row8x8_remaining = tile->mi_row_end - row; |
michael@0 | 1330 | int col8x8_remaining = tile->mi_col_end - col; |
michael@0 | 1331 | int bh, bw; |
michael@0 | 1332 | |
michael@0 | 1333 | // Trap case where we do not have a prediction. |
michael@0 | 1334 | if (!left_in_image && !above_in_image && |
michael@0 | 1335 | ((cm->frame_type == KEY_FRAME) || !cm->prev_mi)) { |
michael@0 | 1336 | *min_block_size = BLOCK_4X4; |
michael@0 | 1337 | *max_block_size = BLOCK_64X64; |
michael@0 | 1338 | } else { |
michael@0 | 1339 | // Default "min to max" and "max to min" |
michael@0 | 1340 | *min_block_size = BLOCK_64X64; |
michael@0 | 1341 | *max_block_size = BLOCK_4X4; |
michael@0 | 1342 | |
michael@0 | 1343 | // NOTE: each call to get_sb_partition_size_range() uses the previous |
michael@0 | 1344 | // passed in values for min and max as a starting point. |
michael@0 | 1345 | // |
michael@0 | 1346 | // Find the min and max partition used in previous frame at this location |
michael@0 | 1347 | if (cm->prev_mi && (cm->frame_type != KEY_FRAME)) { |
michael@0 | 1348 | get_sb_partition_size_range(cpi, prev_mi_8x8, |
michael@0 | 1349 | min_block_size, max_block_size); |
michael@0 | 1350 | } |
michael@0 | 1351 | |
michael@0 | 1352 | // Find the min and max partition sizes used in the left SB64 |
michael@0 | 1353 | if (left_in_image) { |
michael@0 | 1354 | left_sb64_mi_8x8 = &mi_8x8[-MI_BLOCK_SIZE]; |
michael@0 | 1355 | get_sb_partition_size_range(cpi, left_sb64_mi_8x8, |
michael@0 | 1356 | min_block_size, max_block_size); |
michael@0 | 1357 | } |
michael@0 | 1358 | |
michael@0 | 1359 | // Find the min and max partition sizes used in the above SB64. |
michael@0 | 1360 | if (above_in_image) { |
michael@0 | 1361 | above_sb64_mi_8x8 = &mi_8x8[-xd->mode_info_stride * MI_BLOCK_SIZE]; |
michael@0 | 1362 | get_sb_partition_size_range(cpi, above_sb64_mi_8x8, |
michael@0 | 1363 | min_block_size, max_block_size); |
michael@0 | 1364 | } |
michael@0 | 1365 | } |
michael@0 | 1366 | |
michael@0 | 1367 | // Give a bit of leaway either side of the observed min and max |
michael@0 | 1368 | *min_block_size = min_partition_size[*min_block_size]; |
michael@0 | 1369 | *max_block_size = max_partition_size[*max_block_size]; |
michael@0 | 1370 | |
michael@0 | 1371 | // Check border cases where max and min from neighbours may not be legal. |
michael@0 | 1372 | *max_block_size = find_partition_size(*max_block_size, |
michael@0 | 1373 | row8x8_remaining, col8x8_remaining, |
michael@0 | 1374 | &bh, &bw); |
michael@0 | 1375 | *min_block_size = MIN(*min_block_size, *max_block_size); |
michael@0 | 1376 | } |
michael@0 | 1377 | |
michael@0 | 1378 | static void compute_fast_motion_search_level(VP9_COMP *cpi, BLOCK_SIZE bsize) { |
michael@0 | 1379 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 1380 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 1381 | |
michael@0 | 1382 | // Only use 8x8 result for non HD videos. |
michael@0 | 1383 | // int use_8x8 = (MIN(cpi->common.width, cpi->common.height) < 720) ? 1 : 0; |
michael@0 | 1384 | int use_8x8 = 1; |
michael@0 | 1385 | |
michael@0 | 1386 | if (cm->frame_type && !cpi->is_src_frame_alt_ref && |
michael@0 | 1387 | ((use_8x8 && bsize == BLOCK_16X16) || |
michael@0 | 1388 | bsize == BLOCK_32X32 || bsize == BLOCK_64X64)) { |
michael@0 | 1389 | int ref0 = 0, ref1 = 0, ref2 = 0, ref3 = 0; |
michael@0 | 1390 | PICK_MODE_CONTEXT *block_context = NULL; |
michael@0 | 1391 | |
michael@0 | 1392 | if (bsize == BLOCK_16X16) { |
michael@0 | 1393 | block_context = x->sb8x8_context[x->sb_index][x->mb_index]; |
michael@0 | 1394 | } else if (bsize == BLOCK_32X32) { |
michael@0 | 1395 | block_context = x->mb_context[x->sb_index]; |
michael@0 | 1396 | } else if (bsize == BLOCK_64X64) { |
michael@0 | 1397 | block_context = x->sb32_context; |
michael@0 | 1398 | } |
michael@0 | 1399 | |
michael@0 | 1400 | if (block_context) { |
michael@0 | 1401 | ref0 = block_context[0].mic.mbmi.ref_frame[0]; |
michael@0 | 1402 | ref1 = block_context[1].mic.mbmi.ref_frame[0]; |
michael@0 | 1403 | ref2 = block_context[2].mic.mbmi.ref_frame[0]; |
michael@0 | 1404 | ref3 = block_context[3].mic.mbmi.ref_frame[0]; |
michael@0 | 1405 | } |
michael@0 | 1406 | |
michael@0 | 1407 | // Currently, only consider 4 inter reference frames. |
michael@0 | 1408 | if (ref0 && ref1 && ref2 && ref3) { |
michael@0 | 1409 | int d01, d23, d02, d13; |
michael@0 | 1410 | |
michael@0 | 1411 | // Motion vectors for the four subblocks. |
michael@0 | 1412 | int16_t mvr0 = block_context[0].mic.mbmi.mv[0].as_mv.row; |
michael@0 | 1413 | int16_t mvc0 = block_context[0].mic.mbmi.mv[0].as_mv.col; |
michael@0 | 1414 | int16_t mvr1 = block_context[1].mic.mbmi.mv[0].as_mv.row; |
michael@0 | 1415 | int16_t mvc1 = block_context[1].mic.mbmi.mv[0].as_mv.col; |
michael@0 | 1416 | int16_t mvr2 = block_context[2].mic.mbmi.mv[0].as_mv.row; |
michael@0 | 1417 | int16_t mvc2 = block_context[2].mic.mbmi.mv[0].as_mv.col; |
michael@0 | 1418 | int16_t mvr3 = block_context[3].mic.mbmi.mv[0].as_mv.row; |
michael@0 | 1419 | int16_t mvc3 = block_context[3].mic.mbmi.mv[0].as_mv.col; |
michael@0 | 1420 | |
michael@0 | 1421 | // Adjust sign if ref is alt_ref. |
michael@0 | 1422 | if (cm->ref_frame_sign_bias[ref0]) { |
michael@0 | 1423 | mvr0 *= -1; |
michael@0 | 1424 | mvc0 *= -1; |
michael@0 | 1425 | } |
michael@0 | 1426 | |
michael@0 | 1427 | if (cm->ref_frame_sign_bias[ref1]) { |
michael@0 | 1428 | mvr1 *= -1; |
michael@0 | 1429 | mvc1 *= -1; |
michael@0 | 1430 | } |
michael@0 | 1431 | |
michael@0 | 1432 | if (cm->ref_frame_sign_bias[ref2]) { |
michael@0 | 1433 | mvr2 *= -1; |
michael@0 | 1434 | mvc2 *= -1; |
michael@0 | 1435 | } |
michael@0 | 1436 | |
michael@0 | 1437 | if (cm->ref_frame_sign_bias[ref3]) { |
michael@0 | 1438 | mvr3 *= -1; |
michael@0 | 1439 | mvc3 *= -1; |
michael@0 | 1440 | } |
michael@0 | 1441 | |
michael@0 | 1442 | // Calculate mv distances. |
michael@0 | 1443 | d01 = MAX(abs(mvr0 - mvr1), abs(mvc0 - mvc1)); |
michael@0 | 1444 | d23 = MAX(abs(mvr2 - mvr3), abs(mvc2 - mvc3)); |
michael@0 | 1445 | d02 = MAX(abs(mvr0 - mvr2), abs(mvc0 - mvc2)); |
michael@0 | 1446 | d13 = MAX(abs(mvr1 - mvr3), abs(mvc1 - mvc3)); |
michael@0 | 1447 | |
michael@0 | 1448 | if (d01 < FAST_MOTION_MV_THRESH && d23 < FAST_MOTION_MV_THRESH && |
michael@0 | 1449 | d02 < FAST_MOTION_MV_THRESH && d13 < FAST_MOTION_MV_THRESH) { |
michael@0 | 1450 | // Set fast motion search level. |
michael@0 | 1451 | x->fast_ms = 1; |
michael@0 | 1452 | |
michael@0 | 1453 | if (ref0 == ref1 && ref1 == ref2 && ref2 == ref3 && |
michael@0 | 1454 | d01 < 2 && d23 < 2 && d02 < 2 && d13 < 2) { |
michael@0 | 1455 | // Set fast motion search level. |
michael@0 | 1456 | x->fast_ms = 2; |
michael@0 | 1457 | |
michael@0 | 1458 | if (!d01 && !d23 && !d02 && !d13) { |
michael@0 | 1459 | x->fast_ms = 3; |
michael@0 | 1460 | x->subblock_ref = ref0; |
michael@0 | 1461 | } |
michael@0 | 1462 | } |
michael@0 | 1463 | } |
michael@0 | 1464 | } |
michael@0 | 1465 | } |
michael@0 | 1466 | } |
michael@0 | 1467 | |
michael@0 | 1468 | static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) { |
michael@0 | 1469 | vpx_memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv)); |
michael@0 | 1470 | } |
michael@0 | 1471 | |
michael@0 | 1472 | static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) { |
michael@0 | 1473 | vpx_memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv)); |
michael@0 | 1474 | } |
michael@0 | 1475 | |
michael@0 | 1476 | // TODO(jingning,jimbankoski,rbultje): properly skip partition types that are |
michael@0 | 1477 | // unlikely to be selected depending on previous rate-distortion optimization |
michael@0 | 1478 | // results, for encoding speed-up. |
michael@0 | 1479 | static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile, |
michael@0 | 1480 | TOKENEXTRA **tp, int mi_row, |
michael@0 | 1481 | int mi_col, BLOCK_SIZE bsize, int *rate, |
michael@0 | 1482 | int64_t *dist, int do_recon, int64_t best_rd) { |
michael@0 | 1483 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 1484 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 1485 | const int ms = num_8x8_blocks_wide_lookup[bsize] / 2; |
michael@0 | 1486 | ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE]; |
michael@0 | 1487 | PARTITION_CONTEXT sl[8], sa[8]; |
michael@0 | 1488 | TOKENEXTRA *tp_orig = *tp; |
michael@0 | 1489 | int i, pl; |
michael@0 | 1490 | BLOCK_SIZE subsize; |
michael@0 | 1491 | int this_rate, sum_rate = 0, best_rate = INT_MAX; |
michael@0 | 1492 | int64_t this_dist, sum_dist = 0, best_dist = INT64_MAX; |
michael@0 | 1493 | int64_t sum_rd = 0; |
michael@0 | 1494 | int do_split = bsize >= BLOCK_8X8; |
michael@0 | 1495 | int do_rect = 1; |
michael@0 | 1496 | // Override skipping rectangular partition operations for edge blocks |
michael@0 | 1497 | const int force_horz_split = (mi_row + ms >= cm->mi_rows); |
michael@0 | 1498 | const int force_vert_split = (mi_col + ms >= cm->mi_cols); |
michael@0 | 1499 | |
michael@0 | 1500 | int partition_none_allowed = !force_horz_split && !force_vert_split; |
michael@0 | 1501 | int partition_horz_allowed = !force_vert_split && bsize >= BLOCK_8X8; |
michael@0 | 1502 | int partition_vert_allowed = !force_horz_split && bsize >= BLOCK_8X8; |
michael@0 | 1503 | |
michael@0 | 1504 | int partition_split_done = 0; |
michael@0 | 1505 | (void) *tp_orig; |
michael@0 | 1506 | |
michael@0 | 1507 | if (bsize < BLOCK_8X8) { |
michael@0 | 1508 | // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0 |
michael@0 | 1509 | // there is nothing to be done. |
michael@0 | 1510 | if (x->ab_index != 0) { |
michael@0 | 1511 | *rate = 0; |
michael@0 | 1512 | *dist = 0; |
michael@0 | 1513 | return; |
michael@0 | 1514 | } |
michael@0 | 1515 | } |
michael@0 | 1516 | assert(num_8x8_blocks_wide_lookup[bsize] == |
michael@0 | 1517 | num_8x8_blocks_high_lookup[bsize]); |
michael@0 | 1518 | |
michael@0 | 1519 | if (bsize == BLOCK_16X16) { |
michael@0 | 1520 | set_offsets(cpi, tile, mi_row, mi_col, bsize); |
michael@0 | 1521 | x->mb_energy = vp9_block_energy(cpi, x, bsize); |
michael@0 | 1522 | } |
michael@0 | 1523 | |
michael@0 | 1524 | // Determine partition types in search according to the speed features. |
michael@0 | 1525 | // The threshold set here has to be of square block size. |
michael@0 | 1526 | if (cpi->sf.auto_min_max_partition_size) { |
michael@0 | 1527 | partition_none_allowed &= (bsize <= cpi->sf.max_partition_size && |
michael@0 | 1528 | bsize >= cpi->sf.min_partition_size); |
michael@0 | 1529 | partition_horz_allowed &= ((bsize <= cpi->sf.max_partition_size && |
michael@0 | 1530 | bsize > cpi->sf.min_partition_size) || |
michael@0 | 1531 | force_horz_split); |
michael@0 | 1532 | partition_vert_allowed &= ((bsize <= cpi->sf.max_partition_size && |
michael@0 | 1533 | bsize > cpi->sf.min_partition_size) || |
michael@0 | 1534 | force_vert_split); |
michael@0 | 1535 | do_split &= bsize > cpi->sf.min_partition_size; |
michael@0 | 1536 | } |
michael@0 | 1537 | if (cpi->sf.use_square_partition_only) { |
michael@0 | 1538 | partition_horz_allowed &= force_horz_split; |
michael@0 | 1539 | partition_vert_allowed &= force_vert_split; |
michael@0 | 1540 | } |
michael@0 | 1541 | |
michael@0 | 1542 | save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
michael@0 | 1543 | |
michael@0 | 1544 | if (cpi->sf.disable_split_var_thresh && partition_none_allowed) { |
michael@0 | 1545 | unsigned int source_variancey; |
michael@0 | 1546 | vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col); |
michael@0 | 1547 | source_variancey = get_sby_perpixel_variance(cpi, x, bsize); |
michael@0 | 1548 | if (source_variancey < cpi->sf.disable_split_var_thresh) { |
michael@0 | 1549 | do_split = 0; |
michael@0 | 1550 | if (source_variancey < cpi->sf.disable_split_var_thresh / 2) |
michael@0 | 1551 | do_rect = 0; |
michael@0 | 1552 | } |
michael@0 | 1553 | } |
michael@0 | 1554 | |
michael@0 | 1555 | // PARTITION_NONE |
michael@0 | 1556 | if (partition_none_allowed) { |
michael@0 | 1557 | pick_sb_modes(cpi, tile, mi_row, mi_col, &this_rate, &this_dist, bsize, |
michael@0 | 1558 | get_block_context(x, bsize), best_rd); |
michael@0 | 1559 | if (this_rate != INT_MAX) { |
michael@0 | 1560 | if (bsize >= BLOCK_8X8) { |
michael@0 | 1561 | pl = partition_plane_context(cpi->above_seg_context, |
michael@0 | 1562 | cpi->left_seg_context, |
michael@0 | 1563 | mi_row, mi_col, bsize); |
michael@0 | 1564 | this_rate += x->partition_cost[pl][PARTITION_NONE]; |
michael@0 | 1565 | } |
michael@0 | 1566 | sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist); |
michael@0 | 1567 | if (sum_rd < best_rd) { |
michael@0 | 1568 | int64_t stop_thresh = 2048; |
michael@0 | 1569 | |
michael@0 | 1570 | best_rate = this_rate; |
michael@0 | 1571 | best_dist = this_dist; |
michael@0 | 1572 | best_rd = sum_rd; |
michael@0 | 1573 | if (bsize >= BLOCK_8X8) |
michael@0 | 1574 | *(get_sb_partitioning(x, bsize)) = bsize; |
michael@0 | 1575 | |
michael@0 | 1576 | // Adjust threshold according to partition size. |
michael@0 | 1577 | stop_thresh >>= 8 - (b_width_log2_lookup[bsize] + |
michael@0 | 1578 | b_height_log2_lookup[bsize]); |
michael@0 | 1579 | |
michael@0 | 1580 | // If obtained distortion is very small, choose current partition |
michael@0 | 1581 | // and stop splitting. |
michael@0 | 1582 | if (this_dist < stop_thresh) { |
michael@0 | 1583 | do_split = 0; |
michael@0 | 1584 | do_rect = 0; |
michael@0 | 1585 | } |
michael@0 | 1586 | } |
michael@0 | 1587 | } |
michael@0 | 1588 | restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
michael@0 | 1589 | } |
michael@0 | 1590 | |
michael@0 | 1591 | // store estimated motion vector |
michael@0 | 1592 | if (cpi->sf.adaptive_motion_search) |
michael@0 | 1593 | store_pred_mv(x, get_block_context(x, bsize)); |
michael@0 | 1594 | |
michael@0 | 1595 | // PARTITION_SPLIT |
michael@0 | 1596 | sum_rd = 0; |
michael@0 | 1597 | // TODO(jingning): use the motion vectors given by the above search as |
michael@0 | 1598 | // the starting point of motion search in the following partition type check. |
michael@0 | 1599 | if (do_split) { |
michael@0 | 1600 | subsize = get_subsize(bsize, PARTITION_SPLIT); |
michael@0 | 1601 | for (i = 0; i < 4 && sum_rd < best_rd; ++i) { |
michael@0 | 1602 | const int x_idx = (i & 1) * ms; |
michael@0 | 1603 | const int y_idx = (i >> 1) * ms; |
michael@0 | 1604 | |
michael@0 | 1605 | if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols) |
michael@0 | 1606 | continue; |
michael@0 | 1607 | |
michael@0 | 1608 | *get_sb_index(x, subsize) = i; |
michael@0 | 1609 | if (cpi->sf.adaptive_motion_search) |
michael@0 | 1610 | load_pred_mv(x, get_block_context(x, bsize)); |
michael@0 | 1611 | rd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, subsize, |
michael@0 | 1612 | &this_rate, &this_dist, i != 3, best_rd - sum_rd); |
michael@0 | 1613 | |
michael@0 | 1614 | if (this_rate == INT_MAX) { |
michael@0 | 1615 | sum_rd = INT64_MAX; |
michael@0 | 1616 | } else { |
michael@0 | 1617 | sum_rate += this_rate; |
michael@0 | 1618 | sum_dist += this_dist; |
michael@0 | 1619 | sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
michael@0 | 1620 | } |
michael@0 | 1621 | } |
michael@0 | 1622 | if (sum_rd < best_rd && i == 4) { |
michael@0 | 1623 | pl = partition_plane_context(cpi->above_seg_context, |
michael@0 | 1624 | cpi->left_seg_context, |
michael@0 | 1625 | mi_row, mi_col, bsize); |
michael@0 | 1626 | sum_rate += x->partition_cost[pl][PARTITION_SPLIT]; |
michael@0 | 1627 | sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
michael@0 | 1628 | if (sum_rd < best_rd) { |
michael@0 | 1629 | best_rate = sum_rate; |
michael@0 | 1630 | best_dist = sum_dist; |
michael@0 | 1631 | best_rd = sum_rd; |
michael@0 | 1632 | *(get_sb_partitioning(x, bsize)) = subsize; |
michael@0 | 1633 | } |
michael@0 | 1634 | } else { |
michael@0 | 1635 | // skip rectangular partition test when larger block size |
michael@0 | 1636 | // gives better rd cost |
michael@0 | 1637 | if (cpi->sf.less_rectangular_check) |
michael@0 | 1638 | do_rect &= !partition_none_allowed; |
michael@0 | 1639 | } |
michael@0 | 1640 | partition_split_done = 1; |
michael@0 | 1641 | restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
michael@0 | 1642 | } |
michael@0 | 1643 | |
michael@0 | 1644 | x->fast_ms = 0; |
michael@0 | 1645 | x->subblock_ref = 0; |
michael@0 | 1646 | |
michael@0 | 1647 | if (partition_split_done && |
michael@0 | 1648 | cpi->sf.using_small_partition_info) { |
michael@0 | 1649 | compute_fast_motion_search_level(cpi, bsize); |
michael@0 | 1650 | } |
michael@0 | 1651 | |
michael@0 | 1652 | // PARTITION_HORZ |
michael@0 | 1653 | if (partition_horz_allowed && do_rect) { |
michael@0 | 1654 | subsize = get_subsize(bsize, PARTITION_HORZ); |
michael@0 | 1655 | *get_sb_index(x, subsize) = 0; |
michael@0 | 1656 | if (cpi->sf.adaptive_motion_search) |
michael@0 | 1657 | load_pred_mv(x, get_block_context(x, bsize)); |
michael@0 | 1658 | pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize, |
michael@0 | 1659 | get_block_context(x, subsize), best_rd); |
michael@0 | 1660 | sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
michael@0 | 1661 | |
michael@0 | 1662 | if (sum_rd < best_rd && mi_row + ms < cm->mi_rows) { |
michael@0 | 1663 | update_state(cpi, get_block_context(x, subsize), subsize, 0); |
michael@0 | 1664 | encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); |
michael@0 | 1665 | |
michael@0 | 1666 | *get_sb_index(x, subsize) = 1; |
michael@0 | 1667 | if (cpi->sf.adaptive_motion_search) |
michael@0 | 1668 | load_pred_mv(x, get_block_context(x, bsize)); |
michael@0 | 1669 | pick_sb_modes(cpi, tile, mi_row + ms, mi_col, &this_rate, |
michael@0 | 1670 | &this_dist, subsize, get_block_context(x, subsize), |
michael@0 | 1671 | best_rd - sum_rd); |
michael@0 | 1672 | if (this_rate == INT_MAX) { |
michael@0 | 1673 | sum_rd = INT64_MAX; |
michael@0 | 1674 | } else { |
michael@0 | 1675 | sum_rate += this_rate; |
michael@0 | 1676 | sum_dist += this_dist; |
michael@0 | 1677 | sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
michael@0 | 1678 | } |
michael@0 | 1679 | } |
michael@0 | 1680 | if (sum_rd < best_rd) { |
michael@0 | 1681 | pl = partition_plane_context(cpi->above_seg_context, |
michael@0 | 1682 | cpi->left_seg_context, |
michael@0 | 1683 | mi_row, mi_col, bsize); |
michael@0 | 1684 | sum_rate += x->partition_cost[pl][PARTITION_HORZ]; |
michael@0 | 1685 | sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
michael@0 | 1686 | if (sum_rd < best_rd) { |
michael@0 | 1687 | best_rd = sum_rd; |
michael@0 | 1688 | best_rate = sum_rate; |
michael@0 | 1689 | best_dist = sum_dist; |
michael@0 | 1690 | *(get_sb_partitioning(x, bsize)) = subsize; |
michael@0 | 1691 | } |
michael@0 | 1692 | } |
michael@0 | 1693 | restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
michael@0 | 1694 | } |
michael@0 | 1695 | |
michael@0 | 1696 | // PARTITION_VERT |
michael@0 | 1697 | if (partition_vert_allowed && do_rect) { |
michael@0 | 1698 | subsize = get_subsize(bsize, PARTITION_VERT); |
michael@0 | 1699 | |
michael@0 | 1700 | *get_sb_index(x, subsize) = 0; |
michael@0 | 1701 | if (cpi->sf.adaptive_motion_search) |
michael@0 | 1702 | load_pred_mv(x, get_block_context(x, bsize)); |
michael@0 | 1703 | pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize, |
michael@0 | 1704 | get_block_context(x, subsize), best_rd); |
michael@0 | 1705 | sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
michael@0 | 1706 | if (sum_rd < best_rd && mi_col + ms < cm->mi_cols) { |
michael@0 | 1707 | update_state(cpi, get_block_context(x, subsize), subsize, 0); |
michael@0 | 1708 | encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); |
michael@0 | 1709 | |
michael@0 | 1710 | *get_sb_index(x, subsize) = 1; |
michael@0 | 1711 | if (cpi->sf.adaptive_motion_search) |
michael@0 | 1712 | load_pred_mv(x, get_block_context(x, bsize)); |
michael@0 | 1713 | pick_sb_modes(cpi, tile, mi_row, mi_col + ms, &this_rate, |
michael@0 | 1714 | &this_dist, subsize, get_block_context(x, subsize), |
michael@0 | 1715 | best_rd - sum_rd); |
michael@0 | 1716 | if (this_rate == INT_MAX) { |
michael@0 | 1717 | sum_rd = INT64_MAX; |
michael@0 | 1718 | } else { |
michael@0 | 1719 | sum_rate += this_rate; |
michael@0 | 1720 | sum_dist += this_dist; |
michael@0 | 1721 | sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
michael@0 | 1722 | } |
michael@0 | 1723 | } |
michael@0 | 1724 | if (sum_rd < best_rd) { |
michael@0 | 1725 | pl = partition_plane_context(cpi->above_seg_context, |
michael@0 | 1726 | cpi->left_seg_context, |
michael@0 | 1727 | mi_row, mi_col, bsize); |
michael@0 | 1728 | sum_rate += x->partition_cost[pl][PARTITION_VERT]; |
michael@0 | 1729 | sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
michael@0 | 1730 | if (sum_rd < best_rd) { |
michael@0 | 1731 | best_rate = sum_rate; |
michael@0 | 1732 | best_dist = sum_dist; |
michael@0 | 1733 | best_rd = sum_rd; |
michael@0 | 1734 | *(get_sb_partitioning(x, bsize)) = subsize; |
michael@0 | 1735 | } |
michael@0 | 1736 | } |
michael@0 | 1737 | restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
michael@0 | 1738 | } |
michael@0 | 1739 | |
michael@0 | 1740 | |
michael@0 | 1741 | *rate = best_rate; |
michael@0 | 1742 | *dist = best_dist; |
michael@0 | 1743 | |
michael@0 | 1744 | if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) |
michael@0 | 1745 | encode_sb(cpi, tile, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize); |
michael@0 | 1746 | if (bsize == BLOCK_64X64) { |
michael@0 | 1747 | assert(tp_orig < *tp); |
michael@0 | 1748 | assert(best_rate < INT_MAX); |
michael@0 | 1749 | assert(best_dist < INT_MAX); |
michael@0 | 1750 | } else { |
michael@0 | 1751 | assert(tp_orig == *tp); |
michael@0 | 1752 | } |
michael@0 | 1753 | } |
michael@0 | 1754 | |
michael@0 | 1755 | // Examines 64x64 block and chooses a best reference frame |
michael@0 | 1756 | static void rd_pick_reference_frame(VP9_COMP *cpi, const TileInfo *const tile, |
michael@0 | 1757 | int mi_row, int mi_col) { |
michael@0 | 1758 | VP9_COMMON * const cm = &cpi->common; |
michael@0 | 1759 | MACROBLOCK * const x = &cpi->mb; |
michael@0 | 1760 | int bsl = b_width_log2(BLOCK_64X64), bs = 1 << bsl; |
michael@0 | 1761 | int ms = bs / 2; |
michael@0 | 1762 | ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE]; |
michael@0 | 1763 | PARTITION_CONTEXT sl[8], sa[8]; |
michael@0 | 1764 | int pl; |
michael@0 | 1765 | int r; |
michael@0 | 1766 | int64_t d; |
michael@0 | 1767 | |
michael@0 | 1768 | save_context(cpi, mi_row, mi_col, a, l, sa, sl, BLOCK_64X64); |
michael@0 | 1769 | |
michael@0 | 1770 | // Default is non mask (all reference frames allowed. |
michael@0 | 1771 | cpi->ref_frame_mask = 0; |
michael@0 | 1772 | |
michael@0 | 1773 | // Do RD search for 64x64. |
michael@0 | 1774 | if ((mi_row + (ms >> 1) < cm->mi_rows) && |
michael@0 | 1775 | (mi_col + (ms >> 1) < cm->mi_cols)) { |
michael@0 | 1776 | cpi->set_ref_frame_mask = 1; |
michael@0 | 1777 | pick_sb_modes(cpi, tile, mi_row, mi_col, &r, &d, BLOCK_64X64, |
michael@0 | 1778 | get_block_context(x, BLOCK_64X64), INT64_MAX); |
michael@0 | 1779 | pl = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context, |
michael@0 | 1780 | mi_row, mi_col, BLOCK_64X64); |
michael@0 | 1781 | r += x->partition_cost[pl][PARTITION_NONE]; |
michael@0 | 1782 | |
michael@0 | 1783 | *(get_sb_partitioning(x, BLOCK_64X64)) = BLOCK_64X64; |
michael@0 | 1784 | cpi->set_ref_frame_mask = 0; |
michael@0 | 1785 | } |
michael@0 | 1786 | |
michael@0 | 1787 | restore_context(cpi, mi_row, mi_col, a, l, sa, sl, BLOCK_64X64); |
michael@0 | 1788 | } |
michael@0 | 1789 | |
michael@0 | 1790 | static void encode_sb_row(VP9_COMP *cpi, const TileInfo *const tile, |
michael@0 | 1791 | int mi_row, TOKENEXTRA **tp) { |
michael@0 | 1792 | VP9_COMMON * const cm = &cpi->common; |
michael@0 | 1793 | int mi_col; |
michael@0 | 1794 | |
michael@0 | 1795 | // Initialize the left context for the new SB row |
michael@0 | 1796 | vpx_memset(&cpi->left_context, 0, sizeof(cpi->left_context)); |
michael@0 | 1797 | vpx_memset(cpi->left_seg_context, 0, sizeof(cpi->left_seg_context)); |
michael@0 | 1798 | |
michael@0 | 1799 | // Code each SB in the row |
michael@0 | 1800 | for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end; |
michael@0 | 1801 | mi_col += MI_BLOCK_SIZE) { |
michael@0 | 1802 | int dummy_rate; |
michael@0 | 1803 | int64_t dummy_dist; |
michael@0 | 1804 | |
michael@0 | 1805 | vp9_zero(cpi->mb.pred_mv); |
michael@0 | 1806 | |
michael@0 | 1807 | if (cpi->sf.reference_masking) |
michael@0 | 1808 | rd_pick_reference_frame(cpi, tile, mi_row, mi_col); |
michael@0 | 1809 | |
michael@0 | 1810 | if (cpi->sf.use_lastframe_partitioning || |
michael@0 | 1811 | cpi->sf.use_one_partition_size_always ) { |
michael@0 | 1812 | const int idx_str = cm->mode_info_stride * mi_row + mi_col; |
michael@0 | 1813 | MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str; |
michael@0 | 1814 | MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str; |
michael@0 | 1815 | |
michael@0 | 1816 | cpi->mb.source_variance = UINT_MAX; |
michael@0 | 1817 | if (cpi->sf.use_one_partition_size_always) { |
michael@0 | 1818 | set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); |
michael@0 | 1819 | set_partitioning(cpi, tile, mi_8x8, mi_row, mi_col); |
michael@0 | 1820 | rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
michael@0 | 1821 | &dummy_rate, &dummy_dist, 1); |
michael@0 | 1822 | } else { |
michael@0 | 1823 | if ((cpi->common.current_video_frame |
michael@0 | 1824 | % cpi->sf.last_partitioning_redo_frequency) == 0 |
michael@0 | 1825 | || cm->prev_mi == 0 |
michael@0 | 1826 | || cpi->common.show_frame == 0 |
michael@0 | 1827 | || cpi->common.frame_type == KEY_FRAME |
michael@0 | 1828 | || cpi->is_src_frame_alt_ref |
michael@0 | 1829 | || ((cpi->sf.use_lastframe_partitioning == |
michael@0 | 1830 | LAST_FRAME_PARTITION_LOW_MOTION) && |
michael@0 | 1831 | sb_has_motion(cpi, prev_mi_8x8))) { |
michael@0 | 1832 | // If required set upper and lower partition size limits |
michael@0 | 1833 | if (cpi->sf.auto_min_max_partition_size) { |
michael@0 | 1834 | set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); |
michael@0 | 1835 | rd_auto_partition_range(cpi, tile, mi_row, mi_col, |
michael@0 | 1836 | &cpi->sf.min_partition_size, |
michael@0 | 1837 | &cpi->sf.max_partition_size); |
michael@0 | 1838 | } |
michael@0 | 1839 | rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, |
michael@0 | 1840 | &dummy_rate, &dummy_dist, 1, INT64_MAX); |
michael@0 | 1841 | } else { |
michael@0 | 1842 | copy_partitioning(cpi, mi_8x8, prev_mi_8x8); |
michael@0 | 1843 | rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
michael@0 | 1844 | &dummy_rate, &dummy_dist, 1); |
michael@0 | 1845 | } |
michael@0 | 1846 | } |
michael@0 | 1847 | } else { |
michael@0 | 1848 | // If required set upper and lower partition size limits |
michael@0 | 1849 | if (cpi->sf.auto_min_max_partition_size) { |
michael@0 | 1850 | set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); |
michael@0 | 1851 | rd_auto_partition_range(cpi, tile, mi_row, mi_col, |
michael@0 | 1852 | &cpi->sf.min_partition_size, |
michael@0 | 1853 | &cpi->sf.max_partition_size); |
michael@0 | 1854 | } |
michael@0 | 1855 | rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, |
michael@0 | 1856 | &dummy_rate, &dummy_dist, 1, INT64_MAX); |
michael@0 | 1857 | } |
michael@0 | 1858 | } |
michael@0 | 1859 | } |
michael@0 | 1860 | |
michael@0 | 1861 | static void init_encode_frame_mb_context(VP9_COMP *cpi) { |
michael@0 | 1862 | MACROBLOCK *const x = &cpi->mb; |
michael@0 | 1863 | VP9_COMMON *const cm = &cpi->common; |
michael@0 | 1864 | MACROBLOCKD *const xd = &x->e_mbd; |
michael@0 | 1865 | const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); |
michael@0 | 1866 | |
michael@0 | 1867 | x->act_zbin_adj = 0; |
michael@0 | 1868 | cpi->seg0_idx = 0; |
michael@0 | 1869 | |
michael@0 | 1870 | xd->mode_info_stride = cm->mode_info_stride; |
michael@0 | 1871 | |
michael@0 | 1872 | // reset intra mode contexts |
michael@0 | 1873 | if (frame_is_intra_only(cm)) |
michael@0 | 1874 | vp9_init_mbmode_probs(cm); |
michael@0 | 1875 | |
michael@0 | 1876 | // Copy data over into macro block data structures. |
michael@0 | 1877 | vp9_setup_src_planes(x, cpi->Source, 0, 0); |
michael@0 | 1878 | |
michael@0 | 1879 | // TODO(jkoleszar): are these initializations required? |
michael@0 | 1880 | setup_pre_planes(xd, 0, &cm->yv12_fb[cm->ref_frame_map[cpi->lst_fb_idx]], |
michael@0 | 1881 | 0, 0, NULL); |
michael@0 | 1882 | setup_dst_planes(xd, get_frame_new_buffer(cm), 0, 0); |
michael@0 | 1883 | |
michael@0 | 1884 | setup_block_dptrs(&x->e_mbd, cm->subsampling_x, cm->subsampling_y); |
michael@0 | 1885 | |
michael@0 | 1886 | xd->mi_8x8[0]->mbmi.mode = DC_PRED; |
michael@0 | 1887 | xd->mi_8x8[0]->mbmi.uv_mode = DC_PRED; |
michael@0 | 1888 | |
michael@0 | 1889 | vp9_zero(cpi->y_mode_count); |
michael@0 | 1890 | vp9_zero(cpi->y_uv_mode_count); |
michael@0 | 1891 | vp9_zero(cm->counts.inter_mode); |
michael@0 | 1892 | vp9_zero(cpi->partition_count); |
michael@0 | 1893 | vp9_zero(cpi->intra_inter_count); |
michael@0 | 1894 | vp9_zero(cpi->comp_inter_count); |
michael@0 | 1895 | vp9_zero(cpi->single_ref_count); |
michael@0 | 1896 | vp9_zero(cpi->comp_ref_count); |
michael@0 | 1897 | vp9_zero(cm->counts.tx); |
michael@0 | 1898 | vp9_zero(cm->counts.mbskip); |
michael@0 | 1899 | |
michael@0 | 1900 | // Note: this memset assumes above_context[0], [1] and [2] |
michael@0 | 1901 | // are allocated as part of the same buffer. |
michael@0 | 1902 | vpx_memset(cpi->above_context[0], 0, |
michael@0 | 1903 | sizeof(*cpi->above_context[0]) * |
michael@0 | 1904 | 2 * aligned_mi_cols * MAX_MB_PLANE); |
michael@0 | 1905 | vpx_memset(cpi->above_seg_context, 0, |
michael@0 | 1906 | sizeof(*cpi->above_seg_context) * aligned_mi_cols); |
michael@0 | 1907 | } |
michael@0 | 1908 | |
michael@0 | 1909 | static void switch_lossless_mode(VP9_COMP *cpi, int lossless) { |
michael@0 | 1910 | if (lossless) { |
michael@0 | 1911 | // printf("Switching to lossless\n"); |
michael@0 | 1912 | cpi->mb.fwd_txm4x4 = vp9_fwht4x4; |
michael@0 | 1913 | cpi->mb.e_mbd.itxm_add = vp9_iwht4x4_add; |
michael@0 | 1914 | cpi->mb.optimize = 0; |
michael@0 | 1915 | cpi->common.lf.filter_level = 0; |
michael@0 | 1916 | cpi->zbin_mode_boost_enabled = 0; |
michael@0 | 1917 | cpi->common.tx_mode = ONLY_4X4; |
michael@0 | 1918 | } else { |
michael@0 | 1919 | // printf("Not lossless\n"); |
michael@0 | 1920 | cpi->mb.fwd_txm4x4 = vp9_fdct4x4; |
michael@0 | 1921 | cpi->mb.e_mbd.itxm_add = vp9_idct4x4_add; |
michael@0 | 1922 | } |
michael@0 | 1923 | } |
michael@0 | 1924 | |
michael@0 | 1925 | static void switch_tx_mode(VP9_COMP *cpi) { |
michael@0 | 1926 | if (cpi->sf.tx_size_search_method == USE_LARGESTALL && |
michael@0 | 1927 | cpi->common.tx_mode >= ALLOW_32X32) |
michael@0 | 1928 | cpi->common.tx_mode = ALLOW_32X32; |
michael@0 | 1929 | } |
michael@0 | 1930 | |
michael@0 | 1931 | static void encode_frame_internal(VP9_COMP *cpi) { |
michael@0 | 1932 | int mi_row; |
michael@0 | 1933 | MACROBLOCK * const x = &cpi->mb; |
michael@0 | 1934 | VP9_COMMON * const cm = &cpi->common; |
michael@0 | 1935 | MACROBLOCKD * const xd = &x->e_mbd; |
michael@0 | 1936 | |
michael@0 | 1937 | // fprintf(stderr, "encode_frame_internal frame %d (%d) type %d\n", |
michael@0 | 1938 | // cpi->common.current_video_frame, cpi->common.show_frame, |
michael@0 | 1939 | // cm->frame_type); |
michael@0 | 1940 | |
michael@0 | 1941 | // debug output |
michael@0 | 1942 | #if DBG_PRNT_SEGMAP |
michael@0 | 1943 | { |
michael@0 | 1944 | FILE *statsfile; |
michael@0 | 1945 | statsfile = fopen("segmap2.stt", "a"); |
michael@0 | 1946 | fprintf(statsfile, "\n"); |
michael@0 | 1947 | fclose(statsfile); |
michael@0 | 1948 | } |
michael@0 | 1949 | #endif |
michael@0 | 1950 | |
michael@0 | 1951 | vp9_zero(cm->counts.switchable_interp); |
michael@0 | 1952 | vp9_zero(cpi->tx_stepdown_count); |
michael@0 | 1953 | |
michael@0 | 1954 | xd->mi_8x8 = cm->mi_grid_visible; |
michael@0 | 1955 | // required for vp9_frame_init_quantizer |
michael@0 | 1956 | xd->mi_8x8[0] = cm->mi; |
michael@0 | 1957 | |
michael@0 | 1958 | xd->last_mi = cm->prev_mi; |
michael@0 | 1959 | |
michael@0 | 1960 | vp9_zero(cpi->NMVcount); |
michael@0 | 1961 | vp9_zero(cpi->coef_counts); |
michael@0 | 1962 | vp9_zero(cm->counts.eob_branch); |
michael@0 | 1963 | |
michael@0 | 1964 | cpi->mb.e_mbd.lossless = cm->base_qindex == 0 && cm->y_dc_delta_q == 0 |
michael@0 | 1965 | && cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0; |
michael@0 | 1966 | switch_lossless_mode(cpi, cpi->mb.e_mbd.lossless); |
michael@0 | 1967 | |
michael@0 | 1968 | vp9_frame_init_quantizer(cpi); |
michael@0 | 1969 | |
michael@0 | 1970 | vp9_initialize_rd_consts(cpi); |
michael@0 | 1971 | vp9_initialize_me_consts(cpi, cm->base_qindex); |
michael@0 | 1972 | switch_tx_mode(cpi); |
michael@0 | 1973 | |
michael@0 | 1974 | if (cpi->oxcf.tuning == VP8_TUNE_SSIM) { |
michael@0 | 1975 | // Initialize encode frame context. |
michael@0 | 1976 | init_encode_frame_mb_context(cpi); |
michael@0 | 1977 | |
michael@0 | 1978 | // Build a frame level activity map |
michael@0 | 1979 | build_activity_map(cpi); |
michael@0 | 1980 | } |
michael@0 | 1981 | |
michael@0 | 1982 | // Re-initialize encode frame context. |
michael@0 | 1983 | init_encode_frame_mb_context(cpi); |
michael@0 | 1984 | |
michael@0 | 1985 | vp9_zero(cpi->rd_comp_pred_diff); |
michael@0 | 1986 | vp9_zero(cpi->rd_filter_diff); |
michael@0 | 1987 | vp9_zero(cpi->rd_tx_select_diff); |
michael@0 | 1988 | vp9_zero(cpi->rd_tx_select_threshes); |
michael@0 | 1989 | |
michael@0 | 1990 | set_prev_mi(cm); |
michael@0 | 1991 | |
michael@0 | 1992 | { |
michael@0 | 1993 | struct vpx_usec_timer emr_timer; |
michael@0 | 1994 | vpx_usec_timer_start(&emr_timer); |
michael@0 | 1995 | |
michael@0 | 1996 | { |
michael@0 | 1997 | // Take tiles into account and give start/end MB |
michael@0 | 1998 | int tile_col, tile_row; |
michael@0 | 1999 | TOKENEXTRA *tp = cpi->tok; |
michael@0 | 2000 | const int tile_cols = 1 << cm->log2_tile_cols; |
michael@0 | 2001 | const int tile_rows = 1 << cm->log2_tile_rows; |
michael@0 | 2002 | |
michael@0 | 2003 | for (tile_row = 0; tile_row < tile_rows; tile_row++) { |
michael@0 | 2004 | for (tile_col = 0; tile_col < tile_cols; tile_col++) { |
michael@0 | 2005 | TileInfo tile; |
michael@0 | 2006 | TOKENEXTRA *tp_old = tp; |
michael@0 | 2007 | |
michael@0 | 2008 | // For each row of SBs in the frame |
michael@0 | 2009 | vp9_tile_init(&tile, cm, tile_row, tile_col); |
michael@0 | 2010 | for (mi_row = tile.mi_row_start; |
michael@0 | 2011 | mi_row < tile.mi_row_end; mi_row += 8) |
michael@0 | 2012 | encode_sb_row(cpi, &tile, mi_row, &tp); |
michael@0 | 2013 | |
michael@0 | 2014 | cpi->tok_count[tile_row][tile_col] = (unsigned int)(tp - tp_old); |
michael@0 | 2015 | assert(tp - cpi->tok <= get_token_alloc(cm->mb_rows, cm->mb_cols)); |
michael@0 | 2016 | } |
michael@0 | 2017 | } |
michael@0 | 2018 | } |
michael@0 | 2019 | |
michael@0 | 2020 | vpx_usec_timer_mark(&emr_timer); |
michael@0 | 2021 | cpi->time_encode_sb_row += vpx_usec_timer_elapsed(&emr_timer); |
michael@0 | 2022 | } |
michael@0 | 2023 | |
michael@0 | 2024 | if (cpi->sf.skip_encode_sb) { |
michael@0 | 2025 | int j; |
michael@0 | 2026 | unsigned int intra_count = 0, inter_count = 0; |
michael@0 | 2027 | for (j = 0; j < INTRA_INTER_CONTEXTS; ++j) { |
michael@0 | 2028 | intra_count += cpi->intra_inter_count[j][0]; |
michael@0 | 2029 | inter_count += cpi->intra_inter_count[j][1]; |
michael@0 | 2030 | } |
michael@0 | 2031 | cpi->sf.skip_encode_frame = ((intra_count << 2) < inter_count); |
michael@0 | 2032 | cpi->sf.skip_encode_frame &= (cm->frame_type != KEY_FRAME); |
michael@0 | 2033 | cpi->sf.skip_encode_frame &= cm->show_frame; |
michael@0 | 2034 | } else { |
michael@0 | 2035 | cpi->sf.skip_encode_frame = 0; |
michael@0 | 2036 | } |
michael@0 | 2037 | |
michael@0 | 2038 | #if 0 |
michael@0 | 2039 | // Keep record of the total distortion this time around for future use |
michael@0 | 2040 | cpi->last_frame_distortion = cpi->frame_distortion; |
michael@0 | 2041 | #endif |
michael@0 | 2042 | } |
michael@0 | 2043 | |
michael@0 | 2044 | static int check_dual_ref_flags(VP9_COMP *cpi) { |
michael@0 | 2045 | const int ref_flags = cpi->ref_frame_flags; |
michael@0 | 2046 | |
michael@0 | 2047 | if (vp9_segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) { |
michael@0 | 2048 | return 0; |
michael@0 | 2049 | } else { |
michael@0 | 2050 | return (!!(ref_flags & VP9_GOLD_FLAG) + !!(ref_flags & VP9_LAST_FLAG) |
michael@0 | 2051 | + !!(ref_flags & VP9_ALT_FLAG)) >= 2; |
michael@0 | 2052 | } |
michael@0 | 2053 | } |
michael@0 | 2054 | |
michael@0 | 2055 | static int get_skip_flag(MODE_INFO **mi_8x8, int mis, int ymbs, int xmbs) { |
michael@0 | 2056 | int x, y; |
michael@0 | 2057 | |
michael@0 | 2058 | for (y = 0; y < ymbs; y++) { |
michael@0 | 2059 | for (x = 0; x < xmbs; x++) { |
michael@0 | 2060 | if (!mi_8x8[y * mis + x]->mbmi.skip_coeff) |
michael@0 | 2061 | return 0; |
michael@0 | 2062 | } |
michael@0 | 2063 | } |
michael@0 | 2064 | |
michael@0 | 2065 | return 1; |
michael@0 | 2066 | } |
michael@0 | 2067 | |
michael@0 | 2068 | static void set_txfm_flag(MODE_INFO **mi_8x8, int mis, int ymbs, int xmbs, |
michael@0 | 2069 | TX_SIZE tx_size) { |
michael@0 | 2070 | int x, y; |
michael@0 | 2071 | |
michael@0 | 2072 | for (y = 0; y < ymbs; y++) { |
michael@0 | 2073 | for (x = 0; x < xmbs; x++) |
michael@0 | 2074 | mi_8x8[y * mis + x]->mbmi.tx_size = tx_size; |
michael@0 | 2075 | } |
michael@0 | 2076 | } |
michael@0 | 2077 | |
michael@0 | 2078 | static void reset_skip_txfm_size_b(VP9_COMP *cpi, MODE_INFO **mi_8x8, |
michael@0 | 2079 | int mis, TX_SIZE max_tx_size, int bw, int bh, |
michael@0 | 2080 | int mi_row, int mi_col, BLOCK_SIZE bsize) { |
michael@0 | 2081 | VP9_COMMON * const cm = &cpi->common; |
michael@0 | 2082 | |
michael@0 | 2083 | if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) { |
michael@0 | 2084 | return; |
michael@0 | 2085 | } else { |
michael@0 | 2086 | MB_MODE_INFO * const mbmi = &mi_8x8[0]->mbmi; |
michael@0 | 2087 | if (mbmi->tx_size > max_tx_size) { |
michael@0 | 2088 | const int ymbs = MIN(bh, cm->mi_rows - mi_row); |
michael@0 | 2089 | const int xmbs = MIN(bw, cm->mi_cols - mi_col); |
michael@0 | 2090 | |
michael@0 | 2091 | assert(vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) || |
michael@0 | 2092 | get_skip_flag(mi_8x8, mis, ymbs, xmbs)); |
michael@0 | 2093 | set_txfm_flag(mi_8x8, mis, ymbs, xmbs, max_tx_size); |
michael@0 | 2094 | } |
michael@0 | 2095 | } |
michael@0 | 2096 | } |
michael@0 | 2097 | |
michael@0 | 2098 | static void reset_skip_txfm_size_sb(VP9_COMP *cpi, MODE_INFO **mi_8x8, |
michael@0 | 2099 | TX_SIZE max_tx_size, int mi_row, int mi_col, |
michael@0 | 2100 | BLOCK_SIZE bsize) { |
michael@0 | 2101 | VP9_COMMON * const cm = &cpi->common; |
michael@0 | 2102 | const int mis = cm->mode_info_stride; |
michael@0 | 2103 | int bw, bh; |
michael@0 | 2104 | const int bs = num_8x8_blocks_wide_lookup[bsize], hbs = bs / 2; |
michael@0 | 2105 | |
michael@0 | 2106 | if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
michael@0 | 2107 | return; |
michael@0 | 2108 | |
michael@0 | 2109 | bw = num_8x8_blocks_wide_lookup[mi_8x8[0]->mbmi.sb_type]; |
michael@0 | 2110 | bh = num_8x8_blocks_high_lookup[mi_8x8[0]->mbmi.sb_type]; |
michael@0 | 2111 | |
michael@0 | 2112 | if (bw == bs && bh == bs) { |
michael@0 | 2113 | reset_skip_txfm_size_b(cpi, mi_8x8, mis, max_tx_size, bs, bs, mi_row, |
michael@0 | 2114 | mi_col, bsize); |
michael@0 | 2115 | } else if (bw == bs && bh < bs) { |
michael@0 | 2116 | reset_skip_txfm_size_b(cpi, mi_8x8, mis, max_tx_size, bs, hbs, mi_row, |
michael@0 | 2117 | mi_col, bsize); |
michael@0 | 2118 | reset_skip_txfm_size_b(cpi, mi_8x8 + hbs * mis, mis, max_tx_size, bs, hbs, |
michael@0 | 2119 | mi_row + hbs, mi_col, bsize); |
michael@0 | 2120 | } else if (bw < bs && bh == bs) { |
michael@0 | 2121 | reset_skip_txfm_size_b(cpi, mi_8x8, mis, max_tx_size, hbs, bs, mi_row, |
michael@0 | 2122 | mi_col, bsize); |
michael@0 | 2123 | reset_skip_txfm_size_b(cpi, mi_8x8 + hbs, mis, max_tx_size, hbs, bs, mi_row, |
michael@0 | 2124 | mi_col + hbs, bsize); |
michael@0 | 2125 | |
michael@0 | 2126 | } else { |
michael@0 | 2127 | const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize]; |
michael@0 | 2128 | int n; |
michael@0 | 2129 | |
michael@0 | 2130 | assert(bw < bs && bh < bs); |
michael@0 | 2131 | |
michael@0 | 2132 | for (n = 0; n < 4; n++) { |
michael@0 | 2133 | const int mi_dc = hbs * (n & 1); |
michael@0 | 2134 | const int mi_dr = hbs * (n >> 1); |
michael@0 | 2135 | |
michael@0 | 2136 | reset_skip_txfm_size_sb(cpi, &mi_8x8[mi_dr * mis + mi_dc], max_tx_size, |
michael@0 | 2137 | mi_row + mi_dr, mi_col + mi_dc, subsize); |
michael@0 | 2138 | } |
michael@0 | 2139 | } |
michael@0 | 2140 | } |
michael@0 | 2141 | |
michael@0 | 2142 | static void reset_skip_txfm_size(VP9_COMP *cpi, TX_SIZE txfm_max) { |
michael@0 | 2143 | VP9_COMMON * const cm = &cpi->common; |
michael@0 | 2144 | int mi_row, mi_col; |
michael@0 | 2145 | const int mis = cm->mode_info_stride; |
michael@0 | 2146 | // MODE_INFO *mi, *mi_ptr = cm->mi; |
michael@0 | 2147 | MODE_INFO **mi_8x8, **mi_ptr = cm->mi_grid_visible; |
michael@0 | 2148 | |
michael@0 | 2149 | for (mi_row = 0; mi_row < cm->mi_rows; mi_row += 8, mi_ptr += 8 * mis) { |
michael@0 | 2150 | mi_8x8 = mi_ptr; |
michael@0 | 2151 | for (mi_col = 0; mi_col < cm->mi_cols; mi_col += 8, mi_8x8 += 8) { |
michael@0 | 2152 | reset_skip_txfm_size_sb(cpi, mi_8x8, txfm_max, mi_row, mi_col, |
michael@0 | 2153 | BLOCK_64X64); |
michael@0 | 2154 | } |
michael@0 | 2155 | } |
michael@0 | 2156 | } |
michael@0 | 2157 | |
michael@0 | 2158 | static int get_frame_type(VP9_COMP *cpi) { |
michael@0 | 2159 | int frame_type; |
michael@0 | 2160 | if (frame_is_intra_only(&cpi->common)) |
michael@0 | 2161 | frame_type = 0; |
michael@0 | 2162 | else if (cpi->is_src_frame_alt_ref && cpi->refresh_golden_frame) |
michael@0 | 2163 | frame_type = 3; |
michael@0 | 2164 | else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) |
michael@0 | 2165 | frame_type = 1; |
michael@0 | 2166 | else |
michael@0 | 2167 | frame_type = 2; |
michael@0 | 2168 | return frame_type; |
michael@0 | 2169 | } |
michael@0 | 2170 | |
michael@0 | 2171 | static void select_tx_mode(VP9_COMP *cpi) { |
michael@0 | 2172 | if (cpi->oxcf.lossless) { |
michael@0 | 2173 | cpi->common.tx_mode = ONLY_4X4; |
michael@0 | 2174 | } else if (cpi->common.current_video_frame == 0) { |
michael@0 | 2175 | cpi->common.tx_mode = TX_MODE_SELECT; |
michael@0 | 2176 | } else { |
michael@0 | 2177 | if (cpi->sf.tx_size_search_method == USE_LARGESTALL) { |
michael@0 | 2178 | cpi->common.tx_mode = ALLOW_32X32; |
michael@0 | 2179 | } else if (cpi->sf.tx_size_search_method == USE_FULL_RD) { |
michael@0 | 2180 | int frame_type = get_frame_type(cpi); |
michael@0 | 2181 | cpi->common.tx_mode = |
michael@0 | 2182 | cpi->rd_tx_select_threshes[frame_type][ALLOW_32X32] |
michael@0 | 2183 | > cpi->rd_tx_select_threshes[frame_type][TX_MODE_SELECT] ? |
michael@0 | 2184 | ALLOW_32X32 : TX_MODE_SELECT; |
michael@0 | 2185 | } else { |
michael@0 | 2186 | unsigned int total = 0; |
michael@0 | 2187 | int i; |
michael@0 | 2188 | for (i = 0; i < TX_SIZES; ++i) |
michael@0 | 2189 | total += cpi->tx_stepdown_count[i]; |
michael@0 | 2190 | if (total) { |
michael@0 | 2191 | double fraction = (double)cpi->tx_stepdown_count[0] / total; |
michael@0 | 2192 | cpi->common.tx_mode = fraction > 0.90 ? ALLOW_32X32 : TX_MODE_SELECT; |
michael@0 | 2193 | // printf("fraction = %f\n", fraction); |
michael@0 | 2194 | } // else keep unchanged |
michael@0 | 2195 | } |
michael@0 | 2196 | } |
michael@0 | 2197 | } |
michael@0 | 2198 | |
michael@0 | 2199 | void vp9_encode_frame(VP9_COMP *cpi) { |
michael@0 | 2200 | VP9_COMMON * const cm = &cpi->common; |
michael@0 | 2201 | |
michael@0 | 2202 | // In the longer term the encoder should be generalized to match the |
michael@0 | 2203 | // decoder such that we allow compound where one of the 3 buffers has a |
michael@0 | 2204 | // different sign bias and that buffer is then the fixed ref. However, this |
michael@0 | 2205 | // requires further work in the rd loop. For now the only supported encoder |
michael@0 | 2206 | // side behavior is where the ALT ref buffer has opposite sign bias to |
michael@0 | 2207 | // the other two. |
michael@0 | 2208 | if (!frame_is_intra_only(cm)) { |
michael@0 | 2209 | if ((cm->ref_frame_sign_bias[ALTREF_FRAME] |
michael@0 | 2210 | == cm->ref_frame_sign_bias[GOLDEN_FRAME]) |
michael@0 | 2211 | || (cm->ref_frame_sign_bias[ALTREF_FRAME] |
michael@0 | 2212 | == cm->ref_frame_sign_bias[LAST_FRAME])) { |
michael@0 | 2213 | cm->allow_comp_inter_inter = 0; |
michael@0 | 2214 | } else { |
michael@0 | 2215 | cm->allow_comp_inter_inter = 1; |
michael@0 | 2216 | cm->comp_fixed_ref = ALTREF_FRAME; |
michael@0 | 2217 | cm->comp_var_ref[0] = LAST_FRAME; |
michael@0 | 2218 | cm->comp_var_ref[1] = GOLDEN_FRAME; |
michael@0 | 2219 | } |
michael@0 | 2220 | } |
michael@0 | 2221 | |
michael@0 | 2222 | if (cpi->sf.RD) { |
michael@0 | 2223 | int i, pred_type; |
michael@0 | 2224 | INTERPOLATION_TYPE filter_type; |
michael@0 | 2225 | /* |
michael@0 | 2226 | * This code does a single RD pass over the whole frame assuming |
michael@0 | 2227 | * either compound, single or hybrid prediction as per whatever has |
michael@0 | 2228 | * worked best for that type of frame in the past. |
michael@0 | 2229 | * It also predicts whether another coding mode would have worked |
michael@0 | 2230 | * better that this coding mode. If that is the case, it remembers |
michael@0 | 2231 | * that for subsequent frames. |
michael@0 | 2232 | * It does the same analysis for transform size selection also. |
michael@0 | 2233 | */ |
michael@0 | 2234 | int frame_type = get_frame_type(cpi); |
michael@0 | 2235 | |
michael@0 | 2236 | /* prediction (compound, single or hybrid) mode selection */ |
michael@0 | 2237 | if (frame_type == 3 || !cm->allow_comp_inter_inter) |
michael@0 | 2238 | pred_type = SINGLE_PREDICTION_ONLY; |
michael@0 | 2239 | else if (cpi->rd_prediction_type_threshes[frame_type][1] |
michael@0 | 2240 | > cpi->rd_prediction_type_threshes[frame_type][0] |
michael@0 | 2241 | && cpi->rd_prediction_type_threshes[frame_type][1] |
michael@0 | 2242 | > cpi->rd_prediction_type_threshes[frame_type][2] |
michael@0 | 2243 | && check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100) |
michael@0 | 2244 | pred_type = COMP_PREDICTION_ONLY; |
michael@0 | 2245 | else if (cpi->rd_prediction_type_threshes[frame_type][0] |
michael@0 | 2246 | > cpi->rd_prediction_type_threshes[frame_type][2]) |
michael@0 | 2247 | pred_type = SINGLE_PREDICTION_ONLY; |
michael@0 | 2248 | else |
michael@0 | 2249 | pred_type = HYBRID_PREDICTION; |
michael@0 | 2250 | |
michael@0 | 2251 | /* filter type selection */ |
michael@0 | 2252 | // FIXME(rbultje) for some odd reason, we often select smooth_filter |
michael@0 | 2253 | // as default filter for ARF overlay frames. This is a REALLY BAD |
michael@0 | 2254 | // IDEA so we explicitly disable it here. |
michael@0 | 2255 | if (frame_type != 3 && |
michael@0 | 2256 | cpi->rd_filter_threshes[frame_type][1] > |
michael@0 | 2257 | cpi->rd_filter_threshes[frame_type][0] && |
michael@0 | 2258 | cpi->rd_filter_threshes[frame_type][1] > |
michael@0 | 2259 | cpi->rd_filter_threshes[frame_type][2] && |
michael@0 | 2260 | cpi->rd_filter_threshes[frame_type][1] > |
michael@0 | 2261 | cpi->rd_filter_threshes[frame_type][SWITCHABLE_FILTERS]) { |
michael@0 | 2262 | filter_type = EIGHTTAP_SMOOTH; |
michael@0 | 2263 | } else if (cpi->rd_filter_threshes[frame_type][2] > |
michael@0 | 2264 | cpi->rd_filter_threshes[frame_type][0] && |
michael@0 | 2265 | cpi->rd_filter_threshes[frame_type][2] > |
michael@0 | 2266 | cpi->rd_filter_threshes[frame_type][SWITCHABLE_FILTERS]) { |
michael@0 | 2267 | filter_type = EIGHTTAP_SHARP; |
michael@0 | 2268 | } else if (cpi->rd_filter_threshes[frame_type][0] > |
michael@0 | 2269 | cpi->rd_filter_threshes[frame_type][SWITCHABLE_FILTERS]) { |
michael@0 | 2270 | filter_type = EIGHTTAP; |
michael@0 | 2271 | } else { |
michael@0 | 2272 | filter_type = SWITCHABLE; |
michael@0 | 2273 | } |
michael@0 | 2274 | |
michael@0 | 2275 | cpi->mb.e_mbd.lossless = 0; |
michael@0 | 2276 | if (cpi->oxcf.lossless) { |
michael@0 | 2277 | cpi->mb.e_mbd.lossless = 1; |
michael@0 | 2278 | } |
michael@0 | 2279 | |
michael@0 | 2280 | /* transform size selection (4x4, 8x8, 16x16 or select-per-mb) */ |
michael@0 | 2281 | select_tx_mode(cpi); |
michael@0 | 2282 | cpi->common.comp_pred_mode = pred_type; |
michael@0 | 2283 | cpi->common.mcomp_filter_type = filter_type; |
michael@0 | 2284 | encode_frame_internal(cpi); |
michael@0 | 2285 | |
michael@0 | 2286 | for (i = 0; i < NB_PREDICTION_TYPES; ++i) { |
michael@0 | 2287 | const int diff = (int) (cpi->rd_comp_pred_diff[i] / cpi->common.MBs); |
michael@0 | 2288 | cpi->rd_prediction_type_threshes[frame_type][i] += diff; |
michael@0 | 2289 | cpi->rd_prediction_type_threshes[frame_type][i] >>= 1; |
michael@0 | 2290 | } |
michael@0 | 2291 | |
michael@0 | 2292 | for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) { |
michael@0 | 2293 | const int64_t diff = cpi->rd_filter_diff[i] / cpi->common.MBs; |
michael@0 | 2294 | cpi->rd_filter_threshes[frame_type][i] = |
michael@0 | 2295 | (cpi->rd_filter_threshes[frame_type][i] + diff) / 2; |
michael@0 | 2296 | } |
michael@0 | 2297 | |
michael@0 | 2298 | for (i = 0; i < TX_MODES; ++i) { |
michael@0 | 2299 | int64_t pd = cpi->rd_tx_select_diff[i]; |
michael@0 | 2300 | int diff; |
michael@0 | 2301 | if (i == TX_MODE_SELECT) |
michael@0 | 2302 | pd -= RDCOST(cpi->mb.rdmult, cpi->mb.rddiv, |
michael@0 | 2303 | 2048 * (TX_SIZES - 1), 0); |
michael@0 | 2304 | diff = (int) (pd / cpi->common.MBs); |
michael@0 | 2305 | cpi->rd_tx_select_threshes[frame_type][i] += diff; |
michael@0 | 2306 | cpi->rd_tx_select_threshes[frame_type][i] /= 2; |
michael@0 | 2307 | } |
michael@0 | 2308 | |
michael@0 | 2309 | if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) { |
michael@0 | 2310 | int single_count_zero = 0; |
michael@0 | 2311 | int comp_count_zero = 0; |
michael@0 | 2312 | |
michael@0 | 2313 | for (i = 0; i < COMP_INTER_CONTEXTS; i++) { |
michael@0 | 2314 | single_count_zero += cpi->comp_inter_count[i][0]; |
michael@0 | 2315 | comp_count_zero += cpi->comp_inter_count[i][1]; |
michael@0 | 2316 | } |
michael@0 | 2317 | |
michael@0 | 2318 | if (comp_count_zero == 0) { |
michael@0 | 2319 | cpi->common.comp_pred_mode = SINGLE_PREDICTION_ONLY; |
michael@0 | 2320 | vp9_zero(cpi->comp_inter_count); |
michael@0 | 2321 | } else if (single_count_zero == 0) { |
michael@0 | 2322 | cpi->common.comp_pred_mode = COMP_PREDICTION_ONLY; |
michael@0 | 2323 | vp9_zero(cpi->comp_inter_count); |
michael@0 | 2324 | } |
michael@0 | 2325 | } |
michael@0 | 2326 | |
michael@0 | 2327 | if (cpi->common.tx_mode == TX_MODE_SELECT) { |
michael@0 | 2328 | int count4x4 = 0; |
michael@0 | 2329 | int count8x8_lp = 0, count8x8_8x8p = 0; |
michael@0 | 2330 | int count16x16_16x16p = 0, count16x16_lp = 0; |
michael@0 | 2331 | int count32x32 = 0; |
michael@0 | 2332 | |
michael@0 | 2333 | for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { |
michael@0 | 2334 | count4x4 += cm->counts.tx.p32x32[i][TX_4X4]; |
michael@0 | 2335 | count4x4 += cm->counts.tx.p16x16[i][TX_4X4]; |
michael@0 | 2336 | count4x4 += cm->counts.tx.p8x8[i][TX_4X4]; |
michael@0 | 2337 | |
michael@0 | 2338 | count8x8_lp += cm->counts.tx.p32x32[i][TX_8X8]; |
michael@0 | 2339 | count8x8_lp += cm->counts.tx.p16x16[i][TX_8X8]; |
michael@0 | 2340 | count8x8_8x8p += cm->counts.tx.p8x8[i][TX_8X8]; |
michael@0 | 2341 | |
michael@0 | 2342 | count16x16_16x16p += cm->counts.tx.p16x16[i][TX_16X16]; |
michael@0 | 2343 | count16x16_lp += cm->counts.tx.p32x32[i][TX_16X16]; |
michael@0 | 2344 | count32x32 += cm->counts.tx.p32x32[i][TX_32X32]; |
michael@0 | 2345 | } |
michael@0 | 2346 | |
michael@0 | 2347 | if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 |
michael@0 | 2348 | && count32x32 == 0) { |
michael@0 | 2349 | cpi->common.tx_mode = ALLOW_8X8; |
michael@0 | 2350 | reset_skip_txfm_size(cpi, TX_8X8); |
michael@0 | 2351 | } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 |
michael@0 | 2352 | && count8x8_lp == 0 && count16x16_lp == 0 && count32x32 == 0) { |
michael@0 | 2353 | cpi->common.tx_mode = ONLY_4X4; |
michael@0 | 2354 | reset_skip_txfm_size(cpi, TX_4X4); |
michael@0 | 2355 | } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) { |
michael@0 | 2356 | cpi->common.tx_mode = ALLOW_32X32; |
michael@0 | 2357 | } else if (count32x32 == 0 && count8x8_lp == 0 && count4x4 == 0) { |
michael@0 | 2358 | cpi->common.tx_mode = ALLOW_16X16; |
michael@0 | 2359 | reset_skip_txfm_size(cpi, TX_16X16); |
michael@0 | 2360 | } |
michael@0 | 2361 | } |
michael@0 | 2362 | } else { |
michael@0 | 2363 | encode_frame_internal(cpi); |
michael@0 | 2364 | } |
michael@0 | 2365 | } |
michael@0 | 2366 | |
michael@0 | 2367 | static void sum_intra_stats(VP9_COMP *cpi, const MODE_INFO *mi) { |
michael@0 | 2368 | const MB_PREDICTION_MODE y_mode = mi->mbmi.mode; |
michael@0 | 2369 | const MB_PREDICTION_MODE uv_mode = mi->mbmi.uv_mode; |
michael@0 | 2370 | const BLOCK_SIZE bsize = mi->mbmi.sb_type; |
michael@0 | 2371 | |
michael@0 | 2372 | ++cpi->y_uv_mode_count[y_mode][uv_mode]; |
michael@0 | 2373 | |
michael@0 | 2374 | if (bsize < BLOCK_8X8) { |
michael@0 | 2375 | int idx, idy; |
michael@0 | 2376 | const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; |
michael@0 | 2377 | const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; |
michael@0 | 2378 | for (idy = 0; idy < 2; idy += num_4x4_blocks_high) |
michael@0 | 2379 | for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) |
michael@0 | 2380 | ++cpi->y_mode_count[0][mi->bmi[idy * 2 + idx].as_mode]; |
michael@0 | 2381 | } else { |
michael@0 | 2382 | ++cpi->y_mode_count[size_group_lookup[bsize]][y_mode]; |
michael@0 | 2383 | } |
michael@0 | 2384 | } |
michael@0 | 2385 | |
michael@0 | 2386 | // Experimental stub function to create a per MB zbin adjustment based on |
michael@0 | 2387 | // some previously calculated measure of MB activity. |
michael@0 | 2388 | static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x) { |
michael@0 | 2389 | #if USE_ACT_INDEX |
michael@0 | 2390 | x->act_zbin_adj = *(x->mb_activity_ptr); |
michael@0 | 2391 | #else |
michael@0 | 2392 | int64_t a; |
michael@0 | 2393 | int64_t b; |
michael@0 | 2394 | int64_t act = *(x->mb_activity_ptr); |
michael@0 | 2395 | |
michael@0 | 2396 | // Apply the masking to the RD multiplier. |
michael@0 | 2397 | a = act + 4 * cpi->activity_avg; |
michael@0 | 2398 | b = 4 * act + cpi->activity_avg; |
michael@0 | 2399 | |
michael@0 | 2400 | if (act > cpi->activity_avg) |
michael@0 | 2401 | x->act_zbin_adj = (int) (((int64_t) b + (a >> 1)) / a) - 1; |
michael@0 | 2402 | else |
michael@0 | 2403 | x->act_zbin_adj = 1 - (int) (((int64_t) a + (b >> 1)) / b); |
michael@0 | 2404 | #endif |
michael@0 | 2405 | } |
michael@0 | 2406 | static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled, |
michael@0 | 2407 | int mi_row, int mi_col, BLOCK_SIZE bsize) { |
michael@0 | 2408 | VP9_COMMON * const cm = &cpi->common; |
michael@0 | 2409 | MACROBLOCK * const x = &cpi->mb; |
michael@0 | 2410 | MACROBLOCKD * const xd = &x->e_mbd; |
michael@0 | 2411 | MODE_INFO **mi_8x8 = xd->mi_8x8; |
michael@0 | 2412 | MODE_INFO *mi = mi_8x8[0]; |
michael@0 | 2413 | MB_MODE_INFO *mbmi = &mi->mbmi; |
michael@0 | 2414 | PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize); |
michael@0 | 2415 | unsigned int segment_id = mbmi->segment_id; |
michael@0 | 2416 | const int mis = cm->mode_info_stride; |
michael@0 | 2417 | const int mi_width = num_8x8_blocks_wide_lookup[bsize]; |
michael@0 | 2418 | const int mi_height = num_8x8_blocks_high_lookup[bsize]; |
michael@0 | 2419 | x->skip_recode = !x->select_txfm_size && mbmi->sb_type >= BLOCK_8X8; |
michael@0 | 2420 | x->skip_optimize = ctx->is_coded; |
michael@0 | 2421 | ctx->is_coded = 1; |
michael@0 | 2422 | x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct; |
michael@0 | 2423 | x->skip_encode = (!output_enabled && cpi->sf.skip_encode_frame && |
michael@0 | 2424 | x->q_index < QIDX_SKIP_THRESH); |
michael@0 | 2425 | if (x->skip_encode) |
michael@0 | 2426 | return; |
michael@0 | 2427 | |
michael@0 | 2428 | if (cm->frame_type == KEY_FRAME) { |
michael@0 | 2429 | if (cpi->oxcf.tuning == VP8_TUNE_SSIM) { |
michael@0 | 2430 | adjust_act_zbin(cpi, x); |
michael@0 | 2431 | vp9_update_zbin_extra(cpi, x); |
michael@0 | 2432 | } |
michael@0 | 2433 | } else { |
michael@0 | 2434 | vp9_setup_interp_filters(xd, mbmi->interp_filter, cm); |
michael@0 | 2435 | |
michael@0 | 2436 | if (cpi->oxcf.tuning == VP8_TUNE_SSIM) { |
michael@0 | 2437 | // Adjust the zbin based on this MB rate. |
michael@0 | 2438 | adjust_act_zbin(cpi, x); |
michael@0 | 2439 | } |
michael@0 | 2440 | |
michael@0 | 2441 | // Experimental code. Special case for gf and arf zeromv modes. |
michael@0 | 2442 | // Increase zbin size to suppress noise |
michael@0 | 2443 | cpi->zbin_mode_boost = 0; |
michael@0 | 2444 | if (cpi->zbin_mode_boost_enabled) { |
michael@0 | 2445 | if (is_inter_block(mbmi)) { |
michael@0 | 2446 | if (mbmi->mode == ZEROMV) { |
michael@0 | 2447 | if (mbmi->ref_frame[0] != LAST_FRAME) |
michael@0 | 2448 | cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST; |
michael@0 | 2449 | else |
michael@0 | 2450 | cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST; |
michael@0 | 2451 | } else if (mbmi->sb_type < BLOCK_8X8) { |
michael@0 | 2452 | cpi->zbin_mode_boost = SPLIT_MV_ZBIN_BOOST; |
michael@0 | 2453 | } else { |
michael@0 | 2454 | cpi->zbin_mode_boost = MV_ZBIN_BOOST; |
michael@0 | 2455 | } |
michael@0 | 2456 | } else { |
michael@0 | 2457 | cpi->zbin_mode_boost = INTRA_ZBIN_BOOST; |
michael@0 | 2458 | } |
michael@0 | 2459 | } |
michael@0 | 2460 | |
michael@0 | 2461 | vp9_update_zbin_extra(cpi, x); |
michael@0 | 2462 | } |
michael@0 | 2463 | |
michael@0 | 2464 | if (!is_inter_block(mbmi)) { |
michael@0 | 2465 | vp9_encode_intra_block_y(x, MAX(bsize, BLOCK_8X8)); |
michael@0 | 2466 | vp9_encode_intra_block_uv(x, MAX(bsize, BLOCK_8X8)); |
michael@0 | 2467 | if (output_enabled) |
michael@0 | 2468 | sum_intra_stats(cpi, mi); |
michael@0 | 2469 | } else { |
michael@0 | 2470 | int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->ref_frame[0])]; |
michael@0 | 2471 | YV12_BUFFER_CONFIG *ref_fb = &cm->yv12_fb[idx]; |
michael@0 | 2472 | YV12_BUFFER_CONFIG *second_ref_fb = NULL; |
michael@0 | 2473 | if (has_second_ref(mbmi)) { |
michael@0 | 2474 | idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->ref_frame[1])]; |
michael@0 | 2475 | second_ref_fb = &cm->yv12_fb[idx]; |
michael@0 | 2476 | } |
michael@0 | 2477 | |
michael@0 | 2478 | assert(cm->frame_type != KEY_FRAME); |
michael@0 | 2479 | |
michael@0 | 2480 | setup_pre_planes(xd, 0, ref_fb, mi_row, mi_col, |
michael@0 | 2481 | &xd->scale_factor[0]); |
michael@0 | 2482 | setup_pre_planes(xd, 1, second_ref_fb, mi_row, mi_col, |
michael@0 | 2483 | &xd->scale_factor[1]); |
michael@0 | 2484 | |
michael@0 | 2485 | vp9_build_inter_predictors_sb(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8)); |
michael@0 | 2486 | } |
michael@0 | 2487 | |
michael@0 | 2488 | if (!is_inter_block(mbmi)) { |
michael@0 | 2489 | vp9_tokenize_sb(cpi, t, !output_enabled, MAX(bsize, BLOCK_8X8)); |
michael@0 | 2490 | } else if (!x->skip) { |
michael@0 | 2491 | vp9_encode_sb(x, MAX(bsize, BLOCK_8X8)); |
michael@0 | 2492 | vp9_tokenize_sb(cpi, t, !output_enabled, MAX(bsize, BLOCK_8X8)); |
michael@0 | 2493 | } else { |
michael@0 | 2494 | int mb_skip_context = xd->left_available ? mi_8x8[-1]->mbmi.skip_coeff : 0; |
michael@0 | 2495 | mb_skip_context += mi_8x8[-mis] ? mi_8x8[-mis]->mbmi.skip_coeff : 0; |
michael@0 | 2496 | |
michael@0 | 2497 | mbmi->skip_coeff = 1; |
michael@0 | 2498 | if (output_enabled) |
michael@0 | 2499 | cm->counts.mbskip[mb_skip_context][1]++; |
michael@0 | 2500 | reset_skip_context(xd, MAX(bsize, BLOCK_8X8)); |
michael@0 | 2501 | } |
michael@0 | 2502 | |
michael@0 | 2503 | if (output_enabled) { |
michael@0 | 2504 | if (cm->tx_mode == TX_MODE_SELECT && |
michael@0 | 2505 | mbmi->sb_type >= BLOCK_8X8 && |
michael@0 | 2506 | !(is_inter_block(mbmi) && |
michael@0 | 2507 | (mbmi->skip_coeff || |
michael@0 | 2508 | vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)))) { |
michael@0 | 2509 | const uint8_t context = vp9_get_pred_context_tx_size(xd); |
michael@0 | 2510 | ++get_tx_counts(max_txsize_lookup[bsize], |
michael@0 | 2511 | context, &cm->counts.tx)[mbmi->tx_size]; |
michael@0 | 2512 | } else { |
michael@0 | 2513 | int x, y; |
michael@0 | 2514 | TX_SIZE sz = tx_mode_to_biggest_tx_size[cm->tx_mode]; |
michael@0 | 2515 | assert(sizeof(tx_mode_to_biggest_tx_size) / |
michael@0 | 2516 | sizeof(tx_mode_to_biggest_tx_size[0]) == TX_MODES); |
michael@0 | 2517 | // The new intra coding scheme requires no change of transform size |
michael@0 | 2518 | if (is_inter_block(&mi->mbmi)) { |
michael@0 | 2519 | if (sz == TX_32X32 && bsize < BLOCK_32X32) |
michael@0 | 2520 | sz = TX_16X16; |
michael@0 | 2521 | if (sz == TX_16X16 && bsize < BLOCK_16X16) |
michael@0 | 2522 | sz = TX_8X8; |
michael@0 | 2523 | if (sz == TX_8X8 && bsize < BLOCK_8X8) |
michael@0 | 2524 | sz = TX_4X4; |
michael@0 | 2525 | } else if (bsize >= BLOCK_8X8) { |
michael@0 | 2526 | sz = mbmi->tx_size; |
michael@0 | 2527 | } else { |
michael@0 | 2528 | sz = TX_4X4; |
michael@0 | 2529 | } |
michael@0 | 2530 | |
michael@0 | 2531 | for (y = 0; y < mi_height; y++) |
michael@0 | 2532 | for (x = 0; x < mi_width; x++) |
michael@0 | 2533 | if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows) |
michael@0 | 2534 | mi_8x8[mis * y + x]->mbmi.tx_size = sz; |
michael@0 | 2535 | } |
michael@0 | 2536 | } |
michael@0 | 2537 | } |