encodeframe.c 41 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
#include "vpx_config.h"
John Koleszar's avatar
John Koleszar committed
13 14
#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 25
#include "rdopt.h"
#include "pickinter.h"
John Koleszar's avatar
John Koleszar committed
26 27
#include "vp8/common/findnearmv.h"
#include "vp8/common/reconintra.h"
John Koleszar's avatar
John Koleszar committed
28 29
#include <stdio.h>
#include <limits.h>
John Koleszar's avatar
John Koleszar committed
30
#include "vp8/common/subpixel.h"
31
#include "vp8/common/invtrans.h"
John Koleszar's avatar
John Koleszar committed
32 33 34 35 36 37 38 39 40 41
#include "vpx_ports/vpx_timer.h"

#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
extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
42 43 44 45 46 47
extern void vp8_calc_ref_frame_costs(int *ref_frame_cost,
                                     int prob_intra,
                                     int prob_last,
                                     int prob_garf
                                    );
extern void vp8_convert_rfct_to_prob(VP8_COMP *const cpi);
John Koleszar's avatar
John Koleszar committed
48 49 50 51 52 53 54 55 56
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);
void vp8_build_block_offsets(MACROBLOCK *x);
void vp8_setup_block_ptrs(MACROBLOCK *x);
Yunqing Wang's avatar
Yunqing Wang committed
57 58
int vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t, int recon_yoffset, int recon_uvoffset, int mb_row, int mb_col);
int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t, int mb_row, int mb_col);
59
static void adjust_act_zbin( VP8_COMP *cpi, MACROBLOCK *x );
John Koleszar's avatar
John Koleszar committed
60 61 62 63 64 65 66 67 68 69 70

#ifdef MODE_STATS
unsigned int inter_y_modes[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned int inter_uv_modes[4] = {0, 0, 0, 0};
unsigned int inter_b_modes[15]  = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned int y_modes[5]   = {0, 0, 0, 0, 0};
unsigned int uv_modes[4]  = {0, 0, 0, 0};
unsigned int b_modes[14]  = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
#endif


71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
/* 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.
 */
static const unsigned char VP8_VAR_OFFS[16]=
{
    128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
};

88 89

// Original activity measure from Tim T's code.
90
static unsigned int tt_activity_measure( VP8_COMP *cpi, MACROBLOCK *x )
91 92 93 94 95 96 97 98 99 100
{
    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.).
     */
Yaowu Xu's avatar
Yaowu Xu committed
101 102 103
    act =     VARIANCE_INVOKE(&cpi->rtcd.variance, var16x16)(x->src.y_buffer,
                    x->src.y_stride, VP8_VAR_OFFS, 0, &sse);
    act = act<<4;
104

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

109 110 111
    return act;
}

112
// Stub for alternative experimental activity measures.
113 114
static unsigned int alt_activity_measure( VP8_COMP *cpi,
                                          MACROBLOCK *x, int use_dc_pred )
115
{
Tero Rintaluoma's avatar
Tero Rintaluoma committed
116
    return vp8_encode_intra(cpi,x, use_dc_pred);
117 118 119 120 121
}


// Measure the activity of the current macroblock
// What we measure here is TBD so abstracted to this function
122 123 124
#define ALT_ACT_MEASURE 1
static unsigned int mb_activity_measure( VP8_COMP *cpi, MACROBLOCK *x,
                                  int mb_row, int mb_col)
125 126 127
{
    unsigned int mb_activity;

128
    if  ( ALT_ACT_MEASURE )
129
    {
130 131 132 133
        int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);

        // Or use and alternative.
        mb_activity = alt_activity_measure( cpi, x, use_dc_pred );
134 135 136
    }
    else
    {
137 138
        // Original activity measure from Tim T's code.
        mb_activity = tt_activity_measure( cpi, x );
139 140
    }

141 142 143
    if ( mb_activity < VP8_ACTIVITY_AVG_MIN )
        mb_activity = VP8_ACTIVITY_AVG_MIN;

144 145 146 147
    return mb_activity;
}

// Calculate an "average" mb activity value for the frame
148
#define ACT_MEDIAN 0
149
static void calc_av_activity( VP8_COMP *cpi, int64_t activity_sum )
150
{
151 152 153 154 155 156 157 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 187 188 189 190 191 192 193 194
#if ACT_MEDIAN
    // 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;
            }
        }

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

        cpi->activity_avg = median;

        vpx_free(sortlist);
    }
#else
195 196
    // Simple mean for now
    cpi->activity_avg = (unsigned int)(activity_sum/cpi->common.MBs);
197 198
#endif

199 200
    if (cpi->activity_avg < VP8_ACTIVITY_AVG_MIN)
        cpi->activity_avg = VP8_ACTIVITY_AVG_MIN;
201 202 203 204

    // Experimental code: return fixed value normalized for several clips
    if  ( ALT_ACT_MEASURE )
        cpi->activity_avg = 100000;
205 206
}

207
#define USE_ACT_INDEX   0
208
#define OUTPUT_NORM_ACT_STATS   0
209 210 211 212

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

217 218 219
    int64_t act;
    int64_t a;
    int64_t b;
