2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
12 #include "vpx_ports/config.h"
18 #include "entropymode.h"
19 #include "quant_common.h"
20 #include "segmentation.h"
21 #include "setupintrarecon.h"
22 #include "encodeintra.h"
23 #include "reconinter.h"
25 #include "pickinter.h"
26 #include "findnearmv.h"
27 #include "reconintra.h"
31 #include "vpx_ports/vpx_timer.h"
33 #if CONFIG_RUNTIME_CPU_DETECT
34 #define RTCD(x) &cpi->common.rtcd.x
35 #define IF_RTCD(x) (x)
38 #define IF_RTCD(x) NULL
40 extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
42 extern void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex);
43 extern void vp8_auto_select_speed(VP8_COMP *cpi);
44 extern void vp8cx_init_mbrthread_data(VP8_COMP *cpi,
49 void vp8_build_block_offsets(MACROBLOCK *x);
50 void vp8_setup_block_ptrs(MACROBLOCK *x);
51 int vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t, int recon_yoffset, int recon_uvoffset);
52 int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t);
55 unsigned int inter_y_modes[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
56 unsigned int inter_uv_modes[4] = {0, 0, 0, 0};
57 unsigned int inter_b_modes[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
58 unsigned int y_modes[5] = {0, 0, 0, 0, 0};
59 unsigned int uv_modes[4] = {0, 0, 0, 0};
60 unsigned int b_modes[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
63 static const int qrounding_factors[129] =
65 48, 48, 48, 48, 48, 48, 48, 48,
66 48, 48, 48, 48, 48, 48, 48, 48,
67 48, 48, 48, 48, 48, 48, 48, 48,
68 48, 48, 48, 48, 48, 48, 48, 48,
69 48, 48, 48, 48, 48, 48, 48, 48,
70 48, 48, 48, 48, 48, 48, 48, 48,
71 48, 48, 48, 48, 48, 48, 48, 48,
72 48, 48, 48, 48, 48, 48, 48, 48,
73 48, 48, 48, 48, 48, 48, 48, 48,
74 48, 48, 48, 48, 48, 48, 48, 48,
75 48, 48, 48, 48, 48, 48, 48, 48,
76 48, 48, 48, 48, 48, 48, 48, 48,
77 48, 48, 48, 48, 48, 48, 48, 48,
78 48, 48, 48, 48, 48, 48, 48, 48,
79 48, 48, 48, 48, 48, 48, 48, 48,
80 48, 48, 48, 48, 48, 48, 48, 48,
84 static const int qzbin_factors[129] =
86 84, 84, 84, 84, 84, 84, 84, 84,
87 84, 84, 84, 84, 84, 84, 84, 84,
88 84, 84, 84, 84, 84, 84, 84, 84,
89 84, 84, 84, 84, 84, 84, 84, 84,
90 84, 84, 84, 84, 84, 84, 84, 84,
91 84, 84, 84, 84, 84, 84, 84, 84,
92 80, 80, 80, 80, 80, 80, 80, 80,
93 80, 80, 80, 80, 80, 80, 80, 80,
94 80, 80, 80, 80, 80, 80, 80, 80,
95 80, 80, 80, 80, 80, 80, 80, 80,
96 80, 80, 80, 80, 80, 80, 80, 80,
97 80, 80, 80, 80, 80, 80, 80, 80,
98 80, 80, 80, 80, 80, 80, 80, 80,
99 80, 80, 80, 80, 80, 80, 80, 80,
100 80, 80, 80, 80, 80, 80, 80, 80,
101 80, 80, 80, 80, 80, 80, 80, 80,
105 static const int qrounding_factors_y2[129] =
107 48, 48, 48, 48, 48, 48, 48, 48,
108 48, 48, 48, 48, 48, 48, 48, 48,
109 48, 48, 48, 48, 48, 48, 48, 48,
110 48, 48, 48, 48, 48, 48, 48, 48,
111 48, 48, 48, 48, 48, 48, 48, 48,
112 48, 48, 48, 48, 48, 48, 48, 48,
113 48, 48, 48, 48, 48, 48, 48, 48,
114 48, 48, 48, 48, 48, 48, 48, 48,
115 48, 48, 48, 48, 48, 48, 48, 48,
116 48, 48, 48, 48, 48, 48, 48, 48,
117 48, 48, 48, 48, 48, 48, 48, 48,
118 48, 48, 48, 48, 48, 48, 48, 48,
119 48, 48, 48, 48, 48, 48, 48, 48,
120 48, 48, 48, 48, 48, 48, 48, 48,
121 48, 48, 48, 48, 48, 48, 48, 48,
122 48, 48, 48, 48, 48, 48, 48, 48,
126 static const int qzbin_factors_y2[129] =
128 84, 84, 84, 84, 84, 84, 84, 84,
129 84, 84, 84, 84, 84, 84, 84, 84,
130 84, 84, 84, 84, 84, 84, 84, 84,
131 84, 84, 84, 84, 84, 84, 84, 84,
132 84, 84, 84, 84, 84, 84, 84, 84,
133 84, 84, 84, 84, 84, 84, 84, 84,
134 80, 80, 80, 80, 80, 80, 80, 80,
135 80, 80, 80, 80, 80, 80, 80, 80,
136 80, 80, 80, 80, 80, 80, 80, 80,
137 80, 80, 80, 80, 80, 80, 80, 80,
138 80, 80, 80, 80, 80, 80, 80, 80,
139 80, 80, 80, 80, 80, 80, 80, 80,
140 80, 80, 80, 80, 80, 80, 80, 80,
141 80, 80, 80, 80, 80, 80, 80, 80,
142 80, 80, 80, 80, 80, 80, 80, 80,
143 80, 80, 80, 80, 80, 80, 80, 80,
149 static void vp8cx_invert_quant(int improved_quant, short *quant,
150 short *shift, short d)
157 for(l = 0; t > 1; l++)
159 t = 1 + (1<<(16+l))/d;
160 *quant = (short)(t - (1<<16));
165 *quant = (1 << 16) / d;
170 void vp8cx_init_quantizer(VP8_COMP *cpi)
176 int zbin_boost[16] = {0, 0, 8, 10, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 44, 44};
178 for (Q = 0; Q < QINDEX_RANGE; Q++)
181 quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q);
182 cpi->Y1quant_fast[Q][0] = (1 << 16) / quant_val;
183 vp8cx_invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 0,
184 cpi->Y1quant_shift[Q] + 0, quant_val);
185 cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
186 cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
187 cpi->common.Y1dequant[Q][0] = quant_val;
188 cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7;
190 quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q);
191 cpi->Y2quant_fast[Q][0] = (1 << 16) / quant_val;
192 vp8cx_invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 0,
193 cpi->Y2quant_shift[Q] + 0, quant_val);
194 cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
195 cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7;
196 cpi->common.Y2dequant[Q][0] = quant_val;
197 cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7;
199 quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q);
200 cpi->UVquant_fast[Q][0] = (1 << 16) / quant_val;
201 vp8cx_invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 0,
202 cpi->UVquant_shift[Q] + 0, quant_val);
203 cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;;
204 cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
205 cpi->common.UVdequant[Q][0] = quant_val;
206 cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7;
208 // all the ac values = ;
209 for (i = 1; i < 16; i++)
211 int rc = vp8_default_zig_zag1d[i];
213 quant_val = vp8_ac_yquant(Q);
214 cpi->Y1quant_fast[Q][rc] = (1 << 16) / quant_val;
215 vp8cx_invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + rc,
216 cpi->Y1quant_shift[Q] + rc, quant_val);
217 cpi->Y1zbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
218 cpi->Y1round[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7;
219 cpi->common.Y1dequant[Q][rc] = quant_val;
220 cpi->zrun_zbin_boost_y1[Q][i] = (quant_val * zbin_boost[i]) >> 7;
222 quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q);
223 cpi->Y2quant_fast[Q][rc] = (1 << 16) / quant_val;
224 vp8cx_invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + rc,
225 cpi->Y2quant_shift[Q] + rc, quant_val);
226 cpi->Y2zbin[Q][rc] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
227 cpi->Y2round[Q][rc] = (qrounding_factors_y2[Q] * quant_val) >> 7;
228 cpi->common.Y2dequant[Q][rc] = quant_val;
229 cpi->zrun_zbin_boost_y2[Q][i] = (quant_val * zbin_boost[i]) >> 7;
231 quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q);
232 cpi->UVquant_fast[Q][rc] = (1 << 16) / quant_val;
233 vp8cx_invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + rc,
234 cpi->UVquant_shift[Q] + rc, quant_val);
235 cpi->UVzbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
236 cpi->UVround[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7;
237 cpi->common.UVdequant[Q][rc] = quant_val;
238 cpi->zrun_zbin_boost_uv[Q][i] = (quant_val * zbin_boost[i]) >> 7;
243 void vp8cx_init_quantizer(VP8_COMP *cpi)
249 int zbin_boost[16] = {0, 0, 8, 10, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 44, 44};
251 for (Q = 0; Q < QINDEX_RANGE; Q++)
254 quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q);
255 cpi->Y1quant[Q][0] = (1 << 16) / quant_val;
256 cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
257 cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
258 cpi->common.Y1dequant[Q][0] = quant_val;
259 cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7;
261 quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q);
262 cpi->Y2quant[Q][0] = (1 << 16) / quant_val;
263 cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
264 cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7;
265 cpi->common.Y2dequant[Q][0] = quant_val;
266 cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7;
268 quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q);
269 cpi->UVquant[Q][0] = (1 << 16) / quant_val;
270 cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;;
271 cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
272 cpi->common.UVdequant[Q][0] = quant_val;
273 cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7;
275 // all the ac values = ;
276 for (i = 1; i < 16; i++)
278 int rc = vp8_default_zig_zag1d[i];
280 quant_val = vp8_ac_yquant(Q);
281 cpi->Y1quant[Q][rc] = (1 << 16) / quant_val;
282 cpi->Y1zbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
283 cpi->Y1round[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7;
284 cpi->common.Y1dequant[Q][rc] = quant_val;
285 cpi->zrun_zbin_boost_y1[Q][i] = (quant_val * zbin_boost[i]) >> 7;
287 quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q);
288 cpi->Y2quant[Q][rc] = (1 << 16) / quant_val;
289 cpi->Y2zbin[Q][rc] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
290 cpi->Y2round[Q][rc] = (qrounding_factors_y2[Q] * quant_val) >> 7;
291 cpi->common.Y2dequant[Q][rc] = quant_val;
292 cpi->zrun_zbin_boost_y2[Q][i] = (quant_val * zbin_boost[i]) >> 7;
294 quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q);
295 cpi->UVquant[Q][rc] = (1 << 16) / quant_val;
296 cpi->UVzbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
297 cpi->UVround[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7;
298 cpi->common.UVdequant[Q][rc] = quant_val;
299 cpi->zrun_zbin_boost_uv[Q][i] = (quant_val * zbin_boost[i]) >> 7;
304 void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x)
308 MACROBLOCKD *xd = &x->e_mbd;
311 // Select the baseline MB Q index.
312 if (xd->segmentation_enabled)
315 if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA)
317 QIndex = xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id];
321 QIndex = cpi->common.base_qindex + xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id];
322 QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0; // Clamp to valid range
326 QIndex = cpi->common.base_qindex;
329 zbin_extra = (cpi->common.Y1dequant[QIndex][1] * (cpi->zbin_over_quant + cpi->zbin_mode_boost)) >> 7;
331 for (i = 0; i < 16; i++)
333 x->block[i].quant = cpi->Y1quant[QIndex];
334 x->block[i].quant_fast = cpi->Y1quant_fast[QIndex];
335 x->block[i].quant_shift = cpi->Y1quant_shift[QIndex];
336 x->block[i].zbin = cpi->Y1zbin[QIndex];
337 x->block[i].round = cpi->Y1round[QIndex];
338 x->e_mbd.block[i].dequant = cpi->common.Y1dequant[QIndex];
339 x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex];
340 x->block[i].zbin_extra = (short)zbin_extra;
344 zbin_extra = (cpi->common.UVdequant[QIndex][1] * (cpi->zbin_over_quant + cpi->zbin_mode_boost)) >> 7;
346 for (i = 16; i < 24; i++)
348 x->block[i].quant = cpi->UVquant[QIndex];
349 x->block[i].quant_fast = cpi->UVquant_fast[QIndex];
350 x->block[i].quant_shift = cpi->UVquant_shift[QIndex];
351 x->block[i].zbin = cpi->UVzbin[QIndex];
352 x->block[i].round = cpi->UVround[QIndex];
353 x->e_mbd.block[i].dequant = cpi->common.UVdequant[QIndex];
354 x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex];
355 x->block[i].zbin_extra = (short)zbin_extra;
359 zbin_extra = (cpi->common.Y2dequant[QIndex][1] * ((cpi->zbin_over_quant / 2) + cpi->zbin_mode_boost)) >> 7;
360 x->block[24].quant_fast = cpi->Y2quant_fast[QIndex];
361 x->block[24].quant = cpi->Y2quant[QIndex];
362 x->block[24].quant_shift = cpi->Y2quant_shift[QIndex];
363 x->block[24].zbin = cpi->Y2zbin[QIndex];
364 x->block[24].round = cpi->Y2round[QIndex];
365 x->e_mbd.block[24].dequant = cpi->common.Y2dequant[QIndex];
366 x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex];
367 x->block[24].zbin_extra = (short)zbin_extra;
369 /* save this macroblock QIndex for vp8_update_zbin_extra() */
372 void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x)
375 int QIndex = x->q_index;
379 zbin_extra = (cpi->common.Y1dequant[QIndex][1] * (cpi->zbin_over_quant + cpi->zbin_mode_boost)) >> 7;
380 for (i = 0; i < 16; i++)
382 x->block[i].zbin_extra = (short)zbin_extra;
386 zbin_extra = (cpi->common.UVdequant[QIndex][1] * (cpi->zbin_over_quant + cpi->zbin_mode_boost)) >> 7;
387 for (i = 16; i < 24; i++)
389 x->block[i].zbin_extra = (short)zbin_extra;
393 zbin_extra = (cpi->common.Y2dequant[QIndex][1] * ((cpi->zbin_over_quant / 2) + cpi->zbin_mode_boost)) >> 7;
394 x->block[24].zbin_extra = (short)zbin_extra;
397 void vp8cx_frame_init_quantizer(VP8_COMP *cpi)
399 // Clear Zbin mode boost for default case
400 cpi->zbin_mode_boost = 0;
402 // MB level quantizer setup
403 vp8cx_mb_init_quantizer(cpi, &cpi->mb);
407 /* activity_avg must be positive, or flat regions could get a zero weight
408 * (infinite lambda), which confounds analysis.
409 * This also avoids the need for divide by zero checks in
410 * vp8_activity_masking().
412 #define VP8_ACTIVITY_AVG_MIN (64)
414 /* This is used as a reference when computing the source variance for the
415 * purposes of activity masking.
416 * Eventually this should be replaced by custom no-reference routines,
417 * which will be faster.
419 static const unsigned char VP8_VAR_OFFS[16]=
421 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
424 unsigned int vp8_activity_masking(VP8_COMP *cpi, MACROBLOCK *x)
431 /* TODO: This could also be done over smaller areas (8x8), but that would
432 * require extensive changes elsewhere, as lambda is assumed to be fixed
433 * over an entire MB in most of the code.
434 * Another option is to compute four 8x8 variances, and pick a single
435 * lambda using a non-linear combination (e.g., the smallest, or second
438 VARIANCE_INVOKE(&cpi->rtcd.variance, get16x16var)(x->src.y_buffer,
439 x->src.y_stride, VP8_VAR_OFFS, 0, &sse, &sum);
440 /* This requires a full 32 bits of precision. */
441 act = (sse<<8) - sum*sum;
442 /* Drop 4 to give us some headroom to work with. */
443 act = (act + 8) >> 4;
444 /* If the region is flat, lower the activity some more. */
446 act = act < 5<<12 ? act : 5<<12;
447 /* TODO: For non-flat regions, edge regions should receive less masking
448 * than textured regions, but identifying edge regions quickly and
449 * reliably enough is still a subject of experimentation.
450 * This will be most noticable near edges with a complex shape (e.g.,
451 * text), but the 4x4 transform size should make this less of a problem
452 * than it would be for an 8x8 transform.
454 /* Apply the masking to the RD multiplier. */
455 a = act + 4*cpi->activity_avg;
456 b = 4*act + cpi->activity_avg;
457 x->rdmult = (unsigned int)(((INT64)x->rdmult*b + (a>>1))/a);
464 void encode_mb_row(VP8_COMP *cpi,
473 INT64 activity_sum = 0;
475 int recon_yoffset, recon_uvoffset;
477 int ref_fb_idx = cm->lst_fb_idx;
478 int dst_fb_idx = cm->new_fb_idx;
479 int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
480 int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
481 int seg_map_index = (mb_row * cpi->common.mb_cols);
483 #if CONFIG_MULTITHREAD
484 const int nsync = cpi->mt_sync_range;
485 const int rightmost_col = cm->mb_cols - 1;
486 volatile const int *last_row_current_mb_col;
488 if ((cpi->b_multi_threaded != 0) && (mb_row != 0))
489 last_row_current_mb_col = &cpi->mt_current_mb_col[mb_row - 1];
491 last_row_current_mb_col = &rightmost_col;
494 // reset above block coeffs
495 xd->above_context = cm->above_context;
497 xd->up_available = (mb_row != 0);
498 recon_yoffset = (mb_row * recon_y_stride * 16);
499 recon_uvoffset = (mb_row * recon_uv_stride * 8);
501 cpi->tplist[mb_row].start = *tp;
502 //printf("Main mb_row = %d\n", mb_row);
504 // Distance of Mb to the top & bottom edges, specified in 1/8th pel
505 // units as they are always compared to values that are in 1/8th pel units
506 xd->mb_to_top_edge = -((mb_row * 16) << 3);
507 xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
509 // Set up limit values for vertical motion vector components
510 // to prevent them extending beyond the UMV borders
511 x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
512 x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16)
513 + (VP8BORDERINPIXELS - 16);
515 // for each macroblock col in image
516 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
518 // Distance of Mb to the left & right edges, specified in
519 // 1/8th pel units as they are always compared to values
520 // that are in 1/8th pel units
521 xd->mb_to_left_edge = -((mb_col * 16) << 3);
522 xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
524 // Set up limit values for horizontal motion vector components
525 // to prevent them extending beyond the UMV borders
526 x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
527 x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16)
528 + (VP8BORDERINPIXELS - 16);
530 xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
531 xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
532 xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
533 xd->left_available = (mb_col != 0);
535 x->rddiv = cpi->RDDIV;
536 x->rdmult = cpi->RDMULT;
538 #if CONFIG_MULTITHREAD
539 if ((cpi->b_multi_threaded != 0) && (mb_row != 0))
541 if ((mb_col & (nsync - 1)) == 0)
543 while (mb_col > (*last_row_current_mb_col - nsync)
544 && (*last_row_current_mb_col) != (cm->mb_cols - 1))
553 if(cpi->oxcf.tuning == VP8_TUNE_SSIM)
554 activity_sum += vp8_activity_masking(cpi, x);
556 // Is segmentation enabled
557 // MB level adjutment to quantizer
558 if (xd->segmentation_enabled)
560 // Code to set segment id in xd->mbmi.segment_id for current MB (with range checking)
561 if (cpi->segmentation_map[seg_map_index+mb_col] <= 3)
562 xd->mode_info_context->mbmi.segment_id = cpi->segmentation_map[seg_map_index+mb_col];
564 xd->mode_info_context->mbmi.segment_id = 0;
566 vp8cx_mb_init_quantizer(cpi, x);
569 xd->mode_info_context->mbmi.segment_id = 0; // Set to Segment 0 by default
571 x->active_ptr = cpi->active_map + seg_map_index + mb_col;
573 if (cm->frame_type == KEY_FRAME)
575 *totalrate += vp8cx_encode_intra_macro_block(cpi, x, tp);
577 y_modes[xd->mbmi.mode] ++;
582 *totalrate += vp8cx_encode_inter_macroblock(cpi, x, tp, recon_yoffset, recon_uvoffset);
585 inter_y_modes[xd->mbmi.mode] ++;
587 if (xd->mbmi.mode == SPLITMV)
591 for (b = 0; b < xd->mbmi.partition_count; b++)
593 inter_b_modes[x->partition->bmi[b].mode] ++;
599 // Count of last ref frame 0,0 useage
600 if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME))
601 cpi->inter_zz_count ++;
603 // Special case code for cyclic refresh
604 // If cyclic update enabled then copy xd->mbmi.segment_id; (which may have been updated based on mode
605 // during vp8cx_encode_inter_macroblock()) back into the global sgmentation map
606 if (cpi->cyclic_refresh_mode_enabled && xd->segmentation_enabled)
608 cpi->segmentation_map[seg_map_index+mb_col] = xd->mode_info_context->mbmi.segment_id;
610 // If the block has been refreshed mark it as clean (the magnitude of the -ve influences how long it will be before we consider another refresh):
611 // Else if it was coded (last frame 0,0) and has not already been refreshed then mark it as a candidate for cleanup next time (marked 0)
612 // else mark it as dirty (1).
613 if (xd->mode_info_context->mbmi.segment_id)
614 cpi->cyclic_refresh_map[seg_map_index+mb_col] = -1;
615 else if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME))
617 if (cpi->cyclic_refresh_map[seg_map_index+mb_col] == 1)
618 cpi->cyclic_refresh_map[seg_map_index+mb_col] = 0;
621 cpi->cyclic_refresh_map[seg_map_index+mb_col] = 1;
626 cpi->tplist[mb_row].stop = *tp;
628 x->gf_active_ptr++; // Increment pointer into gf useage flags structure for next mb
630 for (i = 0; i < 16; i++)
631 vpx_memcpy(&xd->mode_info_context->bmi[i], &xd->block[i].bmi, sizeof(xd->block[i].bmi));
633 // adjust to the next column of macroblocks
634 x->src.y_buffer += 16;
635 x->src.u_buffer += 8;
636 x->src.v_buffer += 8;
641 // Keep track of segment useage
642 segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
645 xd->mode_info_context++;
649 #if CONFIG_MULTITHREAD
650 if (cpi->b_multi_threaded != 0)
652 cpi->mt_current_mb_col[mb_row] = mb_col;
657 //extend the recon for intra prediction
659 &cm->yv12_fb[dst_fb_idx],
660 xd->dst.y_buffer + 16,
661 xd->dst.u_buffer + 8,
662 xd->dst.v_buffer + 8);
664 // this is to account for the border
665 xd->mode_info_context++;
667 x->activity_sum += activity_sum;
669 #if CONFIG_MULTITHREAD
670 if ((cpi->b_multi_threaded != 0) && (mb_row == cm->mb_rows - 1))
672 sem_post(&cpi->h_event_end_encoding); /* signal frame encoding end */
677 void vp8_encode_frame(VP8_COMP *cpi)
680 MACROBLOCK *const x = & cpi->mb;
681 VP8_COMMON *const cm = & cpi->common;
682 MACROBLOCKD *const xd = & x->e_mbd;
684 TOKENEXTRA *tp = cpi->tok;
685 int segment_counts[MAX_MB_SEGMENTS];
688 // Functions setup for all frame types so we can use MC in AltRef
689 if (cm->mcomp_filter_type == SIXTAP)
691 xd->subpixel_predict = SUBPIX_INVOKE(
692 &cpi->common.rtcd.subpix, sixtap4x4);
693 xd->subpixel_predict8x4 = SUBPIX_INVOKE(
694 &cpi->common.rtcd.subpix, sixtap8x4);
695 xd->subpixel_predict8x8 = SUBPIX_INVOKE(
696 &cpi->common.rtcd.subpix, sixtap8x8);
697 xd->subpixel_predict16x16 = SUBPIX_INVOKE(
698 &cpi->common.rtcd.subpix, sixtap16x16);
702 xd->subpixel_predict = SUBPIX_INVOKE(
703 &cpi->common.rtcd.subpix, bilinear4x4);
704 xd->subpixel_predict8x4 = SUBPIX_INVOKE(
705 &cpi->common.rtcd.subpix, bilinear8x4);
706 xd->subpixel_predict8x8 = SUBPIX_INVOKE(
707 &cpi->common.rtcd.subpix, bilinear8x8);
708 xd->subpixel_predict16x16 = SUBPIX_INVOKE(
709 &cpi->common.rtcd.subpix, bilinear16x16);
712 x->gf_active_ptr = (signed char *)cpi->gf_active_flags; // Point to base of GF active flags data structure
714 x->vector_range = 32;
716 // Count of MBs using the alternate Q if any
719 // Reset frame count of inter 0,0 motion vector useage.
720 cpi->inter_zz_count = 0;
722 vpx_memset(segment_counts, 0, sizeof(segment_counts));
724 cpi->prediction_error = 0;
725 cpi->intra_error = 0;
726 cpi->skip_true_count = 0;
727 cpi->skip_false_count = 0;
731 cpi->frame_distortion = 0;
732 cpi->last_mb_distortion = 0;
737 x->partition_info = x->pi;
739 xd->mode_info_context = cm->mi;
740 xd->mode_info_stride = cm->mode_info_stride;
742 xd->frame_type = cm->frame_type;
744 xd->frames_since_golden = cm->frames_since_golden;
745 xd->frames_till_alt_ref_frame = cm->frames_till_alt_ref_frame;
746 vp8_zero(cpi->MVcount);
747 // vp8_zero( Contexts)
748 vp8_zero(cpi->coef_counts);
750 // reset intra mode contexts
751 if (cm->frame_type == KEY_FRAME)
752 vp8_init_mbmode_probs(cm);
755 vp8cx_frame_init_quantizer(cpi);
757 if (cpi->compressor_speed == 2)
759 if (cpi->oxcf.cpu_used < 0)
760 cpi->Speed = -(cpi->oxcf.cpu_used);
762 vp8_auto_select_speed(cpi);
765 vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
766 vp8cx_initialize_me_consts(cpi, cm->base_qindex);
768 // Copy data over into macro block data sturctures.
770 x->src = * cpi->Source;
771 xd->pre = cm->yv12_fb[cm->lst_fb_idx];
772 xd->dst = cm->yv12_fb[cm->new_fb_idx];
774 // set up frame new frame for intra coded blocks
776 vp8_setup_intra_recon(&cm->yv12_fb[cm->new_fb_idx]);
778 vp8_build_block_offsets(x);
780 vp8_setup_block_dptrs(&x->e_mbd);
782 vp8_setup_block_ptrs(x);
786 xd->mode_info_context->mbmi.mode = DC_PRED;
787 xd->mode_info_context->mbmi.uv_mode = DC_PRED;
789 xd->left_context = &cm->left_context;
791 vp8_zero(cpi->count_mb_ref_frame_usage)
792 vp8_zero(cpi->ymode_count)
793 vp8_zero(cpi->uv_mode_count)
797 vpx_memset(cm->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * cm->mb_cols);
800 struct vpx_usec_timer emr_timer;
801 vpx_usec_timer_start(&emr_timer);
803 if (!cpi->b_multi_threaded)
805 // for each macroblock row in image
806 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
809 vp8_zero(cm->left_context)
811 encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate);
813 // adjust to the next row of mbs
814 x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
815 x->src.u_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
816 x->src.v_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
819 cpi->tok_count = tp - cpi->tok;
824 #if CONFIG_MULTITHREAD
827 vp8cx_init_mbrthread_data(cpi, x, cpi->mb_row_ei, 1, cpi->encoding_thread_count);
829 for (i = 0; i < cm->mb_rows; i++)
830 cpi->mt_current_mb_col[i] = 0;
832 for (i = 0; i < cpi->encoding_thread_count; i++)
834 sem_post(&cpi->h_event_start_encoding[i]);
837 for (mb_row = 0; mb_row < cm->mb_rows; mb_row += (cpi->encoding_thread_count + 1))
839 vp8_zero(cm->left_context)
841 tp = cpi->tok + mb_row * (cm->mb_cols * 16 * 24);
843 encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate);
845 // adjust to the next row of mbs
846 x->src.y_buffer += 16 * x->src.y_stride * (cpi->encoding_thread_count + 1) - 16 * cm->mb_cols;
847 x->src.u_buffer += 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
848 x->src.v_buffer += 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
850 xd->mode_info_context += xd->mode_info_stride * cpi->encoding_thread_count;
851 x->partition_info += xd->mode_info_stride * cpi->encoding_thread_count;
855 sem_wait(&cpi->h_event_end_encoding); /* wait for other threads to finish */
859 for (mb_row = 0; mb_row < cm->mb_rows; mb_row ++)
861 cpi->tok_count += cpi->tplist[mb_row].stop - cpi->tplist[mb_row].start;
864 if (xd->segmentation_enabled)
868 if (xd->segmentation_enabled)
871 for (i = 0; i < cpi->encoding_thread_count; i++)
873 for (j = 0; j < 4; j++)
874 segment_counts[j] += cpi->mb_row_ei[i].segment_counts[j];
879 for (i = 0; i < cpi->encoding_thread_count; i++)
881 totalrate += cpi->mb_row_ei[i].totalrate;
884 for (i = 0; i < cpi->encoding_thread_count; i++)
886 x->activity_sum += cpi->mb_row_ei[i].mb.activity_sum;
893 vpx_usec_timer_mark(&emr_timer);
894 cpi->time_encode_mb_row += vpx_usec_timer_elapsed(&emr_timer);
899 // Work out the segment probabilites if segmentation is enabled
900 if (xd->segmentation_enabled)
906 vpx_memset(xd->mb_segment_tree_probs, 255 , sizeof(xd->mb_segment_tree_probs));
908 tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3];
912 xd->mb_segment_tree_probs[0] = ((segment_counts[0] + segment_counts[1]) * 255) / tot_count;
914 tot_count = segment_counts[0] + segment_counts[1];
918 xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) / tot_count;
921 tot_count = segment_counts[2] + segment_counts[3];
924 xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) / tot_count;
926 // Zero probabilities not allowed
927 for (i = 0; i < MB_FEATURE_TREE_PROBS; i ++)
929 if (xd->mb_segment_tree_probs[i] == 0)
930 xd->mb_segment_tree_probs[i] = 1;
935 // 256 rate units to the bit
936 cpi->projected_frame_size = totalrate >> 8; // projected_frame_size in units of BYTES
938 // Make a note of the percentage MBs coded Intra.
939 if (cm->frame_type == KEY_FRAME)
941 cpi->this_frame_percent_intra = 100;
947 tot_modes = cpi->count_mb_ref_frame_usage[INTRA_FRAME]
948 + cpi->count_mb_ref_frame_usage[LAST_FRAME]
949 + cpi->count_mb_ref_frame_usage[GOLDEN_FRAME]
950 + cpi->count_mb_ref_frame_usage[ALTREF_FRAME];
953 cpi->this_frame_percent_intra = cpi->count_mb_ref_frame_usage[INTRA_FRAME] * 100 / tot_modes;
960 int flag[2] = {0, 0};
962 for (cnt = 0; cnt < MVPcount; cnt++)
964 if (cm->fc.pre_mvc[0][cnt] != cm->fc.mvc[0][cnt])
967 vpx_memcpy(cm->fc.pre_mvc[0], cm->fc.mvc[0], MVPcount);
972 for (cnt = 0; cnt < MVPcount; cnt++)
974 if (cm->fc.pre_mvc[1][cnt] != cm->fc.mvc[1][cnt])
977 vpx_memcpy(cm->fc.pre_mvc[1], cm->fc.mvc[1], MVPcount);
982 if (flag[0] || flag[1])
983 vp8_build_component_cost_table(cpi->mb.mvcost, cpi->mb.mvsadcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
987 // Adjust the projected reference frame useage probability numbers to reflect
988 // what we have just seen. This may be usefull when we make multiple itterations
989 // of the recode loop rather than continuing to use values from the previous frame.
990 if ((cm->frame_type != KEY_FRAME) && !cm->refresh_alt_ref_frame && !cm->refresh_golden_frame)
992 const int *const rfct = cpi->count_mb_ref_frame_usage;
993 const int rf_intra = rfct[INTRA_FRAME];
994 const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
996 if ((rf_intra + rf_inter) > 0)
998 cpi->prob_intra_coded = (rf_intra * 255) / (rf_intra + rf_inter);
1000 if (cpi->prob_intra_coded < 1)
1001 cpi->prob_intra_coded = 1;
1003 if ((cm->frames_since_golden > 0) || cpi->source_alt_ref_active)
1005 cpi->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
1007 if (cpi->prob_last_coded < 1)
1008 cpi->prob_last_coded = 1;
1010 cpi->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
1011 ? (rfct[GOLDEN_FRAME] * 255) / (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
1013 if (cpi->prob_gf_coded < 1)
1014 cpi->prob_gf_coded = 1;
1020 // Keep record of the total distortion this time around for future use
1021 cpi->last_frame_distortion = cpi->frame_distortion;
1024 /* Update the average activity for the next frame.
1025 * This is feed-forward for now; it could also be saved in two-pass, or
1026 * done during lookahead when that is eventually added.
1028 cpi->activity_avg = (unsigned int )(x->activity_sum/cpi->common.MBs);
1029 if (cpi->activity_avg < VP8_ACTIVITY_AVG_MIN)
1030 cpi->activity_avg = VP8_ACTIVITY_AVG_MIN;
1033 void vp8_setup_block_ptrs(MACROBLOCK *x)
1038 for (r = 0; r < 4; r++)
1040 for (c = 0; c < 4; c++)
1042 x->block[r*4+c].src_diff = x->src_diff + r * 4 * 16 + c * 4;
1046 for (r = 0; r < 2; r++)
1048 for (c = 0; c < 2; c++)
1050 x->block[16 + r*2+c].src_diff = x->src_diff + 256 + r * 4 * 8 + c * 4;
1055 for (r = 0; r < 2; r++)
1057 for (c = 0; c < 2; c++)
1059 x->block[20 + r*2+c].src_diff = x->src_diff + 320 + r * 4 * 8 + c * 4;
1063 x->block[24].src_diff = x->src_diff + 384;
1066 for (i = 0; i < 25; i++)
1068 x->block[i].coeff = x->coeff + i * 16;
1072 void vp8_build_block_offsets(MACROBLOCK *x)
1077 vp8_build_block_doffsets(&x->e_mbd);
1080 for (br = 0; br < 4; br++)
1082 for (bc = 0; bc < 4; bc++)
1084 BLOCK *this_block = &x->block[block];
1085 this_block->base_src = &x->src.y_buffer;
1086 this_block->src_stride = x->src.y_stride;
1087 this_block->src = 4 * br * this_block->src_stride + 4 * bc;
1093 for (br = 0; br < 2; br++)
1095 for (bc = 0; bc < 2; bc++)
1097 BLOCK *this_block = &x->block[block];
1098 this_block->base_src = &x->src.u_buffer;
1099 this_block->src_stride = x->src.uv_stride;
1100 this_block->src = 4 * br * this_block->src_stride + 4 * bc;
1106 for (br = 0; br < 2; br++)
1108 for (bc = 0; bc < 2; bc++)
1110 BLOCK *this_block = &x->block[block];
1111 this_block->base_src = &x->src.v_buffer;
1112 this_block->src_stride = x->src.uv_stride;
1113 this_block->src = 4 * br * this_block->src_stride + 4 * bc;
1119 static void sum_intra_stats(VP8_COMP *cpi, MACROBLOCK *x)
1121 const MACROBLOCKD *xd = & x->e_mbd;
1122 const MB_PREDICTION_MODE m = xd->mode_info_context->mbmi.mode;
1123 const MB_PREDICTION_MODE uvm = xd->mode_info_context->mbmi.uv_mode;
1126 const int is_key = cpi->common.frame_type == KEY_FRAME;
1128 ++ (is_key ? uv_modes : inter_uv_modes)[uvm];
1132 unsigned int *const bct = is_key ? b_modes : inter_b_modes;
1138 ++ bct[xd->block[b].bmi.mode];
1145 ++cpi->ymode_count[m];
1146 ++cpi->uv_mode_count[uvm];
1149 int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t)
1151 int Error4x4, Error16x16, error_uv;
1152 int rate4x4, rate16x16, rateuv;
1153 int dist4x4, dist16x16, distuv;
1155 int rate4x4_tokenonly = 0;
1156 int rate16x16_tokenonly = 0;
1157 int rateuv_tokenonly = 0;
1159 x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
1161 #if !(CONFIG_REALTIME_ONLY)
1162 if (cpi->sf.RD && cpi->compressor_speed != 2)
1164 error_uv = vp8_rd_pick_intra_mbuv_mode(cpi, x, &rateuv, &rateuv_tokenonly, &distuv);
1167 Error16x16 = vp8_rd_pick_intra16x16mby_mode(cpi, x, &rate16x16, &rate16x16_tokenonly, &dist16x16);
1169 Error4x4 = vp8_rd_pick_intra4x4mby_modes(cpi, x, &rate4x4, &rate4x4_tokenonly, &dist4x4);
1171 rate += (Error4x4 < Error16x16) ? rate4x4 : rate16x16;
1176 int rate2, best_distortion;
1177 MB_PREDICTION_MODE mode, best_mode = DC_PRED;
1179 Error16x16 = INT_MAX;
1181 vp8_pick_intra_mbuv_mode(x);
1183 for (mode = DC_PRED; mode <= TM_PRED; mode ++)
1187 x->e_mbd.mode_info_context->mbmi.mode = mode;
1188 vp8_build_intra_predictors_mby_ptr(&x->e_mbd);
1189 distortion2 = VARIANCE_INVOKE(&cpi->rtcd.variance, get16x16prederror)(x->src.y_buffer, x->src.y_stride, x->e_mbd.predictor, 16, 0x7fffffff);
1190 rate2 = x->mbmode_cost[x->e_mbd.frame_type][mode];
1191 this_rd = RD_ESTIMATE(x->rdmult, x->rddiv, rate2, distortion2);
1193 if (Error16x16 > this_rd)
1195 Error16x16 = this_rd;
1197 best_distortion = distortion2;
1200 x->e_mbd.mode_info_context->mbmi.mode = best_mode;
1202 Error4x4 = vp8_pick_intra4x4mby_modes(IF_RTCD(&cpi->rtcd), x, &rate2, &best_distortion);
1205 if (Error4x4 < Error16x16)
1207 x->e_mbd.mode_info_context->mbmi.mode = B_PRED;
1208 vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
1212 vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
1215 vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
1216 sum_intra_stats(cpi, x);
1217 vp8_tokenize_mb(cpi, &x->e_mbd, t);
1225 extern void vp8_fix_contexts(MACROBLOCKD *x);
1227 int vp8cx_encode_inter_macroblock
1229 VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
1230 int recon_yoffset, int recon_uvoffset
1233 MACROBLOCKD *const xd = &x->e_mbd;
1235 int intra_error = 0;
1241 if (xd->segmentation_enabled)
1242 x->encode_breakout = cpi->segment_encode_breakout[xd->mode_info_context->mbmi.segment_id];
1244 x->encode_breakout = cpi->oxcf.encode_breakout;
1246 #if !(CONFIG_REALTIME_ONLY)
1250 int zbin_mode_boost_enabled = cpi->zbin_mode_boost_enabled;
1252 /* Are we using the fast quantizer for the mode selection? */
1253 if(cpi->sf.use_fastquant_for_pick)
1255 cpi->mb.quantize_b = QUANTIZE_INVOKE(&cpi->rtcd.quantize, fastquantb);
1257 /* the fast quantizer does not use zbin_extra, so
1258 * do not recalculate */
1259 cpi->zbin_mode_boost_enabled = 0;
1261 inter_error = vp8_rd_pick_inter_mode(cpi, x, recon_yoffset, recon_uvoffset, &rate, &distortion, &intra_error);
1263 /* switch back to the regular quantizer for the encode */
1264 if (cpi->sf.improved_quant)
1266 cpi->mb.quantize_b = QUANTIZE_INVOKE(&cpi->rtcd.quantize, quantb);
1269 /* restore cpi->zbin_mode_boost_enabled */
1270 cpi->zbin_mode_boost_enabled = zbin_mode_boost_enabled;
1275 inter_error = vp8_pick_inter_mode(cpi, x, recon_yoffset, recon_uvoffset, &rate, &distortion, &intra_error);
1278 cpi->prediction_error += inter_error;
1279 cpi->intra_error += intra_error;
1282 // Experimental RD code
1283 cpi->frame_distortion += distortion;
1284 cpi->last_mb_distortion = distortion;
1287 // MB level adjutment to quantizer setup
1288 if (xd->segmentation_enabled)
1290 // If cyclic update enabled
1291 if (cpi->cyclic_refresh_mode_enabled)
1293 // Clear segment_id back to 0 if not coded (last frame 0,0)
1294 if ((xd->mode_info_context->mbmi.segment_id == 1) &&
1295 ((xd->mode_info_context->mbmi.ref_frame != LAST_FRAME) || (xd->mode_info_context->mbmi.mode != ZEROMV)))
1297 xd->mode_info_context->mbmi.segment_id = 0;
1299 /* segment_id changed, so update */
1300 vp8cx_mb_init_quantizer(cpi, x);
1306 // Experimental code. Special case for gf and arf zeromv modes. Increase zbin size to supress noise
1307 if (cpi->zbin_mode_boost_enabled)
1309 if ( xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME )
1310 cpi->zbin_mode_boost = 0;
1313 if (xd->mode_info_context->mbmi.mode == ZEROMV)
1315 if (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME)
1316 cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
1318 cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
1320 else if (xd->mode_info_context->mbmi.mode == SPLITMV)
1321 cpi->zbin_mode_boost = 0;
1323 cpi->zbin_mode_boost = MV_ZBIN_BOOST;
1327 cpi->zbin_mode_boost = 0;
1329 vp8_update_zbin_extra(cpi, x);
1332 cpi->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame] ++;
1334 if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
1336 vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
1338 if (xd->mode_info_context->mbmi.mode == B_PRED)
1340 vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
1344 vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
1347 sum_intra_stats(cpi, x);
1356 vp8_find_near_mvs(xd, xd->mode_info_context,
1357 &nearest, &nearby, &best_ref_mv, mdcounts, xd->mode_info_context->mbmi.ref_frame, cpi->common.ref_frame_sign_bias);
1359 vp8_build_uvmvs(xd, cpi->common.full_pixel);
1361 if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
1362 ref_fb_idx = cpi->common.lst_fb_idx;
1363 else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
1364 ref_fb_idx = cpi->common.gld_fb_idx;
1366 ref_fb_idx = cpi->common.alt_fb_idx;
1368 xd->pre.y_buffer = cpi->common.yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
1369 xd->pre.u_buffer = cpi->common.yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
1370 xd->pre.v_buffer = cpi->common.yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
1372 if (xd->mode_info_context->mbmi.mode == SPLITMV)
1376 for (i = 0; i < 16; i++)
1378 if (xd->block[i].bmi.mode == NEW4X4)
1380 cpi->MVcount[0][mv_max+((xd->block[i].bmi.mv.as_mv.row - best_ref_mv.row) >> 1)]++;
1381 cpi->MVcount[1][mv_max+((xd->block[i].bmi.mv.as_mv.col - best_ref_mv.col) >> 1)]++;
1385 else if (xd->mode_info_context->mbmi.mode == NEWMV)
1387 cpi->MVcount[0][mv_max+((xd->block[0].bmi.mv.as_mv.row - best_ref_mv.row) >> 1)]++;
1388 cpi->MVcount[1][mv_max+((xd->block[0].bmi.mv.as_mv.col - best_ref_mv.col) >> 1)]++;
1391 if (!x->skip && !x->e_mbd.mode_info_context->mbmi.force_no_skip)
1393 vp8_encode_inter16x16(IF_RTCD(&cpi->rtcd), x);
1395 // Clear mb_skip_coeff if mb_no_coeff_skip is not set
1396 if (!cpi->common.mb_no_coeff_skip)
1397 xd->mode_info_context->mbmi.mb_skip_coeff = 0;
1401 vp8_stuff_inter16x16(x);
1405 vp8_tokenize_mb(cpi, xd, t);
1408 if (cpi->common.mb_no_coeff_skip)
1410 if (xd->mode_info_context->mbmi.mode != B_PRED && xd->mode_info_context->mbmi.mode != SPLITMV)
1411 xd->mode_info_context->mbmi.dc_diff = 0;
1413 xd->mode_info_context->mbmi.dc_diff = 1;
1415 xd->mode_info_context->mbmi.mb_skip_coeff = 1;
1416 cpi->skip_true_count ++;
1417 vp8_fix_contexts(xd);
1421 vp8_stuff_mb(cpi, xd, t);
1422 xd->mode_info_context->mbmi.mb_skip_coeff = 0;
1423 cpi->skip_false_count ++;