pickinter.c 30.2 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
16
 */


#include <limits.h>
#include "vpx_ports/config.h"
#include "onyx_int.h"
#include "modecosts.h"
#include "encodeintra.h"
John Koleszar's avatar
John Koleszar committed
17
#include "vp8/common/entropymode.h"
John Koleszar's avatar
John Koleszar committed
18
#include "pickinter.h"
John Koleszar's avatar
John Koleszar committed
19
#include "vp8/common/findnearmv.h"
John Koleszar's avatar
John Koleszar committed
20
#include "encodemb.h"
John Koleszar's avatar
John Koleszar committed
21
22
23
24
#include "vp8/common/reconinter.h"
#include "vp8/common/reconintra.h"
#include "vp8/common/reconintra4x4.h"
#include "vp8/common/g_common.h"
John Koleszar's avatar
John Koleszar committed
25
26
#include "variance.h"
#include "mcomp.h"
27
#include "rdopt.h"
John Koleszar's avatar
John Koleszar committed
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include "vpx_mem/vpx_mem.h"

#if CONFIG_RUNTIME_CPU_DETECT
#define IF_RTCD(x) (x)
#else
#define IF_RTCD(x)  NULL
#endif

extern int VP8_UVSSE(MACROBLOCK *x, const vp8_variance_rtcd_vtable_t *rtcd);

#ifdef SPEEDSTATS
extern unsigned int cnt_pm;
#endif

extern const MV_REFERENCE_FRAME vp8_ref_frame_order[MAX_MODES];
extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES];


extern unsigned int (*vp8_get4x4sse_cs)(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride);
extern int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *best_ref_mv, int best_rd, int *, int *, int *, int, int *mvcost[2], int, int fullpixel);
extern int vp8_cost_mv_ref(MB_PREDICTION_MODE m, const int near_mv_ref_ct[4]);


Scott LaVarnway's avatar
Scott LaVarnway committed
51
52
53
54
55
56
int vp8_skip_fractional_mv_step(MACROBLOCK *mb, BLOCK *b, BLOCKD *d,
                                int_mv *bestmv, int_mv *ref_mv,
                                int error_per_bit,
                                const vp8_variance_fn_ptr_t *vfp,
                                int *mvcost[2], int *distortion,
                                unsigned int *sse)
John Koleszar's avatar
John Koleszar committed
57
58
59
60
61
{
    (void) b;
    (void) d;
    (void) ref_mv;
    (void) error_per_bit;
62
    (void) vfp;
John Koleszar's avatar
John Koleszar committed
63
    (void) mvcost;
64
    (void) distortion;
65
    (void) sse;
Scott LaVarnway's avatar
Scott LaVarnway committed
66
67
    bestmv->as_mv.row <<= 3;
    bestmv->as_mv.col <<= 3;
John Koleszar's avatar
John Koleszar committed
68
69
70
71
    return 0;
}


72
73
74
75
static int get_inter_mbpred_error(MACROBLOCK *mb,
                                  const vp8_variance_fn_ptr_t *vfp,
                                  unsigned int *sse,
                                  int_mv this_mv)
John Koleszar's avatar
John Koleszar committed
76
77
78
79
80
81
82
83
{

    BLOCK *b = &mb->block[0];
    BLOCKD *d = &mb->e_mbd.block[0];
    unsigned char *what = (*(b->base_src) + b->src);
    int what_stride = b->src_stride;
    unsigned char *in_what = *(d->base_pre) + d->pre ;
    int in_what_stride = d->pre_stride;
84
85
    int xoffset = this_mv.as_mv.col & 7;
    int yoffset = this_mv.as_mv.row & 7;
John Koleszar's avatar
John Koleszar committed
86

87
    in_what += (this_mv.as_mv.row >> 3) * d->pre_stride + (this_mv.as_mv.col >> 3);
John Koleszar's avatar
John Koleszar committed
88
89
90

    if (xoffset | yoffset)
    {
91
        return vfp->svf(in_what, in_what_stride, xoffset, yoffset, what, what_stride, sse);
John Koleszar's avatar
John Koleszar committed
92
93
94
    }
    else
    {
95
        return vfp->vf(what, what_stride, in_what, in_what_stride, sse);
John Koleszar's avatar
John Koleszar committed
96
97
98
99
100
101
102
    }

}


unsigned int vp8_get4x4sse_cs_c
(
103
    const unsigned char *src_ptr,
John Koleszar's avatar
John Koleszar committed
104
    int  source_stride,
105
    const unsigned char *ref_ptr,
106
    int  recon_stride
John Koleszar's avatar
John Koleszar committed
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
)
{
    int distortion = 0;
    int r, c;

    for (r = 0; r < 4; r++)
    {
        for (c = 0; c < 4; c++)
        {
            int diff = src_ptr[c] - ref_ptr[c];
            distortion += diff * diff;
        }

        src_ptr += source_stride;
        ref_ptr += recon_stride;
    }

    return distortion;
}

static int get_prediction_error(BLOCK *be, BLOCKD *b, const vp8_variance_rtcd_vtable_t *rtcd)
{
    unsigned char *sptr;
    unsigned char *dptr;
    sptr = (*(be->base_src) + be->src);
    dptr = b->predictor;

134
    return VARIANCE_INVOKE(rtcd, get4x4sse_cs)(sptr, be->src_stride, dptr, 16);
John Koleszar's avatar
John Koleszar committed
135
136
137
138
139
140

}