220 221 222

#if OUTPUT_NORM_ACT_STATS
    FILE *f = fopen("norm_act.stt", "a");
223
    fprintf(f, "\n%12d\n", cpi->activity_avg );
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
#endif

    // Reset pointers to start of activity map
    x->mb_activity_ptr = cpi->mb_activity_map;

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

            // Calculate a normalized activity number
239 240
            a = act + 4*cpi->activity_avg;
            b = 4*act + cpi->activity_avg;
241 242

            if ( b >= a )
243
                *(x->activity_ptr) = (int)((b + (a>>1))/a) - 1;
244
            else
245
                *(x->activity_ptr) = 1 - (int)((a + (b>>1))/b);
246 247

#if OUTPUT_NORM_ACT_STATS
248
            fprintf(f, " %6d", *(x->mb_activity_ptr));
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
#endif
            // Increment activity map pointers
            x->mb_activity_ptr++;
        }

#if OUTPUT_NORM_ACT_STATS
        fprintf(f, "\n");
#endif

    }

#if OUTPUT_NORM_ACT_STATS
    fclose(f);
#endif

}
265
#endif
266 267 268

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

275 276 277 278 279 280
#if ALT_ACT_MEASURE
    YV12_BUFFER_CONFIG *new_yv12 = &cm->yv12_fb[cm->new_fb_idx];
    int recon_yoffset;
    int recon_y_stride = new_yv12->y_stride;
#endif

281 282
    int mb_row, mb_col;
    unsigned int mb_activity;
283
    int64_t activity_sum = 0;
284 285 286 287

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

304
            // measure activity
305
            mb_activity = mb_activity_measure( cpi, x, mb_row, mb_col );
306 307 308 309 310 311 312 313 314 315 316 317 318 319

            // Keep frame sum
            activity_sum += mb_activity;

            // Store MB level activity details.
            *x->mb_activity_ptr = mb_activity;

            // Increment activity map pointer
            x->mb_activity_ptr++;

            // adjust to the next column of source macroblocks
            x->src.y_buffer += 16;
        }

320

321 322
        // adjust to the next row of mbs
        x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
323 324 325 326 327 328 329

#if ALT_ACT_MEASURE
        //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);
#endif

330 331 332 333 334
    }

    // Calculate an "average" MB activity
    calc_av_activity(cpi, activity_sum);

335 336 337 338 339
#if USE_ACT_INDEX
    // Calculate an activity index number of each mb
    calc_activity_index( cpi, x );
#endif

340 341
}

342
// Macroblock activity masking
343 344
void vp8_activity_masking(VP8_COMP *cpi, MACROBLOCK *x)
{
345 346
#if USE_ACT_INDEX
    x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2);
347 348
    x->errorperbit = x->rdmult * 100 /(110 * x->rddiv);
    x->errorperbit += (x->errorperbit==0);
349
#else
350 351 352
    int64_t a;
    int64_t b;
    int64_t act = *(x->mb_activity_ptr);
353 354

    // Apply the masking to the RD multiplier.
355 356
    a = act + (2*cpi->activity_avg);
    b = (2*act) + cpi->activity_avg;
357

358
    x->rdmult = (unsigned int)(((int64_t)x->rdmult*b + (a>>1))/a);
359 360
    x->errorperbit = x->rdmult * 100 /(110 * x->rddiv);
    x->errorperbit += (x->errorperbit==0);
361
#endif
362

363 364
    // Activity based Zbin adjustment
    adjust_act_zbin(cpi, x);
365
}
John Koleszar's avatar
John Koleszar committed
366 367 368 369 370 371 372 373 374 375 376 377 378

static
void encode_mb_row(VP8_COMP *cpi,
                   VP8_COMMON *cm,
                   int mb_row,
                   MACROBLOCK  *x,
                   MACROBLOCKD *xd,
                   TOKENEXTRA **tp,
                   int *segment_counts,
                   int *totalrate)
{
    int recon_yoffset, recon_uvoffset;
    int mb_col;
379 380 381 382
    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;
383
    int map_index = (mb_row * cpi->common.mb_cols);
John Koleszar's avatar
John Koleszar committed
384

Attila Nagy's avatar
Attila Nagy committed
385 386 387 388 389 390 391 392 393 394
#if CONFIG_MULTITHREAD
    const int nsync = cpi->mt_sync_range;
    const int rightmost_col = cm->mb_cols - 1;
    volatile const int *last_row_current_mb_col;

    if ((cpi->b_multi_threaded != 0) && (mb_row != 0))
        last_row_current_mb_col = &cpi->mt_current_mb_col[mb_row - 1];
    else
        last_row_current_mb_col = &rightmost_col;
#endif
John Koleszar's avatar
John Koleszar committed
395 396

    // reset above block coeffs
397
    xd->above_context = cm->above_context;
John Koleszar's avatar
John Koleszar committed
398 399 400 401 402 403 404 405

    xd->up_available = (mb_row != 0);
    recon_yoffset = (mb_row * recon_y_stride * 16);
    recon_uvoffset = (mb_row * recon_uv_stride * 8);

    cpi->tplist[mb_row].start = *tp;
    //printf("Main mb_row = %d\n", mb_row);

406 407 408 409 410 411 412 413
    // Distance of Mb to the top & bottom edges, specified in 1/8th pel
    // units as they are always compared to values that are in 1/8th pel units
    xd->mb_to_top_edge = -((mb_row * 16) << 3);
    xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;

    // Set up limit values for vertical motion vector components
    // to prevent them extending beyond the UMV borders
    x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
414
    x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16)
