encodeframe.c 76.9 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
6
 *  that can be found in the LICENSE file in the root of the source
 *  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.
John Koleszar's avatar
John Koleszar committed
9
10
11
12
13
14
 */


#include "vpx_ports/config.h"
#include "encodemb.h"
#include "encodemv.h"
John Koleszar's avatar
John Koleszar committed
15
#include "vp8/common/common.h"
John Koleszar's avatar
John Koleszar committed
16
#include "onyx_int.h"
John Koleszar's avatar
John Koleszar committed
17
18
19
#include "vp8/common/extend.h"
#include "vp8/common/entropymode.h"
#include "vp8/common/quant_common.h"
20
#include "segmentation.h"
John Koleszar's avatar
John Koleszar committed
21
#include "vp8/common/setupintrarecon.h"
John Koleszar's avatar
John Koleszar committed
22
#include "encodeintra.h"
John Koleszar's avatar
John Koleszar committed
23
#include "vp8/common/reconinter.h"
Ronald S. Bultje's avatar
Ronald S. Bultje committed
24
#include "vp8/common/invtrans.h"
John Koleszar's avatar
John Koleszar committed
25
#include "rdopt.h"
John Koleszar's avatar
John Koleszar committed
26
27
#include "vp8/common/findnearmv.h"
#include "vp8/common/reconintra.h"
Christian Duvivier's avatar
Christian Duvivier committed
28
#include "vp8/common/seg_common.h"
29
#include "vpx_rtcd.h"
John Koleszar's avatar
John Koleszar committed
30
#include <stdio.h>
31
#include <math.h>
John Koleszar's avatar
John Koleszar committed
32
#include <limits.h>
John Koleszar's avatar
John Koleszar committed
33
#include "vp8/common/subpixel.h"
John Koleszar's avatar
John Koleszar committed
34
#include "vpx_ports/vpx_timer.h"
35
#include "vp8/common/pred_common.h"
John Koleszar's avatar
John Koleszar committed
36

37
#define DBG_PRNT_SEGMAP 0
38
#if CONFIG_NEWBESTREFMV
Paul Wilkins's avatar
Paul Wilkins committed
39
40
41
#include "vp8/common/mvref_common.h"
#endif

42

John Koleszar's avatar
John Koleszar committed
43
44
45
46
47
48
49
#if CONFIG_RUNTIME_CPU_DETECT
#define RTCD(x)     &cpi->common.rtcd.x
#define IF_RTCD(x)  (x)
#else
#define RTCD(x)     NULL
#define IF_RTCD(x)  NULL
#endif
50

51
#ifdef ENC_DEBUG
John Koleszar's avatar
John Koleszar committed
52
int enc_debug = 0;
53
54
55
int mb_row_debug, mb_col_debug;
#endif

John Koleszar's avatar
John Koleszar committed
56
57
58
59
60
61
62
extern void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex);
extern void vp8_auto_select_speed(VP8_COMP *cpi);
extern void vp8cx_init_mbrthread_data(VP8_COMP *cpi,
                                      MACROBLOCK *x,
                                      MB_ROW_COMP *mbr_ei,
                                      int mb_row,
                                      int count);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
63
64
65
66
int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
                              int recon_yoffset, int recon_uvoffset,
                              int *returnrate, int *returndistortion);
extern void vp8cx_pick_mode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x,
Adrian Grange's avatar
Adrian Grange committed
67
                                            int recon_yoffset,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
68
                                            int recon_uvoffset, int *r, int *d);
John Koleszar's avatar
John Koleszar committed
69
70
void vp8_build_block_offsets(MACROBLOCK *x);
void vp8_setup_block_ptrs(MACROBLOCK *x);
Adrian Grange's avatar
Adrian Grange committed
71
72
73
void vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
                                   int recon_yoffset, int recon_uvoffset,
                                   int output_enabled);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
74
75
void vp8cx_encode_inter_superblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
                                   int recon_yoffset, int recon_uvoffset, int mb_col, int mb_row);
Adrian Grange's avatar
Adrian Grange committed
76
77
void vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x,
                                    TOKENEXTRA **t, int output_enabled);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
78
79
80
void vp8cx_encode_intra_super_block(VP8_COMP *cpi,
                                    MACROBLOCK *x,
                                    TOKENEXTRA **t, int mb_col);
John Koleszar's avatar
John Koleszar committed
81
static void adjust_act_zbin(VP8_COMP *cpi, MACROBLOCK *x);
82

John Koleszar's avatar
John Koleszar committed
83
#ifdef MODE_STATS
84
85
86
87
88
89
90
91
unsigned int inter_y_modes[MB_MODE_COUNT];
unsigned int inter_uv_modes[VP8_UV_MODES];
unsigned int inter_b_modes[B_MODE_COUNT];
unsigned int y_modes[VP8_YMODES];
unsigned int i8x8_modes[VP8_I8X8_MODES];
unsigned int uv_modes[VP8_UV_MODES];
unsigned int uv_modes_y[VP8_YMODES][VP8_UV_MODES];
unsigned int b_modes[B_MODE_COUNT];
John Koleszar's avatar
John Koleszar committed
92
93
94
#endif


95
96
97
98
99
100
101
102
103
104
105
106
/* activity_avg must be positive, or flat regions could get a zero weight
 *  (infinite lambda), which confounds analysis.
 * This also avoids the need for divide by zero checks in
 *  vp8_activity_masking().
 */
#define VP8_ACTIVITY_AVG_MIN (64)

/* This is used as a reference when computing the source variance for the
 *  purposes of activity masking.
 * Eventually this should be replaced by custom no-reference routines,
 *  which will be faster.
 */
John Koleszar's avatar
John Koleszar committed
107
108
static const unsigned char VP8_VAR_OFFS[16] = {
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
109
110
};

111
112

// Original activity measure from Tim T's code.
John Koleszar's avatar
John Koleszar committed
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
static unsigned int tt_activity_measure(VP8_COMP *cpi, MACROBLOCK *x) {
  unsigned int act;
  unsigned int sse;
  /* TODO: This could also be done over smaller areas (8x8), but that would
   *  require extensive changes elsewhere, as lambda is assumed to be fixed
   *  over an entire MB in most of the code.
   * Another option is to compute four 8x8 variances, and pick a single
   *  lambda using a non-linear combination (e.g., the smallest, or second
   *  smallest, etc.).
   */
  act =     VARIANCE_INVOKE(&cpi->rtcd.variance, var16x16)(x->src.y_buffer,
                                                           x->src.y_stride, VP8_VAR_OFFS, 0, &sse);
  act = act << 4;

  /* If the region is flat, lower the activity some more. */
  if (act < 8 << 12)
    act = act < 5 << 12 ? act : 5 << 12;

  return act;
132
133
}

134
// Stub for alternative experimental activity measures.
John Koleszar's avatar
John Koleszar committed
135
136
137
static unsigned int alt_activity_measure(VP8_COMP *cpi,
                                         MACROBLOCK *x, int use_dc_pred) {
  return vp8_encode_intra(cpi, x, use_dc_pred);
138
139
140
141
142
}


// Measure the activity of the current macroblock
// What we measure here is TBD so abstracted to this function
143
#define ALT_ACT_MEASURE 1
John Koleszar's avatar
John Koleszar committed
144
145
146
static unsigned int mb_activity_measure(VP8_COMP *cpi, MACROBLOCK *x,
                                        int mb_row, int mb_col) {
  unsigned int mb_activity;
147

John Koleszar's avatar
John Koleszar committed
148
149
  if (ALT_ACT_MEASURE) {
    int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
150

John Koleszar's avatar
John Koleszar committed
151
152
153
154
155
156
    // Or use and alternative.
    mb_activity = alt_activity_measure(cpi, x, use_dc_pred);
  } else {
    // Original activity measure from Tim T's code.
    mb_activity = tt_activity_measure(cpi, x);
  }
157

John Koleszar's avatar
John Koleszar committed
158
159
  if (mb_activity < VP8_ACTIVITY_AVG_MIN)
    mb_activity = VP8_ACTIVITY_AVG_MIN;
160

John Koleszar's avatar
John Koleszar committed
161
  return mb_activity;
162
163
164
}

