rdopt.c 143 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
15
 */


#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <assert.h>
John Koleszar's avatar
John Koleszar committed
16
#include "vp8/common/pragmas.h"
John Koleszar's avatar
John Koleszar committed
17
18
19
20
21
22

#include "tokenize.h"
#include "treewriter.h"
#include "onyx_int.h"
#include "modecosts.h"
#include "encodeintra.h"
John Koleszar's avatar
John Koleszar committed
23
24
25
26
27
#include "vp8/common/entropymode.h"
#include "vp8/common/reconinter.h"
#include "vp8/common/reconintra.h"
#include "vp8/common/reconintra4x4.h"
#include "vp8/common/findnearmv.h"
Christian Duvivier's avatar
Christian Duvivier committed
28
#include "vp8/common/quant_common.h"
John Koleszar's avatar
John Koleszar committed
29
30
#include "encodemb.h"
#include "quantize.h"
John Koleszar's avatar
John Koleszar committed
31
32
#include "vp8/common/idct.h"
#include "vp8/common/g_common.h"
John Koleszar's avatar
John Koleszar committed
33
34
#include "variance.h"
#include "mcomp.h"
Yunqing Wang's avatar
Yunqing Wang committed
35
#include "rdopt.h"
Paul Wilkins's avatar
Paul Wilkins committed
36
#include "ratectrl.h"
John Koleszar's avatar
John Koleszar committed
37
38
#include "vpx_mem/vpx_mem.h"
#include "dct.h"
John Koleszar's avatar
John Koleszar committed
39
#include "vp8/common/systemdependent.h"
John Koleszar's avatar
John Koleszar committed
40

41
#include "vp8/common/seg_common.h"
42
#include "vp8/common/pred_common.h"
43

John Koleszar's avatar
John Koleszar committed
44
45
46
47
48
49
#if CONFIG_RUNTIME_CPU_DETECT
#define IF_RTCD(x)  (x)
#else
#define IF_RTCD(x)  NULL
#endif

Scott LaVarnway's avatar
Scott LaVarnway committed
50
51
52
extern void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x);
extern void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x);

53
54
55
56
57
58
#if CONFIG_HIGH_PRECISION_MV
#define XMVCOST (x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost)
#else
#define XMVCOST (x->mvcost)
#endif

John Koleszar's avatar
John Koleszar committed
59
60
#define MAXF(a,b)            (((a) > (b)) ? (a) : (b))

61
62
#define INVALID_MV 0x80008000

63
static const int auto_speed_thresh[17] =
John Koleszar's avatar
John Koleszar committed
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
{
    1000,
    200,
    150,
    130,
    150,
    125,
    120,
    115,
    115,
    115,
    115,
    115,
    115,
    115,
    115,
    115,
    105
};