415 416
                        + (VP8BORDERINPIXELS - 16);

417 418 419
    // Set the mb activity pointer to the start of the row.
    x->mb_activity_ptr = &cpi->mb_activity_map[map_index];

John Koleszar's avatar
John Koleszar committed
420 421 422
    // for each macroblock col in image
    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
    {
423 424
        // Distance of Mb to the left & right edges, specified in
        // 1/8th pel units as they are always compared to values
425
        // that are in 1/8th pel units
John Koleszar's avatar
John Koleszar committed
426 427 428
        xd->mb_to_left_edge = -((mb_col * 16) << 3);
        xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3;

429 430
        // Set up limit values for horizontal motion vector components
        // to prevent them extending beyond the UMV borders
John Koleszar's avatar
John Koleszar committed
431
        x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
432
        x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16)
433
                            + (VP8BORDERINPIXELS - 16);
John Koleszar's avatar
John Koleszar committed
434

435 436 437
        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
438 439
        xd->left_available = (mb_col != 0);

440 441 442
        x->rddiv = cpi->RDDIV;
        x->rdmult = cpi->RDMULT;

443 444 445
        //Copy current mb to a buffer
        RECON_INVOKE(&xd->rtcd->recon, copy16x16)(x->src.y_buffer, x->src.y_stride, x->thismb, 16);

Attila Nagy's avatar
Attila Nagy committed
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
#if CONFIG_MULTITHREAD
        if ((cpi->b_multi_threaded != 0) && (mb_row != 0))
        {
            if ((mb_col & (nsync - 1)) == 0)
            {
                while (mb_col > (*last_row_current_mb_col - nsync)
                        && (*last_row_current_mb_col) != (cm->mb_cols - 1))
                {
                    x86_pause_hint();
                    thread_sleep(0);
                }
            }
        }
#endif

John Koleszar's avatar
John Koleszar committed
461
        if(cpi->oxcf.tuning == VP8_TUNE_SSIM)
462
            vp8_activity_masking(cpi, x);
463

John Koleszar's avatar
John Koleszar committed
464
        // Is segmentation enabled
465
        // MB level adjustment to quantizer
John Koleszar's avatar
John Koleszar committed
466 467 468
        if (xd->segmentation_enabled)
        {
            // Code to set segment id in xd->mbmi.segment_id for current MB (with range checking)
469 470
            if (cpi->segmentation_map[map_index+mb_col] <= 3)
                xd->mode_info_context->mbmi.segment_id = cpi->segmentation_map[map_index+mb_col];
John Koleszar's avatar
John Koleszar committed
471
            else
472
                xd->mode_info_context->mbmi.segment_id = 0;
John Koleszar's avatar
John Koleszar committed
473

474
            vp8cx_mb_init_quantizer(cpi, x, 1);
John Koleszar's avatar
John Koleszar committed
475 476
        }
        else
477
            xd->mode_info_context->mbmi.segment_id = 0;         // Set to Segment 0 by default
John Koleszar's avatar
John Koleszar committed
478

479
        x->active_ptr = cpi->active_map + map_index + mb_col;
John Koleszar's avatar
John Koleszar committed
480 481 482

        if (cm->frame_type == KEY_FRAME)
        {
Yunqing Wang's avatar
Yunqing Wang committed
483
            *totalrate += vp8cx_encode_intra_macro_block(cpi, x, tp, mb_row, mb_col);
John Koleszar's avatar
John Koleszar committed
484 485 486 487 488 489
#ifdef MODE_STATS
            y_modes[xd->mbmi.mode] ++;
#endif
        }
        else
        {
Yunqing Wang's avatar
Yunqing Wang committed
490
            *totalrate += vp8cx_encode_inter_macroblock(cpi, x, tp, recon_yoffset, recon_uvoffset, mb_row, mb_col);
John Koleszar's avatar
John Koleszar committed
491 492 493 494 495 496 497 498 499 500

#ifdef MODE_STATS
            inter_y_modes[xd->mbmi.mode] ++;

            if (xd->mbmi.mode == SPLITMV)
            {
                int b;

                for (b = 0; b < xd->mbmi.partition_count; b++)
                {
501
                    inter_b_modes[x->partition->bmi[b].mode] ++;
John Koleszar's avatar
John Koleszar committed
502 503 504 505 506 507
                }
            }

#endif

            // Count of last ref frame 0,0 useage
508
            if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME))
John Koleszar's avatar
John Koleszar committed
509 510 511 512 513
                cpi->inter_zz_count ++;

            // Special case code for cyclic refresh
            // If cyclic update enabled then copy xd->mbmi.segment_id; (which may have been updated based on mode
            // during vp8cx_encode_inter_macroblock()) back into the global sgmentation map
