encodeframe.c 55.7 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"
John Koleszar's avatar
John Koleszar committed
24
#include "rdopt.h"
John Koleszar's avatar
John Koleszar committed
25
26
#include "vp8/common/findnearmv.h"
#include "vp8/common/reconintra.h"
Christian Duvivier's avatar
Christian Duvivier committed
27
#include "vp8/common/seg_common.h"
John Koleszar's avatar
John Koleszar committed
28
#include <stdio.h>
29
#include <math.h>
John Koleszar's avatar
John Koleszar committed
30
#include <limits.h>
John Koleszar's avatar
John Koleszar committed
31
#include "vp8/common/subpixel.h"
John Koleszar's avatar
John Koleszar committed
32
#include "vpx_ports/vpx_timer.h"
33
#include "vp8/common/pred_common.h"
John Koleszar's avatar
John Koleszar committed
34

John Koleszar's avatar
John Koleszar committed
35
// #define DBG_PRNT_SEGMAP 1
36

John Koleszar's avatar
John Koleszar committed
37
38
39
40
41
42
43
#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
44

45
#ifdef ENC_DEBUG
John Koleszar's avatar
John Koleszar committed
46
int enc_debug = 0;
47
48
49
int mb_row_debug, mb_col_debug;
#endif

John Koleszar's avatar
John Koleszar committed
50
extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t);
John Koleszar's avatar
John Koleszar committed
51
52
53
54
55
56
57
58

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);
Adrian Grange's avatar
Adrian Grange committed
59
60
61
extern int vp8cx_pick_mode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x,
                                            int recon_yoffset,
                                            int recon_uvoffset);
John Koleszar's avatar
John Koleszar committed
62
63
void vp8_build_block_offsets(MACROBLOCK *x);
void vp8_setup_block_ptrs(MACROBLOCK *x);
Adrian Grange's avatar
Adrian Grange committed
64
65
66
67
68
void vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
                                   int recon_yoffset, int recon_uvoffset,
                                   int output_enabled);
void vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x,
                                    TOKENEXTRA **t, int output_enabled);
John Koleszar's avatar
John Koleszar committed
69
static void adjust_act_zbin(VP8_COMP *cpi, MACROBLOCK *x);
John Koleszar's avatar
John Koleszar committed
70

71
72


John Koleszar's avatar
John Koleszar committed
73
#ifdef MODE_STATS
74
75
76
77
78
79
80
81
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
82
83
84
#endif