// Calculate an "average" mb activity value for the frame
165
#define ACT_MEDIAN 0
John Koleszar's avatar
John Koleszar committed
166
static void calc_av_activity(VP8_COMP *cpi, int64_t activity_sum) {
167
#if ACT_MEDIAN
John Koleszar's avatar
John Koleszar committed
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
  // Find median: Simple n^2 algorithm for experimentation
  {
    unsigned int median;
    unsigned int i, j;
    unsigned int *sortlist;
    unsigned int tmp;

    // Create a list to sort to
    CHECK_MEM_ERROR(sortlist,
    vpx_calloc(sizeof(unsigned int),
    cpi->common.MBs));

    // Copy map to sort list
    vpx_memcpy(sortlist, cpi->mb_activity_map,
    sizeof(unsigned int) * cpi->common.MBs);


    // Ripple each value down to its correct position
    for (i = 1; i < cpi->common.MBs; i ++) {
      for (j = i; j > 0; j --) {
        if (sortlist[j] < sortlist[j - 1]) {
          // Swap values
          tmp = sortlist[j - 1];
          sortlist[j - 1] = sortlist[j];
          sortlist[j] = tmp;
        } else
          break;
      }
    }
197

John Koleszar's avatar
John Koleszar committed
198
199
200
    // Even number MBs so estimate median as mean of two either side.
    median = (1 + sortlist[cpi->common.MBs >> 1] +
              sortlist[(cpi->common.MBs >> 1) + 1]) >> 1;
201

John Koleszar's avatar
John Koleszar committed
202
    cpi->activity_avg = median;
203

John Koleszar's avatar
John Koleszar committed
204
205
    vpx_free(sortlist);
  }
206
#else
John Koleszar's avatar
John Koleszar committed
207
208
  // Simple mean for now
  cpi->activity_avg = (unsigned int)(activity_sum / cpi->common.MBs);
209
210
#endif

John Koleszar's avatar
John Koleszar committed
211
212
  if (cpi->activity_avg < VP8_ACTIVITY_AVG_MIN)
    cpi->activity_avg = VP8_ACTIVITY_AVG_MIN;
213

John Koleszar's avatar
John Koleszar committed
214
215
216
  // Experimental code: return fixed value normalized for several clips
  if (ALT_ACT_MEASURE)
    cpi->activity_avg = 100000;
217
218
}

219
#define USE_ACT_INDEX   0
220
#define OUTPUT_NORM_ACT_STATS   0
221
222
223

#if USE_ACT_INDEX
// Calculate and activity index for each mb
John Koleszar's avatar
John Koleszar committed
224
static void calc_activity_index(VP8_COMP *cpi, MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
225
  VP8_COMMON *const cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
226
  int mb_row, mb_col;
227

John Koleszar's avatar
John Koleszar committed
228
229
230
  int64_t act;
  int64_t a;
  int64_t b;
231
232

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
233
234
  FILE *f = fopen("norm_act.stt", "a");
  fprintf(f, "\n%12d\n", cpi->activity_avg);
235
236
#endif

John Koleszar's avatar
John Koleszar committed
237
238
  // Reset pointers to start of activity map
  x->mb_activity_ptr = cpi->mb_activity_map;
239

John Koleszar's avatar
John Koleszar committed
240
241
242
243
244
245
  // Calculate normalized mb activity number.
  for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
    // for each macroblock col in image
    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
      // Read activity from the map
      act = *(x->mb_activity_ptr);
246

John Koleszar's avatar
John Koleszar committed
247
248
249
      // Calculate a normalized activity number
      a = act + 4 * cpi->activity_avg;
      b = 4 * act + cpi->activity_avg;
250

John Koleszar's avatar
John Koleszar committed
251
252
253
254
      if (b >= a)
        *(x->activity_ptr) = (int)((b + (a >> 1)) / a) - 1;
      else
        *(x->activity_ptr) = 1 - (int)((a + (b >> 1)) / b);
255
256

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
257
      fprintf(f, " %6d", *(x->mb_activity_ptr));
258
#endif
John Koleszar's avatar
John Koleszar committed
259
260
261
      // Increment activity map pointers
      x->mb_activity_ptr++;
    }
262
263

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
264
    fprintf(f, "\n");
265
266
#endif

John Koleszar's avatar
John Koleszar committed
267
  }
268
269

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
270
  fclose(f);
271
272
273
#endif

}
274
#endif
275
276
277

// Loop through all MBs. Note activity of each, average activity and
// calculate a normalized activity for each
John Koleszar's avatar
John Koleszar committed
278
static void build_activity_map(VP8_COMP *cpi) {
John Koleszar's avatar
John Koleszar committed
279
  MACROBLOCK *const x = &cpi->mb;
John Koleszar's avatar
John Koleszar committed
280
  MACROBLOCKD *xd = &x->e_mbd;
John Koleszar's avatar
John Koleszar committed
281
  VP8_COMMON *const cm = &cpi->common;
282

283
#if ALT_ACT_MEASURE
John Koleszar's avatar
John Koleszar committed
284
285
286
  YV12_BUFFER_CONFIG *new_yv12 = &cm->yv12_fb[cm->new_fb_idx];
  int recon_yoffset;
  int recon_y_stride = new_yv12->y_stride;
287
288
#endif

John Koleszar's avatar
John Koleszar committed
289
290
291
  int mb_row, mb_col;
  unsigned int mb_activity;
  int64_t activity_sum = 0;
292

John Koleszar's avatar
John Koleszar committed
293
294
  // for each macroblock row in image
  for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
295
#if ALT_ACT_MEASURE
John Koleszar's avatar
John Koleszar committed
296
297
298
    // reset above block coeffs
    xd->up_available = (mb_row != 0);
    recon_yoffset = (mb_row * recon_y_stride * 16);
299
#endif
John Koleszar's avatar
John Koleszar committed
300
301
    // for each macroblock col in image
    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
302
#if ALT_ACT_MEASURE
John Koleszar's avatar
John Koleszar committed
303
304
305
      xd->dst.y_buffer = new_yv12->y_buffer + recon_yoffset;
      xd->left_available = (mb_col != 0);
      recon_yoffset += 16;
306
#endif
John Koleszar's avatar
John Koleszar committed
307
      // Copy current mb to a buffer
Jim Bankoski's avatar
Jim Bankoski committed
308
      vp8_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
309

John Koleszar's avatar
John Koleszar committed
310
311
      // measure activity
      mb_activity = mb_activity_measure(cpi, x, mb_row, mb_col);
312

John Koleszar's avatar
John Koleszar committed
313
314
      // Keep frame sum
      activity_sum += mb_activity;
315

John Koleszar's avatar
John Koleszar committed
316
317
      // Store MB level activity details.
      *x->mb_activity_ptr = mb_activity;
318

John Koleszar's avatar
John Koleszar committed
319
320
      // Increment activity map pointer
      x->mb_activity_ptr++;
321

John Koleszar's avatar
John Koleszar committed
322
323
324
      // adjust to the next column of source macroblocks
      x->src.y_buffer += 16;
    }
325

326

John Koleszar's avatar
John Koleszar committed
327
328
    // adjust to the next row of mbs
    x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
329
330

#if ALT_ACT_MEASURE
John Koleszar's avatar
John Koleszar committed
331
332
333
    // extend the recon for intra prediction
    vp8_extend_mb_row(new_yv12, xd->dst.y_buffer + 16,
                      xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);
334
335
#endif

John Koleszar's avatar
John Koleszar committed
336
  }
337

John Koleszar's avatar
John Koleszar committed
338
339
  // Calculate an "average" MB activity
  calc_av_activity(cpi, activity_sum);