static int pick_intra4x4block(
    const VP8_ENCODER_RTCD *rtcd,
    MACROBLOCK *x,
141
    int ib,
John Koleszar's avatar
John Koleszar committed
142
143
144
145
146
147
148
    B_PREDICTION_MODE *best_mode,
    B_PREDICTION_MODE above,
    B_PREDICTION_MODE left,

    int *bestrate,
    int *bestdistortion)
{
149
150
151

    BLOCKD *b = &x->e_mbd.block[ib];
    BLOCK *be = &x->block[ib];
John Koleszar's avatar
John Koleszar committed
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
    B_PREDICTION_MODE mode;
    int best_rd = INT_MAX;       // 1<<30
    int rate;
    int distortion;
    unsigned int *mode_costs;

    if (x->e_mbd.frame_type == KEY_FRAME)
    {
        mode_costs = x->bmode_costs[above][left];
    }
    else
    {
        mode_costs = x->inter_bmode_costs;
    }

    for (mode = B_DC_PRED; mode <= B_HE_PRED /*B_HU_PRED*/; mode++)
    {
        int this_rd;

        rate = mode_costs[mode];
172
173
        RECON_INVOKE(&rtcd->common->recon, intra4x4_predict)
                     (b, mode, b->predictor);
John Koleszar's avatar
John Koleszar committed
174
        distortion = get_prediction_error(be, b, &rtcd->variance);
Yunqing Wang's avatar
Yunqing Wang committed
175
        this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
John Koleszar's avatar
John Koleszar committed
176
177
178
179
180
181
182
183
184

        if (this_rd < best_rd)
        {
            *bestrate = rate;
            *bestdistortion = distortion;
            best_rd = this_rd;
            *best_mode = mode;
        }
    }
Scott LaVarnway's avatar
Scott LaVarnway committed
185
186

    b->bmi.as_mode = (B_PREDICTION_MODE)(*best_mode);
187
    vp8_encode_intra4x4block(rtcd, x, ib);
John Koleszar's avatar
John Koleszar committed
188
189
190
191
    return best_rd;
}


192
static int pick_intra4x4mby_modes
193
194
195
196
197
198
(
    const VP8_ENCODER_RTCD *rtcd,
    MACROBLOCK *mb,
    int *Rate,
    int *best_dist
)
John Koleszar's avatar
John Koleszar committed
199
200
201
202
{
    MACROBLOCKD *const xd = &mb->e_mbd;
    int i;
    int cost = mb->mbmode_cost [xd->frame_type] [B_PRED];
203
    int error;
John Koleszar's avatar
John Koleszar committed
204
205
206
207
208
209
210
211
    int distortion = 0;

    vp8_intra_prediction_down_copy(xd);

    for (i = 0; i < 16; i++)
    {
        MODE_INFO *const mic = xd->mode_info_context;
        const int mis = xd->mode_info_stride;
Scott LaVarnway's avatar
Scott LaVarnway committed
212
213
214
        const B_PREDICTION_MODE A = above_block_mode(mic, i, mis);
        const B_PREDICTION_MODE L = left_block_mode(mic, i);

John Koleszar's avatar
John Koleszar committed
215
216
217
        B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);
        int UNINITIALIZED_IS_SAFE(r), UNINITIALIZED_IS_SAFE(d);

218
        pick_intra4x4block(rtcd, mb, i, &best_mode, A, L, &r, &d);
John Koleszar's avatar
John Koleszar committed
219
220
221

        cost += r;
        distortion += d;
Scott LaVarnway's avatar
Scott LaVarnway committed
222
        mic->bmi[i].as_mode = best_mode;
John Koleszar's avatar
John Koleszar committed
223

224
225
        // Break out case where we have already exceeded best so far value
        // that was passed in
John Koleszar's avatar
John Koleszar committed
226
227
228
229
230
231
232
        if (distortion > *best_dist)
            break;
    }

    *Rate = cost;

    if (i == 16)
233
    {
John Koleszar's avatar
John Koleszar committed
234
        *best_dist = distortion;
Yunqing Wang's avatar
Yunqing Wang committed
235
        error = RDCOST(mb->rdmult, mb->rddiv, cost, distortion);
236
    }
John Koleszar's avatar
John Koleszar committed
237
    else
238
    {
John Koleszar's avatar
John Koleszar committed
239
        *best_dist = INT_MAX;
240
241
        error = INT_MAX;
    }
John Koleszar's avatar
John Koleszar committed
242
243
244
245

    return error;
}