514 515
            if ((cpi->current_layer == 0) &&
                (cpi->cyclic_refresh_mode_enabled && xd->segmentation_enabled))
John Koleszar's avatar
John Koleszar committed
516
            {
517
                cpi->segmentation_map[map_index+mb_col] = xd->mode_info_context->mbmi.segment_id;
John Koleszar's avatar
John Koleszar committed
518 519 520 521

                // If the block has been refreshed mark it as clean (the magnitude of the -ve influences how long it will be before we consider another refresh):
                // Else if it was coded (last frame 0,0) and has not already been refreshed then mark it as a candidate for cleanup next time (marked 0)
                // else mark it as dirty (1).
522
                if (xd->mode_info_context->mbmi.segment_id)
523
                    cpi->cyclic_refresh_map[map_index+mb_col] = -1;
524
                else if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME))
John Koleszar's avatar
John Koleszar committed
525
                {
526 527
                    if (cpi->cyclic_refresh_map[map_index+mb_col] == 1)
                        cpi->cyclic_refresh_map[map_index+mb_col] = 0;
John Koleszar's avatar
John Koleszar committed
528 529
                }
                else
530
                    cpi->cyclic_refresh_map[map_index+mb_col] = 1;
John Koleszar's avatar
John Koleszar committed
531 532 533 534 535 536

            }
        }

        cpi->tplist[mb_row].stop = *tp;

537 538 539 540 541
        // Increment pointer into gf useage flags structure.
        x->gf_active_ptr++;

        // Increment the activity mask pointers.
        x->mb_activity_ptr++;
John Koleszar's avatar
John Koleszar committed
542 543 544 545 546 547 548 549 550 551

        // adjust to the next column of macroblocks
        x->src.y_buffer += 16;
        x->src.u_buffer += 8;
        x->src.v_buffer += 8;

        recon_yoffset += 16;
        recon_uvoffset += 8;

        // Keep track of segment useage
552
        segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
John Koleszar's avatar
John Koleszar committed
553 554 555

        // skip to next mb
        xd->mode_info_context++;
556
        x->partition_info++;
John Koleszar's avatar
John Koleszar committed
557

558
        xd->above_context++;
Attila Nagy's avatar
Attila Nagy committed
559 560 561 562 563 564
#if CONFIG_MULTITHREAD
        if (cpi->b_multi_threaded != 0)
        {
            cpi->mt_current_mb_col[mb_row] = mb_col;
        }
#endif
John Koleszar's avatar
John Koleszar committed
565 566 567 568
    }

    //extend the recon for intra prediction
    vp8_extend_mb_row(
569
        &cm->yv12_fb[dst_fb_idx],
John Koleszar's avatar
John Koleszar committed
570 571 572 573 574 575
        xd->dst.y_buffer + 16,
        xd->dst.u_buffer + 8,
        xd->dst.v_buffer + 8);

    // this is to account for the border
    xd->mode_info_context++;
576
    x->partition_info++;
John Koleszar's avatar
John Koleszar committed
577

Attila Nagy's avatar
Attila Nagy committed
578 579 580 581 582 583 584
#if CONFIG_MULTITHREAD
    if ((cpi->b_multi_threaded != 0) && (mb_row == cm->mb_rows - 1))
    {
        sem_post(&cpi->h_event_end_encoding); /* signal frame encoding end */
    }
#endif
}
John Koleszar's avatar
John Koleszar committed
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
void init_encode_frame_mb_context(VP8_COMP *cpi)
{
    MACROBLOCK *const x = & cpi->mb;
    VP8_COMMON *const cm = & cpi->common;
    MACROBLOCKD *const xd = & x->e_mbd;

    // GF active flags data structure
    x->gf_active_ptr = (signed char *)cpi->gf_active_flags;

    // Activity map pointer
    x->mb_activity_ptr = cpi->mb_activity_map;

    x->vector_range = 32;

    x->act_zbin_adj = 0;

    x->partition_info = x->pi;

    xd->mode_info_context = cm->mi;
    xd->mode_info_stride = cm->mode_info_stride;

    xd->frame_type = cm->frame_type;

    xd->frames_since_golden = cm->frames_since_golden;
    xd->frames_till_alt_ref_frame = cm->frames_till_alt_ref_frame;

    // reset intra mode contexts
    if (cm->frame_type == KEY_FRAME)
        vp8_init_mbmode_probs(cm);

    // Copy data over into macro block data sturctures.
    x->src = * cpi->Source;
    xd->pre = cm->yv12_fb[cm->lst_fb_idx];
    xd->dst = cm->yv12_fb[cm->new_fb_idx];

    // set up frame for intra coded blocks
    vp8_setup_intra_recon(&cm->yv12_fb[cm->new_fb_idx]);

    vp8_build_block_offsets(x);

    vp8_setup_block_dptrs(&x->e_mbd);

    vp8_setup_block_ptrs(x);

    xd->mode_info_context->mbmi.mode = DC_PRED;
    xd->mode_info_context->mbmi.uv_mode = DC_PRED;

    xd->left_context = &cm->left_context;

    vp8_zero(cpi->count_mb_ref_frame_usage)
    vp8_zero(cpi->ymode_count)
    vp8_zero(cpi->uv_mode_count)

    x->mvc = cm->fc.mvc;

    vpx_memset(cm->above_context, 0,
               sizeof(ENTROPY_CONTEXT_PLANES) * cm->mb_cols);
643 644 645

    // Special case treatment when GF and ARF are not sensible options for reference
    if (cpi->ref_frame_flags == VP8_LAST_FLAG)
646 647
        vp8_calc_ref_frame_costs(xd->ref_frame_cost,
                                 cpi->prob_intra_coded,255,128);
648 649
    else if ((cpi->oxcf.number_of_layers > 1) &&
               (cpi->ref_frame_flags == VP8_GOLD_FLAG))
650 651
        vp8_calc_ref_frame_costs(xd->ref_frame_cost,
                                 cpi->prob_intra_coded,1,255);
652 653
    else if ((cpi->oxcf.number_of_layers > 1) &&
                (cpi->ref_frame_flags == VP8_ALT_FLAG))
654 655
        vp8_calc_ref_frame_costs(xd->ref_frame_cost,
                                 cpi->prob_intra_coded,1,1);
656
    else
657 658 659 660
        vp8_calc_ref_frame_costs(xd->ref_frame_cost,
                                 cpi->prob_intra_coded,
                                 cpi->prob_last_coded,
                                 cpi->prob_gf_coded);
661

662 663 664
    xd->fullpixel_mask = 0xffffffff;
    if(cm->full_pixel)
        xd->fullpixel_mask = 0xfffffff8;
665 666
}