340

341
#if USE_ACT_INDEX
John Koleszar's avatar
John Koleszar committed
342
343
  // Calculate an activity index number of each mb
  calc_activity_index(cpi, x);
344
345
#endif

346
347
}

348
// Macroblock activity masking
John Koleszar's avatar
John Koleszar committed
349
void vp8_activity_masking(VP8_COMP *cpi, MACROBLOCK *x) {
350
#if USE_ACT_INDEX
John Koleszar's avatar
John Koleszar committed
351
352
353
  x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2);
  x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
  x->errorperbit += (x->errorperbit == 0);
354
#else
John Koleszar's avatar
John Koleszar committed
355
356
357
  int64_t a;
  int64_t b;
  int64_t act = *(x->mb_activity_ptr);
358

John Koleszar's avatar
John Koleszar committed
359
360
361
  // Apply the masking to the RD multiplier.
  a = act + (2 * cpi->activity_avg);
  b = (2 * act) + cpi->activity_avg;
362

John Koleszar's avatar
John Koleszar committed
363
364
365
  x->rdmult = (unsigned int)(((int64_t)x->rdmult * b + (a >> 1)) / a);
  x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
  x->errorperbit += (x->errorperbit == 0);
366
#endif
367

John Koleszar's avatar
John Koleszar committed
368
369
  // Activity based Zbin adjustment
  adjust_act_zbin(cpi, x);
370
}
John Koleszar's avatar
John Koleszar committed
371

John Koleszar's avatar
John Koleszar committed
372
373
374
375
static void update_state(VP8_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
  int i;
  MACROBLOCKD *xd = &x->e_mbd;
  MODE_INFO *mi = &ctx->mic;
Paul Wilkins's avatar
Paul Wilkins committed
376
  MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
John Koleszar's avatar
John Koleszar committed
377
378
  int mb_mode = mi->mbmi.mode;
  int mb_mode_index = ctx->best_mode_index;
Adrian Grange's avatar
Adrian Grange committed
379
380

#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
381
382
383
  assert(mb_mode < MB_MODE_COUNT);
  assert(mb_mode_index < MAX_MODES);
  assert(mi->mbmi.ref_frame < MAX_REF_FRAMES);
Adrian Grange's avatar
Adrian Grange committed
384
385
#endif

John Koleszar's avatar
John Koleszar committed
386
387
388
  // Restore the coding context of the MB to that that was in place
  // when the mode was picked for it
  vpx_memcpy(xd->mode_info_context, mi, sizeof(MODE_INFO));
Ronald S. Bultje's avatar
Ronald S. Bultje committed
389
390
391
392
393
394
395
#if CONFIG_SUPERBLOCKS
  if (mi->mbmi.encoded_as_sb) {
    vpx_memcpy(xd->mode_info_context + 1, mi, sizeof(MODE_INFO));
    vpx_memcpy(xd->mode_info_context + cpi->common.mode_info_stride, mi, sizeof(MODE_INFO));
    vpx_memcpy(xd->mode_info_context + cpi->common.mode_info_stride + 1, mi, sizeof(MODE_INFO));
  }
#endif
Adrian Grange's avatar
Adrian Grange committed
396

John Koleszar's avatar
John Koleszar committed
397
398
399
400
  if (mb_mode == B_PRED) {
    for (i = 0; i < 16; i++) {
      xd->block[i].bmi.as_mode = xd->mode_info_context->bmi[i].as_mode;
      assert(xd->block[i].bmi.as_mode.first < MB_MODE_COUNT);
Adrian Grange's avatar
Adrian Grange committed
401
    }
John Koleszar's avatar
John Koleszar committed
402
403
404
  } else if (mb_mode == I8X8_PRED) {
    for (i = 0; i < 16; i++) {
      xd->block[i].bmi = xd->mode_info_context->bmi[i];
Adrian Grange's avatar
Adrian Grange committed
405
    }
John Koleszar's avatar
John Koleszar committed
406
407
408
409
  } else if (mb_mode == SPLITMV) {
    vpx_memcpy(x->partition_info, &ctx->partition_info,
               sizeof(PARTITION_INFO));

410
411
    mbmi->mv[0].as_int = x->partition_info->bmi[15].mv.as_int;
    mbmi->mv[1].as_int = x->partition_info->bmi[15].second_mv.as_int;
John Koleszar's avatar
John Koleszar committed
412
413
  }

414
415
416
417
418
419
420
421
422
423
424
425
#if CONFIG_TX_SELECT
  {
    int segment_id = mbmi->segment_id;
    if (!segfeature_active(xd, segment_id, SEG_LVL_EOB) ||
        get_segdata(xd, segment_id, SEG_LVL_EOB)) {
      for (i = 0; i < NB_TXFM_MODES; i++) {
        cpi->rd_tx_select_diff[i] += ctx->txfm_rd_diff[i];
      }
    }
  }
#endif

John Koleszar's avatar
John Koleszar committed
426
427
428
429
430
431
432
433
434
  if (cpi->common.frame_type == KEY_FRAME) {
    // Restore the coding modes to that held in the coding context
    // if (mb_mode == B_PRED)
    //    for (i = 0; i < 16; i++)
    //    {
    //        xd->block[i].bmi.as_mode =
    //                          xd->mode_info_context->bmi[i].as_mode;
    //        assert(xd->mode_info_context->bmi[i].as_mode < MB_MODE_COUNT);
    //    }
435
#if CONFIG_INTERNAL_STATS
John Koleszar's avatar
John Koleszar committed
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
    static const int kf_mode_index[] = {
      THR_DC /*DC_PRED*/,
      THR_V_PRED /*V_PRED*/,
      THR_H_PRED /*H_PRED*/,
      THR_D45_PRED /*D45_PRED*/,
      THR_D135_PRED /*D135_PRED*/,
      THR_D117_PRED /*D117_PRED*/,
      THR_D153_PRED /*D153_PRED*/,
      THR_D27_PRED /*D27_PRED*/,
      THR_D63_PRED /*D63_PRED*/,
      THR_TM /*TM_PRED*/,
      THR_I8X8_PRED /*I8X8_PRED*/,
      THR_B_PRED /*B_PRED*/,
    };
    cpi->mode_chosen_counts[kf_mode_index[mb_mode]]++;
451
#endif
John Koleszar's avatar
John Koleszar committed
452
453
454
455
456
457
458
  } else {
    /*
            // Reduce the activation RD thresholds for the best choice mode
            if ((cpi->rd_baseline_thresh[mb_mode_index] > 0) &&
                (cpi->rd_baseline_thresh[mb_mode_index] < (INT_MAX >> 2)))
            {
                int best_adjustment = (cpi->rd_thresh_mult[mb_mode_index] >> 2);
Adrian Grange's avatar
Adrian Grange committed
459

John Koleszar's avatar
John Koleszar committed
460
461
462
463
464
465
466
467
                cpi->rd_thresh_mult[mb_mode_index] =
                        (cpi->rd_thresh_mult[mb_mode_index]
                         >= (MIN_THRESHMULT + best_adjustment)) ?
                                cpi->rd_thresh_mult[mb_mode_index] - best_adjustment :
                                MIN_THRESHMULT;
                cpi->rd_threshes[mb_mode_index] =
                        (cpi->rd_baseline_thresh[mb_mode_index] >> 7)
                        * cpi->rd_thresh_mult[mb_mode_index];
Adrian Grange's avatar
Adrian Grange committed
468

John Koleszar's avatar
John Koleszar committed
469
470
471
472
            }
    */
    // Note how often each mode chosen as best
    cpi->mode_chosen_counts[mb_mode_index]++;
Adrian Grange's avatar
Adrian Grange committed
473

John Koleszar's avatar
John Koleszar committed
474
    rd_update_mvcount(cpi, x, &ctx->best_ref_mv, &ctx->second_best_ref_mv);
Adrian Grange's avatar
Adrian Grange committed
475

John Koleszar's avatar
John Koleszar committed
476
477
    cpi->prediction_error += ctx->distortion;
    cpi->intra_error += ctx->intra_error;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
478
479
480
481

    cpi->rd_comp_pred_diff[0] += ctx->single_pred_diff;
    cpi->rd_comp_pred_diff[1] += ctx->comp_pred_diff;
    cpi->rd_comp_pred_diff[2] += ctx->hybrid_pred_diff;
John Koleszar's avatar
John Koleszar committed
482
  }
Adrian Grange's avatar
Adrian Grange committed
483
484
}