246
static void pick_intra_mbuv_mode(MACROBLOCK *mb)
John Koleszar's avatar
John Koleszar committed
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
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
379
380
381
382
383
384
385
386
387
388
389
{

    MACROBLOCKD *x = &mb->e_mbd;
    unsigned char *uabove_row = x->dst.u_buffer - x->dst.uv_stride;
    unsigned char *vabove_row = x->dst.v_buffer - x->dst.uv_stride;
    unsigned char *usrc_ptr = (mb->block[16].src + *mb->block[16].base_src);
    unsigned char *vsrc_ptr = (mb->block[20].src + *mb->block[20].base_src);
    int uvsrc_stride = mb->block[16].src_stride;
    unsigned char uleft_col[8];
    unsigned char vleft_col[8];
    unsigned char utop_left = uabove_row[-1];
    unsigned char vtop_left = vabove_row[-1];
    int i, j;
    int expected_udc;
    int expected_vdc;
    int shift;
    int Uaverage = 0;
    int Vaverage = 0;
    int diff;
    int pred_error[4] = {0, 0, 0, 0}, best_error = INT_MAX;
    MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);


    for (i = 0; i < 8; i++)
    {
        uleft_col[i] = x->dst.u_buffer [i* x->dst.uv_stride -1];
        vleft_col[i] = x->dst.v_buffer [i* x->dst.uv_stride -1];
    }

    if (!x->up_available && !x->left_available)
    {
        expected_udc = 128;
        expected_vdc = 128;
    }
    else
    {
        shift = 2;

        if (x->up_available)
        {

            for (i = 0; i < 8; i++)
            {
                Uaverage += uabove_row[i];
                Vaverage += vabove_row[i];
            }

            shift ++;

        }

        if (x->left_available)
        {
            for (i = 0; i < 8; i++)
            {
                Uaverage += uleft_col[i];
                Vaverage += vleft_col[i];
            }

            shift ++;

        }

        expected_udc = (Uaverage + (1 << (shift - 1))) >> shift;
        expected_vdc = (Vaverage + (1 << (shift - 1))) >> shift;
    }


    for (i = 0; i < 8; i++)
    {
        for (j = 0; j < 8; j++)
        {

            int predu = uleft_col[i] + uabove_row[j] - utop_left;
            int predv = vleft_col[i] + vabove_row[j] - vtop_left;
            int u_p, v_p;

            u_p = usrc_ptr[j];
            v_p = vsrc_ptr[j];

            if (predu < 0)
                predu = 0;

            if (predu > 255)
                predu = 255;

            if (predv < 0)
                predv = 0;

            if (predv > 255)
                predv = 255;


            diff = u_p - expected_udc;
            pred_error[DC_PRED] += diff * diff;
            diff = v_p - expected_vdc;
            pred_error[DC_PRED] += diff * diff;


            diff = u_p - uabove_row[j];
            pred_error[V_PRED] += diff * diff;
            diff = v_p - vabove_row[j];
            pred_error[V_PRED] += diff * diff;


            diff = u_p - uleft_col[i];
            pred_error[H_PRED] += diff * diff;
            diff = v_p - vleft_col[i];
            pred_error[H_PRED] += diff * diff;


            diff = u_p - predu;
            pred_error[TM_PRED] += diff * diff;
            diff = v_p - predv;
            pred_error[TM_PRED] += diff * diff;


        }

        usrc_ptr += uvsrc_stride;
        vsrc_ptr += uvsrc_stride;

        if (i == 3)
        {
            usrc_ptr = (mb->block[18].src + *mb->block[18].base_src);
            vsrc_ptr = (mb->block[22].src + *mb->block[22].base_src);
        }



    }


    for (i = DC_PRED; i <= TM_PRED; i++)
    {
        if (best_error > pred_error[i])
        {
            best_error = pred_error[i];
            best_mode = (MB_PREDICTION_MODE)i;
        }
    }


390
    mb->e_mbd.mode_info_context->mbmi.uv_mode = best_mode;
John Koleszar's avatar
John Koleszar committed
391
392
393

}

394
static void update_mvcount(VP8_COMP *cpi, MACROBLOCKD *xd, int_mv *best_ref_mv)
395
{
396
397
    /* Split MV modes currently not supported when RD is nopt enabled,
     * therefore, only need to modify MVcount in NEWMV mode. */
398
399
    if (xd->mode_info_context->mbmi.mode == NEWMV)
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
400
        cpi->MVcount[0][mv_max+((xd->mode_info_context->mbmi.mv.as_mv.row -
401
                                      best_ref_mv->as_mv.row) >> 1)]++;
Scott LaVarnway's avatar
Scott LaVarnway committed
402
        cpi->MVcount[1][mv_max+((xd->mode_info_context->mbmi.mv.as_mv.col -
403
                                      best_ref_mv->as_mv.col) >> 1)]++;
404
405
406
    }
}

407
408
409
void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
                         int recon_uvoffset, int *returnrate,
                         int *returndistortion, int *returnintra)