John Koleszar's avatar
John Koleszar committed
667 668 669 670 671 672 673 674 675 676 677
void vp8_encode_frame(VP8_COMP *cpi)
{
    int mb_row;
    MACROBLOCK *const x = & cpi->mb;
    VP8_COMMON *const cm = & cpi->common;
    MACROBLOCKD *const xd = & x->e_mbd;

    TOKENEXTRA *tp = cpi->tok;
    int segment_counts[MAX_MB_SEGMENTS];
    int totalrate;

678 679 680 681 682 683 684 685 686 687 688
    vpx_memset(segment_counts, 0, sizeof(segment_counts));
    totalrate = 0;

    if (cpi->compressor_speed == 2)
    {
        if (cpi->oxcf.cpu_used < 0)
            cpi->Speed = -(cpi->oxcf.cpu_used);
        else
            vp8_auto_select_speed(cpi);
    }

689 690
    // Functions setup for all frame types so we can use MC in AltRef
    if (cm->mcomp_filter_type == SIXTAP)
John Koleszar's avatar
John Koleszar committed
691
    {
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710
        xd->subpixel_predict        = SUBPIX_INVOKE(
                                        &cpi->common.rtcd.subpix, sixtap4x4);
        xd->subpixel_predict8x4     = SUBPIX_INVOKE(
                                        &cpi->common.rtcd.subpix, sixtap8x4);
        xd->subpixel_predict8x8     = SUBPIX_INVOKE(
                                        &cpi->common.rtcd.subpix, sixtap8x8);
        xd->subpixel_predict16x16   = SUBPIX_INVOKE(
                                        &cpi->common.rtcd.subpix, sixtap16x16);
    }
    else
    {
        xd->subpixel_predict        = SUBPIX_INVOKE(
                                        &cpi->common.rtcd.subpix, bilinear4x4);
        xd->subpixel_predict8x4     = SUBPIX_INVOKE(
                                        &cpi->common.rtcd.subpix, bilinear8x4);
        xd->subpixel_predict8x8     = SUBPIX_INVOKE(
                                        &cpi->common.rtcd.subpix, bilinear8x8);
        xd->subpixel_predict16x16   = SUBPIX_INVOKE(
                                      &cpi->common.rtcd.subpix, bilinear16x16);
John Koleszar's avatar
John Koleszar committed
711 712 713 714 715 716 717 718 719 720 721 722 723 724
    }

    // Reset frame count of inter 0,0 motion vector useage.
    cpi->inter_zz_count = 0;

    vpx_memset(segment_counts, 0, sizeof(segment_counts));

    cpi->prediction_error = 0;
    cpi->intra_error = 0;
    cpi->skip_true_count = 0;
    cpi->skip_false_count = 0;

#if 0
    // Experimental code
725
    cpi->frame_distortion = 0;
John Koleszar's avatar
John Koleszar committed
726 727 728
    cpi->last_mb_distortion = 0;
#endif

729 730
    xd->mode_info_context = cm->mi;

John Koleszar's avatar
John Koleszar committed
731 732 733 734 735
    vp8_zero(cpi->MVcount);
    vp8_zero(cpi->coef_counts);

    vp8cx_frame_init_quantizer(cpi);

736 737
    vp8_initialize_rd_consts(cpi,
                             vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
John Koleszar's avatar
John Koleszar committed
738 739 740

    vp8cx_initialize_me_consts(cpi, cm->base_qindex);

741 742
    if(cpi->oxcf.tuning == VP8_TUNE_SSIM)
    {
743 744
        // Initialize encode frame context.
        init_encode_frame_mb_context(cpi);
745

746 747
        // Build a frame level activity map
        build_activity_map(cpi);
748 749
    }

750 751 752
    // re-initencode frame context.
    init_encode_frame_mb_context(cpi);

John Koleszar's avatar
John Koleszar committed
753 754 755 756 757
    {
        struct vpx_usec_timer  emr_timer;
        vpx_usec_timer_start(&emr_timer);

#if CONFIG_MULTITHREAD
758 759
        if (cpi->b_multi_threaded)
        {
760 761
            int i;

John Koleszar's avatar
John Koleszar committed
762 763
            vp8cx_init_mbrthread_data(cpi, x, cpi->mb_row_ei, 1,  cpi->encoding_thread_count);

Attila Nagy's avatar
Attila Nagy committed
764
            for (i = 0; i < cm->mb_rows; i++)
765
                cpi->mt_current_mb_col[i] = -1;
John Koleszar's avatar
John Koleszar committed
766

Attila Nagy's avatar
Attila Nagy committed
767 768 769 770
            for (i = 0; i < cpi->encoding_thread_count; i++)
            {
                sem_post(&cpi->h_event_start_encoding[i]);
            }
John Koleszar's avatar
John Koleszar committed
771

Attila Nagy's avatar
Attila Nagy committed
772 773
            for (mb_row = 0; mb_row < cm->mb_rows; mb_row += (cpi->encoding_thread_count + 1))
            {
John Koleszar's avatar
John Koleszar committed
774 775 776 777 778 779 780 781 782 783 784 785
                vp8_zero(cm->left_context)

                tp = cpi->tok + mb_row * (cm->mb_cols * 16 * 24);

                encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate);

                // adjust to the next row of mbs
                x->src.y_buffer += 16 * x->src.y_stride * (cpi->encoding_thread_count + 1) - 16 * cm->mb_cols;
                x->src.u_buffer +=  8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
                x->src.v_buffer +=  8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;

                xd->mode_info_context += xd->mode_info_stride * cpi->encoding_thread_count;
786
                x->partition_info  += xd->mode_info_stride * cpi->encoding_thread_count;
787
                x->gf_active_ptr   += cm->mb_cols * cpi->encoding_thread_count;
John Koleszar's avatar
John Koleszar committed
788 789 790

            }

Attila Nagy's avatar
Attila Nagy committed
791
            sem_wait(&cpi->h_event_end_encoding); /* wait for other threads to finish */
John Koleszar's avatar
John Koleszar committed
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819

            cpi->tok_count = 0;

            for (mb_row = 0; mb_row < cm->mb_rows; mb_row ++)
            {
                cpi->tok_count += cpi->tplist[mb_row].stop - cpi->tplist[mb_row].start;
            }

            if (xd->segmentation_enabled)
            {
                int i, j;

                if (xd->segmentation_enabled)
                {

                    for (i = 0; i < cpi->encoding_thread_count; i++)
                    {
                        for (j = 0; j < 4; j++)
                            segment_counts[j] += cpi->mb_row_ei[i].segment_counts[j];
                    }
                }
            }

            for (i = 0; i < cpi->encoding_thread_count; i++)
            {
                totalrate += cpi->mb_row_ei[i].totalrate;
            }

820 821
        }
        else
John Koleszar's avatar
John Koleszar committed
822
#endif
823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838
        {
            // for each macroblock row in image
            for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
            {

                vp8_zero(cm->left_context)

                encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate);

                // adjust to the next row of mbs
                x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
                x->src.u_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
                x->src.v_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
            }

            cpi->tok_count = tp - cpi->tok;
John Koleszar's avatar
John Koleszar committed
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 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931

        }

        vpx_usec_timer_mark(&emr_timer);
        cpi->time_encode_mb_row += vpx_usec_timer_elapsed(&emr_timer);

    }


    // Work out the segment probabilites if segmentation is enabled
    if (xd->segmentation_enabled)
    {
        int tot_count;
        int i;

        // Set to defaults
        vpx_memset(xd->mb_segment_tree_probs, 255 , sizeof(xd->mb_segment_tree_probs));

        tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3];

        if (tot_count)
        {
            xd->mb_segment_tree_probs[0] = ((segment_counts[0] + segment_counts[1]) * 255) / tot_count;

            tot_count = segment_counts[0] + segment_counts[1];

            if (tot_count > 0)
            {
                xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) / tot_count;
            }

            tot_count = segment_counts[2] + segment_counts[3];

            if (tot_count > 0)
                xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) / tot_count;

            // Zero probabilities not allowed
            for (i = 0; i < MB_FEATURE_TREE_PROBS; i ++)
            {
                if (xd->mb_segment_tree_probs[i] == 0)
                    xd->mb_segment_tree_probs[i] = 1;
            }
        }
    }

    // 256 rate units to the bit
    cpi->projected_frame_size = totalrate >> 8;   // projected_frame_size in units of BYTES

    // Make a note of the percentage MBs coded Intra.
    if (cm->frame_type == KEY_FRAME)
    {
        cpi->this_frame_percent_intra = 100;
    }
    else
    {
        int tot_modes;

        tot_modes = cpi->count_mb_ref_frame_usage[INTRA_FRAME]
                    + cpi->count_mb_ref_frame_usage[LAST_FRAME]
                    + cpi->count_mb_ref_frame_usage[GOLDEN_FRAME]
                    + cpi->count_mb_ref_frame_usage[ALTREF_FRAME];

        if (tot_modes)
            cpi->this_frame_percent_intra = cpi->count_mb_ref_frame_usage[INTRA_FRAME] * 100 / tot_modes;

    }