John Koleszar's avatar
John Koleszar committed
485
486
487
488
489
490
491
static void pick_mb_modes(VP8_COMP *cpi,
                          VP8_COMMON *cm,
                          int mb_row,
                          int mb_col,
                          MACROBLOCK  *x,
                          MACROBLOCKD *xd,
                          TOKENEXTRA **tp,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
492
493
                          int *totalrate,
                          int *totaldist) {
John Koleszar's avatar
John Koleszar committed
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
  int i;
  int map_index;
  int recon_yoffset, recon_uvoffset;
  int ref_fb_idx = cm->lst_fb_idx;
  int dst_fb_idx = cm->new_fb_idx;
  int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
  int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
  ENTROPY_CONTEXT_PLANES left_context[2];
  ENTROPY_CONTEXT_PLANES above_context[2];
  ENTROPY_CONTEXT_PLANES *initial_above_context_ptr = cm->above_context
                                                      + mb_col;

  // Offsets to move pointers from MB to MB within a SB in raster order
  int row_delta[4] = { 0, +1,  0, -1};
  int col_delta[4] = { +1, -1, +1, +1};

  /* Function should not modify L & A contexts; save and restore on exit */
  vpx_memcpy(left_context,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
512
             cm->left_context,
John Koleszar's avatar
John Koleszar committed
513
514
515
516
517
518
519
520
521
522
523
             sizeof(left_context));
  vpx_memcpy(above_context,
             initial_above_context_ptr,
             sizeof(above_context));

  /* Encode MBs in raster order within the SB */
  for (i = 0; i < 4; i++) {
    int dy = row_delta[i];
    int dx = col_delta[i];
    int offset_unextended = dy * cm->mb_cols + dx;
    int offset_extended   = dy * xd->mode_info_stride + dx;
Paul Wilkins's avatar
Paul Wilkins committed
524
    MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
John Koleszar's avatar
John Koleszar committed
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541

    // TODO Many of the index items here can be computed more efficiently!

    if ((mb_row >= cm->mb_rows) || (mb_col >= cm->mb_cols)) {
      // MB lies outside frame, move on
      mb_row += dy;
      mb_col += dx;

      // Update pointers
      x->src.y_buffer += 16 * (dx + dy * x->src.y_stride);
      x->src.u_buffer += 8  * (dx + dy * x->src.uv_stride);
      x->src.v_buffer += 8  * (dx + dy * x->src.uv_stride);

      x->gf_active_ptr += offset_unextended;
      x->partition_info += offset_extended;
      xd->mode_info_context += offset_extended;
      xd->prev_mode_info_context += offset_extended;
Adrian Grange's avatar
Adrian Grange committed
542
#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
543
544
      assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
             (xd->mode_info_context - cpi->common.mip));
Adrian Grange's avatar
Adrian Grange committed
545
#endif
John Koleszar's avatar
John Koleszar committed
546
547
      continue;
    }
548

John Koleszar's avatar
John Koleszar committed
549
550
551
552
553
554
555
556
557
558
559
    // Index of the MB in the SB 0..3
    xd->mb_index = i;

    map_index = (mb_row * cpi->common.mb_cols) + mb_col;
    x->mb_activity_ptr = &cpi->mb_activity_map[map_index];

    // set above context pointer
    xd->above_context = cm->above_context + mb_col;

    // Restore the appropriate left context depending on which
    // row in the SB the MB is situated
Ronald S. Bultje's avatar
Ronald S. Bultje committed
560
    xd->left_context = cm->left_context + (i >> 1);
John Koleszar's avatar
John Koleszar committed
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587

    // Set up distance of MB to edge of frame in 1/8th pel units
    xd->mb_to_top_edge    = -((mb_row * 16) << 3);
    xd->mb_to_left_edge   = -((mb_col * 16) << 3);
    xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
    xd->mb_to_right_edge  = ((cm->mb_cols - 1 - mb_col) * 16) << 3;

    // Set up limit values for MV components to prevent them from
    // extending beyond the UMV borders assuming 16x16 block size
    x->mv_row_min = -((mb_row * 16) + VP8BORDERINPIXELS - INTERP_EXTEND);
    x->mv_col_min = -((mb_col * 16) + VP8BORDERINPIXELS - INTERP_EXTEND);
    x->mv_row_max = ((cm->mb_rows - mb_row) * 16 +
                     (VP8BORDERINPIXELS - 16 - INTERP_EXTEND));
    x->mv_col_max = ((cm->mb_cols - mb_col) * 16 +
                     (VP8BORDERINPIXELS - 16 - INTERP_EXTEND));

    xd->up_available   = (mb_row != 0);
    xd->left_available = (mb_col != 0);

    recon_yoffset  = (mb_row * recon_y_stride * 16) + (mb_col * 16);
    recon_uvoffset = (mb_row * recon_uv_stride * 8) + (mb_col *  8);

    xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
    xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
    xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;

    // Copy current MB to a work buffer
Jim Bankoski's avatar
Jim Bankoski committed
588
    vp8_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
John Koleszar's avatar
John Koleszar committed
589
590
591
592
593
594
595
596
597
598

    x->rddiv = cpi->RDDIV;
    x->rdmult = cpi->RDMULT;

    if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
      vp8_activity_masking(cpi, x);

    // Is segmentation enabled
    if (xd->segmentation_enabled) {
      // Code to set segment id in xd->mbmi.segment_id
Ronald S. Bultje's avatar
Ronald S. Bultje committed
599
      if (xd->update_mb_segmentation_map)
Paul Wilkins's avatar
Paul Wilkins committed
600
        mbmi->segment_id = cpi->segmentation_map[map_index];
John Koleszar's avatar
John Koleszar committed
601
      else
Ronald S. Bultje's avatar
Ronald S. Bultje committed
602
603
        mbmi->segment_id = cm->last_frame_seg_map[map_index];
      if (mbmi->segment_id > 3)
Paul Wilkins's avatar
Paul Wilkins committed
604
        mbmi->segment_id = 0;
John Koleszar's avatar
John Koleszar committed
605
606
607
608

      vp8cx_mb_init_quantizer(cpi, x);
    } else
      // Set to Segment 0 by default
Paul Wilkins's avatar
Paul Wilkins committed
609
      mbmi->segment_id = 0;
John Koleszar's avatar
John Koleszar committed
610
611
612

    x->active_ptr = cpi->active_map + map_index;

Ronald S. Bultje's avatar
Ronald S. Bultje committed
613
614
615
616
#if CONFIG_SUPERBLOCKS
    xd->mode_info_context->mbmi.encoded_as_sb = 0;
#endif

John Koleszar's avatar
John Koleszar committed
617
618
619
620
621
    cpi->update_context = 0;    // TODO Do we need this now??

    // Find best coding mode & reconstruct the MB so it is available
    // as a predictor for MBs that follow in the SB
    if (cm->frame_type == KEY_FRAME) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
622
623
624
625
      int r, d;
      vp8_rd_pick_intra_mode(cpi, x, &r, &d);
      *totalrate += r;
      *totaldist += d;
John Koleszar's avatar
John Koleszar committed
626
627
628
629

      // Dummy encode, do not do the tokenization
      vp8cx_encode_intra_macro_block(cpi, x, tp, 0);
      // Note the encoder may have changed the segment_id
Ronald S. Bultje's avatar
Ronald S. Bultje committed
630
631
632
633

      // Save the coding context
      vpx_memcpy(&x->mb_context[i].mic, xd->mode_info_context,
                 sizeof(MODE_INFO));
John Koleszar's avatar
John Koleszar committed
634
    } else {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
635
      int seg_id, r, d;
John Koleszar's avatar
John Koleszar committed
636
637
638
639
640
641
642
643
644
645
646
647
648

      if (xd->segmentation_enabled && cpi->seg0_cnt > 0 &&
          !segfeature_active(xd, 0, SEG_LVL_REF_FRAME) &&
          segfeature_active(xd, 1, SEG_LVL_REF_FRAME) &&
          check_segref(xd, 1, INTRA_FRAME)  +
          check_segref(xd, 1, LAST_FRAME)   +
          check_segref(xd, 1, GOLDEN_FRAME) +
          check_segref(xd, 1, ALTREF_FRAME) == 1) {
        cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt;
      } else {
        cpi->seg0_progress = (((mb_col & ~1) * 2 + (mb_row & ~1) * cm->mb_cols + i) << 16) / cm->MBs;
      }

Ronald S. Bultje's avatar
Ronald S. Bultje committed
649
650
651
652
      vp8cx_pick_mode_inter_macroblock(cpi, x, recon_yoffset,
                                       recon_uvoffset, &r, &d);
      *totalrate += r;
      *totaldist += d;
John Koleszar's avatar
John Koleszar committed
653
654
655
656
657

      // Dummy encode, do not do the tokenization
      vp8cx_encode_inter_macroblock(cpi, x, tp,
                                    recon_yoffset, recon_uvoffset, 0);

Paul Wilkins's avatar
Paul Wilkins committed
658
      seg_id = mbmi->segment_id;
John Koleszar's avatar
John Koleszar committed
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
      if (cpi->mb.e_mbd.segmentation_enabled && seg_id == 0) {
        cpi->seg0_idx++;
      }
      if (!xd->segmentation_enabled ||
          !segfeature_active(xd, seg_id, SEG_LVL_REF_FRAME) ||
          check_segref(xd, seg_id, INTRA_FRAME)  +
          check_segref(xd, seg_id, LAST_FRAME)   +
          check_segref(xd, seg_id, GOLDEN_FRAME) +
          check_segref(xd, seg_id, ALTREF_FRAME) > 1) {
        // Get the prediction context and status
        int pred_flag = get_pred_flag(xd, PRED_REF);
        int pred_context = get_pred_context(cm, xd, PRED_REF);

        // Count prediction success
        cpi->ref_pred_count[pred_context][pred_flag]++;
      }
    }