John Koleszar's avatar
John Koleszar committed
410
411
412
413
414
{
    BLOCK *b = &x->block[0];
    BLOCKD *d = &x->e_mbd.block[0];
    MACROBLOCKD *xd = &x->e_mbd;
    MB_MODE_INFO best_mbmode;
415

Scott LaVarnway's avatar
Scott LaVarnway committed
416
417
    int_mv best_ref_mv;
    int_mv mode_mv[MB_MODE_COUNT];
John Koleszar's avatar
John Koleszar committed
418
419
    MB_PREDICTION_MODE this_mode;
    int num00;
420

John Koleszar's avatar
John Koleszar committed
421
422
423
424
425
426
427
428
429
430
    int mdcounts[4];
    int best_rd = INT_MAX; // 1 << 30;
    int best_intra_rd = INT_MAX;
    int mode_index;
    int rate;
    int rate2;
    int distortion2;
    int bestsme;
    //int all_rds[MAX_MODES];         // Experimental debug code.
    int best_mode_index = 0;
431
    unsigned int sse = INT_MAX;
John Koleszar's avatar
John Koleszar committed
432

Scott LaVarnway's avatar
Scott LaVarnway committed
433
    int_mv mvp;
434
435
436
437
    int near_sadidx[8] = {0, 1, 2, 3, 4, 5, 6, 7};
    int saddone=0;
    int sr=0;    //search range got from mv_pred(). It uses step_param levels. (0-7)

Scott LaVarnway's avatar
Scott LaVarnway committed
438
439
440
    int_mv nearest_mv[4];
    int_mv near_mv[4];
    int_mv frame_best_ref_mv[4];
John Koleszar's avatar
John Koleszar committed
441
442
443
444
445
446
447
    int MDCounts[4][4];
    unsigned char *y_buffer[4];
    unsigned char *u_buffer[4];
    unsigned char *v_buffer[4];

    int skip_mode[4] = {0, 0, 0, 0};

448
449
    int have_subp_search = cpi->sf.half_pixel_search;  /* In real-time mode, when Speed >= 15, no sub-pixel search. */

John Koleszar's avatar
John Koleszar committed
450
451
452
    vpx_memset(mode_mv, 0, sizeof(mode_mv));
    vpx_memset(nearest_mv, 0, sizeof(nearest_mv));
    vpx_memset(near_mv, 0, sizeof(near_mv));
453
    vpx_memset(&best_mbmode, 0, sizeof(best_mbmode));
John Koleszar's avatar
John Koleszar committed
454
455
456
457
458


    // set up all the refframe dependent pointers.
    if (cpi->ref_frame_flags & VP8_LAST_FLAG)
    {
459
460
        YV12_BUFFER_CONFIG *lst_yv12 = &cpi->common.yv12_fb[cpi->common.lst_fb_idx];

John Koleszar's avatar
John Koleszar committed
461
        vp8_find_near_mvs(&x->e_mbd, x->e_mbd.mode_info_context, &nearest_mv[LAST_FRAME], &near_mv[LAST_FRAME],
462
                          &frame_best_ref_mv[LAST_FRAME], MDCounts[LAST_FRAME], LAST_FRAME, cpi->common.ref_frame_sign_bias);
John Koleszar's avatar
John Koleszar committed
463

464
465
466
        y_buffer[LAST_FRAME] = lst_yv12->y_buffer + recon_yoffset;
        u_buffer[LAST_FRAME] = lst_yv12->u_buffer + recon_uvoffset;
        v_buffer[LAST_FRAME] = lst_yv12->v_buffer + recon_uvoffset;
John Koleszar's avatar
John Koleszar committed
467
468
469
470
471
472
    }
    else
        skip_mode[LAST_FRAME] = 1;

    if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
    {
473
474
        YV12_BUFFER_CONFIG *gld_yv12 = &cpi->common.yv12_fb[cpi->common.gld_fb_idx];

John Koleszar's avatar
John Koleszar committed
475
        vp8_find_near_mvs(&x->e_mbd, x->e_mbd.mode_info_context, &nearest_mv[GOLDEN_FRAME], &near_mv[GOLDEN_FRAME],
476
                          &frame_best_ref_mv[GOLDEN_FRAME], MDCounts[GOLDEN_FRAME], GOLDEN_FRAME, cpi->common.ref_frame_sign_bias);
John Koleszar's avatar
John Koleszar committed
477

478
479
480
        y_buffer[GOLDEN_FRAME] = gld_yv12->y_buffer + recon_yoffset;
        u_buffer[GOLDEN_FRAME] = gld_yv12->u_buffer + recon_uvoffset;
        v_buffer[GOLDEN_FRAME] = gld_yv12->v_buffer + recon_uvoffset;
John Koleszar's avatar
John Koleszar committed
481
482
483
484
485
486
    }
    else
        skip_mode[GOLDEN_FRAME] = 1;

    if (cpi->ref_frame_flags & VP8_ALT_FLAG && cpi->source_alt_ref_active)
    {
487
488
        YV12_BUFFER_CONFIG *alt_yv12 = &cpi->common.yv12_fb[cpi->common.alt_fb_idx];

John Koleszar's avatar
John Koleszar committed
489
        vp8_find_near_mvs(&x->e_mbd, x->e_mbd.mode_info_context, &nearest_mv[ALTREF_FRAME], &near_mv[ALTREF_FRAME],
490
                          &frame_best_ref_mv[ALTREF_FRAME], MDCounts[ALTREF_FRAME], ALTREF_FRAME, cpi->common.ref_frame_sign_bias);
John Koleszar's avatar
John Koleszar committed
491

492
493
494
        y_buffer[ALTREF_FRAME] = alt_yv12->y_buffer + recon_yoffset;
        u_buffer[ALTREF_FRAME] = alt_yv12->u_buffer + recon_uvoffset;
        v_buffer[ALTREF_FRAME] = alt_yv12->v_buffer + recon_uvoffset;
John Koleszar's avatar
John Koleszar committed
495
496
497
498
499
500
    }
    else
        skip_mode[ALTREF_FRAME] = 1;

    cpi->mbs_tested_so_far++;          // Count of the number of MBs tested so far this frame

Paul Wilkins's avatar
Paul Wilkins committed
501
    *returnintra = INT_MAX;
John Koleszar's avatar
John Koleszar committed
502
503
    x->skip = 0;

504
    x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
John Koleszar's avatar
John Koleszar committed
505
506
507
508
509
510
511
512
513
514
515

    // if we encode a new mv this is important
    // find the best new motion vector
    for (mode_index = 0; mode_index < MAX_MODES; mode_index++)
    {
        int frame_cost;
        int this_rd = INT_MAX;

        if (best_rd <= cpi->rd_threshes[mode_index])
            continue;

516
        x->e_mbd.mode_info_context->mbmi.ref_frame = vp8_ref_frame_order[mode_index];
John Koleszar's avatar
John Koleszar committed
517

518
        if (skip_mode[x->e_mbd.mode_info_context->mbmi.ref_frame])
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
            continue;

        // Check to see if the testing frequency for this mode is at its max
        // If so then prevent it from being tested and increase the threshold for its testing
        if (cpi->mode_test_hit_counts[mode_index] && (cpi->mode_check_freq[mode_index] > 1))
        {
            //if ( (cpi->mbs_tested_so_far / cpi->mode_test_hit_counts[mode_index]) <= cpi->mode_check_freq[mode_index] )
            if (cpi->mbs_tested_so_far <= (cpi->mode_check_freq[mode_index] * cpi->mode_test_hit_counts[mode_index]))
            {
                // Increase the threshold for coding this mode to make it less likely to be chosen
                cpi->rd_thresh_mult[mode_index] += 4;

                if (cpi->rd_thresh_mult[mode_index] > MAX_THRESHMULT)
                    cpi->rd_thresh_mult[mode_index] = MAX_THRESHMULT;

                cpi->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * cpi->rd_thresh_mult[mode_index];

                continue;
            }
        }

        // We have now reached the point where we are going to test the current mode so increment the counter for the number of times it has been tested
        cpi->mode_test_hit_counts[mode_index] ++;

        rate2 = 0;
        distortion2 = 0;

        this_mode = vp8_mode_order[mode_index];
547

John Koleszar's avatar
John Koleszar committed
548
549
550
        // Experimental debug code.
        //all_rds[mode_index] = -1;

551
552
        x->e_mbd.mode_info_context->mbmi.mode = this_mode;
        x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
John Koleszar's avatar
John Koleszar committed
553
554

        // Work out the cost assosciated with selecting the reference frame
555
556
        frame_cost =
            x->e_mbd.ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
John Koleszar's avatar
John Koleszar committed
557
558
559
        rate2 += frame_cost;

        // everything but intra
560
        if (x->e_mbd.mode_info_context->mbmi.ref_frame)
John Koleszar's avatar
John Koleszar committed
561
        {
562
563
564
565
566
            x->e_mbd.pre.y_buffer = y_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame];
            x->e_mbd.pre.u_buffer = u_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame];
            x->e_mbd.pre.v_buffer = v_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame];
            mode_mv[NEARESTMV] = nearest_mv[x->e_mbd.mode_info_context->mbmi.ref_frame];
            mode_mv[NEARMV] = near_mv[x->e_mbd.mode_info_context->mbmi.ref_frame];