#if 0
    {
        int cnt = 0;
        int flag[2] = {0, 0};

        for (cnt = 0; cnt < MVPcount; cnt++)
        {
            if (cm->fc.pre_mvc[0][cnt] != cm->fc.mvc[0][cnt])
            {
                flag[0] = 1;
                vpx_memcpy(cm->fc.pre_mvc[0], cm->fc.mvc[0], MVPcount);
                break;
            }
        }

        for (cnt = 0; cnt < MVPcount; cnt++)
        {
            if (cm->fc.pre_mvc[1][cnt] != cm->fc.mvc[1][cnt])
            {
                flag[1] = 1;
                vpx_memcpy(cm->fc.pre_mvc[1], cm->fc.mvc[1], MVPcount);
                break;
            }
        }

        if (flag[0] || flag[1])
932
            vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
John Koleszar's avatar
John Koleszar committed
933 934 935 936 937 938
    }
#endif

    // Adjust the projected reference frame useage probability numbers to reflect
    // what we have just seen. This may be usefull when we make multiple itterations
    // of the recode loop rather than continuing to use values from the previous frame.
939 940
    if ((cm->frame_type != KEY_FRAME) && ((cpi->oxcf.number_of_layers > 1) ||
        (!cm->refresh_alt_ref_frame && !cm->refresh_golden_frame)))