Adrian Grange's avatar
Adrian Grange committed
676

John Koleszar's avatar
John Koleszar committed
677
678
679
    // Next MB
    mb_row += dy;
    mb_col += dx;
Adrian Grange's avatar
Adrian Grange committed
680

John Koleszar's avatar
John Koleszar committed
681
682
683
    x->src.y_buffer += 16 * (dx + dy * x->src.y_stride);
    x->src.u_buffer += 8  * (dx + dy * x->src.uv_stride);
    x->src.v_buffer += 8  * (dx + dy * x->src.uv_stride);
Adrian Grange's avatar
Adrian Grange committed
684

John Koleszar's avatar
John Koleszar committed
685
686
687
688
    x->gf_active_ptr += offset_unextended;
    x->partition_info += offset_extended;
    xd->mode_info_context += offset_extended;
    xd->prev_mode_info_context += offset_extended;
Adrian Grange's avatar
Adrian Grange committed
689
690

#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
691
692
    assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
           (xd->mode_info_context - cpi->common.mip));
Adrian Grange's avatar
Adrian Grange committed
693
#endif
John Koleszar's avatar
John Koleszar committed
694
695
696
  }

  /* Restore L & A coding context to those in place on entry */
Ronald S. Bultje's avatar
Ronald S. Bultje committed
697
  vpx_memcpy(cm->left_context,
John Koleszar's avatar
John Koleszar committed
698
699
700
701
702
             left_context,
             sizeof(left_context));
  vpx_memcpy(initial_above_context_ptr,
             above_context,
             sizeof(above_context));
Adrian Grange's avatar
Adrian Grange committed
703
704
}

Ronald S. Bultje's avatar
Ronald S. Bultje committed
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
#if CONFIG_SUPERBLOCKS
static void pick_sb_modes (VP8_COMP *cpi,
                           VP8_COMMON *cm,
                           int mb_row,
                           int mb_col,
                           MACROBLOCK  *x,
                           MACROBLOCKD *xd,
                           TOKENEXTRA **tp,
                           int *totalrate,
                           int *totaldist)
{
  int map_index;
  int recon_yoffset, recon_uvoffset;
  int ref_fb_idx = cm->lst_fb_idx;
  int dst_fb_idx = cm->new_fb_idx;
  int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
  int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
  ENTROPY_CONTEXT_PLANES left_context[2];
  ENTROPY_CONTEXT_PLANES above_context[2];
  ENTROPY_CONTEXT_PLANES *initial_above_context_ptr = cm->above_context
    + mb_col;

  /* Function should not modify L & A contexts; save and restore on exit */
  vpx_memcpy (left_context,
              cm->left_context,
              sizeof(left_context));
  vpx_memcpy (above_context,
              initial_above_context_ptr,
              sizeof(above_context));

  map_index = (mb_row * cpi->common.mb_cols) + mb_col;
  x->mb_activity_ptr = &cpi->mb_activity_map[map_index];

  /* set above context pointer */
  xd->above_context = cm->above_context + mb_col;

  /* Restore the appropriate left context depending on which
   * row in the SB the MB is situated */
  xd->left_context = cm->left_context;

  // Set up distance of MB to edge of frame in 1/8th pel units
  xd->mb_to_top_edge    = -((mb_row * 16) << 3);
  xd->mb_to_left_edge   = -((mb_col * 16) << 3);
  xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
  xd->mb_to_right_edge  = ((cm->mb_cols - 1 - mb_col) * 16) << 3;

  /* Set up limit values for MV components to prevent them from
   * extending beyond the UMV borders assuming 16x16 block size */
  x->mv_row_min = -((mb_row * 16) + VP8BORDERINPIXELS - INTERP_EXTEND);
  x->mv_col_min = -((mb_col * 16) + VP8BORDERINPIXELS - INTERP_EXTEND);
  x->mv_row_max = ((cm->mb_rows - mb_row) * 16 +
                   (VP8BORDERINPIXELS - 32 - INTERP_EXTEND));
  x->mv_col_max = ((cm->mb_cols - mb_col) * 16 +
                   (VP8BORDERINPIXELS - 32 - INTERP_EXTEND));

  xd->up_available   = (mb_row != 0);
  xd->left_available = (mb_col != 0);

  recon_yoffset  = (mb_row * recon_y_stride * 16) + (mb_col * 16);
  recon_uvoffset = (mb_row * recon_uv_stride * 8) + (mb_col *  8);

  xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
  xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
  xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
#if 0 // FIXME
  /* Copy current MB to a work buffer */
Jim Bankoski's avatar
Jim Bankoski committed
771
  vp8_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
#endif
  x->rddiv = cpi->RDDIV;
  x->rdmult = cpi->RDMULT;
  if(cpi->oxcf.tuning == VP8_TUNE_SSIM)
    vp8_activity_masking(cpi, x);
  /* Is segmentation enabled */
  if (xd->segmentation_enabled)
  {
    /* Code to set segment id in xd->mbmi.segment_id */
    if (xd->update_mb_segmentation_map)
      xd->mode_info_context->mbmi.segment_id =
            cpi->segmentation_map[map_index] &&
            cpi->segmentation_map[map_index + 1] &&
            cpi->segmentation_map[map_index + cm->mb_cols] &&
            cpi->segmentation_map[map_index + cm->mb_cols + 1];
    else
      xd->mode_info_context->mbmi.segment_id =
            cm->last_frame_seg_map[map_index] &&
            cm->last_frame_seg_map[map_index + 1] &&
            cm->last_frame_seg_map[map_index + cm->mb_cols] &&
            cm->last_frame_seg_map[map_index + cm->mb_cols + 1];
    if (xd->mode_info_context->mbmi.segment_id > 3)
      xd->mode_info_context->mbmi.segment_id = 0;

    vp8cx_mb_init_quantizer(cpi, x);
  }
  else
    /* Set to Segment 0 by default */
    xd->mode_info_context->mbmi.segment_id = 0;

  x->active_ptr = cpi->active_map + map_index;
  
  cpi->update_context = 0;    // TODO Do we need this now??

  /* Find best coding mode & reconstruct the MB so it is available
   * as a predictor for MBs that follow in the SB */
  if (cm->frame_type == KEY_FRAME)
  {
    vp8_rd_pick_intra_mode_sb(cpi, x,
                              totalrate,
                              totaldist);

    /* Save the coding context */
    vpx_memcpy(&x->sb_context[0].mic, xd->mode_info_context,
               sizeof(MODE_INFO));
  }
  else
  {
    if (xd->segmentation_enabled && cpi->seg0_cnt > 0 &&
        !segfeature_active( xd, 0, SEG_LVL_REF_FRAME ) &&
        segfeature_active( xd, 1, SEG_LVL_REF_FRAME ) &&
        check_segref(xd, 1, INTRA_FRAME)  +
        check_segref(xd, 1, LAST_FRAME)   +
        check_segref(xd, 1, GOLDEN_FRAME) +
        check_segref(xd, 1, ALTREF_FRAME) == 1)
    {
      cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt;
    }
    else
    {
      cpi->seg0_progress =
        (((mb_col & ~1) * 2 + (mb_row & ~1) * cm->mb_cols) << 16) / cm->MBs;
    }

    vp8_rd_pick_inter_mode_sb(cpi, x,
                              recon_yoffset,
                              recon_uvoffset,
                              totalrate,
                              totaldist);
  }

  /* Restore L & A coding context to those in place on entry */
  vpx_memcpy (cm->left_context,
              left_context,
              sizeof(left_context));
  vpx_memcpy (initial_above_context_ptr,
              above_context,
              sizeof(above_context));
}
#endif