567
            best_ref_mv = frame_best_ref_mv[x->e_mbd.mode_info_context->mbmi.ref_frame];
568
            memcpy(mdcounts, MDCounts[x->e_mbd.mode_info_context->mbmi.ref_frame], sizeof(mdcounts));
John Koleszar's avatar
John Koleszar committed
569
570
        }

571
572
573
574
        // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
        // unless ARNR filtering is enabled in which case we want
        // an unfiltered alternative
        if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
John Koleszar's avatar
John Koleszar committed
575
        {
576
            if (this_mode != ZEROMV || x->e_mbd.mode_info_context->mbmi.ref_frame != ALTREF_FRAME)
John Koleszar's avatar
John Koleszar committed
577
578
579
                continue;
        }

580
        if(cpi->sf.improved_mv_pred && x->e_mbd.mode_info_context->mbmi.mode == NEWMV)
581
582
583
584
585
586
587
588
589
590
591
        {
            if(!saddone)
            {
                vp8_cal_sad(cpi,xd,x, recon_yoffset ,&near_sadidx[0] );
                saddone = 1;
            }

            vp8_mv_pred(cpi, &x->e_mbd, x->e_mbd.mode_info_context, &mvp,
                        x->e_mbd.mode_info_context->mbmi.ref_frame, cpi->common.ref_frame_sign_bias, &sr, &near_sadidx[0]);

            /* adjust mvp to make sure it is within MV range */
Scott LaVarnway's avatar
Scott LaVarnway committed
592
593
            vp8_clamp_mv(&mvp,
                         best_ref_mv.as_mv.col - MAX_FULL_PEL_VAL,
594
595
596
                         best_ref_mv.as_mv.col + MAX_FULL_PEL_VAL,
                         best_ref_mv.as_mv.row - MAX_FULL_PEL_VAL,
                         best_ref_mv.as_mv.row + MAX_FULL_PEL_VAL);
597
598
        }