85
86
87
88
89
90
91
92
93
94
95
96
/* 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
97
98
static const unsigned char VP8_VAR_OFFS[16] = {
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
99
100
};

101
102

// Original activity measure from Tim T's code.
John Koleszar's avatar
John Koleszar committed
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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;
122
123
}

124
// Stub for alternative experimental activity measures.
John Koleszar's avatar
John Koleszar committed
125
126
127
static unsigned int alt_activity_measure(VP8_COMP *cpi,
                                         MACROBLOCK *x, int use_dc_pred) {
  return vp8_encode_intra(cpi, x, use_dc_pred);
128
129
130
131
132
}


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

John Koleszar's avatar
John Koleszar committed
138
139
  if (ALT_ACT_MEASURE) {
    int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
140

John Koleszar's avatar
John Koleszar committed
141
142
143
144
145
146
    // 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);
  }
147

John Koleszar's avatar
John Koleszar committed
148
149
  if (mb_activity < VP8_ACTIVITY_AVG_MIN)
    mb_activity = VP8_ACTIVITY_AVG_MIN;
150

John Koleszar's avatar
John Koleszar committed
151
  return mb_activity;
152
153
154
}

// Calculate an "average" mb activity value for the frame
155
#define ACT_MEDIAN 0
John Koleszar's avatar
John Koleszar committed
156
static void calc_av_activity(VP8_COMP *cpi, int64_t activity_sum) {
157
#if ACT_MEDIAN
John Koleszar's avatar
John Koleszar committed
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
  // 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;
      }
    }
187

John Koleszar's avatar
John Koleszar committed
188
189
190
    // 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;
191

John Koleszar's avatar
John Koleszar committed
192
    cpi->activity_avg = median;
193

John Koleszar's avatar
John Koleszar committed
194
195
    vpx_free(sortlist);
  }
196
#else
John Koleszar's avatar
John Koleszar committed
197
198
  // Simple mean for now
  cpi->activity_avg = (unsigned int)(activity_sum / cpi->common.MBs);
199
200
#endif

John Koleszar's avatar
John Koleszar committed
201
202
  if (cpi->activity_avg < VP8_ACTIVITY_AVG_MIN)
    cpi->activity_avg = VP8_ACTIVITY_AVG_MIN;
203

John Koleszar's avatar
John Koleszar committed
204
205
206
  // Experimental code: return fixed value normalized for several clips
  if (ALT_ACT_MEASURE)
    cpi->activity_avg = 100000;
207
208
}

209
#define USE_ACT_INDEX   0
210
#define OUTPUT_NORM_ACT_STATS   0
211
212
213

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

John Koleszar's avatar
John Koleszar committed
218
219
220
  int64_t act;
  int64_t a;
  int64_t b;
221
222

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

John Koleszar's avatar
John Koleszar committed
227
228
  // Reset pointers to start of activity map
  x->mb_activity_ptr = cpi->mb_activity_map;
229

John Koleszar's avatar
John Koleszar committed
230
231
232
233
234
235
  // 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);
236

John Koleszar's avatar
John Koleszar committed
237
238
239
      // Calculate a normalized activity number
      a = act + 4 * cpi->activity_avg;
      b = 4 * act + cpi->activity_avg;
240

John Koleszar's avatar
John Koleszar committed
241
242
243
244
      if (b >= a)
        *(x->activity_ptr) = (int)((b + (a >> 1)) / a) - 1;
      else
        *(x->activity_ptr) = 1 - (int)((a + (b >> 1)) / b);
245
246

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
247
      fprintf(f, " %6d", *(x->mb_activity_ptr));
248
#endif
John Koleszar's avatar
John Koleszar committed
249
250
251
      // Increment activity map pointers
      x->mb_activity_ptr++;
    }
252
253

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
254
    fprintf(f, "\n");
255
256
#endif

John Koleszar's avatar
John Koleszar committed
257
  }
258
259

#if OUTPUT_NORM_ACT_STATS
John Koleszar's avatar
John Koleszar committed
260
  fclose(f);
261
262
263
#endif

}
264
#endif
265
266
267

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

273
#if ALT_ACT_MEASURE
John Koleszar's avatar
John Koleszar committed
274
275
276
  YV12_BUFFER_CONFIG *new_yv12 = &cm->yv12_fb[cm->new_fb_idx];
  int recon_yoffset;
  int recon_y_stride = new_yv12->y_stride;
277
278
#endif

John Koleszar's avatar
John Koleszar committed
279
280
281
  int mb_row, mb_col;
  unsigned int mb_activity;
  int64_t activity_sum = 0;
282

John Koleszar's avatar
John Koleszar committed
283
284
  // for each macroblock row in image
  for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
285
#if ALT_ACT_MEASURE
John Koleszar's avatar
John Koleszar committed
286
287
288
    // reset above block coeffs
    xd->up_available = (mb_row != 0);
    recon_yoffset = (mb_row * recon_y_stride * 16);
289
#endif
John Koleszar's avatar
John Koleszar committed
290
291
    // for each macroblock col in image
    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
292
#if ALT_ACT_MEASURE
John Koleszar's avatar
John Koleszar committed
293
294
295
      xd->dst.y_buffer = new_yv12->y_buffer + recon_yoffset;
      xd->left_available = (mb_col != 0);
      recon_yoffset += 16;
296
#endif
John Koleszar's avatar
John Koleszar committed
297
298
299
300
      // Copy current mb to a buffer
      RECON_INVOKE(&xd->rtcd->recon, copy16x16)(x->src.y_buffer,
                                                x->src.y_stride,
                                                x->thismb, 16);
301

John Koleszar's avatar
John Koleszar committed
302
303
      // measure activity
      mb_activity = mb_activity_measure(cpi, x, mb_row, mb_col);
304

John Koleszar's avatar
John Koleszar committed
305
306
      // Keep frame sum
      activity_sum += mb_activity;
307

John Koleszar's avatar
John Koleszar committed
308
309
      // Store MB level activity details.
      *x->mb_activity_ptr = mb_activity;
310

John Koleszar's avatar
John Koleszar committed
311
312
      // Increment activity map pointer
      x->mb_activity_ptr++;
313

John Koleszar's avatar
John Koleszar committed
314
315
316
      // adjust to the next column of source macroblocks
      x->src.y_buffer += 16;
    }
317

318

John Koleszar's avatar
John Koleszar committed
319
320
    // adjust to the next row of mbs
    x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
321
322

#if ALT_ACT_MEASURE
John Koleszar's avatar
John Koleszar committed
323
324
325
    // 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);
326
327
#endif

John Koleszar's avatar
John Koleszar committed
328
  }
329

John Koleszar's avatar
John Koleszar committed
330
331
  // Calculate an "average" MB activity
  calc_av_activity(cpi, activity_sum);
332

333
#if USE_ACT_INDEX
John Koleszar's avatar
John Koleszar committed
334
335
  // Calculate an activity index number of each mb
  calc_activity_index(cpi, x);
336
337
#endif

338
339
}

340
// Macroblock activity masking
John Koleszar's avatar
John Koleszar committed
341
void vp8_activity_masking(VP8_COMP *cpi, MACROBLOCK *x) {
342
#if USE_ACT_INDEX
John Koleszar's avatar
John Koleszar committed
343
344
345
  x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2);
  x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
  x->errorperbit += (x->errorperbit == 0);
346
#else
John Koleszar's avatar
John Koleszar committed
347
348
349
  int64_t a;
  int64_t b;
  int64_t act = *(x->mb_activity_ptr);
350

John Koleszar's avatar
John Koleszar committed
351
352
353
  // Apply the masking to the RD multiplier.
  a = act + (2 * cpi->activity_avg);
  b = (2 * act) + cpi->activity_avg;
354

John Koleszar's avatar
John Koleszar committed
355
356
357
  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);
358
#endif
359

John Koleszar's avatar
John Koleszar committed
360
361
  // Activity based Zbin adjustment
  adjust_act_zbin(cpi, x);
362
}
John Koleszar's avatar
John Koleszar committed
363

John Koleszar's avatar
John Koleszar committed
364
365
366
367
368
369
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;
  int mb_mode = mi->mbmi.mode;
  int mb_mode_index = ctx->best_mode_index;
Adrian Grange's avatar
Adrian Grange committed
370
371

#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
372
373
374
  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
375
376
#endif

John Koleszar's avatar
John Koleszar committed
377
378
379
  // 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));
Adrian Grange's avatar
Adrian Grange committed
380

John Koleszar's avatar
John Koleszar committed
381
382
383
384
  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
385
    }
John Koleszar's avatar
John Koleszar committed
386
387
388
  } 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
389
    }
John Koleszar's avatar
John Koleszar committed
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
  } else if (mb_mode == SPLITMV) {
    vpx_memcpy(x->partition_info, &ctx->partition_info,
               sizeof(PARTITION_INFO));

    xd->mode_info_context->mbmi.mv.as_int =
      x->partition_info->bmi[15].mv.as_int;
    xd->mode_info_context->mbmi.second_mv.as_int =
      x->partition_info->bmi[15].second_mv.as_int;
  }

  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);
    //    }
409
#if CONFIG_INTERNAL_STATS
John Koleszar's avatar
John Koleszar committed
410
411
412
413
    static const int kf_mode_index[] = {
      THR_DC /*DC_PRED*/,
      THR_V_PRED /*V_PRED*/,
      THR_H_PRED /*H_PRED*/,