John Koleszar's avatar
John Koleszar committed
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
static void encode_sb(VP8_COMP *cpi,
                      VP8_COMMON *cm,
                      int mbrow,
                      int mbcol,
                      MACROBLOCK  *x,
                      MACROBLOCKD *xd,
                      TOKENEXTRA **tp) {
  int i;
  int map_index;
  int mb_row, mb_col;
  int recon_yoffset, recon_uvoffset;
  int ref_fb_idx = cm->lst_fb_idx;
  int dst_fb_idx = cm->new_fb_idx;
  int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
  int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
  int row_delta[4] = { 0, +1,  0, -1};
  int col_delta[4] = { +1, -1, +1, +1};

  mb_row = mbrow;
  mb_col = mbcol;

  /* Encode MBs in raster order within the SB */
  for (i = 0; i < 4; i++) {
    int dy = row_delta[i];
    int dx = col_delta[i];
    int offset_extended   = dy * xd->mode_info_stride + dx;
    int offset_unextended = dy * cm->mb_cols + dx;
Paul Wilkins's avatar
Paul Wilkins committed
880
    MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
John Koleszar's avatar
John Koleszar committed
881
882
883
884
885
886
887
888
889
890
891
892
893
894

    if ((mb_row >= cm->mb_rows) || (mb_col >= cm->mb_cols)) {
      // MB lies outside frame, move on
      mb_row += dy;
      mb_col += dx;

      x->src.y_buffer += 16 * (dx + dy * x->src.y_stride);
      x->src.u_buffer += 8  * (dx + dy * x->src.uv_stride);
      x->src.v_buffer += 8  * (dx + dy * x->src.uv_stride);

      x->gf_active_ptr      += offset_unextended;
      x->partition_info     += offset_extended;
      xd->mode_info_context += offset_extended;
      xd->prev_mode_info_context += offset_extended;
Adrian Grange's avatar
Adrian Grange committed
895
896

#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
897
898
      assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
             (xd->mode_info_context - cpi->common.mip));
Adrian Grange's avatar
Adrian Grange committed
899
#endif
John Koleszar's avatar
John Koleszar committed
900
901
      continue;
    }
Adrian Grange's avatar
Adrian Grange committed
902

John Koleszar's avatar
John Koleszar committed
903
    xd->mb_index = i;
Adrian Grange's avatar
Adrian Grange committed
904

905
#ifdef ENC_DEBUG
John Koleszar's avatar
John Koleszar committed
906
907
908
909
    enc_debug = (cpi->common.current_video_frame == 0 &&
                 mb_row == 0 && mb_col == 0);
    mb_col_debug = mb_col;
    mb_row_debug = mb_row;
910
#endif
Adrian Grange's avatar
Adrian Grange committed
911

John Koleszar's avatar
John Koleszar committed
912
    // Restore MB state to that when it was picked
Adrian Grange's avatar
Adrian Grange committed
913
#if CONFIG_SUPERBLOCKS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
914
    if (xd->mode_info_context->mbmi.encoded_as_sb) {
John Koleszar's avatar
John Koleszar committed
915
      update_state(cpi, x, &x->sb_context[i]);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
916
917
      cpi->sb_count++;
    } else
Adrian Grange's avatar
Adrian Grange committed
918
#endif
John Koleszar's avatar
John Koleszar committed
919
920
921
922
923
924
925
      update_state(cpi, x, &x->mb_context[i]);

    map_index = (mb_row * cpi->common.mb_cols) + mb_col;
    x->mb_activity_ptr = &cpi->mb_activity_map[map_index];

    // reset above block coeffs
    xd->above_context = cm->above_context + mb_col;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
926
    xd->left_context  = cm->left_context + (i >> 1);
John Koleszar's avatar
John Koleszar committed
927
928
929
930
931
932
933

    // Set up distance of MB to edge of the frame in 1/8th pel units
    xd->mb_to_top_edge    = -((mb_row * 16) << 3);
    xd->mb_to_left_edge   = -((mb_col * 16) << 3);
    xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
    xd->mb_to_right_edge  = ((cm->mb_cols - 1 - mb_col) * 16) << 3;

Adrian Grange's avatar
Adrian Grange committed
934
#if CONFIG_SUPERBLOCKS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
    if (xd->mode_info_context->mbmi.encoded_as_sb) {
      // Set up limit values for MV components to prevent them from
      // extending beyond the UMV borders assuming 32x32 block size
      x->mv_row_min = -((mb_row * 16) + VP8BORDERINPIXELS - INTERP_EXTEND);
      x->mv_col_min = -((mb_col * 16) + VP8BORDERINPIXELS - INTERP_EXTEND);
      x->mv_row_max = ((cm->mb_rows - mb_row) * 16 +
                       (VP8BORDERINPIXELS - 32 - INTERP_EXTEND));
      x->mv_col_max = ((cm->mb_cols - mb_col) * 16 +
                       (VP8BORDERINPIXELS - 32 - INTERP_EXTEND));
    } else {
#endif
      // Set up limit values for MV components to prevent them from
      // extending beyond the UMV borders assuming 16x16 block size
      x->mv_row_min = -((mb_row * 16) + VP8BORDERINPIXELS - INTERP_EXTEND);
      x->mv_col_min = -((mb_col * 16) + VP8BORDERINPIXELS - INTERP_EXTEND);
      x->mv_row_max = ((cm->mb_rows - mb_row) * 16 +
                       (VP8BORDERINPIXELS - 16 - INTERP_EXTEND));
      x->mv_col_max = ((cm->mb_cols - mb_col) * 16 +
                       (VP8BORDERINPIXELS - 16 - INTERP_EXTEND));
#if CONFIG_SUPERBLOCKS
    }
Adrian Grange's avatar
Adrian Grange committed
956
957
#endif

John Koleszar's avatar
John Koleszar committed
958
959
    xd->up_available = (mb_row != 0);
    xd->left_available = (mb_col != 0);
Adrian Grange's avatar
Adrian Grange committed
960

John Koleszar's avatar
John Koleszar committed
961
962
    recon_yoffset = (mb_row * recon_y_stride * 16) + (mb_col * 16);
    recon_uvoffset = (mb_row * recon_uv_stride * 8) + (mb_col * 8);
Adrian Grange's avatar
Adrian Grange committed
963

John Koleszar's avatar
John Koleszar committed
964
965
966
    xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
    xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
    xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
John Koleszar's avatar
John Koleszar committed
967

John Koleszar's avatar
John Koleszar committed
968
    // Copy current MB to a work buffer
Jim Bankoski's avatar
Jim Bankoski committed
969
    vp8_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
970

John Koleszar's avatar
John Koleszar committed
971
972
    if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
      vp8_activity_masking(cpi, x);
973

John Koleszar's avatar
John Koleszar committed
974
975
976
    // Is segmentation enabled
    if (xd->segmentation_enabled) {
      vp8cx_mb_init_quantizer(cpi, x);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
977
    }
John Koleszar's avatar
John Koleszar committed
978

John Koleszar's avatar
John Koleszar committed
979
    x->active_ptr = cpi->active_map + map_index;
980

John Koleszar's avatar
John Koleszar committed
981
982
983
    cpi->update_context = 0;

    if (cm->frame_type == KEY_FRAME) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
984
985
986
987
988
989
990
#if CONFIG_SUPERBLOCKS
      if (xd->mode_info_context->mbmi.encoded_as_sb)
        vp8cx_encode_intra_super_block(cpi, x, tp, mb_col);
      else
#endif
        vp8cx_encode_intra_macro_block(cpi, x, tp, 1);
        // Note the encoder may have changed the segment_id
991

John Koleszar's avatar
John Koleszar committed
992
#ifdef MODE_STATS
Paul Wilkins's avatar
Paul Wilkins committed
993
      y_modes[mbmi->mode]++;
John Koleszar's avatar
John Koleszar committed
994
#endif
John Koleszar's avatar
John Koleszar committed
995
996
997
    } else {
      unsigned char *segment_id;
      int seg_ref_active;
998

Ronald S. Bultje's avatar
Ronald S. Bultje committed
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
      if (xd->mode_info_context->mbmi.ref_frame) {
        unsigned char pred_context;

        pred_context = get_pred_context(cm, xd, PRED_COMP);

        if (xd->mode_info_context->mbmi.second_ref_frame == INTRA_FRAME)
          cpi->single_pred_count[pred_context]++;
        else
          cpi->comp_pred_count[pred_context]++;
      }

#if CONFIG_SUPERBLOCKS
      if (xd->mode_info_context->mbmi.encoded_as_sb)
        vp8cx_encode_inter_superblock(cpi, x, tp, recon_yoffset, recon_uvoffset, mb_col, mb_row);
      else
#endif
        vp8cx_encode_inter_macroblock(cpi, x, tp,
                                      recon_yoffset, recon_uvoffset, 1);
        // Note the encoder may have changed the segment_id
John Koleszar's avatar
John Koleszar committed
1018
1019

#ifdef MODE_STATS
Paul Wilkins's avatar
Paul Wilkins committed
1020
      inter_y_modes[mbmi->mode]++;
John Koleszar's avatar
John Koleszar committed
1021

Paul Wilkins's avatar
Paul Wilkins committed
1022
      if (mbmi->mode == SPLITMV) {
John Koleszar's avatar
John Koleszar committed
1023
        int b;
John Koleszar's avatar
John Koleszar committed
1024

John Koleszar's avatar
John Koleszar committed
1025
1026
1027
1028
        for (b = 0; b < x->partition_info->count; b++) {
          inter_b_modes[x->partition_info->bmi[b].mode]++;
        }
      }
John Koleszar's avatar
John Koleszar committed
1029
1030
1031

#endif

John Koleszar's avatar
John Koleszar committed
1032
1033
1034
1035
1036
      // If we have just a single reference frame coded for a segment then
      // exclude from the reference frame counts used to work out
      // probabilities. NOTE: At the moment we dont support custom trees
      // for the reference frame coding for each segment but this is a
      // possible future action.
Paul Wilkins's avatar
Paul Wilkins committed
1037
      segment_id = &mbmi->segment_id;
John Koleszar's avatar
John Koleszar committed
1038
1039
1040
1041
1042
1043
1044
      seg_ref_active = segfeature_active(xd, *segment_id, SEG_LVL_REF_FRAME);
      if (!seg_ref_active ||
          ((check_segref(xd, *segment_id, INTRA_FRAME) +
            check_segref(xd, *segment_id, LAST_FRAME) +
            check_segref(xd, *segment_id, GOLDEN_FRAME) +
            check_segref(xd, *segment_id, ALTREF_FRAME)) > 1)) {
        {
Paul Wilkins's avatar
Paul Wilkins committed
1045
          cpi->count_mb_ref_frame_usage[mbmi->ref_frame]++;
John Koleszar's avatar
John Koleszar committed
1046
        }
John Koleszar's avatar
John Koleszar committed
1047
      }
John Koleszar's avatar
John Koleszar committed
1048

John Koleszar's avatar
John Koleszar committed
1049
      // Count of last ref frame 0,0 usage
Paul Wilkins's avatar
Paul Wilkins committed
1050
      if ((mbmi->mode == ZEROMV) && (mbmi->ref_frame == LAST_FRAME))
John Koleszar's avatar
John Koleszar committed
1051
1052
        cpi->inter_zz_count++;
    }