John Koleszar's avatar
John Koleszar committed
599
600
601
        switch (this_mode)
        {
        case B_PRED:
602
            // Pass best so far to pick_intra4x4mby_modes to use as breakout
603
            distortion2 = *returndistortion;
604
            pick_intra4x4mby_modes(IF_RTCD(&cpi->rtcd), x, &rate, &distortion2);
John Koleszar's avatar
John Koleszar committed
605
606
607
608
609
610
611

            if (distortion2 == INT_MAX)
            {
                this_rd = INT_MAX;
            }
            else
            {
612
613
                rate2 += rate;
                distortion2 = VARIANCE_INVOKE
614
                                (&cpi->rtcd.variance, var16x16)(
615
                                    x->src.y_buffer, x->src.y_stride,
616
                                    x->e_mbd.predictor, 16, &sse);
Yunqing Wang's avatar
Yunqing Wang committed
617
                this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
John Koleszar's avatar
John Koleszar committed
618
619
620
621

                if (this_rd < best_intra_rd)
                {
                    best_intra_rd = this_rd;
Paul Wilkins's avatar
Paul Wilkins committed
622
                    *returnintra = distortion2;
John Koleszar's avatar
John Koleszar committed
623
624
625
626
627
628
629
630
631
632
633
634
635
636
                }
            }

            break;

        case SPLITMV:

            // Split MV modes currently not supported when RD is nopt enabled.
            break;

        case DC_PRED:
        case V_PRED:
        case H_PRED:
        case TM_PRED:
637
638
            RECON_INVOKE(&cpi->common.rtcd.recon, build_intra_predictors_mby)
                (&x->e_mbd);
639
640
641
            distortion2 = VARIANCE_INVOKE(&cpi->rtcd.variance, var16x16)
                                          (x->src.y_buffer, x->src.y_stride,
                                          x->e_mbd.predictor, 16, &sse);
642
            rate2 += x->mbmode_cost[x->e_mbd.frame_type][x->e_mbd.mode_info_context->mbmi.mode];
Yunqing Wang's avatar
Yunqing Wang committed
643
            this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
John Koleszar's avatar
John Koleszar committed
644
645
646
647

            if (this_rd < best_intra_rd)
            {
                best_intra_rd = this_rd;
Paul Wilkins's avatar
Paul Wilkins committed
648
                *returnintra = distortion2;
John Koleszar's avatar
John Koleszar committed
649
650
651
652
653
654
655
656
657
            }
            break;

        case NEWMV:
        {
            int thissme;
            int step_param;
            int further_steps;
            int n = 0;
658
            int sadpb = x->sadperbit16;
John Koleszar's avatar
John Koleszar committed
659

660
661
662
663
            int col_min;
            int col_max;
            int row_min;
            int row_max;
664
665
666
667
668
669

            int tmp_col_min = x->mv_col_min;
            int tmp_col_max = x->mv_col_max;
            int tmp_row_min = x->mv_row_min;
            int tmp_row_max = x->mv_row_max;

670
            int speed_adjust = (cpi->Speed > 5) ? ((cpi->Speed >= 8)? 3 : 2) : 1;
John Koleszar's avatar
John Koleszar committed
671

672
            // Further step/diamond searches as necessary
673
674
675
            step_param = cpi->sf.first_step + speed_adjust;

            if(cpi->sf.improved_mv_pred)
John Koleszar's avatar
John Koleszar committed
676
            {
677
678
679
680
                sr += speed_adjust;
                //adjust search range according to sr from mv prediction
                if(sr > step_param)
                    step_param = sr;
681
682
            }else
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
683
                mvp.as_int = best_ref_mv.as_int;
John Koleszar's avatar
John Koleszar committed
684
685
            }

686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
            col_min = (best_ref_mv.as_mv.col - MAX_FULL_PEL_VAL) >>3;
            col_max = (best_ref_mv.as_mv.col + MAX_FULL_PEL_VAL) >>3;
            row_min = (best_ref_mv.as_mv.row - MAX_FULL_PEL_VAL) >>3;
            row_max = (best_ref_mv.as_mv.row + MAX_FULL_PEL_VAL) >>3;

            // Get intersection of UMV window and valid MV window to reduce # of checks in diamond search.
            if (x->mv_col_min < col_min )
                x->mv_col_min = col_min;
            if (x->mv_col_max > col_max )
                x->mv_col_max = col_max;
            if (x->mv_row_min < row_min )
                x->mv_row_min = row_min;
            if (x->mv_row_max > row_max )
                x->mv_row_max = row_max;

701
702
            further_steps = (cpi->Speed >= 8)? 0: (cpi->sf.max_step_search_steps - 1 - step_param);

John Koleszar's avatar
John Koleszar committed
703
704
            if (cpi->sf.search_method == HEX)
            {
705
                bestsme = vp8_hex_search(x, b, d, &mvp, &d->bmi.mv, step_param,
706
                                      sadpb, &cpi->fn_ptr[BLOCK_16X16],
707
                                      x->mvsadcost, x->mvcost, &best_ref_mv);
Scott LaVarnway's avatar
Scott LaVarnway committed
708
                mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
John Koleszar's avatar
John Koleszar committed
709
710
711
            }
            else
            {
712
713
714
715
                bestsme = cpi->diamond_search_sad(x, b, d, &mvp, &d->bmi.mv,
                                      step_param, sadpb, &num00,
                                      &cpi->fn_ptr[BLOCK_16X16],
                                      x->mvcost, &best_ref_mv);
Scott LaVarnway's avatar
Scott LaVarnway committed
716
                mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
John Koleszar's avatar
John Koleszar committed
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732

                // Further step/diamond searches as necessary
                n = 0;
                //further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;

                n = num00;
                num00 = 0;

                while (n < further_steps)
                {
                    n++;

                    if (num00)
                        num00--;
                    else
                    {
Scott LaVarnway's avatar
Scott LaVarnway committed
733
734
735
736
                        thissme =
                        cpi->diamond_search_sad(x, b, d, &mvp,
                                                &d->bmi.mv,
                                                step_param + n,
737
                                                sadpb, &num00,
Scott LaVarnway's avatar
Scott LaVarnway committed
738
739
                                                &cpi->fn_ptr[BLOCK_16X16],
                                                x->mvcost, &best_ref_mv);
John Koleszar's avatar
John Koleszar committed
740
741
742
                        if (thissme < bestsme)
                        {
                            bestsme = thissme;
Scott LaVarnway's avatar
Scott LaVarnway committed
743
                            mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
John Koleszar's avatar
John Koleszar committed
744
745
746
                        }
                        else
                        {
Scott LaVarnway's avatar
Scott LaVarnway committed
747
                            d->bmi.mv.as_int = mode_mv[NEWMV].as_int;
John Koleszar's avatar
John Koleszar committed
748
749
750
751
752
                        }
                    }
                }
            }

753
754
755
756
            x->mv_col_min = tmp_col_min;
            x->mv_col_max = tmp_col_max;
            x->mv_row_min = tmp_row_min;
            x->mv_row_max = tmp_row_max;
John Koleszar's avatar
John Koleszar committed
757

758
            if (bestsme < INT_MAX)
759
760
761
762
763
                cpi->find_fractional_mv_step(x, b, d, &d->bmi.mv, &best_ref_mv,
                                             x->errorperbit,
                                             &cpi->fn_ptr[BLOCK_16X16],
                                             cpi->mb.mvcost,
                                             &distortion2,&sse);
John Koleszar's avatar
John Koleszar committed
764

Scott LaVarnway's avatar
Scott LaVarnway committed
765
            mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
John Koleszar's avatar
John Koleszar committed
766

767
768
769
            // mv cost;
            rate2 += vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv, cpi->mb.mvcost, 128);
        }