414
#if CONFIG_NEWINTRAMODES
John Koleszar's avatar
John Koleszar committed
415
416
417
418
419
420
      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*/,
421
#endif
John Koleszar's avatar
John Koleszar committed
422
423
424
425
426
      THR_TM /*TM_PRED*/,
      THR_I8X8_PRED /*I8X8_PRED*/,
      THR_B_PRED /*B_PRED*/,
    };
    cpi->mode_chosen_counts[kf_mode_index[mb_mode]]++;
427
#endif
John Koleszar's avatar
John Koleszar committed
428
429
430
431
432
433
434
  } 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
435

John Koleszar's avatar
John Koleszar committed
436
437
438
439
440
441
442
443
                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
444

John Koleszar's avatar
John Koleszar committed
445
446
447
448
            }
    */
    // Note how often each mode chosen as best
    cpi->mode_chosen_counts[mb_mode_index]++;
Adrian Grange's avatar
Adrian Grange committed
449

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

John Koleszar's avatar
John Koleszar committed
452
453
454
    cpi->prediction_error += ctx->distortion;
    cpi->intra_error += ctx->intra_error;
  }
Adrian Grange's avatar
Adrian Grange committed
455
456
}

John Koleszar's avatar
John Koleszar committed
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
static void pick_mb_modes(VP8_COMP *cpi,
                          VP8_COMMON *cm,
                          int mb_row,
                          int mb_col,
                          MACROBLOCK  *x,
                          MACROBLOCKD *xd,
                          TOKENEXTRA **tp,
                          int *totalrate) {
  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,
             cpi->left_context,
             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;

    // 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
512
#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
513
514
      assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
             (xd->mode_info_context - cpi->common.mip));