John Koleszar's avatar
John Koleszar committed
941
    {
942
      vp8_convert_rfct_to_prob(cpi);
John Koleszar's avatar
John Koleszar committed
943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
    }

#if 0
    // Keep record of the total distortion this time around for future use
    cpi->last_frame_distortion = cpi->frame_distortion;
#endif

}
void vp8_setup_block_ptrs(MACROBLOCK *x)
{
    int r, c;
    int i;

    for (r = 0; r < 4; r++)
    {
        for (c = 0; c < 4; c++)
        {
            x->block[r*4+c].src_diff = x->src_diff + r * 4 * 16 + c * 4;
        }
    }

    for (r = 0; r < 2; r++)
    {
        for (c = 0; c < 2; c++)
        {
            x->block[16 + r*2+c].src_diff = x->src_diff + 256 + r * 4 * 8 + c * 4;
        }
    }


    for (r = 0; r < 2; r++)
    {
        for (c = 0; c < 2; c++)
        {
            x->block[20 + r*2+c].src_diff = x->src_diff + 320 + r * 4 * 8 + c * 4;
        }
    }

    x->block[24].src_diff = x->src_diff + 384;


    for (i = 0; i < 25; i++)
    {
        x->block[i].coeff = x->coeff + i * 16;
    }
}

void vp8_build_block_offsets(MACROBLOCK *x)
{
    int block = 0;
    int br, bc;

    vp8_build_block_doffsets(&x->e_mbd);

    // y blocks
998
    x->thismb_ptr = &x->thismb[0];
John Koleszar's avatar
John Koleszar committed
999 1000 1001 1002 1003
    for (br = 0; br < 4; br++)
    {
        for (bc = 0; bc < 4; bc++)
        {
            BLOCK *this_block = &x->block[block];
1004 1005 1006 1007 1008 1009
            //this_block->base_src = &x->src.y_buffer;
            //this_block->src_stride = x->src.y_stride;
            //this_block->src = 4 * br * this_block->src_stride + 4 * bc;
            this_block->base_src = &x->thismb_ptr;
            this_block->src_stride = 16;
            this_block->src = 4 * br * 16 + 4 * bc;
John Koleszar's avatar
John Koleszar committed
1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
            ++block;
        }
    }

    // u blocks
    for (br = 0; br < 2; br++)
    {
        for (bc = 0; bc < 2; bc++)
        {
            BLOCK *this_block = &x->block[block];
            this_block->base_src = &x->src.u_buffer;
            this_block->src_stride = x->src.uv_stride;
            this_block->src = 4 * br * this_block->src_stride + 4 * bc;
            ++block;
        }
    }

    // v blocks
    for (br = 0; br < 2; br++)
    {
        for (bc = 0; bc < 2; bc++)
        {
            BLOCK *this_block = &x->block[block];
            this_block->base_src = &x->src.v_buffer;
            this_block->src_stride = x->src.uv_stride;
            this_block->src = 4 * br * this_block->src_stride + 4 * bc;
            ++block;
        }
    }
}