84
85
#if CONFIG_PRED_FILTER
const MODE_DEFINITION vp8_mode_order[MAX_MODES] =
John Koleszar's avatar
John Koleszar committed
86
{
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    {ZEROMV,    LAST_FRAME,   0,  0},
    {ZEROMV,    LAST_FRAME,   0,  1},
    {DC_PRED,   INTRA_FRAME,  0,  0},

    {NEARESTMV, LAST_FRAME,   0,  0},
    {NEARESTMV, LAST_FRAME,   0,  1},
    {NEARMV,    LAST_FRAME,   0,  0},
    {NEARMV,    LAST_FRAME,   0,  1},

    {ZEROMV,    GOLDEN_FRAME, 0,  0},
    {ZEROMV,    GOLDEN_FRAME, 0,  1},
    {NEARESTMV, GOLDEN_FRAME, 0,  0},
    {NEARESTMV, GOLDEN_FRAME, 0,  1},

    {ZEROMV,    ALTREF_FRAME, 0,  0},
    {ZEROMV,    ALTREF_FRAME, 0,  1},
    {NEARESTMV, ALTREF_FRAME, 0,  0},
    {NEARESTMV, ALTREF_FRAME, 0,  1},

    {NEARMV,    GOLDEN_FRAME, 0,  0},
    {NEARMV,    GOLDEN_FRAME, 0,  1},
    {NEARMV,    ALTREF_FRAME, 0,  0},
    {NEARMV,    ALTREF_FRAME, 0,  1},

    {V_PRED,    INTRA_FRAME,  0,  0},
    {H_PRED,    INTRA_FRAME,  0,  0},
113
#if CONFIG_NEWINTRAMODES
114
115
116
117
118
119
    {D45_PRED,	INTRA_FRAME,  0,  0},
    {D135_PRED,	INTRA_FRAME,  0,  0},
    {D117_PRED,	INTRA_FRAME,  0,  0},
    {D153_PRED,	INTRA_FRAME,  0,  0},
    {D27_PRED,	INTRA_FRAME,  0,  0},
    {D63_PRED,	INTRA_FRAME,  0,  0},
120
#endif
John Koleszar's avatar
John Koleszar committed
121

122
    {TM_PRED,   INTRA_FRAME,  0,  0},
John Koleszar's avatar
John Koleszar committed
123

124
125
126
127
128
129
    {NEWMV,     LAST_FRAME,   0,  0},
    {NEWMV,     LAST_FRAME,   0,  1},
    {NEWMV,     GOLDEN_FRAME, 0,  0},
    {NEWMV,     GOLDEN_FRAME, 0,  1},
    {NEWMV,     ALTREF_FRAME, 0,  0},
    {NEWMV,     ALTREF_FRAME, 0,  1},
John Koleszar's avatar
John Koleszar committed
130

131
132
133
134
135
136
    {SPLITMV,   LAST_FRAME,   0,  0},
    {SPLITMV,   GOLDEN_FRAME, 0,  0},
    {SPLITMV,   ALTREF_FRAME, 0,  0},

    {B_PRED,    INTRA_FRAME,  0,  0},
    {I8X8_PRED, INTRA_FRAME,  0,  0},
137

138
    /* compound prediction modes */
139
140
141
    {ZEROMV,    LAST_FRAME,   GOLDEN_FRAME, 0},
    {NEARESTMV, LAST_FRAME,   GOLDEN_FRAME, 0},
    {NEARMV,    LAST_FRAME,   GOLDEN_FRAME, 0},
142

143
144
145
    {ZEROMV,    ALTREF_FRAME, LAST_FRAME,   0},
    {NEARESTMV, ALTREF_FRAME, LAST_FRAME,   0},
    {NEARMV,    ALTREF_FRAME, LAST_FRAME,   0},
146

147
148
149
    {ZEROMV,    GOLDEN_FRAME, ALTREF_FRAME, 0},
    {NEARESTMV, GOLDEN_FRAME, ALTREF_FRAME, 0},
    {NEARMV,    GOLDEN_FRAME, ALTREF_FRAME, 0},
150

151
152
153
    {NEWMV,     LAST_FRAME,   GOLDEN_FRAME, 0},
    {NEWMV,     ALTREF_FRAME, LAST_FRAME,   0},
    {NEWMV,     GOLDEN_FRAME, ALTREF_FRAME, 0},
154

155
156
157
    {SPLITMV,   LAST_FRAME,   GOLDEN_FRAME, 0},
    {SPLITMV,   ALTREF_FRAME, LAST_FRAME,   0},
    {SPLITMV,   GOLDEN_FRAME, ALTREF_FRAME, 0}
John Koleszar's avatar
John Koleszar committed
158
};
159
160
#else
const MODE_DEFINITION vp8_mode_order[MAX_MODES] =
John Koleszar's avatar
John Koleszar committed
161
{
162
163
    {ZEROMV,    LAST_FRAME,   0},
    {DC_PRED,   INTRA_FRAME,  0},
John Koleszar's avatar
John Koleszar committed
164

165
166
    {NEARESTMV, LAST_FRAME,   0},
    {NEARMV,    LAST_FRAME,   0},
John Koleszar's avatar
John Koleszar committed
167

168
169
    {ZEROMV,    GOLDEN_FRAME, 0},
    {NEARESTMV, GOLDEN_FRAME, 0},
John Koleszar's avatar
John Koleszar committed
170

171
172
    {ZEROMV,    ALTREF_FRAME, 0},
    {NEARESTMV, ALTREF_FRAME, 0},
John Koleszar's avatar
John Koleszar committed
173

174
175
    {NEARMV,    GOLDEN_FRAME, 0},
    {NEARMV,    ALTREF_FRAME, 0},
John Koleszar's avatar
John Koleszar committed
176

177
178
    {V_PRED,    INTRA_FRAME,  0},
    {H_PRED,    INTRA_FRAME,  0},
179
#if CONFIG_NEWINTRAMODES
180
181
182
183
184
185
    {D45_PRED,  INTRA_FRAME,  0},
    {D135_PRED, INTRA_FRAME,  0},
    {D117_PRED, INTRA_FRAME,  0},
    {D153_PRED, INTRA_FRAME,  0},
    {D27_PRED,  INTRA_FRAME,  0},
    {D63_PRED,  INTRA_FRAME,  0},
186
#endif
John Koleszar's avatar
John Koleszar committed
187

188
    {TM_PRED,   INTRA_FRAME,  0},
John Koleszar's avatar
John Koleszar committed
189

190
191
192
    {NEWMV,     LAST_FRAME,   0},
    {NEWMV,     GOLDEN_FRAME, 0},
    {NEWMV,     ALTREF_FRAME, 0},
John Koleszar's avatar
John Koleszar committed
193

194
195
196
    {SPLITMV,   LAST_FRAME,   0},
    {SPLITMV,   GOLDEN_FRAME, 0},
    {SPLITMV,   ALTREF_FRAME, 0},
197

198
199
    {B_PRED,    INTRA_FRAME,  0},
    {I8X8_PRED, INTRA_FRAME,  0},
200

201
    /* compound prediction modes */
202
203
204
    {ZEROMV,    LAST_FRAME,   GOLDEN_FRAME},
    {NEARESTMV, LAST_FRAME,   GOLDEN_FRAME},
    {NEARMV,    LAST_FRAME,   GOLDEN_FRAME},
205

206
207
208
    {ZEROMV,    ALTREF_FRAME, LAST_FRAME},
    {NEARESTMV, ALTREF_FRAME, LAST_FRAME},
    {NEARMV,    ALTREF_FRAME, LAST_FRAME},
209

210
211
212
    {ZEROMV,    GOLDEN_FRAME, ALTREF_FRAME},
    {NEARESTMV, GOLDEN_FRAME, ALTREF_FRAME},
    {NEARMV,    GOLDEN_FRAME, ALTREF_FRAME},
213

214
215
216
    {NEWMV,     LAST_FRAME,   GOLDEN_FRAME},
    {NEWMV,     ALTREF_FRAME, LAST_FRAME  },
    {NEWMV,     GOLDEN_FRAME, ALTREF_FRAME},
217

218
219
220
    {SPLITMV,   LAST_FRAME,   GOLDEN_FRAME},
    {SPLITMV,   ALTREF_FRAME, LAST_FRAME  },
    {SPLITMV,   GOLDEN_FRAME, ALTREF_FRAME}
John Koleszar's avatar
John Koleszar committed
221
};
222
#endif
John Koleszar's avatar
John Koleszar committed
223
224