John Koleszar's avatar
John Koleszar committed
1053

Ronald S. Bultje's avatar
Ronald S. Bultje committed
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
#if CONFIG_SUPERBLOCKS
    if (xd->mode_info_context->mbmi.encoded_as_sb) {
      x->src.y_buffer += 32;
      x->src.u_buffer += 16;
      x->src.v_buffer += 16;

      x->gf_active_ptr      += 2;
      x->partition_info     += 2;
      xd->mode_info_context += 2;
      xd->prev_mode_info_context += 2;
      
1065
1066
      (*tp)->Token = EOSB_TOKEN;
      (*tp)++;
1067
      if (mb_row < cm->mb_rows) cpi->tplist[mb_row].stop = *tp;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1068
1069
1070
      break;
    }
#endif
John Koleszar's avatar
John Koleszar committed
1071

John Koleszar's avatar
John Koleszar committed
1072
1073
1074
    // Next MB
    mb_row += dy;
    mb_col += dx;
John Koleszar's avatar
John Koleszar committed
1075

John Koleszar's avatar
John Koleszar committed
1076
1077
1078
1079
1080
1081
1082
1083
    x->src.y_buffer += 16 * (dx + dy * x->src.y_stride);
    x->src.u_buffer += 8  * (dx + dy * x->src.uv_stride);
    x->src.v_buffer += 8  * (dx + dy * x->src.uv_stride);

    x->gf_active_ptr      += offset_unextended;
    x->partition_info     += offset_extended;
    xd->mode_info_context += offset_extended;
    xd->prev_mode_info_context += offset_extended;
1084

Adrian Grange's avatar
Adrian Grange committed
1085
#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
1086
1087
    assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
           (xd->mode_info_context - cpi->common.mip));
Adrian Grange's avatar
Adrian Grange committed
1088
#endif
1089
1090
    (*tp)->Token = EOSB_TOKEN;
    (*tp)++;
1091
    if (mb_row < cm->mb_rows) cpi->tplist[mb_row].stop = *tp;
