1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libvpx/vp8/encoder/encodemb.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,648 @@ 1.4 +/* 1.5 + * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license 1.8 + * that can be found in the LICENSE file in the root of the source 1.9 + * tree. An additional intellectual property rights grant can be found 1.10 + * in the file PATENTS. All contributing project authors may 1.11 + * be found in the AUTHORS file in the root of the source tree. 1.12 + */ 1.13 + 1.14 + 1.15 +#include "vpx_config.h" 1.16 +#include "vp8_rtcd.h" 1.17 +#include "encodemb.h" 1.18 +#include "vp8/common/reconinter.h" 1.19 +#include "quantize.h" 1.20 +#include "tokenize.h" 1.21 +#include "vp8/common/invtrans.h" 1.22 +#include "vpx_mem/vpx_mem.h" 1.23 +#include "rdopt.h" 1.24 + 1.25 +void vp8_subtract_b_c(BLOCK *be, BLOCKD *bd, int pitch) 1.26 +{ 1.27 + unsigned char *src_ptr = (*(be->base_src) + be->src); 1.28 + short *diff_ptr = be->src_diff; 1.29 + unsigned char *pred_ptr = bd->predictor; 1.30 + int src_stride = be->src_stride; 1.31 + 1.32 + int r, c; 1.33 + 1.34 + for (r = 0; r < 4; r++) 1.35 + { 1.36 + for (c = 0; c < 4; c++) 1.37 + { 1.38 + diff_ptr[c] = src_ptr[c] - pred_ptr[c]; 1.39 + } 1.40 + 1.41 + diff_ptr += pitch; 1.42 + pred_ptr += pitch; 1.43 + src_ptr += src_stride; 1.44 + } 1.45 +} 1.46 + 1.47 +void vp8_subtract_mbuv_c(short *diff, unsigned char *usrc, unsigned char *vsrc, 1.48 + int src_stride, unsigned char *upred, 1.49 + unsigned char *vpred, int pred_stride) 1.50 +{ 1.51 + short *udiff = diff + 256; 1.52 + short *vdiff = diff + 320; 1.53 + 1.54 + int r, c; 1.55 + 1.56 + for (r = 0; r < 8; r++) 1.57 + { 1.58 + for (c = 0; c < 8; c++) 1.59 + { 1.60 + udiff[c] = usrc[c] - upred[c]; 1.61 + } 1.62 + 1.63 + udiff += 8; 1.64 + upred += pred_stride; 1.65 + usrc += src_stride; 1.66 + } 1.67 + 1.68 + for (r = 0; r < 8; r++) 1.69 + { 1.70 + for (c = 0; c < 8; c++) 1.71 + { 1.72 + vdiff[c] = vsrc[c] - vpred[c]; 1.73 + } 1.74 + 1.75 + vdiff += 8; 1.76 + vpred += pred_stride; 1.77 + vsrc += src_stride; 1.78 + } 1.79 +} 1.80 + 1.81 +void vp8_subtract_mby_c(short *diff, unsigned char *src, int src_stride, 1.82 + unsigned char *pred, int pred_stride) 1.83 +{ 1.84 + int r, c; 1.85 + 1.86 + for (r = 0; r < 16; r++) 1.87 + { 1.88 + for (c = 0; c < 16; c++) 1.89 + { 1.90 + diff[c] = src[c] - pred[c]; 1.91 + } 1.92 + 1.93 + diff += 16; 1.94 + pred += pred_stride; 1.95 + src += src_stride; 1.96 + } 1.97 +} 1.98 + 1.99 +static void vp8_subtract_mb(MACROBLOCK *x) 1.100 +{ 1.101 + BLOCK *b = &x->block[0]; 1.102 + 1.103 + vp8_subtract_mby(x->src_diff, *(b->base_src), 1.104 + b->src_stride, x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride); 1.105 + vp8_subtract_mbuv(x->src_diff, x->src.u_buffer, 1.106 + x->src.v_buffer, x->src.uv_stride, x->e_mbd.dst.u_buffer, 1.107 + x->e_mbd.dst.v_buffer, x->e_mbd.dst.uv_stride); 1.108 +} 1.109 + 1.110 +static void build_dcblock(MACROBLOCK *x) 1.111 +{ 1.112 + short *src_diff_ptr = &x->src_diff[384]; 1.113 + int i; 1.114 + 1.115 + for (i = 0; i < 16; i++) 1.116 + { 1.117 + src_diff_ptr[i] = x->coeff[i * 16]; 1.118 + } 1.119 +} 1.120 + 1.121 +void vp8_transform_mbuv(MACROBLOCK *x) 1.122 +{ 1.123 + int i; 1.124 + 1.125 + for (i = 16; i < 24; i += 2) 1.126 + { 1.127 + x->short_fdct8x4(&x->block[i].src_diff[0], 1.128 + &x->block[i].coeff[0], 16); 1.129 + } 1.130 +} 1.131 + 1.132 + 1.133 +void vp8_transform_intra_mby(MACROBLOCK *x) 1.134 +{ 1.135 + int i; 1.136 + 1.137 + for (i = 0; i < 16; i += 2) 1.138 + { 1.139 + x->short_fdct8x4(&x->block[i].src_diff[0], 1.140 + &x->block[i].coeff[0], 32); 1.141 + } 1.142 + 1.143 + /* build dc block from 16 y dc values */ 1.144 + build_dcblock(x); 1.145 + 1.146 + /* do 2nd order transform on the dc block */ 1.147 + x->short_walsh4x4(&x->block[24].src_diff[0], 1.148 + &x->block[24].coeff[0], 8); 1.149 + 1.150 +} 1.151 + 1.152 + 1.153 +static void transform_mb(MACROBLOCK *x) 1.154 +{ 1.155 + int i; 1.156 + 1.157 + for (i = 0; i < 16; i += 2) 1.158 + { 1.159 + x->short_fdct8x4(&x->block[i].src_diff[0], 1.160 + &x->block[i].coeff[0], 32); 1.161 + } 1.162 + 1.163 + /* build dc block from 16 y dc values */ 1.164 + if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) 1.165 + build_dcblock(x); 1.166 + 1.167 + for (i = 16; i < 24; i += 2) 1.168 + { 1.169 + x->short_fdct8x4(&x->block[i].src_diff[0], 1.170 + &x->block[i].coeff[0], 16); 1.171 + } 1.172 + 1.173 + /* do 2nd order transform on the dc block */ 1.174 + if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) 1.175 + x->short_walsh4x4(&x->block[24].src_diff[0], 1.176 + &x->block[24].coeff[0], 8); 1.177 + 1.178 +} 1.179 + 1.180 + 1.181 +static void transform_mby(MACROBLOCK *x) 1.182 +{ 1.183 + int i; 1.184 + 1.185 + for (i = 0; i < 16; i += 2) 1.186 + { 1.187 + x->short_fdct8x4(&x->block[i].src_diff[0], 1.188 + &x->block[i].coeff[0], 32); 1.189 + } 1.190 + 1.191 + /* build dc block from 16 y dc values */ 1.192 + if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) 1.193 + { 1.194 + build_dcblock(x); 1.195 + x->short_walsh4x4(&x->block[24].src_diff[0], 1.196 + &x->block[24].coeff[0], 8); 1.197 + } 1.198 +} 1.199 + 1.200 + 1.201 + 1.202 +#define RDTRUNC(RM,DM,R,D) ( (128+(R)*(RM)) & 0xFF ) 1.203 + 1.204 +typedef struct vp8_token_state vp8_token_state; 1.205 + 1.206 +struct vp8_token_state{ 1.207 + int rate; 1.208 + int error; 1.209 + signed char next; 1.210 + signed char token; 1.211 + short qc; 1.212 +}; 1.213 + 1.214 +/* TODO: experiments to find optimal multiple numbers */ 1.215 +#define Y1_RD_MULT 4 1.216 +#define UV_RD_MULT 2 1.217 +#define Y2_RD_MULT 16 1.218 + 1.219 +static const int plane_rd_mult[4]= 1.220 +{ 1.221 + Y1_RD_MULT, 1.222 + Y2_RD_MULT, 1.223 + UV_RD_MULT, 1.224 + Y1_RD_MULT 1.225 +}; 1.226 + 1.227 +static void optimize_b(MACROBLOCK *mb, int ib, int type, 1.228 + ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) 1.229 +{ 1.230 + BLOCK *b; 1.231 + BLOCKD *d; 1.232 + vp8_token_state tokens[17][2]; 1.233 + unsigned best_mask[2]; 1.234 + const short *dequant_ptr; 1.235 + const short *coeff_ptr; 1.236 + short *qcoeff_ptr; 1.237 + short *dqcoeff_ptr; 1.238 + int eob; 1.239 + int i0; 1.240 + int rc; 1.241 + int x; 1.242 + int sz = 0; 1.243 + int next; 1.244 + int rdmult; 1.245 + int rddiv; 1.246 + int final_eob; 1.247 + int rd_cost0; 1.248 + int rd_cost1; 1.249 + int rate0; 1.250 + int rate1; 1.251 + int error0; 1.252 + int error1; 1.253 + int t0; 1.254 + int t1; 1.255 + int best; 1.256 + int band; 1.257 + int pt; 1.258 + int i; 1.259 + int err_mult = plane_rd_mult[type]; 1.260 + 1.261 + b = &mb->block[ib]; 1.262 + d = &mb->e_mbd.block[ib]; 1.263 + 1.264 + /* Enable this to test the effect of RDO as a replacement for the dynamic 1.265 + * zero bin instead of an augmentation of it. 1.266 + */ 1.267 +#if 0 1.268 + vp8_strict_quantize_b(b, d); 1.269 +#endif 1.270 + 1.271 + dequant_ptr = d->dequant; 1.272 + coeff_ptr = b->coeff; 1.273 + qcoeff_ptr = d->qcoeff; 1.274 + dqcoeff_ptr = d->dqcoeff; 1.275 + i0 = !type; 1.276 + eob = *d->eob; 1.277 + 1.278 + /* Now set up a Viterbi trellis to evaluate alternative roundings. */ 1.279 + rdmult = mb->rdmult * err_mult; 1.280 + if(mb->e_mbd.mode_info_context->mbmi.ref_frame==INTRA_FRAME) 1.281 + rdmult = (rdmult * 9)>>4; 1.282 + 1.283 + rddiv = mb->rddiv; 1.284 + best_mask[0] = best_mask[1] = 0; 1.285 + /* Initialize the sentinel node of the trellis. */ 1.286 + tokens[eob][0].rate = 0; 1.287 + tokens[eob][0].error = 0; 1.288 + tokens[eob][0].next = 16; 1.289 + tokens[eob][0].token = DCT_EOB_TOKEN; 1.290 + tokens[eob][0].qc = 0; 1.291 + *(tokens[eob] + 1) = *(tokens[eob] + 0); 1.292 + next = eob; 1.293 + for (i = eob; i-- > i0;) 1.294 + { 1.295 + int base_bits; 1.296 + int d2; 1.297 + int dx; 1.298 + 1.299 + rc = vp8_default_zig_zag1d[i]; 1.300 + x = qcoeff_ptr[rc]; 1.301 + /* Only add a trellis state for non-zero coefficients. */ 1.302 + if (x) 1.303 + { 1.304 + int shortcut=0; 1.305 + error0 = tokens[next][0].error; 1.306 + error1 = tokens[next][1].error; 1.307 + /* Evaluate the first possibility for this state. */ 1.308 + rate0 = tokens[next][0].rate; 1.309 + rate1 = tokens[next][1].rate; 1.310 + t0 = (vp8_dct_value_tokens_ptr + x)->Token; 1.311 + /* Consider both possible successor states. */ 1.312 + if (next < 16) 1.313 + { 1.314 + band = vp8_coef_bands[i + 1]; 1.315 + pt = vp8_prev_token_class[t0]; 1.316 + rate0 += 1.317 + mb->token_costs[type][band][pt][tokens[next][0].token]; 1.318 + rate1 += 1.319 + mb->token_costs[type][band][pt][tokens[next][1].token]; 1.320 + } 1.321 + rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0); 1.322 + rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1); 1.323 + if (rd_cost0 == rd_cost1) 1.324 + { 1.325 + rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0); 1.326 + rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1); 1.327 + } 1.328 + /* And pick the best. */ 1.329 + best = rd_cost1 < rd_cost0; 1.330 + base_bits = *(vp8_dct_value_cost_ptr + x); 1.331 + dx = dqcoeff_ptr[rc] - coeff_ptr[rc]; 1.332 + d2 = dx*dx; 1.333 + tokens[i][0].rate = base_bits + (best ? rate1 : rate0); 1.334 + tokens[i][0].error = d2 + (best ? error1 : error0); 1.335 + tokens[i][0].next = next; 1.336 + tokens[i][0].token = t0; 1.337 + tokens[i][0].qc = x; 1.338 + best_mask[0] |= best << i; 1.339 + /* Evaluate the second possibility for this state. */ 1.340 + rate0 = tokens[next][0].rate; 1.341 + rate1 = tokens[next][1].rate; 1.342 + 1.343 + if((abs(x)*dequant_ptr[rc]>abs(coeff_ptr[rc])) && 1.344 + (abs(x)*dequant_ptr[rc]<abs(coeff_ptr[rc])+dequant_ptr[rc])) 1.345 + shortcut = 1; 1.346 + else 1.347 + shortcut = 0; 1.348 + 1.349 + if(shortcut) 1.350 + { 1.351 + sz = -(x < 0); 1.352 + x -= 2*sz + 1; 1.353 + } 1.354 + 1.355 + /* Consider both possible successor states. */ 1.356 + if (!x) 1.357 + { 1.358 + /* If we reduced this coefficient to zero, check to see if 1.359 + * we need to move the EOB back here. 1.360 + */ 1.361 + t0 = tokens[next][0].token == DCT_EOB_TOKEN ? 1.362 + DCT_EOB_TOKEN : ZERO_TOKEN; 1.363 + t1 = tokens[next][1].token == DCT_EOB_TOKEN ? 1.364 + DCT_EOB_TOKEN : ZERO_TOKEN; 1.365 + } 1.366 + else 1.367 + { 1.368 + t0=t1 = (vp8_dct_value_tokens_ptr + x)->Token; 1.369 + } 1.370 + if (next < 16) 1.371 + { 1.372 + band = vp8_coef_bands[i + 1]; 1.373 + if(t0!=DCT_EOB_TOKEN) 1.374 + { 1.375 + pt = vp8_prev_token_class[t0]; 1.376 + rate0 += mb->token_costs[type][band][pt][ 1.377 + tokens[next][0].token]; 1.378 + } 1.379 + if(t1!=DCT_EOB_TOKEN) 1.380 + { 1.381 + pt = vp8_prev_token_class[t1]; 1.382 + rate1 += mb->token_costs[type][band][pt][ 1.383 + tokens[next][1].token]; 1.384 + } 1.385 + } 1.386 + 1.387 + rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0); 1.388 + rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1); 1.389 + if (rd_cost0 == rd_cost1) 1.390 + { 1.391 + rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0); 1.392 + rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1); 1.393 + } 1.394 + /* And pick the best. */ 1.395 + best = rd_cost1 < rd_cost0; 1.396 + base_bits = *(vp8_dct_value_cost_ptr + x); 1.397 + 1.398 + if(shortcut) 1.399 + { 1.400 + dx -= (dequant_ptr[rc] + sz) ^ sz; 1.401 + d2 = dx*dx; 1.402 + } 1.403 + tokens[i][1].rate = base_bits + (best ? rate1 : rate0); 1.404 + tokens[i][1].error = d2 + (best ? error1 : error0); 1.405 + tokens[i][1].next = next; 1.406 + tokens[i][1].token =best?t1:t0; 1.407 + tokens[i][1].qc = x; 1.408 + best_mask[1] |= best << i; 1.409 + /* Finally, make this the new head of the trellis. */ 1.410 + next = i; 1.411 + } 1.412 + /* There's no choice to make for a zero coefficient, so we don't 1.413 + * add a new trellis node, but we do need to update the costs. 1.414 + */ 1.415 + else 1.416 + { 1.417 + band = vp8_coef_bands[i + 1]; 1.418 + t0 = tokens[next][0].token; 1.419 + t1 = tokens[next][1].token; 1.420 + /* Update the cost of each path if we're past the EOB token. */ 1.421 + if (t0 != DCT_EOB_TOKEN) 1.422 + { 1.423 + tokens[next][0].rate += mb->token_costs[type][band][0][t0]; 1.424 + tokens[next][0].token = ZERO_TOKEN; 1.425 + } 1.426 + if (t1 != DCT_EOB_TOKEN) 1.427 + { 1.428 + tokens[next][1].rate += mb->token_costs[type][band][0][t1]; 1.429 + tokens[next][1].token = ZERO_TOKEN; 1.430 + } 1.431 + /* Don't update next, because we didn't add a new node. */ 1.432 + } 1.433 + } 1.434 + 1.435 + /* Now pick the best path through the whole trellis. */ 1.436 + band = vp8_coef_bands[i + 1]; 1.437 + VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); 1.438 + rate0 = tokens[next][0].rate; 1.439 + rate1 = tokens[next][1].rate; 1.440 + error0 = tokens[next][0].error; 1.441 + error1 = tokens[next][1].error; 1.442 + t0 = tokens[next][0].token; 1.443 + t1 = tokens[next][1].token; 1.444 + rate0 += mb->token_costs[type][band][pt][t0]; 1.445 + rate1 += mb->token_costs[type][band][pt][t1]; 1.446 + rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0); 1.447 + rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1); 1.448 + if (rd_cost0 == rd_cost1) 1.449 + { 1.450 + rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0); 1.451 + rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1); 1.452 + } 1.453 + best = rd_cost1 < rd_cost0; 1.454 + final_eob = i0 - 1; 1.455 + for (i = next; i < eob; i = next) 1.456 + { 1.457 + x = tokens[i][best].qc; 1.458 + if (x) 1.459 + final_eob = i; 1.460 + rc = vp8_default_zig_zag1d[i]; 1.461 + qcoeff_ptr[rc] = x; 1.462 + dqcoeff_ptr[rc] = x * dequant_ptr[rc]; 1.463 + next = tokens[i][best].next; 1.464 + best = (best_mask[best] >> i) & 1; 1.465 + } 1.466 + final_eob++; 1.467 + 1.468 + *a = *l = (final_eob != !type); 1.469 + *d->eob = (char)final_eob; 1.470 +} 1.471 +static void check_reset_2nd_coeffs(MACROBLOCKD *x, int type, 1.472 + ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) 1.473 +{ 1.474 + int sum=0; 1.475 + int i; 1.476 + BLOCKD *bd = &x->block[24]; 1.477 + 1.478 + if(bd->dequant[0]>=35 && bd->dequant[1]>=35) 1.479 + return; 1.480 + 1.481 + for(i=0;i<(*bd->eob);i++) 1.482 + { 1.483 + int coef = bd->dqcoeff[vp8_default_zig_zag1d[i]]; 1.484 + sum+= (coef>=0)?coef:-coef; 1.485 + if(sum>=35) 1.486 + return; 1.487 + } 1.488 + /************************************************************************** 1.489 + our inverse hadamard transform effectively is weighted sum of all 16 inputs 1.490 + with weight either 1 or -1. It has a last stage scaling of (sum+3)>>3. And 1.491 + dc only idct is (dc+4)>>3. So if all the sums are between -35 and 29, the 1.492 + output after inverse wht and idct will be all zero. A sum of absolute value 1.493 + smaller than 35 guarantees all 16 different (+1/-1) weighted sums in wht 1.494 + fall between -35 and +35. 1.495 + **************************************************************************/ 1.496 + if(sum < 35) 1.497 + { 1.498 + for(i=0;i<(*bd->eob);i++) 1.499 + { 1.500 + int rc = vp8_default_zig_zag1d[i]; 1.501 + bd->qcoeff[rc]=0; 1.502 + bd->dqcoeff[rc]=0; 1.503 + } 1.504 + *bd->eob = 0; 1.505 + *a = *l = (*bd->eob != !type); 1.506 + } 1.507 +} 1.508 + 1.509 +static void optimize_mb(MACROBLOCK *x) 1.510 +{ 1.511 + int b; 1.512 + int type; 1.513 + int has_2nd_order; 1.514 + 1.515 + ENTROPY_CONTEXT_PLANES t_above, t_left; 1.516 + ENTROPY_CONTEXT *ta; 1.517 + ENTROPY_CONTEXT *tl; 1.518 + 1.519 + vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES)); 1.520 + vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES)); 1.521 + 1.522 + ta = (ENTROPY_CONTEXT *)&t_above; 1.523 + tl = (ENTROPY_CONTEXT *)&t_left; 1.524 + 1.525 + has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED 1.526 + && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); 1.527 + type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC; 1.528 + 1.529 + for (b = 0; b < 16; b++) 1.530 + { 1.531 + optimize_b(x, b, type, 1.532 + ta + vp8_block2above[b], tl + vp8_block2left[b]); 1.533 + } 1.534 + 1.535 + for (b = 16; b < 24; b++) 1.536 + { 1.537 + optimize_b(x, b, PLANE_TYPE_UV, 1.538 + ta + vp8_block2above[b], tl + vp8_block2left[b]); 1.539 + } 1.540 + 1.541 + if (has_2nd_order) 1.542 + { 1.543 + b=24; 1.544 + optimize_b(x, b, PLANE_TYPE_Y2, 1.545 + ta + vp8_block2above[b], tl + vp8_block2left[b]); 1.546 + check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2, 1.547 + ta + vp8_block2above[b], tl + vp8_block2left[b]); 1.548 + } 1.549 +} 1.550 + 1.551 + 1.552 +void vp8_optimize_mby(MACROBLOCK *x) 1.553 +{ 1.554 + int b; 1.555 + int type; 1.556 + int has_2nd_order; 1.557 + 1.558 + ENTROPY_CONTEXT_PLANES t_above, t_left; 1.559 + ENTROPY_CONTEXT *ta; 1.560 + ENTROPY_CONTEXT *tl; 1.561 + 1.562 + if (!x->e_mbd.above_context) 1.563 + return; 1.564 + 1.565 + if (!x->e_mbd.left_context) 1.566 + return; 1.567 + 1.568 + vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES)); 1.569 + vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES)); 1.570 + 1.571 + ta = (ENTROPY_CONTEXT *)&t_above; 1.572 + tl = (ENTROPY_CONTEXT *)&t_left; 1.573 + 1.574 + has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED 1.575 + && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); 1.576 + type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC; 1.577 + 1.578 + for (b = 0; b < 16; b++) 1.579 + { 1.580 + optimize_b(x, b, type, 1.581 + ta + vp8_block2above[b], tl + vp8_block2left[b]); 1.582 + } 1.583 + 1.584 + 1.585 + if (has_2nd_order) 1.586 + { 1.587 + b=24; 1.588 + optimize_b(x, b, PLANE_TYPE_Y2, 1.589 + ta + vp8_block2above[b], tl + vp8_block2left[b]); 1.590 + check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2, 1.591 + ta + vp8_block2above[b], tl + vp8_block2left[b]); 1.592 + } 1.593 +} 1.594 + 1.595 +void vp8_optimize_mbuv(MACROBLOCK *x) 1.596 +{ 1.597 + int b; 1.598 + ENTROPY_CONTEXT_PLANES t_above, t_left; 1.599 + ENTROPY_CONTEXT *ta; 1.600 + ENTROPY_CONTEXT *tl; 1.601 + 1.602 + if (!x->e_mbd.above_context) 1.603 + return; 1.604 + 1.605 + if (!x->e_mbd.left_context) 1.606 + return; 1.607 + 1.608 + vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES)); 1.609 + vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES)); 1.610 + 1.611 + ta = (ENTROPY_CONTEXT *)&t_above; 1.612 + tl = (ENTROPY_CONTEXT *)&t_left; 1.613 + 1.614 + for (b = 16; b < 24; b++) 1.615 + { 1.616 + optimize_b(x, b, PLANE_TYPE_UV, 1.617 + ta + vp8_block2above[b], tl + vp8_block2left[b]); 1.618 + } 1.619 +} 1.620 + 1.621 +void vp8_encode_inter16x16(MACROBLOCK *x) 1.622 +{ 1.623 + vp8_build_inter_predictors_mb(&x->e_mbd); 1.624 + 1.625 + vp8_subtract_mb(x); 1.626 + 1.627 + transform_mb(x); 1.628 + 1.629 + vp8_quantize_mb(x); 1.630 + 1.631 + if (x->optimize) 1.632 + optimize_mb(x); 1.633 +} 1.634 + 1.635 +/* this funciton is used by first pass only */ 1.636 +void vp8_encode_inter16x16y(MACROBLOCK *x) 1.637 +{ 1.638 + BLOCK *b = &x->block[0]; 1.639 + 1.640 + vp8_build_inter16x16_predictors_mby(&x->e_mbd, x->e_mbd.dst.y_buffer, 1.641 + x->e_mbd.dst.y_stride); 1.642 + 1.643 + vp8_subtract_mby(x->src_diff, *(b->base_src), 1.644 + b->src_stride, x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride); 1.645 + 1.646 + transform_mby(x); 1.647 + 1.648 + vp8_quantize_mby(x); 1.649 + 1.650 + vp8_inverse_transform_mby(&x->e_mbd); 1.651 +}