static void fill_token_costs(
225
226
227
    unsigned int (*c)[COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS],
    const vp8_prob (*p)[COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES],
    int block_type_counts)
John Koleszar's avatar
John Koleszar committed
228
229
230
{
    int i, j, k;

231
    for (i = 0; i < block_type_counts; i++)
John Koleszar's avatar
John Koleszar committed
232
233
        for (j = 0; j < COEF_BANDS; j++)
            for (k = 0; k < PREV_COEF_CONTEXTS; k++)
234
235
            {
                if(k == 0 && ((j > 0 && i > 0) || (j > 1 && i == 0)))
236
237
238
                    vp8_cost_tokens_skip((int *)( c [i][j][k]),
                                                  p [i][j][k],
                                                  vp8_coef_tree);
239
                else
240
241
242
                    vp8_cost_tokens((int *)(c [i][j][k]),
                                            p [i][j][k],
                                            vp8_coef_tree);
243
            }
John Koleszar's avatar
John Koleszar committed
244
245
}

246

Paul Wilkins's avatar
Paul Wilkins committed
247
static int rd_iifactor [ 32 ] =  {    4,   4,   3,   2,   1,   0,   0,   0,
John Koleszar's avatar
John Koleszar committed
248
249
250
251
252
                                      0,   0,   0,   0,   0,   0,   0,   0,
                                      0,   0,   0,   0,   0,   0,   0,   0,
                                      0,   0,   0,   0,   0,   0,   0,   0,
                                 };

253
// 3* dc_qlookup[Q]*dc_qlookup[Q];
254

255
/* values are now correlated to quantizer */
Paul Wilkins's avatar
Paul Wilkins committed
256
257
258
259
static int sad_per_bit16lut[QINDEX_RANGE];
static int sad_per_bit4lut[QINDEX_RANGE];

void vp8_init_me_luts()
John Koleszar's avatar
John Koleszar committed
260
{
Paul Wilkins's avatar
Paul Wilkins committed
261
262
263
264
265
266
267
268
269
270
271
272
    int i;

    // Initialize the sad lut tables using a formulaic calculation for now
    // This is to make it easier to resolve the impact of experimental changes
    // to the quantizer tables.
    for ( i = 0; i < QINDEX_RANGE; i++ )
    {
        sad_per_bit16lut[i] =
            (int)((0.0418*vp8_convert_qindex_to_q(i)) + 2.4107);
        sad_per_bit4lut[i] = (int)((0.063*vp8_convert_qindex_to_q(i)) + 2.742);
    }
}
John Koleszar's avatar
John Koleszar committed
273

274
275
276
277
278
int compute_rd_mult( int qindex )
{
    int q;

    q = vp8_dc_quant(qindex,0);
279
    return (11 * q * q) >> 6;
280
281
}

John Koleszar's avatar
John Koleszar committed
282
283
void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex)
{
Yaowu Xu's avatar
Yaowu Xu committed
284
285
    cpi->mb.sadperbit16 =  sad_per_bit16lut[QIndex];
    cpi->mb.sadperbit4  =  sad_per_bit4lut[QIndex];
John Koleszar's avatar
John Koleszar committed
286
287
}

288
289