Adrian Grange's avatar
Adrian Grange committed
515
#endif
John Koleszar's avatar
John Koleszar committed
516
517
      continue;
    }
518

John Koleszar's avatar
John Koleszar committed
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
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
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
    // 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
    vpx_memcpy(&cm->left_context,
               &cpi->left_context[i >> 1],
               sizeof(ENTROPY_CONTEXT_PLANES));

    // 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
    RECON_INVOKE(&xd->rtcd->recon, copy16x16)(x->src.y_buffer,
                                              x->src.y_stride,
                                              x->thismb, 16);

    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 (cpi->segmentation_map[map_index] <= 3)
        xd->mode_info_context->mbmi.segment_id =
          cpi->segmentation_map[map_index];
      else
        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;

    /* force 4x4 transform for mode selection */
    xd->mode_info_context->mbmi.txfm_size = TX_4X4; // TODO IS this right??

    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) {
      *totalrate += vp8_rd_pick_intra_mode(cpi, x);

      // Save the coding context
      vpx_memcpy(&x->mb_context[i].mic, xd->mode_info_context,
                 sizeof(MODE_INFO));

      // 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
    } else {
      int seg_id;

      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;
      }

      *totalrate += vp8cx_pick_mode_inter_macroblock(cpi, x,
                                                     recon_yoffset,
                                                     recon_uvoffset);

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

      seg_id = xd->mode_info_context->mbmi.segment_id;
      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
644

John Koleszar's avatar
John Koleszar committed
645
646
647
648
    // Keep a copy of the updated left context
    vpx_memcpy(&cpi->left_context[i >> 1],
               &cm->left_context,
               sizeof(ENTROPY_CONTEXT_PLANES));
Adrian Grange's avatar
Adrian Grange committed
649

John Koleszar's avatar
John Koleszar committed
650
651
652
    // Next MB
    mb_row += dy;
    mb_col += dx;
Adrian Grange's avatar
Adrian Grange committed
653

John Koleszar's avatar
John Koleszar committed
654
655
656
    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
657