static void sum_intra_stats(VP8_COMP *cpi, MACROBLOCK *x)
{
    const MACROBLOCKD *xd = & x->e_mbd;
1044 1045
    const MB_PREDICTION_MODE m = xd->mode_info_context->mbmi.mode;
    const MB_PREDICTION_MODE uvm = xd->mode_info_context->mbmi.uv_mode;
John Koleszar's avatar
John Koleszar committed
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070

#ifdef MODE_STATS
    const int is_key = cpi->common.frame_type == KEY_FRAME;

    ++ (is_key ? uv_modes : inter_uv_modes)[uvm];

    if (m == B_PRED)
    {
        unsigned int *const bct = is_key ? b_modes : inter_b_modes;

        int b = 0;

        do
        {
            ++ bct[xd->block[b].bmi.mode];
        }
        while (++b < 16);
    }

#endif

    ++cpi->ymode_count[m];
    ++cpi->uv_mode_count[uvm];

}
1071 1072 1073

// Experimental stub function to create a per MB zbin adjustment based on
// some previously calculated measure of MB activity.
1074
static void adjust_act_zbin( VP8_COMP *cpi, MACROBLOCK *x )
1075
{
1076 1077 1078
#if USE_ACT_INDEX
    x->act_zbin_adj = *(x->mb_activity_ptr);
#else
1079 1080 1081
    int64_t a;
    int64_t b;
    int64_t act = *(x->mb_activity_ptr);
1082

1083
    // Apply the masking to the RD multiplier.
1084 1085 1086
    a = act + 4*cpi->activity_avg;
    b = 4*act + cpi->activity_avg;

1087
    if ( act > cpi->activity_avg )
1088
        x->act_zbin_adj = (int)(((int64_t)b + (a>>1))/a) - 1;
1089
    else
1090
        x->act_zbin_adj = 1 - (int)(((int64_t)a + (b>>1))/b);
1091
#endif
1092 1093
}

1094 1095
int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
                                   int mb_row, int mb_col)
John Koleszar's avatar
John Koleszar committed
1096
{
1097
    MACROBLOCKD *xd = &x->e_mbd;
1098
    int rate;
John Koleszar's avatar
John Koleszar committed
1099

1100
    if (cpi->sf.RD && cpi->compressor_speed != 2)
1101
        vp8_rd_pick_intra_mode(cpi, x, &rate);
John Koleszar's avatar
John Koleszar committed
1102
    else
1103
        vp8_pick_intra_mode(cpi, x, &rate);
John Koleszar's avatar
John Koleszar committed
1104

1105 1106 1107 1108 1109 1110
    if(cpi->oxcf.tuning == VP8_TUNE_SSIM)
    {
        adjust_act_zbin( cpi, x );
        vp8_update_zbin_extra(cpi, x);
    }

1111
    if (x->e_mbd.mode_info_context->mbmi.mode == B_PRED)
1112 1113 1114 1115 1116
        vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
    else
        vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);

    vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
1117

1118 1119
    sum_intra_stats(cpi, x);
    vp8_tokenize_mb(cpi, &x->e_mbd, t);
John Koleszar's avatar
John Koleszar committed
1120

1121 1122
    if (xd->mode_info_context->mbmi.mode != B_PRED)
        vp8_inverse_transform_mby(xd, IF_RTCD(&cpi->common.rtcd));
1123

1124 1125 1126 1127
    DEQUANT_INVOKE (&cpi->common.rtcd.dequant, idct_add_uv_block)
                    (xd->qcoeff+16*16, xd->block[16].dequant,
                     xd->dst.u_buffer, xd->dst.v_buffer,
                     xd->dst.uv_stride, xd->eobs+16);
John Koleszar's avatar
John Koleszar committed
1128 1129 1130 1131 1132 1133
    return rate;
}
#ifdef SPEEDSTATS
extern int cnt_pm;
#endif

1134
extern void vp8_fix_contexts(MACROBLOCKD *x);
John Koleszar's avatar
John Koleszar committed
1135 1136 1137 1138

int vp8cx_encode_inter_macroblock
(
    VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
Yunqing Wang's avatar
Yunqing Wang committed
1139 1140
    int recon_yoffset, int recon_uvoffset,
    int mb_row, int mb_col
John Koleszar's avatar
John Koleszar committed
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150
)
{
    MACROBLOCKD *const xd = &x->e_mbd;
    int intra_error = 0;
    int rate;
    int distortion;

    x->skip = 0;

    if (xd->segmentation_enabled)
1151
        x->encode_breakout = cpi->segment_encode_breakout[xd->mode_info_context->mbmi.segment_id];
John Koleszar's avatar
John Koleszar committed
1152 1153 1154 1155 1156
    else
        x->encode_breakout = cpi->oxcf.encode_breakout;

    if (cpi->sf.RD)
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
1157 1158
        int zbin_mode_boost_enabled = cpi->zbin_mode_boost_enabled;

1159 1160
        /* Are we using the fast quantizer for the mode selection? */
        if(cpi->sf.use_fastquant_for_pick)
Scott LaVarnway's avatar
Scott LaVarnway committed
1161
        {
1162 1163 1164 1165
            cpi->mb.quantize_b      = QUANTIZE_INVOKE(&cpi->rtcd.quantize,
                                                      fastquantb);
            cpi->mb.quantize_b_pair = QUANTIZE_INVOKE(&cpi->rtcd.quantize,
                                                      fastquantb_pair);