void vp8_initialize_rd_consts(VP8_COMP *cpi, int QIndex)
John Koleszar's avatar
John Koleszar committed
290
291
292
293
294
295
{
    int q;
    int i;

    vp8_clear_system_state();  //__asm emms;

296
297
298
299
    // Further tests required to see if optimum is different
    // for key frames, golden frames and arf frames.
    // if (cpi->common.refresh_golden_frame ||
    //     cpi->common.refresh_alt_ref_frame)
Paul Wilkins's avatar
Paul Wilkins committed
300
    QIndex=(QIndex<0)? 0 : ((QIndex>MAXQ)?MAXQ : QIndex);
301
302

    cpi->RDMULT = compute_rd_mult(QIndex);
John Koleszar's avatar
John Koleszar committed
303

304
305
306
307
308
309
310
311
    // Extend rate multiplier along side quantizer zbin increases
    if (cpi->zbin_over_quant  > 0)
    {
        double oq_factor;

        // Experimental code using the same basic equation as used for Q above
        // The units of cpi->zbin_over_quant are 1/128 of Q bin size
        oq_factor = 1.0 + ((double)0.0015625 * cpi->zbin_over_quant);
312
        cpi->RDMULT = (int)((double)cpi->RDMULT * oq_factor * oq_factor);
313
    }
John Koleszar's avatar
John Koleszar committed
314

Paul Wilkins's avatar
Paul Wilkins committed
315
    if (cpi->pass == 2 && (cpi->common.frame_type != KEY_FRAME))
John Koleszar's avatar
John Koleszar committed
316
    {
317
        if (cpi->twopass.next_iiratio > 31)
Paul Wilkins's avatar
Paul Wilkins committed
318
            cpi->RDMULT += (cpi->RDMULT * rd_iifactor[31]) >> 4;
John Koleszar's avatar
John Koleszar committed
319
        else
320
321
            cpi->RDMULT +=
                (cpi->RDMULT * rd_iifactor[cpi->twopass.next_iiratio]) >> 4;
John Koleszar's avatar
John Koleszar committed
322
323
    }

324
325
    if (cpi->RDMULT < 7)
        cpi->RDMULT = 7;
326

327
    cpi->mb.errorperbit = (cpi->RDMULT / 110);
328
329
    cpi->mb.errorperbit += (cpi->mb.errorperbit==0);

John Koleszar's avatar
John Koleszar committed
330
331
    vp8_set_speed_features(cpi);

332
333
    q = (int)pow(vp8_dc_quant(QIndex,0)>>2, 1.25);
    q = q << 2;
334
    cpi->RDMULT = cpi->RDMULT << 4;
Paul Wilkins's avatar
Paul Wilkins committed
335

336
337
    if (q < 8)
        q = 8;
338

John Koleszar's avatar
John Koleszar committed
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
    if (cpi->RDMULT > 1000)
    {
        cpi->RDDIV = 1;
        cpi->RDMULT /= 100;

        for (i = 0; i < MAX_MODES; i++)
        {
            if (cpi->sf.thresh_mult[i] < INT_MAX)
            {
                cpi->rd_threshes[i] = cpi->sf.thresh_mult[i] * q / 100;
            }
            else
            {
                cpi->rd_threshes[i] = INT_MAX;
            }

            cpi->rd_baseline_thresh[i] = cpi->rd_threshes[i];
        }
    }
    else
    {
        cpi->RDDIV = 100;

        for (i = 0; i < MAX_MODES; i++)
        {
            if (cpi->sf.thresh_mult[i] < (INT_MAX / q))
            {
                cpi->rd_threshes[i] = cpi->sf.thresh_mult[i] * q;
            }
            else
            {
                cpi->rd_threshes[i] = INT_MAX;
            }

            cpi->rd_baseline_thresh[i] = cpi->rd_threshes[i];
        }
    }

    fill_token_costs(
        cpi->mb.token_costs,
379
380
        (const vp8_prob( *)[8][PREV_COEF_CONTEXTS][11]) cpi->common.fc.coef_probs,
        BLOCK_TYPES);
John Koleszar's avatar
John Koleszar committed
381

382
383
    fill_token_costs(
        cpi->mb.token_costs_8x8,
384
385
386
        (const vp8_prob( *)[8][PREV_COEF_CONTEXTS][11]) cpi->common.fc.coef_probs_8x8,
        BLOCK_TYPES_8X8);

Yaowu Xu's avatar
Yaowu Xu committed
387
    /*rough estimate for costing*/
388
    cpi->common.kf_ymode_probs_index = cpi->common.base_qindex>>4;
John Koleszar's avatar
John Koleszar committed
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
    vp8_init_mode_costs(cpi);

}

void vp8_auto_select_speed(VP8_COMP *cpi)
{
    int milliseconds_for_compress = (int)(1000000 / cpi->oxcf.frame_rate);

    milliseconds_for_compress = milliseconds_for_compress * (16 - cpi->oxcf.cpu_used) / 16;

#if 0

    if (0)
    {
        FILE *f;

        f = fopen("speed.stt", "a");
        fprintf(f, " %8ld %10ld %10ld %10ld\n",
                cpi->common.current_video_frame, cpi->Speed, milliseconds_for_compress, cpi->avg_pick_mode_time);
        fclose(f);
    }

#endif

    /*
    // this is done during parameter valid check
Johann's avatar
Johann committed
415
416
417
418
    if( cpi->oxcf.cpu_used > 16)
        cpi->oxcf.cpu_used = 16;
    if( cpi->oxcf.cpu_used < -16)
        cpi->oxcf.cpu_used = -16;
John Koleszar's avatar
John Koleszar committed
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
    */

    if (cpi->avg_pick_mode_time < milliseconds_for_compress && (cpi->avg_encode_time - cpi->avg_pick_mode_time) < milliseconds_for_compress)
    {
        if (cpi->avg_pick_mode_time == 0)
        {
            cpi->Speed = 4;
        }
        else
        {
            if (milliseconds_for_compress * 100 < cpi->avg_encode_time * 95)
            {
                cpi->Speed          += 2;
                cpi->avg_pick_mode_time = 0;
                cpi->avg_encode_time = 0;

                if (cpi->Speed > 16)
                {
                    cpi->Speed = 16;
                }
            }

441
            if (milliseconds_for_compress * 100 > cpi->avg_encode_time * auto_speed_thresh[cpi->Speed])
John Koleszar's avatar
John Koleszar committed
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
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
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
            {
                cpi->Speed          -= 1;
                cpi->avg_pick_mode_time = 0;
                cpi->avg_encode_time = 0;

                // In real-time mode, cpi->speed is in [4, 16].
                if (cpi->Speed < 4)        //if ( cpi->Speed < 0 )
                {
                    cpi->Speed = 4;        //cpi->Speed = 0;
                }
            }
        }
    }
    else
    {
        cpi->Speed += 4;

        if (cpi->Speed > 16)
            cpi->Speed = 16;


        cpi->avg_pick_mode_time = 0;
        cpi->avg_encode_time = 0;
    }
}

int vp8_block_error_c(short *coeff, short *dqcoeff)
{
    int i;
    int error = 0;

    for (i = 0; i < 16; i++)
    {
        int this_diff = coeff[i] - dqcoeff[i];
        error += this_diff * this_diff;
    }

    return error;
}

int vp8_mbblock_error_c(MACROBLOCK *mb, int dc)
{
    BLOCK  *be;
    BLOCKD *bd;
    int i, j;
    int berror, error = 0;

    for (i = 0; i < 16; i++)
    {
        be = &mb->block[i];
        bd = &mb->e_mbd.block[i];

        berror = 0;

        for (j = dc; j < 16; j++)
        {
            int this_diff = be->coeff[j] - bd->dqcoeff[j];
            berror += this_diff * this_diff;
        }

        error += berror;
    }

    return error;
}