John Koleszar's avatar
John Koleszar committed
1092
  }
John Koleszar's avatar
John Koleszar committed
1093

John Koleszar's avatar
John Koleszar committed
1094
  // debug output
Adrian Grange's avatar
Adrian Grange committed
1095
#if DBG_PRNT_SEGMAP
John Koleszar's avatar
John Koleszar committed
1096
1097
1098
1099
1100
1101
1102
  {
    FILE *statsfile;
    statsfile = fopen("segmap2.stt", "a");
    fprintf(statsfile, "\n");
    fclose(statsfile);
  }
#endif
Adrian Grange's avatar
Adrian Grange committed
1103
}
John Koleszar's avatar
John Koleszar committed
1104

Adrian Grange's avatar
Adrian Grange committed
1105
static
John Koleszar's avatar
John Koleszar committed
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
void encode_sb_row(VP8_COMP *cpi,
                   VP8_COMMON *cm,
                   int mb_row,
                   MACROBLOCK  *x,
                   MACROBLOCKD *xd,
                   TOKENEXTRA **tp,
                   int *totalrate) {
  int mb_col;
  int mb_cols = cm->mb_cols;

  // Initialize the left context for the new SB row
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1117
  vpx_memset(cm->left_context, 0, sizeof(cm->left_context));
John Koleszar's avatar
John Koleszar committed
1118
1119
1120

  // Code each SB in the row
  for (mb_col = 0; mb_col < mb_cols; mb_col += 2) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1121
    int mb_rate = 0, mb_dist = 0;
Adrian Grange's avatar
Adrian Grange committed
1122
#if CONFIG_SUPERBLOCKS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1123
    int sb_rate = INT_MAX, sb_dist;
Adrian Grange's avatar
Adrian Grange committed
1124
1125
1126
#endif

#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
1127
1128
1129
1130
1131
1132
    MODE_INFO *mic = xd->mode_info_context;
    PARTITION_INFO *pi = x->partition_info;
    signed char  *gfa = x->gf_active_ptr;
    unsigned char *yb = x->src.y_buffer;
    unsigned char *ub = x->src.u_buffer;
    unsigned char *vb = x->src.v_buffer;
Adrian Grange's avatar
Adrian Grange committed
1133
1134
#endif

Ronald S. Bultje's avatar
Ronald S. Bultje committed
1135
#if CONFIG_SUPERBLOCKS
John Koleszar's avatar
John Koleszar committed
1136
    // Pick modes assuming the SB is coded as 4 independent MBs
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1137
1138
1139
1140
1141
1142
    xd->mode_info_context->mbmi.encoded_as_sb = 0;
#endif
    pick_mb_modes(cpi, cm, mb_row, mb_col, x, xd, tp, &mb_rate, &mb_dist);
#if CONFIG_SUPERBLOCKS
    mb_rate += vp8_cost_bit(cm->sb_coded, 0);
#endif
Adrian Grange's avatar
Adrian Grange committed
1143

John Koleszar's avatar
John Koleszar committed
1144
1145
1146
    x->src.y_buffer -= 32;
    x->src.u_buffer -= 16;
    x->src.v_buffer -= 16;
Adrian Grange's avatar
Adrian Grange committed
1147

John Koleszar's avatar
John Koleszar committed
1148
1149
1150
1151
    x->gf_active_ptr -= 2;
    x->partition_info -= 2;
    xd->mode_info_context -= 2;
    xd->prev_mode_info_context -= 2;
Adrian Grange's avatar
Adrian Grange committed
1152
1153

#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
1154
1155
1156
1157
1158
1159
    assert(x->gf_active_ptr == gfa);
    assert(x->partition_info == pi);
    assert(xd->mode_info_context == mic);
    assert(x->src.y_buffer == yb);
    assert(x->src.u_buffer == ub);
    assert(x->src.v_buffer == vb);
Adrian Grange's avatar
Adrian Grange committed
1160
1161
1162
#endif

#if CONFIG_SUPERBLOCKS
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1163
1164
1165
1166
1167
1168
1169
    if (!(((    mb_cols & 1) && mb_col ==     mb_cols - 1) ||
          ((cm->mb_rows & 1) && mb_row == cm->mb_rows - 1))) {
      /* Pick a mode assuming that it applies to all 4 of the MBs in the SB */
      xd->mode_info_context->mbmi.encoded_as_sb = 1;
      pick_sb_modes(cpi, cm, mb_row, mb_col, x, xd, tp, &sb_rate, &sb_dist);
      sb_rate += vp8_cost_bit(cm->sb_coded, 1);
    }
John Koleszar's avatar
John Koleszar committed
1170

Ronald S. Bultje's avatar
Ronald S. Bultje committed
1171
1172
1173
1174
1175
1176
1177
1178
    /* Decide whether to encode as a SB or 4xMBs */
    if (sb_rate < INT_MAX &&
        RDCOST(x->rdmult, x->rddiv, sb_rate, sb_dist) <
          RDCOST(x->rdmult, x->rddiv, mb_rate, mb_dist)) {
      xd->mode_info_context->mbmi.encoded_as_sb = 1;
      xd->mode_info_context[1].mbmi.encoded_as_sb = 1;
      xd->mode_info_context[cm->mode_info_stride].mbmi.encoded_as_sb = 1;
      xd->mode_info_context[1 + cm->mode_info_stride].mbmi.encoded_as_sb = 1;
John Koleszar's avatar
John Koleszar committed
1179
1180
      *totalrate += sb_rate;
    } else
Adrian Grange's avatar
Adrian Grange committed
1181
#endif
John Koleszar's avatar
John Koleszar committed
1182
    {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
#if CONFIG_SUPERBLOCKS
      xd->mode_info_context->mbmi.encoded_as_sb = 0;
      if (cm->mb_cols - 1 > mb_col)
        xd->mode_info_context[1].mbmi.encoded_as_sb = 0;
      if (cm->mb_rows - 1 > mb_row) {
        xd->mode_info_context[cm->mode_info_stride].mbmi.encoded_as_sb = 0;
        if (cm->mb_cols - 1 > mb_col)
          xd->mode_info_context[1 + cm->mode_info_stride].mbmi.encoded_as_sb = 0;
      }
#endif
John Koleszar's avatar
John Koleszar committed
1193
1194
      *totalrate += mb_rate;
    }
Adrian Grange's avatar
Adrian Grange committed
1195

Ronald S. Bultje's avatar
Ronald S. Bultje committed
1196
    /* Encode SB using best computed mode(s) */
John Koleszar's avatar
John Koleszar committed
1197
    encode_sb(cpi, cm, mb_row, mb_col, x, xd, tp);
Adrian Grange's avatar
Adrian Grange committed
1198
1199

#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
1200
1201
1202
1203
1204
1205
    assert(x->gf_active_ptr == gfa + 2);
    assert(x->partition_info == pi + 2);
    assert(xd->mode_info_context == mic + 2);
    assert(x->src.y_buffer == yb + 32);
    assert(x->src.u_buffer == ub + 16);
    assert(x->src.v_buffer == vb + 16);
Adrian Grange's avatar
Adrian Grange committed
1206
#endif
John Koleszar's avatar
John Koleszar committed
1207
  }
Adrian Grange's avatar
Adrian Grange committed
1208

John Koleszar's avatar
John Koleszar committed
1209
1210
1211
1212
1213
  // this is to account for the border
  x->gf_active_ptr += mb_cols - (mb_cols & 0x1);
  x->partition_info += xd->mode_info_stride + 1 - (mb_cols & 0x1);
  xd->mode_info_context += xd->mode_info_stride + 1 - (mb_cols & 0x1);
  xd->prev_mode_info_context += xd->mode_info_stride + 1 - (mb_cols & 0x1);
Adrian Grange's avatar
Adrian Grange committed
1214
1215

#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
1216
1217
  assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
         (xd->mode_info_context - cpi->common.mip));