media/libvpx/vp8/encoder/encodemb.c

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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
michael@0 12 #include "vpx_config.h"
michael@0 13 #include "vp8_rtcd.h"
michael@0 14 #include "encodemb.h"
michael@0 15 #include "vp8/common/reconinter.h"
michael@0 16 #include "quantize.h"
michael@0 17 #include "tokenize.h"
michael@0 18 #include "vp8/common/invtrans.h"
michael@0 19 #include "vpx_mem/vpx_mem.h"
michael@0 20 #include "rdopt.h"
michael@0 21
michael@0 22 void vp8_subtract_b_c(BLOCK *be, BLOCKD *bd, int pitch)
michael@0 23 {
michael@0 24 unsigned char *src_ptr = (*(be->base_src) + be->src);
michael@0 25 short *diff_ptr = be->src_diff;
michael@0 26 unsigned char *pred_ptr = bd->predictor;
michael@0 27 int src_stride = be->src_stride;
michael@0 28
michael@0 29 int r, c;
michael@0 30
michael@0 31 for (r = 0; r < 4; r++)
michael@0 32 {
michael@0 33 for (c = 0; c < 4; c++)
michael@0 34 {
michael@0 35 diff_ptr[c] = src_ptr[c] - pred_ptr[c];
michael@0 36 }
michael@0 37
michael@0 38 diff_ptr += pitch;
michael@0 39 pred_ptr += pitch;
michael@0 40 src_ptr += src_stride;
michael@0 41 }
michael@0 42 }
michael@0 43
michael@0 44 void vp8_subtract_mbuv_c(short *diff, unsigned char *usrc, unsigned char *vsrc,
michael@0 45 int src_stride, unsigned char *upred,
michael@0 46 unsigned char *vpred, int pred_stride)
michael@0 47 {
michael@0 48 short *udiff = diff + 256;
michael@0 49 short *vdiff = diff + 320;
michael@0 50
michael@0 51 int r, c;
michael@0 52
michael@0 53 for (r = 0; r < 8; r++)
michael@0 54 {
michael@0 55 for (c = 0; c < 8; c++)
michael@0 56 {
michael@0 57 udiff[c] = usrc[c] - upred[c];
michael@0 58 }
michael@0 59
michael@0 60 udiff += 8;
michael@0 61 upred += pred_stride;
michael@0 62 usrc += src_stride;
michael@0 63 }
michael@0 64
michael@0 65 for (r = 0; r < 8; r++)
michael@0 66 {
michael@0 67 for (c = 0; c < 8; c++)
michael@0 68 {
michael@0 69 vdiff[c] = vsrc[c] - vpred[c];
michael@0 70 }
michael@0 71
michael@0 72 vdiff += 8;
michael@0 73 vpred += pred_stride;
michael@0 74 vsrc += src_stride;
michael@0 75 }
michael@0 76 }
michael@0 77
michael@0 78 void vp8_subtract_mby_c(short *diff, unsigned char *src, int src_stride,
michael@0 79 unsigned char *pred, int pred_stride)
michael@0 80 {
michael@0 81 int r, c;
michael@0 82
michael@0 83 for (r = 0; r < 16; r++)
michael@0 84 {
michael@0 85 for (c = 0; c < 16; c++)
michael@0 86 {
michael@0 87 diff[c] = src[c] - pred[c];
michael@0 88 }
michael@0 89
michael@0 90 diff += 16;
michael@0 91 pred += pred_stride;
michael@0 92 src += src_stride;
michael@0 93 }
michael@0 94 }
michael@0 95
michael@0 96 static void vp8_subtract_mb(MACROBLOCK *x)
michael@0 97 {
michael@0 98 BLOCK *b = &x->block[0];
michael@0 99
michael@0 100 vp8_subtract_mby(x->src_diff, *(b->base_src),
michael@0 101 b->src_stride, x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride);
michael@0 102 vp8_subtract_mbuv(x->src_diff, x->src.u_buffer,
michael@0 103 x->src.v_buffer, x->src.uv_stride, x->e_mbd.dst.u_buffer,
michael@0 104 x->e_mbd.dst.v_buffer, x->e_mbd.dst.uv_stride);
michael@0 105 }
michael@0 106
michael@0 107 static void build_dcblock(MACROBLOCK *x)
michael@0 108 {
michael@0 109 short *src_diff_ptr = &x->src_diff[384];
michael@0 110 int i;
michael@0 111
michael@0 112 for (i = 0; i < 16; i++)
michael@0 113 {
michael@0 114 src_diff_ptr[i] = x->coeff[i * 16];
michael@0 115 }
michael@0 116 }
michael@0 117
michael@0 118 void vp8_transform_mbuv(MACROBLOCK *x)
michael@0 119 {
michael@0 120 int i;
michael@0 121
michael@0 122 for (i = 16; i < 24; i += 2)
michael@0 123 {
michael@0 124 x->short_fdct8x4(&x->block[i].src_diff[0],
michael@0 125 &x->block[i].coeff[0], 16);
michael@0 126 }
michael@0 127 }
michael@0 128
michael@0 129
michael@0 130 void vp8_transform_intra_mby(MACROBLOCK *x)
michael@0 131 {
michael@0 132 int i;
michael@0 133
michael@0 134 for (i = 0; i < 16; i += 2)
michael@0 135 {
michael@0 136 x->short_fdct8x4(&x->block[i].src_diff[0],
michael@0 137 &x->block[i].coeff[0], 32);
michael@0 138 }
michael@0 139
michael@0 140 /* build dc block from 16 y dc values */
michael@0 141 build_dcblock(x);
michael@0 142
michael@0 143 /* do 2nd order transform on the dc block */
michael@0 144 x->short_walsh4x4(&x->block[24].src_diff[0],
michael@0 145 &x->block[24].coeff[0], 8);
michael@0 146
michael@0 147 }
michael@0 148
michael@0 149
michael@0 150 static void transform_mb(MACROBLOCK *x)
michael@0 151 {
michael@0 152 int i;
michael@0 153
michael@0 154 for (i = 0; i < 16; i += 2)
michael@0 155 {
michael@0 156 x->short_fdct8x4(&x->block[i].src_diff[0],
michael@0 157 &x->block[i].coeff[0], 32);
michael@0 158 }
michael@0 159
michael@0 160 /* build dc block from 16 y dc values */
michael@0 161 if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV)
michael@0 162 build_dcblock(x);
michael@0 163
michael@0 164 for (i = 16; i < 24; i += 2)
michael@0 165 {
michael@0 166 x->short_fdct8x4(&x->block[i].src_diff[0],
michael@0 167 &x->block[i].coeff[0], 16);
michael@0 168 }
michael@0 169
michael@0 170 /* do 2nd order transform on the dc block */
michael@0 171 if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV)
michael@0 172 x->short_walsh4x4(&x->block[24].src_diff[0],
michael@0 173 &x->block[24].coeff[0], 8);
michael@0 174
michael@0 175 }
michael@0 176
michael@0 177
michael@0 178 static void transform_mby(MACROBLOCK *x)
michael@0 179 {
michael@0 180 int i;
michael@0 181
michael@0 182 for (i = 0; i < 16; i += 2)
michael@0 183 {
michael@0 184 x->short_fdct8x4(&x->block[i].src_diff[0],
michael@0 185 &x->block[i].coeff[0], 32);
michael@0 186 }
michael@0 187
michael@0 188 /* build dc block from 16 y dc values */
michael@0 189 if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV)
michael@0 190 {
michael@0 191 build_dcblock(x);
michael@0 192 x->short_walsh4x4(&x->block[24].src_diff[0],
michael@0 193 &x->block[24].coeff[0], 8);
michael@0 194 }
michael@0 195 }
michael@0 196
michael@0 197
michael@0 198
michael@0 199 #define RDTRUNC(RM,DM,R,D) ( (128+(R)*(RM)) & 0xFF )
michael@0 200
michael@0 201 typedef struct vp8_token_state vp8_token_state;
michael@0 202
michael@0 203 struct vp8_token_state{
michael@0 204 int rate;
michael@0 205 int error;
michael@0 206 signed char next;
michael@0 207 signed char token;
michael@0 208 short qc;
michael@0 209 };
michael@0 210
michael@0 211 /* TODO: experiments to find optimal multiple numbers */
michael@0 212 #define Y1_RD_MULT 4
michael@0 213 #define UV_RD_MULT 2
michael@0 214 #define Y2_RD_MULT 16
michael@0 215
michael@0 216 static const int plane_rd_mult[4]=
michael@0 217 {
michael@0 218 Y1_RD_MULT,
michael@0 219 Y2_RD_MULT,
michael@0 220 UV_RD_MULT,
michael@0 221 Y1_RD_MULT
michael@0 222 };
michael@0 223
michael@0 224 static void optimize_b(MACROBLOCK *mb, int ib, int type,
michael@0 225 ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l)
michael@0 226 {
michael@0 227 BLOCK *b;
michael@0 228 BLOCKD *d;
michael@0 229 vp8_token_state tokens[17][2];
michael@0 230 unsigned best_mask[2];
michael@0 231 const short *dequant_ptr;
michael@0 232 const short *coeff_ptr;
michael@0 233 short *qcoeff_ptr;
michael@0 234 short *dqcoeff_ptr;
michael@0 235 int eob;
michael@0 236 int i0;
michael@0 237 int rc;
michael@0 238 int x;
michael@0 239 int sz = 0;
michael@0 240 int next;
michael@0 241 int rdmult;
michael@0 242 int rddiv;
michael@0 243 int final_eob;
michael@0 244 int rd_cost0;
michael@0 245 int rd_cost1;
michael@0 246 int rate0;
michael@0 247 int rate1;
michael@0 248 int error0;
michael@0 249 int error1;
michael@0 250 int t0;
michael@0 251 int t1;
michael@0 252 int best;
michael@0 253 int band;
michael@0 254 int pt;
michael@0 255 int i;
michael@0 256 int err_mult = plane_rd_mult[type];
michael@0 257
michael@0 258 b = &mb->block[ib];
michael@0 259 d = &mb->e_mbd.block[ib];
michael@0 260
michael@0 261 /* Enable this to test the effect of RDO as a replacement for the dynamic
michael@0 262 * zero bin instead of an augmentation of it.
michael@0 263 */
michael@0 264 #if 0
michael@0 265 vp8_strict_quantize_b(b, d);
michael@0 266 #endif
michael@0 267
michael@0 268 dequant_ptr = d->dequant;
michael@0 269 coeff_ptr = b->coeff;
michael@0 270 qcoeff_ptr = d->qcoeff;
michael@0 271 dqcoeff_ptr = d->dqcoeff;
michael@0 272 i0 = !type;
michael@0 273 eob = *d->eob;
michael@0 274
michael@0 275 /* Now set up a Viterbi trellis to evaluate alternative roundings. */
michael@0 276 rdmult = mb->rdmult * err_mult;
michael@0 277 if(mb->e_mbd.mode_info_context->mbmi.ref_frame==INTRA_FRAME)
michael@0 278 rdmult = (rdmult * 9)>>4;
michael@0 279
michael@0 280 rddiv = mb->rddiv;
michael@0 281 best_mask[0] = best_mask[1] = 0;
michael@0 282 /* Initialize the sentinel node of the trellis. */
michael@0 283 tokens[eob][0].rate = 0;
michael@0 284 tokens[eob][0].error = 0;
michael@0 285 tokens[eob][0].next = 16;
michael@0 286 tokens[eob][0].token = DCT_EOB_TOKEN;
michael@0 287 tokens[eob][0].qc = 0;
michael@0 288 *(tokens[eob] + 1) = *(tokens[eob] + 0);
michael@0 289 next = eob;
michael@0 290 for (i = eob; i-- > i0;)
michael@0 291 {
michael@0 292 int base_bits;
michael@0 293 int d2;
michael@0 294 int dx;
michael@0 295
michael@0 296 rc = vp8_default_zig_zag1d[i];
michael@0 297 x = qcoeff_ptr[rc];
michael@0 298 /* Only add a trellis state for non-zero coefficients. */
michael@0 299 if (x)
michael@0 300 {
michael@0 301 int shortcut=0;
michael@0 302 error0 = tokens[next][0].error;
michael@0 303 error1 = tokens[next][1].error;
michael@0 304 /* Evaluate the first possibility for this state. */
michael@0 305 rate0 = tokens[next][0].rate;
michael@0 306 rate1 = tokens[next][1].rate;
michael@0 307 t0 = (vp8_dct_value_tokens_ptr + x)->Token;
michael@0 308 /* Consider both possible successor states. */
michael@0 309 if (next < 16)
michael@0 310 {
michael@0 311 band = vp8_coef_bands[i + 1];
michael@0 312 pt = vp8_prev_token_class[t0];
michael@0 313 rate0 +=
michael@0 314 mb->token_costs[type][band][pt][tokens[next][0].token];
michael@0 315 rate1 +=
michael@0 316 mb->token_costs[type][band][pt][tokens[next][1].token];
michael@0 317 }
michael@0 318 rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
michael@0 319 rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
michael@0 320 if (rd_cost0 == rd_cost1)
michael@0 321 {
michael@0 322 rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
michael@0 323 rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
michael@0 324 }
michael@0 325 /* And pick the best. */
michael@0 326 best = rd_cost1 < rd_cost0;
michael@0 327 base_bits = *(vp8_dct_value_cost_ptr + x);
michael@0 328 dx = dqcoeff_ptr[rc] - coeff_ptr[rc];
michael@0 329 d2 = dx*dx;
michael@0 330 tokens[i][0].rate = base_bits + (best ? rate1 : rate0);
michael@0 331 tokens[i][0].error = d2 + (best ? error1 : error0);
michael@0 332 tokens[i][0].next = next;
michael@0 333 tokens[i][0].token = t0;
michael@0 334 tokens[i][0].qc = x;
michael@0 335 best_mask[0] |= best << i;
michael@0 336 /* Evaluate the second possibility for this state. */
michael@0 337 rate0 = tokens[next][0].rate;
michael@0 338 rate1 = tokens[next][1].rate;
michael@0 339
michael@0 340 if((abs(x)*dequant_ptr[rc]>abs(coeff_ptr[rc])) &&
michael@0 341 (abs(x)*dequant_ptr[rc]<abs(coeff_ptr[rc])+dequant_ptr[rc]))
michael@0 342 shortcut = 1;
michael@0 343 else
michael@0 344 shortcut = 0;
michael@0 345
michael@0 346 if(shortcut)
michael@0 347 {
michael@0 348 sz = -(x < 0);
michael@0 349 x -= 2*sz + 1;
michael@0 350 }
michael@0 351
michael@0 352 /* Consider both possible successor states. */
michael@0 353 if (!x)
michael@0 354 {
michael@0 355 /* If we reduced this coefficient to zero, check to see if
michael@0 356 * we need to move the EOB back here.
michael@0 357 */
michael@0 358 t0 = tokens[next][0].token == DCT_EOB_TOKEN ?
michael@0 359 DCT_EOB_TOKEN : ZERO_TOKEN;
michael@0 360 t1 = tokens[next][1].token == DCT_EOB_TOKEN ?
michael@0 361 DCT_EOB_TOKEN : ZERO_TOKEN;
michael@0 362 }
michael@0 363 else
michael@0 364 {
michael@0 365 t0=t1 = (vp8_dct_value_tokens_ptr + x)->Token;
michael@0 366 }
michael@0 367 if (next < 16)
michael@0 368 {
michael@0 369 band = vp8_coef_bands[i + 1];
michael@0 370 if(t0!=DCT_EOB_TOKEN)
michael@0 371 {
michael@0 372 pt = vp8_prev_token_class[t0];
michael@0 373 rate0 += mb->token_costs[type][band][pt][
michael@0 374 tokens[next][0].token];
michael@0 375 }
michael@0 376 if(t1!=DCT_EOB_TOKEN)
michael@0 377 {
michael@0 378 pt = vp8_prev_token_class[t1];
michael@0 379 rate1 += mb->token_costs[type][band][pt][
michael@0 380 tokens[next][1].token];
michael@0 381 }
michael@0 382 }
michael@0 383
michael@0 384 rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
michael@0 385 rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
michael@0 386 if (rd_cost0 == rd_cost1)
michael@0 387 {
michael@0 388 rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
michael@0 389 rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
michael@0 390 }
michael@0 391 /* And pick the best. */
michael@0 392 best = rd_cost1 < rd_cost0;
michael@0 393 base_bits = *(vp8_dct_value_cost_ptr + x);
michael@0 394
michael@0 395 if(shortcut)
michael@0 396 {
michael@0 397 dx -= (dequant_ptr[rc] + sz) ^ sz;
michael@0 398 d2 = dx*dx;
michael@0 399 }
michael@0 400 tokens[i][1].rate = base_bits + (best ? rate1 : rate0);
michael@0 401 tokens[i][1].error = d2 + (best ? error1 : error0);
michael@0 402 tokens[i][1].next = next;
michael@0 403 tokens[i][1].token =best?t1:t0;
michael@0 404 tokens[i][1].qc = x;
michael@0 405 best_mask[1] |= best << i;
michael@0 406 /* Finally, make this the new head of the trellis. */
michael@0 407 next = i;
michael@0 408 }
michael@0 409 /* There's no choice to make for a zero coefficient, so we don't
michael@0 410 * add a new trellis node, but we do need to update the costs.
michael@0 411 */
michael@0 412 else
michael@0 413 {
michael@0 414 band = vp8_coef_bands[i + 1];
michael@0 415 t0 = tokens[next][0].token;
michael@0 416 t1 = tokens[next][1].token;
michael@0 417 /* Update the cost of each path if we're past the EOB token. */
michael@0 418 if (t0 != DCT_EOB_TOKEN)
michael@0 419 {
michael@0 420 tokens[next][0].rate += mb->token_costs[type][band][0][t0];
michael@0 421 tokens[next][0].token = ZERO_TOKEN;
michael@0 422 }
michael@0 423 if (t1 != DCT_EOB_TOKEN)
michael@0 424 {
michael@0 425 tokens[next][1].rate += mb->token_costs[type][band][0][t1];
michael@0 426 tokens[next][1].token = ZERO_TOKEN;
michael@0 427 }
michael@0 428 /* Don't update next, because we didn't add a new node. */
michael@0 429 }
michael@0 430 }
michael@0 431
michael@0 432 /* Now pick the best path through the whole trellis. */
michael@0 433 band = vp8_coef_bands[i + 1];
michael@0 434 VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
michael@0 435 rate0 = tokens[next][0].rate;
michael@0 436 rate1 = tokens[next][1].rate;
michael@0 437 error0 = tokens[next][0].error;
michael@0 438 error1 = tokens[next][1].error;
michael@0 439 t0 = tokens[next][0].token;
michael@0 440 t1 = tokens[next][1].token;
michael@0 441 rate0 += mb->token_costs[type][band][pt][t0];
michael@0 442 rate1 += mb->token_costs[type][band][pt][t1];
michael@0 443 rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
michael@0 444 rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
michael@0 445 if (rd_cost0 == rd_cost1)
michael@0 446 {
michael@0 447 rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
michael@0 448 rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
michael@0 449 }
michael@0 450 best = rd_cost1 < rd_cost0;
michael@0 451 final_eob = i0 - 1;
michael@0 452 for (i = next; i < eob; i = next)
michael@0 453 {
michael@0 454 x = tokens[i][best].qc;
michael@0 455 if (x)
michael@0 456 final_eob = i;
michael@0 457 rc = vp8_default_zig_zag1d[i];
michael@0 458 qcoeff_ptr[rc] = x;
michael@0 459 dqcoeff_ptr[rc] = x * dequant_ptr[rc];
michael@0 460 next = tokens[i][best].next;
michael@0 461 best = (best_mask[best] >> i) & 1;
michael@0 462 }
michael@0 463 final_eob++;
michael@0 464
michael@0 465 *a = *l = (final_eob != !type);
michael@0 466 *d->eob = (char)final_eob;
michael@0 467 }
michael@0 468 static void check_reset_2nd_coeffs(MACROBLOCKD *x, int type,
michael@0 469 ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l)
michael@0 470 {
michael@0 471 int sum=0;
michael@0 472 int i;
michael@0 473 BLOCKD *bd = &x->block[24];
michael@0 474
michael@0 475 if(bd->dequant[0]>=35 && bd->dequant[1]>=35)
michael@0 476 return;
michael@0 477
michael@0 478 for(i=0;i<(*bd->eob);i++)
michael@0 479 {
michael@0 480 int coef = bd->dqcoeff[vp8_default_zig_zag1d[i]];
michael@0 481 sum+= (coef>=0)?coef:-coef;
michael@0 482 if(sum>=35)
michael@0 483 return;
michael@0 484 }
michael@0 485 /**************************************************************************
michael@0 486 our inverse hadamard transform effectively is weighted sum of all 16 inputs
michael@0 487 with weight either 1 or -1. It has a last stage scaling of (sum+3)>>3. And
michael@0 488 dc only idct is (dc+4)>>3. So if all the sums are between -35 and 29, the
michael@0 489 output after inverse wht and idct will be all zero. A sum of absolute value
michael@0 490 smaller than 35 guarantees all 16 different (+1/-1) weighted sums in wht
michael@0 491 fall between -35 and +35.
michael@0 492 **************************************************************************/
michael@0 493 if(sum < 35)
michael@0 494 {
michael@0 495 for(i=0;i<(*bd->eob);i++)
michael@0 496 {
michael@0 497 int rc = vp8_default_zig_zag1d[i];
michael@0 498 bd->qcoeff[rc]=0;
michael@0 499 bd->dqcoeff[rc]=0;
michael@0 500 }
michael@0 501 *bd->eob = 0;
michael@0 502 *a = *l = (*bd->eob != !type);
michael@0 503 }
michael@0 504 }
michael@0 505
michael@0 506 static void optimize_mb(MACROBLOCK *x)
michael@0 507 {
michael@0 508 int b;
michael@0 509 int type;
michael@0 510 int has_2nd_order;
michael@0 511
michael@0 512 ENTROPY_CONTEXT_PLANES t_above, t_left;
michael@0 513 ENTROPY_CONTEXT *ta;
michael@0 514 ENTROPY_CONTEXT *tl;
michael@0 515
michael@0 516 vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
michael@0 517 vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
michael@0 518
michael@0 519 ta = (ENTROPY_CONTEXT *)&t_above;
michael@0 520 tl = (ENTROPY_CONTEXT *)&t_left;
michael@0 521
michael@0 522 has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
michael@0 523 && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
michael@0 524 type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
michael@0 525
michael@0 526 for (b = 0; b < 16; b++)
michael@0 527 {
michael@0 528 optimize_b(x, b, type,
michael@0 529 ta + vp8_block2above[b], tl + vp8_block2left[b]);
michael@0 530 }
michael@0 531
michael@0 532 for (b = 16; b < 24; b++)
michael@0 533 {
michael@0 534 optimize_b(x, b, PLANE_TYPE_UV,
michael@0 535 ta + vp8_block2above[b], tl + vp8_block2left[b]);
michael@0 536 }
michael@0 537
michael@0 538 if (has_2nd_order)
michael@0 539 {
michael@0 540 b=24;
michael@0 541 optimize_b(x, b, PLANE_TYPE_Y2,
michael@0 542 ta + vp8_block2above[b], tl + vp8_block2left[b]);
michael@0 543 check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2,
michael@0 544 ta + vp8_block2above[b], tl + vp8_block2left[b]);
michael@0 545 }
michael@0 546 }
michael@0 547
michael@0 548
michael@0 549 void vp8_optimize_mby(MACROBLOCK *x)
michael@0 550 {
michael@0 551 int b;
michael@0 552 int type;
michael@0 553 int has_2nd_order;
michael@0 554
michael@0 555 ENTROPY_CONTEXT_PLANES t_above, t_left;
michael@0 556 ENTROPY_CONTEXT *ta;
michael@0 557 ENTROPY_CONTEXT *tl;
michael@0 558
michael@0 559 if (!x->e_mbd.above_context)
michael@0 560 return;
michael@0 561
michael@0 562 if (!x->e_mbd.left_context)
michael@0 563 return;
michael@0 564
michael@0 565 vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
michael@0 566 vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
michael@0 567
michael@0 568 ta = (ENTROPY_CONTEXT *)&t_above;
michael@0 569 tl = (ENTROPY_CONTEXT *)&t_left;
michael@0 570
michael@0 571 has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
michael@0 572 && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
michael@0 573 type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
michael@0 574
michael@0 575 for (b = 0; b < 16; b++)
michael@0 576 {
michael@0 577 optimize_b(x, b, type,
michael@0 578 ta + vp8_block2above[b], tl + vp8_block2left[b]);
michael@0 579 }
michael@0 580
michael@0 581
michael@0 582 if (has_2nd_order)
michael@0 583 {
michael@0 584 b=24;
michael@0 585 optimize_b(x, b, PLANE_TYPE_Y2,
michael@0 586 ta + vp8_block2above[b], tl + vp8_block2left[b]);
michael@0 587 check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2,
michael@0 588 ta + vp8_block2above[b], tl + vp8_block2left[b]);
michael@0 589 }
michael@0 590 }
michael@0 591
michael@0 592 void vp8_optimize_mbuv(MACROBLOCK *x)
michael@0 593 {
michael@0 594 int b;
michael@0 595 ENTROPY_CONTEXT_PLANES t_above, t_left;
michael@0 596 ENTROPY_CONTEXT *ta;
michael@0 597 ENTROPY_CONTEXT *tl;
michael@0 598
michael@0 599 if (!x->e_mbd.above_context)
michael@0 600 return;
michael@0 601
michael@0 602 if (!x->e_mbd.left_context)
michael@0 603 return;
michael@0 604
michael@0 605 vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
michael@0 606 vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
michael@0 607
michael@0 608 ta = (ENTROPY_CONTEXT *)&t_above;
michael@0 609 tl = (ENTROPY_CONTEXT *)&t_left;
michael@0 610
michael@0 611 for (b = 16; b < 24; b++)
michael@0 612 {
michael@0 613 optimize_b(x, b, PLANE_TYPE_UV,
michael@0 614 ta + vp8_block2above[b], tl + vp8_block2left[b]);
michael@0 615 }
michael@0 616 }
michael@0 617
michael@0 618 void vp8_encode_inter16x16(MACROBLOCK *x)
michael@0 619 {
michael@0 620 vp8_build_inter_predictors_mb(&x->e_mbd);
michael@0 621
michael@0 622 vp8_subtract_mb(x);
michael@0 623
michael@0 624 transform_mb(x);
michael@0 625
michael@0 626 vp8_quantize_mb(x);
michael@0 627
michael@0 628 if (x->optimize)
michael@0 629 optimize_mb(x);
michael@0 630 }
michael@0 631
michael@0 632 /* this funciton is used by first pass only */
michael@0 633 void vp8_encode_inter16x16y(MACROBLOCK *x)
michael@0 634 {
michael@0 635 BLOCK *b = &x->block[0];
michael@0 636
michael@0 637 vp8_build_inter16x16_predictors_mby(&x->e_mbd, x->e_mbd.dst.y_buffer,
michael@0 638 x->e_mbd.dst.y_stride);
michael@0 639
michael@0 640 vp8_subtract_mby(x->src_diff, *(b->base_src),
michael@0 641 b->src_stride, x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride);
michael@0 642
michael@0 643 transform_mby(x);
michael@0 644
michael@0 645 vp8_quantize_mby(x);
michael@0 646
michael@0 647 vp8_inverse_transform_mby(&x->e_mbd);
michael@0 648 }

mercurial