int vp8_mbuverror_c(MACROBLOCK *mb)
{

    BLOCK  *be;
    BLOCKD *bd;


    int i;
    int error = 0;

    for (i = 16; i < 24; i++)
    {
        be = &mb->block[i];
        bd = &mb->e_mbd.block[i];

        error += vp8_block_error_c(be->coeff, bd->dqcoeff);
    }

    return error;
}

int VP8_UVSSE(MACROBLOCK *x, const vp8_variance_rtcd_vtable_t *rtcd)
{
    unsigned char *uptr, *vptr;
    unsigned char *upred_ptr = (*(x->block[16].base_src) + x->block[16].src);
    unsigned char *vpred_ptr = (*(x->block[20].base_src) + x->block[20].src);
    int uv_stride = x->block[16].src_stride;

    unsigned int sse1 = 0;
    unsigned int sse2 = 0;
538
539
    int mv_row = x->e_mbd.mode_info_context->mbmi.mv.as_mv.row;
    int mv_col = x->e_mbd.mode_info_context->mbmi.mv.as_mv.col;
John Koleszar's avatar
John Koleszar committed
540
541
542
    int offset;
    int pre_stride = x->e_mbd.block[16].pre_stride;

543
544
545
546
547
548
549
550
551
552
553
554
    if (mv_row < 0)
        mv_row -= 1;
    else
        mv_row += 1;

    if (mv_col < 0)
        mv_col -= 1;
    else
        mv_col += 1;

    mv_row /= 2;
    mv_col /= 2;
John Koleszar's avatar
John Koleszar committed
555
556
557
558
559
560
561

    offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
    uptr = x->e_mbd.pre.u_buffer + offset;
    vptr = x->e_mbd.pre.v_buffer + offset;

    if ((mv_row | mv_col) & 7)
    {
562
563
564
565
566
567
#if CONFIG_SIXTEENTH_SUBPEL_UV
        VARIANCE_INVOKE(rtcd, subpixvar8x8)(uptr, pre_stride,
            (mv_col & 7)<<1, (mv_row & 7)<<1, upred_ptr, uv_stride, &sse2);
        VARIANCE_INVOKE(rtcd, subpixvar8x8)(vptr, pre_stride,
            (mv_col & 7)<<1, (mv_row & 7)<<1, vpred_ptr, uv_stride, &sse1);
#else
568
569
570
571
        VARIANCE_INVOKE(rtcd, subpixvar8x8)(uptr, pre_stride,
            mv_col & 7, mv_row & 7, upred_ptr, uv_stride, &sse2);
        VARIANCE_INVOKE(rtcd, subpixvar8x8)(vptr, pre_stride,
            mv_col & 7, mv_row & 7, vpred_ptr, uv_stride, &sse1);
572
#endif
John Koleszar's avatar
John Koleszar committed
573
574
575
576
        sse2 += sse1;
    }
    else
    {
577
578
579
580
        VARIANCE_INVOKE(rtcd, var8x8)(uptr, pre_stride,
            upred_ptr, uv_stride, &sse2);
        VARIANCE_INVOKE(rtcd, var8x8)(vptr, pre_stride,
            vpred_ptr, uv_stride, &sse1);
John Koleszar's avatar
John Koleszar committed
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
        sse2 += sse1;
    }
    return sse2;

}

static int cost_coeffs(MACROBLOCK *mb, BLOCKD *b, int type, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l)
{
    int c = !type;              /* start at coef 0, unless Y with Y2 */
    int eob = b->eob;
    int pt ;    /* surrounding block/prev coef predictor */
    int cost = 0;
    short *qcoeff_ptr = b->qcoeff;

    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);

# define QC( I)  ( qcoeff_ptr [vp8_default_zig_zag1d[I]] )

    for (; c < eob; c++)
    {
        int v = QC(c);
        int t = vp8_dct_value_tokens_ptr[v].Token;
        cost += mb->token_costs [type] [vp8_coef_bands[c]] [pt] [t];
        cost += vp8_dct_value_cost_ptr[v];
        pt = vp8_prev_token_class[t];
    }

# undef QC

    if (c < 16)
        cost += mb->token_costs [type] [vp8_coef_bands[c]] [pt] [DCT_EOB_TOKEN];

    pt = (c != !type); // is eob first coefficient;
    *a = *l = pt;

    return cost;
}