John Koleszar's avatar
John Koleszar committed
658
659
660
661
    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
662
663

#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
664
665
    assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
           (xd->mode_info_context - cpi->common.mip));
Adrian Grange's avatar
Adrian Grange committed
666
#endif
John Koleszar's avatar
John Koleszar committed
667
668
669
670
671
672
673
674
675
  }

  /* Restore L & A coding context to those in place on entry */
  vpx_memcpy(cpi->left_context,
             left_context,
             sizeof(left_context));
  vpx_memcpy(initial_above_context_ptr,
             above_context,
             sizeof(above_context));
Adrian Grange's avatar
Adrian Grange committed
676
677
}

John Koleszar's avatar
John Koleszar committed
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
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;

    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
719
720

#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
721
722
      assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
             (xd->mode_info_context - cpi->common.mip));
Adrian Grange's avatar
Adrian Grange committed
723
#endif
John Koleszar's avatar
John Koleszar committed
724
725
      continue;
    }
Adrian Grange's avatar
Adrian Grange committed
726

John Koleszar's avatar
John Koleszar committed
727
    xd->mb_index = i;
Adrian Grange's avatar
Adrian Grange committed
728

729
#ifdef ENC_DEBUG
John Koleszar's avatar
John Koleszar committed
730
731
732
733
    enc_debug = (cpi->common.current_video_frame == 0 &&
                 mb_row == 0 && mb_col == 0);
    mb_col_debug = mb_col;
    mb_row_debug = mb_row;
734
#endif
Adrian Grange's avatar
Adrian Grange committed
735

John Koleszar's avatar
John Koleszar committed
736
    // Restore MB state to that when it was picked
Adrian Grange's avatar
Adrian Grange committed
737
#if CONFIG_SUPERBLOCKS
John Koleszar's avatar
John Koleszar committed
738
739
740
    if (x->encode_as_sb)
      update_state(cpi, x, &x->sb_context[i]);
    else
Adrian Grange's avatar
Adrian Grange committed
741
#endif
John Koleszar's avatar
John Koleszar committed
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
      update_state(cpi, x, &x->mb_context[i]);

    // Copy in the appropriate left context
    vpx_memcpy(&cm->left_context,
               &cpi->left_context[i >> 1],
               sizeof(ENTROPY_CONTEXT_PLANES));

    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;

    // 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;

    // 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));
John Koleszar's avatar
John Koleszar committed
769

Adrian Grange's avatar
Adrian Grange committed
770
#if CONFIG_SUPERBLOCKS
John Koleszar's avatar
John Koleszar committed
771
772
773
774
775
776
777
778
    // Set up limit values for MV components to prevent them from
    // extending beyond the UMV borders assuming 32x32 block size
    x->mv_row_min_sb = -((mb_row * 16) + VP8BORDERINPIXELS - INTERP_EXTEND);
    x->mv_col_min_sb = -((mb_col * 16) + VP8BORDERINPIXELS - INTERP_EXTEND);
    x->mv_row_max_sb = ((cm->mb_rows - mb_row) * 16 +
                        (VP8BORDERINPIXELS - 32 - INTERP_EXTEND));
    x->mv_col_max_sb = ((cm->mb_cols - mb_col) * 16 +
                        (VP8BORDERINPIXELS - 32 - INTERP_EXTEND));
Adrian Grange's avatar
Adrian Grange committed
779
780
#endif

John Koleszar's avatar
John Koleszar committed
781
782
    xd->up_available = (mb_row != 0);
    xd->left_available = (mb_col != 0);
Adrian Grange's avatar
Adrian Grange committed
783

John Koleszar's avatar
John Koleszar committed
784
785
    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
786

John Koleszar's avatar
John Koleszar committed
787
788
789
    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
790

John Koleszar's avatar
John Koleszar committed
791
792
793
794
    // Copy current MB to a work buffer
    RECON_INVOKE(&xd->rtcd->recon, copy16x16)(x->src.y_buffer,
                                              x->src.y_stride,
                                              x->thismb, 16);