John Koleszar's avatar
John Koleszar committed
770
771
772
773

        case NEARESTMV:
        case NEARMV:

Scott LaVarnway's avatar
Scott LaVarnway committed
774
            if (mode_mv[this_mode].as_int == 0)
John Koleszar's avatar
John Koleszar committed
775
776
777
778
779
780
781
                continue;

        case ZEROMV:

            // Trap vectors that reach beyond the UMV borders
            // Note that ALL New MV, Nearest MV Near MV and Zero MV code drops through to this point
            // because of the lack of break statements in the previous two cases.
Scott LaVarnway's avatar
Scott LaVarnway committed
782
783
            if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) || ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) ||
                ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) || ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max))
John Koleszar's avatar
John Koleszar committed
784
785
786
                continue;

            rate2 += vp8_cost_mv_ref(this_mode, mdcounts);
787
788
            x->e_mbd.mode_info_context->mbmi.mv.as_int =
                                                    mode_mv[this_mode].as_int;
John Koleszar's avatar
John Koleszar committed
789

790
791
792
793
794
            if((this_mode != NEWMV) ||
                !(have_subp_search) || cpi->common.full_pixel==1)
                distortion2 = get_inter_mbpred_error(x,
                                                     &cpi->fn_ptr[BLOCK_16X16],
                                                     &sse, mode_mv[this_mode]);
John Koleszar's avatar
John Koleszar committed
795

Yunqing Wang's avatar
Yunqing Wang committed
796
            this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