Scott LaVarnway's avatar
Scott LaVarnway committed
619
static int vp8_rdcost_mby(MACROBLOCK *mb)
John Koleszar's avatar
John Koleszar committed
620
621
622
623
{
    int cost = 0;
    int b;
    MACROBLOCKD *x = &mb->e_mbd;
624
625
626
627
628
629
    ENTROPY_CONTEXT_PLANES t_above, t_left;
    ENTROPY_CONTEXT *ta;
    ENTROPY_CONTEXT *tl;

    vpx_memcpy(&t_above, mb->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
    vpx_memcpy(&t_left, mb->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
John Koleszar's avatar
John Koleszar committed
630

631
632
    ta = (ENTROPY_CONTEXT *)&t_above;
    tl = (ENTROPY_CONTEXT *)&t_left;
John Koleszar's avatar
John Koleszar committed
633
634

    for (b = 0; b < 16; b++)
Scott LaVarnway's avatar
Scott LaVarnway committed
635
        cost += cost_coeffs(mb, x->block + b, PLANE_TYPE_Y_NO_DC,
636
                    ta + vp8_block2above[b], tl + vp8_block2left[b]);
John Koleszar's avatar
John Koleszar committed
637

Scott LaVarnway's avatar
Scott LaVarnway committed
638
    cost += cost_coeffs(mb, x->block + 24, PLANE_TYPE_Y2,
Scott LaVarnway's avatar
Scott LaVarnway committed
639
                ta + vp8_block2above[24], tl + vp8_block2left[24]);
John Koleszar's avatar
John Koleszar committed
640
641
642
643

    return cost;
}

644
645
646
static void macro_block_yrd( MACROBLOCK *mb,
                             int *Rate,
                             int *Distortion,
647
                             const VP8_ENCODER_RTCD *rtcd)
648
649
650
651
652
653
654
655
656
{
    int b;
    MACROBLOCKD *const x = &mb->e_mbd;
    BLOCK   *const mb_y2 = mb->block + 24;
    BLOCKD *const x_y2  = x->block + 24;
    short *Y2DCPtr = mb_y2->src_diff;
    BLOCK *beptr;
    int d;

657
658
659
660
661
    ENCODEMB_INVOKE(&rtcd->encodemb, submby)(
        mb->src_diff,
        *(mb->block[0].base_src),
        mb->e_mbd.predictor,
        mb->block[0].src_stride );
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683

    // Fdct and building the 2nd order block
    for (beptr = mb->block; beptr < mb->block + 16; beptr += 2)
    {
        mb->vp8_short_fdct8x4(beptr->src_diff, beptr->coeff, 32);
        *Y2DCPtr++ = beptr->coeff[0];
        *Y2DCPtr++ = beptr->coeff[16];
    }

    // 2nd order fdct
    mb->short_walsh4x4(mb_y2->src_diff, mb_y2->coeff, 8);

    // Quantization
    for (b = 0; b < 16; b++)
    {
        mb->quantize_b(&mb->block[b], &mb->e_mbd.block[b]);
    }

    // DC predication and Quantization of 2nd Order block
    mb->quantize_b(mb_y2, x_y2);

    // Distortion
684
    d = ENCODEMB_INVOKE(&rtcd->encodemb, mberr)(mb, 1);
685

686
    d += ENCODEMB_INVOKE(&rtcd->encodemb, berr)(mb_y2->coeff, x_y2->dqcoeff);
687

688
    *Distortion = (d >> 2);
689
690
691
    // rate
    *Rate = vp8_rdcost_mby(mb);
}
John Koleszar's avatar
John Koleszar committed
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
719
720
721
722
723
724
725
726
727
728
729
730

static int cost_coeffs_2x2(MACROBLOCK *mb,
                           BLOCKD *b, int type,
                           ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l)
{
    int c = !type;              /* start at coef 0, unless Y with Y2 */
    int eob = b->eob;
    int pt ;    /* surrounding block/prev coef predictor */
    int cost = 0;
    short *qcoeff_ptr = b->qcoeff;

    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
    assert(eob<=4);

# define QC2X2( I)  ( qcoeff_ptr [vp8_default_zig_zag1d[I]] )

    for (; c < eob; c++)
    {
        int v = QC2X2(c);
        int t = vp8_dct_value_tokens_ptr[v].Token;
        cost += mb->token_costs_8x8[type] [vp8_coef_bands[c]] [pt] [t];
        cost += vp8_dct_value_cost_ptr[v];
        pt = vp8_prev_token_class[t];
    }

# undef QC2X2
    if (c < 4)
        cost += mb->token_costs_8x8 [type][vp8_coef_bands[c]]
                                    [pt] [DCT_EOB_TOKEN];

    pt = (c != !type); // is eob first coefficient;
    *a = *l = pt;
    return cost;
}


static int cost_coeffs_8x8(MACROBLOCK *mb,
                           BLOCKD *b, int type,
731
                           ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l)
732
733
734
735
736
737
738
{
    int c = !type;              /* start at coef 0, unless Y with Y2 */
    int eob = b->eob;
    int pt ;    /* surrounding block/prev coef predictor */
    int cost = 0;
    short *qcoeff_ptr = b->qcoeff;

739
    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
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
771
772
773
774
775
776
777

# define QC8X8( I)  ( qcoeff_ptr [vp8_default_zig_zag1d_8x8[I]] )

    for (; c < eob; c++)
    {
        int v = QC8X8(c);
        int t = vp8_dct_value_tokens_ptr[v].Token;
        cost += mb->token_costs_8x8[type] [vp8_coef_bands_8x8[c]] [pt] [t];
        cost += vp8_dct_value_cost_ptr[v];
        pt = vp8_prev_token_class[t];
    }

# undef QC8X8
    if (c < 64)
        cost += mb->token_costs_8x8 [type][vp8_coef_bands_8x8[c]]
                                    [pt] [DCT_EOB_TOKEN];

    pt = (c != !type); // is eob first coefficient;
    *a = *l = pt;
    return cost;
}
static int vp8_rdcost_mby_8x8(MACROBLOCK *mb)
{
    int cost = 0;
    int b;
    MACROBLOCKD *x = &mb->e_mbd;
    ENTROPY_CONTEXT_PLANES t_above, t_left;
    ENTROPY_CONTEXT *ta;
    ENTROPY_CONTEXT *tl;

    vpx_memcpy(&t_above, mb->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
    vpx_memcpy(&t_left, mb->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));

    ta = (ENTROPY_CONTEXT *)&t_above;
    tl = (ENTROPY_CONTEXT *)&t_left;

    for (b = 0; b < 16; b+=4)
        cost += cost_coeffs_8x8(mb, x->block + b, PLANE_TYPE_Y_NO_DC,
778
                    ta + vp8_block2above_8x8[b], tl + vp8_block2left_8x8[b]);
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794

    cost += cost_coeffs_2x2(mb, x->block + 24, PLANE_TYPE_Y2,
                ta + vp8_block2above[24], tl + vp8_block2left[24]);
    return cost;
}

static void macro_block_yrd_8x8( MACROBLOCK *mb,
                             int *Rate,
                             int *Distortion,
                             const VP8_ENCODER_RTCD *rtcd)
{
    MACROBLOCKD *const x = &mb->e_mbd;
    BLOCK   *const mb_y2 = mb->block + 24;
    BLOCKD *const x_y2  = x->block + 24;
    int d;

795
796
797
798
799
    ENCODEMB_INVOKE(&rtcd->encodemb, submby)(
        mb->src_diff,
        *(mb->block[0].base_src),
        mb->e_mbd.predictor,
        mb->block[0].src_stride );
800
801
802
803
804
805
806
807
808
809
810
811
812
813

    vp8_transform_mby_8x8(mb);
    vp8_quantize_mby_8x8(mb);

    /* remove 1st order dc to properly combine 1st/2nd order distortion */
    mb->coeff[0] = 0;
    mb->coeff[64] = 0;
    mb->coeff[128] = 0;
    mb->coeff[192] = 0;
    mb->e_mbd.dqcoeff[0] = 0;
    mb->e_mbd.dqcoeff[64] = 0;
    mb->e_mbd.dqcoeff[128] = 0;
    mb->e_mbd.dqcoeff[192] = 0;

814
815
    d = ENCODEMB_INVOKE(&rtcd->encodemb, mberr)(mb, 0);
    d += ENCODEMB_INVOKE(&rtcd->encodemb, berr)(mb_y2->coeff, x_y2->dqcoeff);
816

817
    *Distortion = (d >> 2);
818
819
820
    // rate
    *Rate = vp8_rdcost_mby_8x8(mb);
}
821

822
static void copy_predictor(unsigned char *dst, const unsigned char *predictor)
823
{
824
825
826
827
828
829
    const unsigned int *p = (const unsigned int *)predictor;
    unsigned int *d = (unsigned int *)dst;
    d[0] = p[0];
    d[4] = p[4];
    d[8] = p[8];
    d[12] = p[12];
830
}
Yaowu Xu's avatar
Yaowu Xu committed
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853

static void copy_predictor_8x8(unsigned char *dst, const unsigned char *predictor)
{
    const unsigned int *p = (const unsigned int *)predictor;
    unsigned int *d = (unsigned int *)dst;
    d[0] = p[0];
    d[1] = p[1];
    d[4] = p[4];
    d[5] = p[5];
    d[8] = p[8];
    d[9] = p[9];
    d[12] = p[12];
    d[13] = p[13];
    d[16] = p[16];
    d[17] = p[17];
    d[20] = p[20];
    d[21] = p[21];
    d[24] = p[24];
    d[25] = p[25];
    d[28] = p[28];
    d[29] = p[29];
}

854
static int rd_pick_intra4x4block(
John Koleszar's avatar
John Koleszar committed
855
856
857
858
859
    VP8_COMP *cpi,
    MACROBLOCK *x,
    BLOCK *be,
    BLOCKD *b,
    B_PREDICTION_MODE *best_mode,
860
861
#if CONFIG_COMP_INTRA_PRED
    B_PREDICTION_MODE *best_second_mode,
862
    int allow_comp,
863
#endif
Christian Duvivier's avatar
Christian Duvivier committed
864
    int *bmode_costs,
John Koleszar's avatar
John Koleszar committed
865
866
867
868
869
    ENTROPY_CONTEXT *a,
    ENTROPY_CONTEXT *l,

    int *bestrate,
    int *bestratey,
870
    int *bestdistortion)
John Koleszar's avatar
John Koleszar committed
871
872
{
    B_PREDICTION_MODE mode;
873
874
875
#if CONFIG_COMP_INTRA_PRED
    B_PREDICTION_MODE mode2;
#endif
876
    int best_rd = INT_MAX;
John Koleszar's avatar
John Koleszar committed
877
878
879
880
881
    int rate = 0;
    int distortion;

    ENTROPY_CONTEXT ta = *a, tempa = *a;
    ENTROPY_CONTEXT tl = *l, templ = *l;
882
883
884
885
886
887
888
    /*
     * The predictor buffer is a 2d buffer with a stride of 16.  Create
     * a temp buffer that meets the stride requirements, but we are only
     * interested in the left 4x4 block
     * */
    DECLARE_ALIGNED_ARRAY(16, unsigned char,  best_predictor, 16*4);
    DECLARE_ALIGNED_ARRAY(16, short, best_dqcoeff, 16);
John Koleszar's avatar
John Koleszar committed
889
890
891

    for (mode = B_DC_PRED; mode <= B_HU_PRED; mode++)
    {
892
#if CONFIG_COMP_INTRA_PRED
893
        for (mode2 = (allow_comp ? 0 : (B_DC_PRED - 1)); mode2 != (allow_comp ? (mode + 1) : 0); mode2++)
894
895
        {
#endif
John Koleszar's avatar
John Koleszar committed
896
897
898
        int this_rd;
        int ratey;

Adrian Grange's avatar
Adrian Grange committed
899
900
901
902
903
        // TODO Temporarily ignore modes that need the above-right data. SB
        // encoding means this data is not available for the bottom right MB
        // Do we need to do this for mode2 also?
        if (mode==B_LD_PRED || mode==B_VL_PRED)
            continue;
904
905
        rate = bmode_costs[mode];

906
907
908
909
#if CONFIG_COMP_INTRA_PRED
            if (mode2 == (B_PREDICTION_MODE) (B_DC_PRED - 1))
            {
#endif
910
911
        RECON_INVOKE(&cpi->rtcd.common->recon, intra4x4_predict)
                     (b, mode, b->predictor);
912
913
914
915
916
917
918
919
920
#if CONFIG_COMP_INTRA_PRED
            }
            else
            {
                RECON_INVOKE(&cpi->rtcd.common->recon, comp_intra4x4_predict)
                    (b, mode, mode2, b->predictor);
                rate += bmode_costs[mode2];
            }
#endif
921
922
923
        ENCODEMB_INVOKE(IF_RTCD(&cpi->rtcd.encodemb), subb)(be, b, 16);
        x->vp8_short_fdct4x4(be->src_diff, be->coeff, 32);
        x->quantize_b(be, b);
John Koleszar's avatar
John Koleszar committed
924
925
926
927

        tempa = ta;
        templ = tl;

Scott LaVarnway's avatar
Scott LaVarnway committed
928
        ratey = cost_coeffs(x, b, PLANE_TYPE_Y_WITH_DC, &tempa, &templ);
John Koleszar's avatar
John Koleszar committed
929
        rate += ratey;
Yaowu Xu's avatar
Yaowu Xu committed
930
931
        distortion = ENCODEMB_INVOKE(IF_RTCD(&cpi->rtcd.encodemb), berr)(
            be->coeff, b->dqcoeff) >> 2;
John Koleszar's avatar
John Koleszar committed
932
933
934
935
936
937
938
939
940
941

        this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);

        if (this_rd < best_rd)
        {
            *bestrate = rate;
            *bestratey = ratey;
            *bestdistortion = distortion;
            best_rd = this_rd;
            *best_mode = mode;
942
943
944
#if CONFIG_COMP_INTRA_PRED
            *best_second_mode = mode2;
#endif
John Koleszar's avatar
John Koleszar committed
945
946
            *a = tempa;
            *l = templ;
947
948
            copy_predictor(best_predictor, b->predictor);
            vpx_memcpy(best_dqcoeff, b->dqcoeff, 32);
949
950
951
#if CONFIG_COMP_INTRA_PRED
        }
#endif
John Koleszar's avatar
John Koleszar committed
952
953
        }
    }
954
955
956
957
    b->bmi.as_mode.first = (B_PREDICTION_MODE)(*best_mode);
#if CONFIG_COMP_INTRA_PRED
    b->bmi.as_mode.second = (B_PREDICTION_MODE)(*best_second_mode);
#endif
958

959
960
    IDCT_INVOKE(IF_RTCD(&cpi->rtcd.common->idct), idct16)(best_dqcoeff, b->diff, 32);
    RECON_INVOKE(IF_RTCD(&cpi->rtcd.common->recon), recon)(best_predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
John Koleszar's avatar
John Koleszar committed
961

962
    return best_rd;
John Koleszar's avatar
John Koleszar committed
963
964
}

965
static int rd_pick_intra4x4mby_modes(VP8_COMP *cpi, MACROBLOCK *mb, int *Rate,
966
                                     int *rate_y, int *Distortion, int best_rd,
967
968
969
970
#if CONFIG_COMP_INTRA_PRED
                                     int allow_comp,
#endif
                                     int update_contexts)
John Koleszar's avatar
John Koleszar committed
971
972
{
    int i;
Adrian Grange's avatar
Adrian Grange committed
973
    MACROBLOCKD *const xd = &mb->e_mbd;
John Koleszar's avatar
John Koleszar committed
974
975
976
    int cost = mb->mbmode_cost [xd->frame_type] [B_PRED];
    int distortion = 0;
    int tot_rate_y = 0;
977
    int64_t total_rd = 0;
978
979
980
    ENTROPY_CONTEXT_PLANES t_above, t_left;
    ENTROPY_CONTEXT *ta;
    ENTROPY_CONTEXT *tl;
Christian Duvivier's avatar
Christian Duvivier committed
981
    int *bmode_costs;
982

Adrian Grange's avatar
Adrian Grange committed
983
984
985
986
987
988
989
990
991
992
993
    if (update_contexts)
    {
        ta = (ENTROPY_CONTEXT *)mb->e_mbd.above_context;
        tl = (ENTROPY_CONTEXT *)mb->e_mbd.left_context;
    }
    else
    {
        vpx_memcpy(&t_above, mb->e_mbd.above_context,
                   sizeof(ENTROPY_CONTEXT_PLANES));
        vpx_memcpy(&t_left, mb->e_mbd.left_context,
                   sizeof(ENTROPY_CONTEXT_PLANES));
994

Adrian Grange's avatar
Adrian Grange committed
995
996
997
        ta = (ENTROPY_CONTEXT *)&t_above;
        tl = (ENTROPY_CONTEXT *)&t_left;
    }
John Koleszar's avatar
John Koleszar committed
998

Christian Duvivier's avatar
Christian Duvivier committed
999
1000
    // TODO(agrange)
    //vp8_intra_prediction_down_copy(xd);
For faster browsing, not all history is shown. View entire blame