795

John Koleszar's avatar
John Koleszar committed
796
797
    if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
      vp8_activity_masking(cpi, x);
798

John Koleszar's avatar
John Koleszar committed
799
800
801
802
803
804
805
806
    // Is segmentation enabled
    if (xd->segmentation_enabled) {
      // Code to set segment id in xd->mbmi.segment_id
      if (cpi->segmentation_map[map_index] <= 3)
        xd->mode_info_context->mbmi.segment_id =
          cpi->segmentation_map[map_index];
      else
        xd->mode_info_context->mbmi.segment_id = 0;
John Koleszar's avatar
John Koleszar committed
807

John Koleszar's avatar
John Koleszar committed
808
809
810
811
      vp8cx_mb_init_quantizer(cpi, x);
    } else
      // Set to Segment 0 by default
      xd->mode_info_context->mbmi.segment_id = 0;
John Koleszar's avatar
John Koleszar committed
812

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

John Koleszar's avatar
John Koleszar committed
815
816
817
818
819
    cpi->update_context = 0;

    if (cm->frame_type == KEY_FRAME) {
      vp8cx_encode_intra_macro_block(cpi, x, tp, 1);
      // Note the encoder may have changed the segment_id
820

John Koleszar's avatar
John Koleszar committed
821
#ifdef MODE_STATS
John Koleszar's avatar
John Koleszar committed
822
      y_modes[xd->mode_info_context->mbmi.mode]++;
John Koleszar's avatar
John Koleszar committed
823
#endif
John Koleszar's avatar
John Koleszar committed
824
825
826
    } else {
      unsigned char *segment_id;
      int seg_ref_active;
827

John Koleszar's avatar
John Koleszar committed
828
829
830
      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
831
832

#ifdef MODE_STATS
John Koleszar's avatar
John Koleszar committed
833
      inter_y_modes[xd->mode_info_context->mbmi.mode]++;
John Koleszar's avatar
John Koleszar committed
834

John Koleszar's avatar
John Koleszar committed
835
836
      if (xd->mode_info_context->mbmi.mode == SPLITMV) {
        int b;
John Koleszar's avatar
John Koleszar committed
837

John Koleszar's avatar
John Koleszar committed
838
839
840
841
        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
842
843
844

#endif

John Koleszar's avatar
John Koleszar committed
845
846
847
848
849
850
851
852
853
854
855
856
      // 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.
      segment_id = &xd->mode_info_context->mbmi.segment_id;
      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)) {
857
858
859
// TODO this may not be a good idea as it makes sample size small and means
// the predictor functions cannot use data about most likely value only most
// likely unpredicted value.
John Koleszar's avatar
John Koleszar committed
860
// #if CONFIG_COMPRED
861
862
//        // Only update count for incorrectly predicted cases
//        if ( !ref_pred_flag )
John Koleszar's avatar
John Koleszar committed
863
864
865
866
// #endif
        {
          cpi->count_mb_ref_frame_usage
          [xd->mode_info_context->mbmi.ref_frame]++;
John Koleszar's avatar
John Koleszar committed
867
        }
John Koleszar's avatar
John Koleszar committed
868
      }
John Koleszar's avatar
John Koleszar committed
869

John Koleszar's avatar
John Koleszar committed
870
871
872
873
874
      // Count of last ref frame 0,0 usage
      if ((xd->mode_info_context->mbmi.mode == ZEROMV) &&
          (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME))
        cpi->inter_zz_count++;
    }
John Koleszar's avatar
John Koleszar committed
875

John Koleszar's avatar
John Koleszar committed
876
877
    // TODO Partitioning is broken!
    cpi->tplist[mb_row].stop = *tp;
John Koleszar's avatar
John Koleszar committed
878

John Koleszar's avatar
John Koleszar committed
879
880
881
882
    // Copy back updated left context
    vpx_memcpy(&cpi->left_context[i >> 1],
               &cm->left_context,
               sizeof(ENTROPY_CONTEXT_PLANES));