John Koleszar's avatar
John Koleszar committed
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

            if (cpi->active_map_enabled && x->active_ptr[0] == 0)
            {
                x->skip = 1;
            }
            else if (sse < x->encode_breakout)
            {
                // Check u and v to make sure skip is ok
                int sse2 = 0;

                sse2 = VP8_UVSSE(x, IF_RTCD(&cpi->rtcd.variance));

                if (sse2 * 2 < x->encode_breakout)
                    x->skip = 1;
                else
                    x->skip = 0;
            }

            break;
        default:
            break;
        }

        // Experimental debug code.
        //all_rds[mode_index] = this_rd;

        if (this_rd < best_rd || x->skip)
        {
            // Note index of best mode
            best_mode_index = mode_index;

            *returnrate = rate2;
            *returndistortion = distortion2;
            best_rd = this_rd;
831
            vpx_memcpy(&best_mbmode, &x->e_mbd.mode_info_context->mbmi, sizeof(MB_MODE_INFO));
John Koleszar's avatar
John Koleszar committed
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873

            // Testing this mode gave rise to an improvement in best error score. Lower threshold a bit for next time
            cpi->rd_thresh_mult[mode_index] = (cpi->rd_thresh_mult[mode_index] >= (MIN_THRESHMULT + 2)) ? cpi->rd_thresh_mult[mode_index] - 2 : MIN_THRESHMULT;
            cpi->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * cpi->rd_thresh_mult[mode_index];
        }

        // If the mode did not help improve the best error case then raise the threshold for testing that mode next time around.
        else
        {
            cpi->rd_thresh_mult[mode_index] += 4;

            if (cpi->rd_thresh_mult[mode_index] > MAX_THRESHMULT)
                cpi->rd_thresh_mult[mode_index] = MAX_THRESHMULT;

            cpi->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * cpi->rd_thresh_mult[mode_index];
        }

        if (x->skip)
            break;
    }

    // Reduce the activation RD thresholds for the best choice mode
    if ((cpi->rd_baseline_thresh[best_mode_index] > 0) && (cpi->rd_baseline_thresh[best_mode_index] < (INT_MAX >> 2)))
    {
        int best_adjustment = (cpi->rd_thresh_mult[best_mode_index] >> 3);

        cpi->rd_thresh_mult[best_mode_index] = (cpi->rd_thresh_mult[best_mode_index] >= (MIN_THRESHMULT + best_adjustment)) ? cpi->rd_thresh_mult[best_mode_index] - best_adjustment : MIN_THRESHMULT;
        cpi->rd_threshes[best_mode_index] = (cpi->rd_baseline_thresh[best_mode_index] >> 7) * cpi->rd_thresh_mult[best_mode_index];
    }


    {
        int this_rdbin = (*returndistortion >> 7);

        if (this_rdbin >= 1024)
        {
            this_rdbin = 1023;
        }

        cpi->error_bins[this_rdbin] ++;
    }

874
875
    if (cpi->is_src_frame_alt_ref &&
        (best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME))
John Koleszar's avatar
John Koleszar committed
876
    {
877
878
        x->e_mbd.mode_info_context->mbmi.mode = ZEROMV;
        x->e_mbd.mode_info_context->mbmi.ref_frame = ALTREF_FRAME;
879
        x->e_mbd.mode_info_context->mbmi.mv.as_int = 0;
880
881
882
883
884
        x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
        x->e_mbd.mode_info_context->mbmi.mb_skip_coeff =
                                        (cpi->common.mb_no_coeff_skip) ? 1 : 0;
        x->e_mbd.mode_info_context->mbmi.partitioning = 0;

885
        return;
John Koleszar's avatar
John Koleszar committed
886
887
    }

888
    /* set to the best mb mode */
889
    vpx_memcpy(&x->e_mbd.mode_info_context->mbmi, &best_mbmode, sizeof(MB_MODE_INFO));
John Koleszar's avatar
John Koleszar committed
890

891
892
893
    if (best_mbmode.mode <= B_PRED)
    {
        /* set mode_info_context->mbmi.uv_mode */
894
        pick_intra_mbuv_mode(x);
895
    }
Scott LaVarnway's avatar
Scott LaVarnway committed
896

897
    update_mvcount(cpi, &x->e_mbd, &frame_best_ref_mv[xd->mode_info_context->mbmi.ref_frame]);
John Koleszar's avatar
John Koleszar committed
898
}
899
900
901
902
903


void vp8_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate_)
{
    int error4x4, error16x16 = INT_MAX;
904
    int rate, best_rate = 0, distortion, best_distortion;
905
906
    MB_PREDICTION_MODE mode, best_mode = DC_PRED;
    int this_rd;
907
    unsigned int sse;
908

909
910
    x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;

911
912
913
914
915
916
917
    pick_intra_mbuv_mode(x);

    for (mode = DC_PRED; mode <= TM_PRED; mode ++)
    {
        x->e_mbd.mode_info_context->mbmi.mode = mode;
        RECON_INVOKE(&cpi->common.rtcd.recon, build_intra_predictors_mby)
            (&x->e_mbd);
918
919
        distortion = VARIANCE_INVOKE(&cpi->rtcd.variance, var16x16)
            (x->src.y_buffer, x->src.y_stride, x->e_mbd.predictor, 16, &sse);
920
921
922
923
924
925
926
927
        rate = x->mbmode_cost[x->e_mbd.frame_type][mode];
        this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);

        if (error16x16 > this_rd)
        {
            error16x16 = this_rd;
            best_mode = mode;
            best_distortion = distortion;
928
            best_rate = rate;
929
930
931
932
933
934
935
        }
    }
    x->e_mbd.mode_info_context->mbmi.mode = best_mode;

    error4x4 = pick_intra4x4mby_modes(IF_RTCD(&cpi->rtcd), x, &rate,
                                      &best_distortion);
    if (error4x4 < error16x16)
936
    {
937
        x->e_mbd.mode_info_context->mbmi.mode = B_PRED;
938
939
        best_rate = rate;
    }
940

941
    *rate_ = best_rate;
942
}