John Koleszar's avatar
John Koleszar committed
883

John Koleszar's avatar
John Koleszar committed
884
885
886
    // Next MB
    mb_row += dy;
    mb_col += dx;
John Koleszar's avatar
John Koleszar committed
887

John Koleszar's avatar
John Koleszar committed
888
889
890
891
892
893
894
895
    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;
896

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

John Koleszar's avatar
John Koleszar committed
903
  // debug output
Adrian Grange's avatar
Adrian Grange committed
904
#if DBG_PRNT_SEGMAP
John Koleszar's avatar
John Koleszar committed
905
906
907
908
909
910
911
  {
    FILE *statsfile;
    statsfile = fopen("segmap2.stt", "a");
    fprintf(statsfile, "\n");
    fclose(statsfile);
  }
#endif
Adrian Grange's avatar
Adrian Grange committed
912
}
John Koleszar's avatar
John Koleszar committed
913

Adrian Grange's avatar
Adrian Grange committed
914
static
John Koleszar's avatar
John Koleszar committed
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
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
  vpx_memset(cpi->left_context, 0, sizeof(cpi->left_context));
  vpx_memset(&cm->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));

  // Code each SB in the row
  for (mb_col = 0; mb_col < mb_cols; mb_col += 2) {
    int mb_rate = 0;
Adrian Grange's avatar
Adrian Grange committed
932
#if CONFIG_SUPERBLOCKS
John Koleszar's avatar
John Koleszar committed
933
    int sb_rate = INT_MAX;
Adrian Grange's avatar
Adrian Grange committed
934
935
936
#endif

#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
937
938
939
940
941
942
    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
943
944
#endif

John Koleszar's avatar
John Koleszar committed
945
946
    // Pick modes assuming the SB is coded as 4 independent MBs
    pick_mb_modes(cpi, cm, mb_row, mb_col, x, xd, tp, &mb_rate);
Adrian Grange's avatar
Adrian Grange committed
947

John Koleszar's avatar
John Koleszar committed
948
949
950
    x->src.y_buffer -= 32;
    x->src.u_buffer -= 16;
    x->src.v_buffer -= 16;
Adrian Grange's avatar
Adrian Grange committed
951

John Koleszar's avatar
John Koleszar committed
952
953
954
955
    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
956
957

#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
958
959
960
961
962
963
    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
964
965
966
#endif

#if CONFIG_SUPERBLOCKS
John Koleszar's avatar
John Koleszar committed
967
968
969
970
971
972
973
974
    // Pick a mode assuming that it applies all 4 of the MBs in the SB
    pick_sb_modes(cpi, cm, mb_row, mb_col, x, xd, &sb_rate);

    // Decide whether to encode as a SB or 4xMBs
    if (sb_rate < mb_rate) {
      x->encode_as_sb = 1;
      *totalrate += sb_rate;
    } else
Adrian Grange's avatar
Adrian Grange committed
975
#endif
John Koleszar's avatar
John Koleszar committed
976
977
978
979
    {
      x->encode_as_sb = 0;
      *totalrate += mb_rate;
    }
Adrian Grange's avatar
Adrian Grange committed
980

John Koleszar's avatar
John Koleszar committed
981
982
    // Encode SB using best computed mode(s)
    encode_sb(cpi, cm, mb_row, mb_col, x, xd, tp);
Adrian Grange's avatar
Adrian Grange committed
983
984

#if CONFIG_DEBUG
John Koleszar's avatar
John Koleszar committed
985
986
987
988
989
990
    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
991
#endif
John Koleszar's avatar
John Koleszar committed
992
  }
Adrian Grange's avatar
Adrian Grange committed
993

John Koleszar's avatar
John Koleszar committed
994
995
996
997
998
  // 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
999
1000

#if CONFIG_DEBUG
For faster browsing, not all history is shown. View entire blame