Home | History | Annotate | Download | only in encoder
      1 /*
      2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  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.
      9  */
     10 
     11 
     12 #include "vpx_ports/config.h"
     13 #include "encodemb.h"
     14 #include "encodemv.h"
     15 #include "common.h"
     16 #include "onyx_int.h"
     17 #include "extend.h"
     18 #include "entropymode.h"
     19 #include "quant_common.h"
     20 #include "segmentation.h"
     21 #include "setupintrarecon.h"
     22 #include "encodeintra.h"
     23 #include "reconinter.h"
     24 #include "rdopt.h"
     25 #include "pickinter.h"
     26 #include "findnearmv.h"
     27 #include "reconintra.h"
     28 #include <stdio.h>
     29 #include <limits.h>
     30 #include "subpixel.h"
     31 #include "vpx_ports/vpx_timer.h"
     32 
     33 #if CONFIG_RUNTIME_CPU_DETECT
     34 #define RTCD(x)     &cpi->common.rtcd.x
     35 #define IF_RTCD(x)  (x)
     36 #else
     37 #define RTCD(x)     NULL
     38 #define IF_RTCD(x)  NULL
     39 #endif
     40 extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
     41 
     42 extern void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex);
     43 extern void vp8_auto_select_speed(VP8_COMP *cpi);
     44 extern void vp8cx_init_mbrthread_data(VP8_COMP *cpi,
     45                                       MACROBLOCK *x,
     46                                       MB_ROW_COMP *mbr_ei,
     47                                       int mb_row,
     48                                       int count);
     49 void vp8_build_block_offsets(MACROBLOCK *x);
     50 void vp8_setup_block_ptrs(MACROBLOCK *x);
     51 int vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t, int recon_yoffset, int recon_uvoffset);
     52 int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t);
     53 
     54 #ifdef MODE_STATS
     55 unsigned int inter_y_modes[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
     56 unsigned int inter_uv_modes[4] = {0, 0, 0, 0};
     57 unsigned int inter_b_modes[15]  = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
     58 unsigned int y_modes[5]   = {0, 0, 0, 0, 0};
     59 unsigned int uv_modes[4]  = {0, 0, 0, 0};
     60 unsigned int b_modes[14]  = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
     61 #endif
     62 
     63 static const int qrounding_factors[129] =
     64 {
     65     56, 56, 56, 56, 48, 48, 56, 56,
     66     48, 48, 48, 48, 48, 48, 48, 48,
     67     48, 48, 48, 48, 48, 48, 48, 48,
     68     48, 48, 48, 48, 48, 48, 48, 48,
     69     48, 48, 48, 48, 48, 48, 48, 48,
     70     48, 48, 48, 48, 48, 48, 48, 48,
     71     48, 48, 48, 48, 48, 48, 48, 48,
     72     48, 48, 48, 48, 48, 48, 48, 48,
     73     48, 48, 48, 48, 48, 48, 48, 48,
     74     48, 48, 48, 48, 48, 48, 48, 48,
     75     48, 48, 48, 48, 48, 48, 48, 48,
     76     48, 48, 48, 48, 48, 48, 48, 48,
     77     48, 48, 48, 48, 48, 48, 48, 48,
     78     48, 48, 48, 48, 48, 48, 48, 48,
     79     48, 48, 48, 48, 48, 48, 48, 48,
     80     48, 48, 48, 48, 48, 48, 48, 48,
     81     48,
     82 };
     83 
     84 static const int qzbin_factors[129] =
     85 {
     86     72, 72, 72, 72, 80, 80, 72, 72,
     87     80, 80, 80, 80, 80, 80, 80, 80,
     88     80, 80, 80, 80, 80, 80, 80, 80,
     89     80, 80, 80, 80, 80, 80, 80, 80,
     90     80, 80, 80, 80, 80, 80, 80, 80,
     91     80, 80, 80, 80, 80, 80, 80, 80,
     92     80, 80, 80, 80, 80, 80, 80, 80,
     93     80, 80, 80, 80, 80, 80, 80, 80,
     94     80, 80, 80, 80, 80, 80, 80, 80,
     95     80, 80, 80, 80, 80, 80, 80, 80,
     96     80, 80, 80, 80, 80, 80, 80, 80,
     97     80, 80, 80, 80, 80, 80, 80, 80,
     98     80, 80, 80, 80, 80, 80, 80, 80,
     99     80, 80, 80, 80, 80, 80, 80, 80,
    100     80, 80, 80, 80, 80, 80, 80, 80,
    101     80, 80, 80, 80, 80, 80, 80, 80,
    102     80,
    103 };
    104 
    105 static const int qrounding_factors_y2[129] =
    106 {
    107     56, 56, 56, 56, 48, 48, 56, 56,
    108     48, 48, 48, 48, 48, 48, 48, 48,
    109     48, 48, 48, 48, 48, 48, 48, 48,
    110     48, 48, 48, 48, 48, 48, 48, 48,
    111     48, 48, 48, 48, 48, 48, 48, 48,
    112     48, 48, 48, 48, 48, 48, 48, 48,
    113     48, 48, 48, 48, 48, 48, 48, 48,
    114     48, 48, 48, 48, 48, 48, 48, 48,
    115     48, 48, 48, 48, 48, 48, 48, 48,
    116     48, 48, 48, 48, 48, 48, 48, 48,
    117     48, 48, 48, 48, 48, 48, 48, 48,
    118     48, 48, 48, 48, 48, 48, 48, 48,
    119     48, 48, 48, 48, 48, 48, 48, 48,
    120     48, 48, 48, 48, 48, 48, 48, 48,
    121     48, 48, 48, 48, 48, 48, 48, 48,
    122     48, 48, 48, 48, 48, 48, 48, 48,
    123     48,
    124 };
    125 
    126 static const int qzbin_factors_y2[129] =
    127 {
    128     72, 72, 72, 72, 80, 80, 72, 72,
    129     80, 80, 80, 80, 80, 80, 80, 80,
    130     80, 80, 80, 80, 80, 80, 80, 80,
    131     80, 80, 80, 80, 80, 80, 80, 80,
    132     80, 80, 80, 80, 80, 80, 80, 80,
    133     80, 80, 80, 80, 80, 80, 80, 80,
    134     80, 80, 80, 80, 80, 80, 80, 80,
    135     80, 80, 80, 80, 80, 80, 80, 80,
    136     80, 80, 80, 80, 80, 80, 80, 80,
    137     80, 80, 80, 80, 80, 80, 80, 80,
    138     80, 80, 80, 80, 80, 80, 80, 80,
    139     80, 80, 80, 80, 80, 80, 80, 80,
    140     80, 80, 80, 80, 80, 80, 80, 80,
    141     80, 80, 80, 80, 80, 80, 80, 80,
    142     80, 80, 80, 80, 80, 80, 80, 80,
    143     80, 80, 80, 80, 80, 80, 80, 80,
    144     80,
    145 };
    146 
    147 //#define EXACT_QUANT
    148 #ifdef EXACT_QUANT
    149 static void vp8cx_invert_quant(short *quant, short *shift, short d)
    150 {
    151     unsigned t;
    152     int l;
    153     t = d;
    154     for(l = 0; t > 1; l++)
    155         t>>=1;
    156     t = 1 + (1<<(16+l))/d;
    157     *quant = (short)(t - (1<<16));
    158     *shift = l;
    159 }
    160 
    161 void vp8cx_init_quantizer(VP8_COMP *cpi)
    162 {
    163     int i;
    164     int quant_val;
    165     int Q;
    166 
    167     int zbin_boost[16] = {0, 0, 8, 10, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 44, 44};
    168 
    169     for (Q = 0; Q < QINDEX_RANGE; Q++)
    170     {
    171         // dc values
    172         quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q);
    173         vp8cx_invert_quant(cpi->Y1quant[Q] + 0,
    174                            cpi->Y1quant_shift[Q] + 0, quant_val);
    175         cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
    176         cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
    177         cpi->common.Y1dequant[Q][0] = quant_val;
    178         cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7;
    179 
    180         quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q);
    181         vp8cx_invert_quant(cpi->Y2quant[Q] + 0,
    182                            cpi->Y2quant_shift[Q] + 0, quant_val);
    183         cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
    184         cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7;
    185         cpi->common.Y2dequant[Q][0] = quant_val;
    186         cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7;
    187 
    188         quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q);
    189         vp8cx_invert_quant(cpi->UVquant[Q] + 0,
    190                            cpi->UVquant_shift[Q] + 0, quant_val);
    191         cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;;
    192         cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
    193         cpi->common.UVdequant[Q][0] = quant_val;
    194         cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7;
    195 
    196         // all the ac values = ;
    197         for (i = 1; i < 16; i++)
    198         {
    199             int rc = vp8_default_zig_zag1d[i];
    200 
    201             quant_val = vp8_ac_yquant(Q);
    202             vp8cx_invert_quant(cpi->Y1quant[Q] + rc,
    203                                cpi->Y1quant_shift[Q] + rc, quant_val);
    204             cpi->Y1zbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
    205             cpi->Y1round[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7;
    206             cpi->common.Y1dequant[Q][rc] = quant_val;
    207             cpi->zrun_zbin_boost_y1[Q][i] = (quant_val * zbin_boost[i]) >> 7;
    208 
    209             quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q);
    210             vp8cx_invert_quant(cpi->Y2quant[Q] + rc,
    211                                cpi->Y2quant_shift[Q] + rc, quant_val);
    212             cpi->Y2zbin[Q][rc] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
    213             cpi->Y2round[Q][rc] = (qrounding_factors_y2[Q] * quant_val) >> 7;
    214             cpi->common.Y2dequant[Q][rc] = quant_val;
    215             cpi->zrun_zbin_boost_y2[Q][i] = (quant_val * zbin_boost[i]) >> 7;
    216 
    217             quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q);
    218             vp8cx_invert_quant(cpi->UVquant[Q] + rc,
    219                                cpi->UVquant_shift[Q] + rc, quant_val);
    220             cpi->UVzbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
    221             cpi->UVround[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7;
    222             cpi->common.UVdequant[Q][rc] = quant_val;
    223             cpi->zrun_zbin_boost_uv[Q][i] = (quant_val * zbin_boost[i]) >> 7;
    224         }
    225     }
    226 }
    227 #else
    228 void vp8cx_init_quantizer(VP8_COMP *cpi)
    229 {
    230     int i;
    231     int quant_val;
    232     int Q;
    233 
    234     int zbin_boost[16] = {0, 0, 8, 10, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 44, 44};
    235 
    236     for (Q = 0; Q < QINDEX_RANGE; Q++)
    237     {
    238         // dc values
    239         quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q);
    240         cpi->Y1quant[Q][0] = (1 << 16) / quant_val;
    241         cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
    242         cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
    243         cpi->common.Y1dequant[Q][0] = quant_val;
    244         cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7;
    245 
    246         quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q);
    247         cpi->Y2quant[Q][0] = (1 << 16) / quant_val;
    248         cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
    249         cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7;
    250         cpi->common.Y2dequant[Q][0] = quant_val;
    251         cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7;
    252 
    253         quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q);
    254         cpi->UVquant[Q][0] = (1 << 16) / quant_val;
    255         cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;;
    256         cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
    257         cpi->common.UVdequant[Q][0] = quant_val;
    258         cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7;
    259 
    260         // all the ac values = ;
    261         for (i = 1; i < 16; i++)
    262         {
    263             int rc = vp8_default_zig_zag1d[i];
    264 
    265             quant_val = vp8_ac_yquant(Q);
    266             cpi->Y1quant[Q][rc] = (1 << 16) / quant_val;
    267             cpi->Y1zbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
    268             cpi->Y1round[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7;
    269             cpi->common.Y1dequant[Q][rc] = quant_val;
    270             cpi->zrun_zbin_boost_y1[Q][i] = (quant_val * zbin_boost[i]) >> 7;
    271 
    272             quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q);
    273             cpi->Y2quant[Q][rc] = (1 << 16) / quant_val;
    274             cpi->Y2zbin[Q][rc] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
    275             cpi->Y2round[Q][rc] = (qrounding_factors_y2[Q] * quant_val) >> 7;
    276             cpi->common.Y2dequant[Q][rc] = quant_val;
    277             cpi->zrun_zbin_boost_y2[Q][i] = (quant_val * zbin_boost[i]) >> 7;
    278 
    279             quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q);
    280             cpi->UVquant[Q][rc] = (1 << 16) / quant_val;
    281             cpi->UVzbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
    282             cpi->UVround[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7;
    283             cpi->common.UVdequant[Q][rc] = quant_val;
    284             cpi->zrun_zbin_boost_uv[Q][i] = (quant_val * zbin_boost[i]) >> 7;
    285         }
    286     }
    287 }
    288 #endif
    289 void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x)
    290 {
    291     int i;
    292     int QIndex;
    293     MACROBLOCKD *xd = &x->e_mbd;
    294     int zbin_extra;
    295 
    296     // Select the baseline MB Q index.
    297     if (xd->segmentation_enabled)
    298     {
    299         // Abs Value
    300         if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA)
    301 
    302             QIndex = xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id];
    303         // Delta Value
    304         else
    305         {
    306             QIndex = cpi->common.base_qindex + xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id];
    307             QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0;    // Clamp to valid range
    308         }
    309     }
    310     else
    311         QIndex = cpi->common.base_qindex;
    312 
    313     // Y
    314     zbin_extra = (cpi->common.Y1dequant[QIndex][1] * (cpi->zbin_over_quant + cpi->zbin_mode_boost)) >> 7;
    315 
    316     for (i = 0; i < 16; i++)
    317     {
    318         x->block[i].quant = cpi->Y1quant[QIndex];
    319         x->block[i].quant_shift = cpi->Y1quant_shift[QIndex];
    320         x->block[i].zbin = cpi->Y1zbin[QIndex];
    321         x->block[i].round = cpi->Y1round[QIndex];
    322         x->e_mbd.block[i].dequant = cpi->common.Y1dequant[QIndex];
    323         x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex];
    324         x->block[i].zbin_extra = (short)zbin_extra;
    325     }
    326 
    327     // UV
    328     zbin_extra = (cpi->common.UVdequant[QIndex][1] * (cpi->zbin_over_quant + cpi->zbin_mode_boost)) >> 7;
    329 
    330     for (i = 16; i < 24; i++)
    331     {
    332         x->block[i].quant = cpi->UVquant[QIndex];
    333         x->block[i].quant_shift = cpi->UVquant_shift[QIndex];
    334         x->block[i].zbin = cpi->UVzbin[QIndex];
    335         x->block[i].round = cpi->UVround[QIndex];
    336         x->e_mbd.block[i].dequant = cpi->common.UVdequant[QIndex];
    337         x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex];
    338         x->block[i].zbin_extra = (short)zbin_extra;
    339     }
    340 
    341     // Y2
    342     zbin_extra = (cpi->common.Y2dequant[QIndex][1] * ((cpi->zbin_over_quant / 2) + cpi->zbin_mode_boost)) >> 7;
    343     x->block[24].quant = cpi->Y2quant[QIndex];
    344     x->block[24].quant_shift = cpi->Y2quant_shift[QIndex];
    345     x->block[24].zbin = cpi->Y2zbin[QIndex];
    346     x->block[24].round = cpi->Y2round[QIndex];
    347     x->e_mbd.block[24].dequant = cpi->common.Y2dequant[QIndex];
    348     x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex];
    349     x->block[24].zbin_extra = (short)zbin_extra;
    350 }
    351 
    352 void vp8cx_frame_init_quantizer(VP8_COMP *cpi)
    353 {
    354     // vp8cx_init_quantizer() is first called in vp8_create_compressor(). A check is added here so that vp8cx_init_quantizer() is only called
    355     // when these values are not all zero.
    356     if (cpi->common.y1dc_delta_q | cpi->common.y2dc_delta_q | cpi->common.uvdc_delta_q | cpi->common.y2ac_delta_q | cpi->common.uvac_delta_q)
    357     {
    358         vp8cx_init_quantizer(cpi);
    359     }
    360 
    361     // MB level quantizer setup
    362     vp8cx_mb_init_quantizer(cpi, &cpi->mb);
    363 }
    364 
    365 
    366 
    367 static
    368 void encode_mb_row(VP8_COMP *cpi,
    369                    VP8_COMMON *cm,
    370                    int mb_row,
    371                    MACROBLOCK  *x,
    372                    MACROBLOCKD *xd,
    373                    TOKENEXTRA **tp,
    374                    int *segment_counts,
    375                    int *totalrate)
    376 {
    377     int i;
    378     int recon_yoffset, recon_uvoffset;
    379     int mb_col;
    380     int ref_fb_idx = cm->lst_fb_idx;
    381     int dst_fb_idx = cm->new_fb_idx;
    382     int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
    383     int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
    384     int seg_map_index = (mb_row * cpi->common.mb_cols);
    385 
    386 
    387     // reset above block coeffs
    388     xd->above_context = cm->above_context;
    389 
    390     xd->up_available = (mb_row != 0);
    391     recon_yoffset = (mb_row * recon_y_stride * 16);
    392     recon_uvoffset = (mb_row * recon_uv_stride * 8);
    393 
    394     cpi->tplist[mb_row].start = *tp;
    395     //printf("Main mb_row = %d\n", mb_row);
    396 
    397     // Distance of Mb to the top & bottom edges, specified in 1/8th pel
    398     // units as they are always compared to values that are in 1/8th pel units
    399     xd->mb_to_top_edge = -((mb_row * 16) << 3);
    400     xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
    401 
    402     // Set up limit values for vertical motion vector components
    403     // to prevent them extending beyond the UMV borders
    404     x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
    405     x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16)
    406                         + (VP8BORDERINPIXELS - 16);
    407 
    408     // for each macroblock col in image
    409     for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
    410     {
    411         // Distance of Mb to the left & right edges, specified in
    412         // 1/8th pel units as they are always compared to values
    413         // that are in 1/8th pel units
    414         xd->mb_to_left_edge = -((mb_col * 16) << 3);
    415         xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
    416 
    417         // Set up limit values for horizontal motion vector components
    418         // to prevent them extending beyond the UMV borders
    419         x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
    420         x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16)
    421                             + (VP8BORDERINPIXELS - 16);
    422 
    423         xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
    424         xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
    425         xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
    426         xd->left_available = (mb_col != 0);
    427 
    428         // Is segmentation enabled
    429         // MB level adjutment to quantizer
    430         if (xd->segmentation_enabled)
    431         {
    432             // Code to set segment id in xd->mbmi.segment_id for current MB (with range checking)
    433             if (cpi->segmentation_map[seg_map_index+mb_col] <= 3)
    434                 xd->mode_info_context->mbmi.segment_id = cpi->segmentation_map[seg_map_index+mb_col];
    435             else
    436                 xd->mode_info_context->mbmi.segment_id = 0;
    437 
    438             vp8cx_mb_init_quantizer(cpi, x);
    439         }
    440         else
    441             xd->mode_info_context->mbmi.segment_id = 0;         // Set to Segment 0 by default
    442 
    443         x->active_ptr = cpi->active_map + seg_map_index + mb_col;
    444 
    445         if (cm->frame_type == KEY_FRAME)
    446         {
    447             *totalrate += vp8cx_encode_intra_macro_block(cpi, x, tp);
    448 #ifdef MODE_STATS
    449             y_modes[xd->mbmi.mode] ++;
    450 #endif
    451         }
    452         else
    453         {
    454             *totalrate += vp8cx_encode_inter_macroblock(cpi, x, tp, recon_yoffset, recon_uvoffset);
    455 
    456 #ifdef MODE_STATS
    457             inter_y_modes[xd->mbmi.mode] ++;
    458 
    459             if (xd->mbmi.mode == SPLITMV)
    460             {
    461                 int b;
    462 
    463                 for (b = 0; b < xd->mbmi.partition_count; b++)
    464                 {
    465                     inter_b_modes[x->partition->bmi[b].mode] ++;
    466                 }
    467             }
    468 
    469 #endif
    470 
    471             // Count of last ref frame 0,0 useage
    472             if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME))
    473                 cpi->inter_zz_count ++;
    474 
    475             // Special case code for cyclic refresh
    476             // If cyclic update enabled then copy xd->mbmi.segment_id; (which may have been updated based on mode
    477             // during vp8cx_encode_inter_macroblock()) back into the global sgmentation map
    478             if (cpi->cyclic_refresh_mode_enabled && xd->segmentation_enabled)
    479             {
    480                 cpi->segmentation_map[seg_map_index+mb_col] = xd->mode_info_context->mbmi.segment_id;
    481 
    482                 // 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):
    483                 // 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)
    484                 // else mark it as dirty (1).
    485                 if (xd->mode_info_context->mbmi.segment_id)
    486                     cpi->cyclic_refresh_map[seg_map_index+mb_col] = -1;
    487                 else if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME))
    488                 {
    489                     if (cpi->cyclic_refresh_map[seg_map_index+mb_col] == 1)
    490                         cpi->cyclic_refresh_map[seg_map_index+mb_col] = 0;
    491                 }
    492                 else
    493                     cpi->cyclic_refresh_map[seg_map_index+mb_col] = 1;
    494 
    495             }
    496         }
    497 
    498         cpi->tplist[mb_row].stop = *tp;
    499 
    500         x->gf_active_ptr++;      // Increment pointer into gf useage flags structure for next mb
    501 
    502         for (i = 0; i < 16; i++)
    503             vpx_memcpy(&xd->mode_info_context->bmi[i], &xd->block[i].bmi, sizeof(xd->block[i].bmi));
    504 
    505         // adjust to the next column of macroblocks
    506         x->src.y_buffer += 16;
    507         x->src.u_buffer += 8;
    508         x->src.v_buffer += 8;
    509 
    510         recon_yoffset += 16;
    511         recon_uvoffset += 8;
    512 
    513         // Keep track of segment useage
    514         segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
    515 
    516         // skip to next mb
    517         xd->mode_info_context++;
    518         x->partition_info++;
    519 
    520         xd->above_context++;
    521         cpi->current_mb_col_main = mb_col;
    522     }
    523 
    524     //extend the recon for intra prediction
    525     vp8_extend_mb_row(
    526         &cm->yv12_fb[dst_fb_idx],
    527         xd->dst.y_buffer + 16,
    528         xd->dst.u_buffer + 8,
    529         xd->dst.v_buffer + 8);
    530 
    531     // this is to account for the border
    532     xd->mode_info_context++;
    533     x->partition_info++;
    534 }
    535 
    536 
    537 
    538 
    539 
    540 void vp8_encode_frame(VP8_COMP *cpi)
    541 {
    542     int mb_row;
    543     MACROBLOCK *const x = & cpi->mb;
    544     VP8_COMMON *const cm = & cpi->common;
    545     MACROBLOCKD *const xd = & x->e_mbd;
    546 
    547     int i;
    548     TOKENEXTRA *tp = cpi->tok;
    549     int segment_counts[MAX_MB_SEGMENTS];
    550     int totalrate;
    551 
    552     // Functions setup for all frame types so we can use MC in AltRef
    553     if (cm->mcomp_filter_type == SIXTAP)
    554     {
    555         xd->subpixel_predict        = SUBPIX_INVOKE(
    556                                         &cpi->common.rtcd.subpix, sixtap4x4);
    557         xd->subpixel_predict8x4     = SUBPIX_INVOKE(
    558                                         &cpi->common.rtcd.subpix, sixtap8x4);
    559         xd->subpixel_predict8x8     = SUBPIX_INVOKE(
    560                                         &cpi->common.rtcd.subpix, sixtap8x8);
    561         xd->subpixel_predict16x16   = SUBPIX_INVOKE(
    562                                         &cpi->common.rtcd.subpix, sixtap16x16);
    563     }
    564     else
    565     {
    566         xd->subpixel_predict        = SUBPIX_INVOKE(
    567                                         &cpi->common.rtcd.subpix, bilinear4x4);
    568         xd->subpixel_predict8x4     = SUBPIX_INVOKE(
    569                                         &cpi->common.rtcd.subpix, bilinear8x4);
    570         xd->subpixel_predict8x8     = SUBPIX_INVOKE(
    571                                         &cpi->common.rtcd.subpix, bilinear8x8);
    572         xd->subpixel_predict16x16   = SUBPIX_INVOKE(
    573                                       &cpi->common.rtcd.subpix, bilinear16x16);
    574     }
    575 
    576     x->gf_active_ptr = (signed char *)cpi->gf_active_flags;     // Point to base of GF active flags data structure
    577 
    578     x->vector_range = 32;
    579 
    580     // Count of MBs using the alternate Q if any
    581     cpi->alt_qcount = 0;
    582 
    583     // Reset frame count of inter 0,0 motion vector useage.
    584     cpi->inter_zz_count = 0;
    585 
    586     vpx_memset(segment_counts, 0, sizeof(segment_counts));
    587 
    588     cpi->prediction_error = 0;
    589     cpi->intra_error = 0;
    590     cpi->skip_true_count = 0;
    591     cpi->skip_false_count = 0;
    592 
    593 #if 0
    594     // Experimental code
    595     cpi->frame_distortion = 0;
    596     cpi->last_mb_distortion = 0;
    597 #endif
    598 
    599     totalrate = 0;
    600 
    601     x->partition_info = x->pi;
    602 
    603     xd->mode_info_context = cm->mi;
    604     xd->mode_info_stride = cm->mode_info_stride;
    605 
    606     xd->frame_type = cm->frame_type;
    607 
    608     xd->frames_since_golden = cm->frames_since_golden;
    609     xd->frames_till_alt_ref_frame = cm->frames_till_alt_ref_frame;
    610     vp8_zero(cpi->MVcount);
    611     // vp8_zero( Contexts)
    612     vp8_zero(cpi->coef_counts);
    613 
    614     // reset intra mode contexts
    615     if (cm->frame_type == KEY_FRAME)
    616         vp8_init_mbmode_probs(cm);
    617 
    618 
    619     vp8cx_frame_init_quantizer(cpi);
    620 
    621     if (cpi->compressor_speed == 2)
    622     {
    623         if (cpi->oxcf.cpu_used < 0)
    624             cpi->Speed = -(cpi->oxcf.cpu_used);
    625         else
    626             vp8_auto_select_speed(cpi);
    627     }
    628 
    629     vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
    630     //vp8_initialize_rd_consts( cpi, vp8_dc_quant(cpi->avg_frame_qindex, cm->y1dc_delta_q) );
    631     vp8cx_initialize_me_consts(cpi, cm->base_qindex);
    632     //vp8cx_initialize_me_consts( cpi, cpi->avg_frame_qindex);
    633 
    634     // Copy data over into macro block data sturctures.
    635 
    636     x->src = * cpi->Source;
    637     xd->pre = cm->yv12_fb[cm->lst_fb_idx];
    638     xd->dst = cm->yv12_fb[cm->new_fb_idx];
    639 
    640     // set up frame new frame for intra coded blocks
    641 
    642     vp8_setup_intra_recon(&cm->yv12_fb[cm->new_fb_idx]);
    643 
    644     vp8_build_block_offsets(x);
    645 
    646     vp8_setup_block_dptrs(&x->e_mbd);
    647 
    648     vp8_setup_block_ptrs(x);
    649 
    650     x->rddiv = cpi->RDDIV;
    651     x->rdmult = cpi->RDMULT;
    652 
    653 #if 0
    654     // Experimental rd code
    655     // 2 Pass - Possibly set Rdmult based on last frame distortion + this frame target bits or other metrics
    656     // such as cpi->rate_correction_factor that indicate relative complexity.
    657     /*if ( cpi->pass == 2 && (cpi->last_frame_distortion > 0) && (cpi->target_bits_per_mb > 0) )
    658     {
    659         //x->rdmult = ((cpi->last_frame_distortion * 256)/cpi->common.MBs)/ cpi->target_bits_per_mb;
    660         x->rdmult = (int)(cpi->RDMULT * cpi->rate_correction_factor);
    661     }
    662     else
    663         x->rdmult = cpi->RDMULT; */
    664     //x->rdmult = (int)(cpi->RDMULT * pow( (cpi->rate_correction_factor * 2.0), 0.75 ));
    665 #endif
    666 
    667     xd->mode_info_context->mbmi.mode = DC_PRED;
    668     xd->mode_info_context->mbmi.uv_mode = DC_PRED;
    669 
    670     xd->left_context = &cm->left_context;
    671 
    672     vp8_zero(cpi->count_mb_ref_frame_usage)
    673     vp8_zero(cpi->ymode_count)
    674     vp8_zero(cpi->uv_mode_count)
    675 
    676     x->mvc = cm->fc.mvc;
    677 
    678     vpx_memset(cm->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * cm->mb_cols);
    679 
    680     {
    681         struct vpx_usec_timer  emr_timer;
    682         vpx_usec_timer_start(&emr_timer);
    683 
    684         if (!cpi->b_multi_threaded)
    685         {
    686             // for each macroblock row in image
    687             for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
    688             {
    689 
    690                 vp8_zero(cm->left_context)
    691 
    692                 encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate);
    693 
    694                 // adjust to the next row of mbs
    695                 x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
    696                 x->src.u_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
    697                 x->src.v_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
    698             }
    699 
    700             cpi->tok_count = tp - cpi->tok;
    701 
    702         }
    703         else
    704         {
    705 #if CONFIG_MULTITHREAD
    706             vp8cx_init_mbrthread_data(cpi, x, cpi->mb_row_ei, 1,  cpi->encoding_thread_count);
    707 
    708             for (mb_row = 0; mb_row < cm->mb_rows; mb_row += (cpi->encoding_thread_count + 1))
    709             {
    710                 int i;
    711                 cpi->current_mb_col_main = -1;
    712 
    713                 for (i = 0; i < cpi->encoding_thread_count; i++)
    714                 {
    715                     if ((mb_row + i + 1) >= cm->mb_rows)
    716                         break;
    717 
    718                     cpi->mb_row_ei[i].mb_row = mb_row + i + 1;
    719                     cpi->mb_row_ei[i].tp  = cpi->tok + (mb_row + i + 1) * (cm->mb_cols * 16 * 24);
    720                     cpi->mb_row_ei[i].current_mb_col = -1;
    721                     //SetEvent(cpi->h_event_mbrencoding[i]);
    722                     sem_post(&cpi->h_event_mbrencoding[i]);
    723                 }
    724 
    725                 vp8_zero(cm->left_context)
    726 
    727                 tp = cpi->tok + mb_row * (cm->mb_cols * 16 * 24);
    728 
    729                 encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate);
    730 
    731                 // adjust to the next row of mbs
    732                 x->src.y_buffer += 16 * x->src.y_stride * (cpi->encoding_thread_count + 1) - 16 * cm->mb_cols;
    733                 x->src.u_buffer +=  8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
    734                 x->src.v_buffer +=  8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
    735 
    736                 xd->mode_info_context += xd->mode_info_stride * cpi->encoding_thread_count;
    737                 x->partition_info  += xd->mode_info_stride * cpi->encoding_thread_count;
    738 
    739                 if (mb_row < cm->mb_rows - 1)
    740                     //WaitForSingleObject(cpi->h_event_main, INFINITE);
    741                     sem_wait(&cpi->h_event_main);
    742             }
    743 
    744             /*
    745             for( ;mb_row<cm->mb_rows; mb_row ++)
    746             {
    747             vp8_zero( cm->left_context)
    748 
    749             tp = cpi->tok + mb_row * (cm->mb_cols * 16 * 24);
    750 
    751             encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate);
    752             // adjust to the next row of mbs
    753             x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
    754             x->src.u_buffer +=  8 * x->src.uv_stride - 8 * cm->mb_cols;
    755             x->src.v_buffer +=  8 * x->src.uv_stride - 8 * cm->mb_cols;
    756 
    757             }
    758             */
    759             cpi->tok_count = 0;
    760 
    761             for (mb_row = 0; mb_row < cm->mb_rows; mb_row ++)
    762             {
    763                 cpi->tok_count += cpi->tplist[mb_row].stop - cpi->tplist[mb_row].start;
    764             }
    765 
    766             if (xd->segmentation_enabled)
    767             {
    768 
    769                 int i, j;
    770 
    771                 if (xd->segmentation_enabled)
    772                 {
    773 
    774                     for (i = 0; i < cpi->encoding_thread_count; i++)
    775                     {
    776                         for (j = 0; j < 4; j++)
    777                             segment_counts[j] += cpi->mb_row_ei[i].segment_counts[j];
    778                     }
    779                 }
    780 
    781             }
    782 
    783             for (i = 0; i < cpi->encoding_thread_count; i++)
    784             {
    785                 totalrate += cpi->mb_row_ei[i].totalrate;
    786             }
    787 
    788 #endif
    789 
    790         }
    791 
    792         vpx_usec_timer_mark(&emr_timer);
    793         cpi->time_encode_mb_row += vpx_usec_timer_elapsed(&emr_timer);
    794 
    795     }
    796 
    797 
    798     // Work out the segment probabilites if segmentation is enabled
    799     if (xd->segmentation_enabled)
    800     {
    801         int tot_count;
    802         int i;
    803 
    804         // Set to defaults
    805         vpx_memset(xd->mb_segment_tree_probs, 255 , sizeof(xd->mb_segment_tree_probs));
    806 
    807         tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3];
    808 
    809         if (tot_count)
    810         {
    811             xd->mb_segment_tree_probs[0] = ((segment_counts[0] + segment_counts[1]) * 255) / tot_count;
    812 
    813             tot_count = segment_counts[0] + segment_counts[1];
    814 
    815             if (tot_count > 0)
    816             {
    817                 xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) / tot_count;
    818             }
    819 
    820             tot_count = segment_counts[2] + segment_counts[3];
    821 
    822             if (tot_count > 0)
    823                 xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) / tot_count;
    824 
    825             // Zero probabilities not allowed
    826             for (i = 0; i < MB_FEATURE_TREE_PROBS; i ++)
    827             {
    828                 if (xd->mb_segment_tree_probs[i] == 0)
    829                     xd->mb_segment_tree_probs[i] = 1;
    830             }
    831         }
    832     }
    833 
    834     // 256 rate units to the bit
    835     cpi->projected_frame_size = totalrate >> 8;   // projected_frame_size in units of BYTES
    836 
    837     // Make a note of the percentage MBs coded Intra.
    838     if (cm->frame_type == KEY_FRAME)
    839     {
    840         cpi->this_frame_percent_intra = 100;
    841     }
    842     else
    843     {
    844         int tot_modes;
    845 
    846         tot_modes = cpi->count_mb_ref_frame_usage[INTRA_FRAME]
    847                     + cpi->count_mb_ref_frame_usage[LAST_FRAME]
    848                     + cpi->count_mb_ref_frame_usage[GOLDEN_FRAME]
    849                     + cpi->count_mb_ref_frame_usage[ALTREF_FRAME];
    850 
    851         if (tot_modes)
    852             cpi->this_frame_percent_intra = cpi->count_mb_ref_frame_usage[INTRA_FRAME] * 100 / tot_modes;
    853 
    854     }
    855 
    856 #if 0
    857     {
    858         int cnt = 0;
    859         int flag[2] = {0, 0};
    860 
    861         for (cnt = 0; cnt < MVPcount; cnt++)
    862         {
    863             if (cm->fc.pre_mvc[0][cnt] != cm->fc.mvc[0][cnt])
    864             {
    865                 flag[0] = 1;
    866                 vpx_memcpy(cm->fc.pre_mvc[0], cm->fc.mvc[0], MVPcount);
    867                 break;
    868             }
    869         }
    870 
    871         for (cnt = 0; cnt < MVPcount; cnt++)
    872         {
    873             if (cm->fc.pre_mvc[1][cnt] != cm->fc.mvc[1][cnt])
    874             {
    875                 flag[1] = 1;
    876                 vpx_memcpy(cm->fc.pre_mvc[1], cm->fc.mvc[1], MVPcount);
    877                 break;
    878             }
    879         }
    880 
    881         if (flag[0] || flag[1])
    882             vp8_build_component_cost_table(cpi->mb.mvcost, cpi->mb.mvsadcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
    883     }
    884 #endif
    885 
    886     // Adjust the projected reference frame useage probability numbers to reflect
    887     // what we have just seen. This may be usefull when we make multiple itterations
    888     // of the recode loop rather than continuing to use values from the previous frame.
    889     if ((cm->frame_type != KEY_FRAME) && !cm->refresh_alt_ref_frame && !cm->refresh_golden_frame)
    890     {
    891         const int *const rfct = cpi->count_mb_ref_frame_usage;
    892         const int rf_intra = rfct[INTRA_FRAME];
    893         const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
    894 
    895         if ((rf_intra + rf_inter) > 0)
    896         {
    897             cpi->prob_intra_coded = (rf_intra * 255) / (rf_intra + rf_inter);
    898 
    899             if (cpi->prob_intra_coded < 1)
    900                 cpi->prob_intra_coded = 1;
    901 
    902             if ((cm->frames_since_golden > 0) || cpi->source_alt_ref_active)
    903             {
    904                 cpi->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
    905 
    906                 if (cpi->prob_last_coded < 1)
    907                     cpi->prob_last_coded = 1;
    908 
    909                 cpi->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
    910                                      ? (rfct[GOLDEN_FRAME] * 255) / (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
    911 
    912                 if (cpi->prob_gf_coded < 1)
    913                     cpi->prob_gf_coded = 1;
    914             }
    915         }
    916     }
    917 
    918 #if 0
    919     // Keep record of the total distortion this time around for future use
    920     cpi->last_frame_distortion = cpi->frame_distortion;
    921 #endif
    922 
    923 }
    924 void vp8_setup_block_ptrs(MACROBLOCK *x)
    925 {
    926     int r, c;
    927     int i;
    928 
    929     for (r = 0; r < 4; r++)
    930     {
    931         for (c = 0; c < 4; c++)
    932         {
    933             x->block[r*4+c].src_diff = x->src_diff + r * 4 * 16 + c * 4;
    934         }
    935     }
    936 
    937     for (r = 0; r < 2; r++)
    938     {
    939         for (c = 0; c < 2; c++)
    940         {
    941             x->block[16 + r*2+c].src_diff = x->src_diff + 256 + r * 4 * 8 + c * 4;
    942         }
    943     }
    944 
    945 
    946     for (r = 0; r < 2; r++)
    947     {
    948         for (c = 0; c < 2; c++)
    949         {
    950             x->block[20 + r*2+c].src_diff = x->src_diff + 320 + r * 4 * 8 + c * 4;
    951         }
    952     }
    953 
    954     x->block[24].src_diff = x->src_diff + 384;
    955 
    956 
    957     for (i = 0; i < 25; i++)
    958     {
    959         x->block[i].coeff = x->coeff + i * 16;
    960     }
    961 }
    962 
    963 void vp8_build_block_offsets(MACROBLOCK *x)
    964 {
    965     int block = 0;
    966     int br, bc;
    967 
    968     vp8_build_block_doffsets(&x->e_mbd);
    969 
    970     // y blocks
    971     for (br = 0; br < 4; br++)
    972     {
    973         for (bc = 0; bc < 4; bc++)
    974         {
    975             BLOCK *this_block = &x->block[block];
    976             this_block->base_src = &x->src.y_buffer;
    977             this_block->src_stride = x->src.y_stride;
    978             this_block->src = 4 * br * this_block->src_stride + 4 * bc;
    979             ++block;
    980         }
    981     }
    982 
    983     // u blocks
    984     for (br = 0; br < 2; br++)
    985     {
    986         for (bc = 0; bc < 2; bc++)
    987         {
    988             BLOCK *this_block = &x->block[block];
    989             this_block->base_src = &x->src.u_buffer;
    990             this_block->src_stride = x->src.uv_stride;
    991             this_block->src = 4 * br * this_block->src_stride + 4 * bc;
    992             ++block;
    993         }
    994     }
    995 
    996     // v blocks
    997     for (br = 0; br < 2; br++)
    998     {
    999         for (bc = 0; bc < 2; bc++)
   1000         {
   1001             BLOCK *this_block = &x->block[block];
   1002             this_block->base_src = &x->src.v_buffer;
   1003             this_block->src_stride = x->src.uv_stride;
   1004             this_block->src = 4 * br * this_block->src_stride + 4 * bc;
   1005             ++block;
   1006         }
   1007     }
   1008 }
   1009 
   1010 static void sum_intra_stats(VP8_COMP *cpi, MACROBLOCK *x)
   1011 {
   1012     const MACROBLOCKD *xd = & x->e_mbd;
   1013     const MB_PREDICTION_MODE m = xd->mode_info_context->mbmi.mode;
   1014     const MB_PREDICTION_MODE uvm = xd->mode_info_context->mbmi.uv_mode;
   1015 
   1016 #ifdef MODE_STATS
   1017     const int is_key = cpi->common.frame_type == KEY_FRAME;
   1018 
   1019     ++ (is_key ? uv_modes : inter_uv_modes)[uvm];
   1020 
   1021     if (m == B_PRED)
   1022     {
   1023         unsigned int *const bct = is_key ? b_modes : inter_b_modes;
   1024 
   1025         int b = 0;
   1026 
   1027         do
   1028         {
   1029             ++ bct[xd->block[b].bmi.mode];
   1030         }
   1031         while (++b < 16);
   1032     }
   1033 
   1034 #endif
   1035 
   1036     ++cpi->ymode_count[m];
   1037     ++cpi->uv_mode_count[uvm];
   1038 
   1039 }
   1040 int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t)
   1041 {
   1042     int Error4x4, Error16x16, error_uv;
   1043     B_PREDICTION_MODE intra_bmodes[16];
   1044     int rate4x4, rate16x16, rateuv;
   1045     int dist4x4, dist16x16, distuv;
   1046     int rate = 0;
   1047     int rate4x4_tokenonly = 0;
   1048     int rate16x16_tokenonly = 0;
   1049     int rateuv_tokenonly = 0;
   1050     int i;
   1051 
   1052     x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
   1053 
   1054 #if !(CONFIG_REALTIME_ONLY)
   1055 
   1056     if (cpi->sf.RD || cpi->compressor_speed != 2)
   1057     {
   1058         Error4x4 = vp8_rd_pick_intra4x4mby_modes(cpi, x, &rate4x4, &rate4x4_tokenonly, &dist4x4);
   1059 
   1060         //save the b modes for possible later use
   1061         for (i = 0; i < 16; i++)
   1062             intra_bmodes[i] = x->e_mbd.block[i].bmi.mode;
   1063 
   1064         Error16x16 = vp8_rd_pick_intra16x16mby_mode(cpi, x, &rate16x16, &rate16x16_tokenonly, &dist16x16);
   1065 
   1066         error_uv = vp8_rd_pick_intra_mbuv_mode(cpi, x, &rateuv, &rateuv_tokenonly, &distuv);
   1067 
   1068         vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
   1069         rate += rateuv;
   1070 
   1071         if (Error4x4 < Error16x16)
   1072         {
   1073             rate += rate4x4;
   1074             x->e_mbd.mode_info_context->mbmi.mode = B_PRED;
   1075 
   1076             // get back the intra block modes
   1077             for (i = 0; i < 16; i++)
   1078                 x->e_mbd.block[i].bmi.mode = intra_bmodes[i];
   1079 
   1080             vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
   1081             cpi->prediction_error += Error4x4 ;
   1082 #if 0
   1083             // Experimental RD code
   1084             cpi->frame_distortion += dist4x4;
   1085 #endif
   1086         }
   1087         else
   1088         {
   1089             vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
   1090             rate += rate16x16;
   1091 
   1092 #if 0
   1093             // Experimental RD code
   1094             cpi->prediction_error += Error16x16;
   1095             cpi->frame_distortion += dist16x16;
   1096 #endif
   1097         }
   1098 
   1099         sum_intra_stats(cpi, x);
   1100 
   1101         vp8_tokenize_mb(cpi, &x->e_mbd, t);
   1102     }
   1103     else
   1104 #endif
   1105     {
   1106 
   1107         int rate2, distortion2;
   1108         MB_PREDICTION_MODE mode, best_mode = DC_PRED;
   1109         int this_rd;
   1110         Error16x16 = INT_MAX;
   1111 
   1112         for (mode = DC_PRED; mode <= TM_PRED; mode ++)
   1113         {
   1114             x->e_mbd.mode_info_context->mbmi.mode = mode;
   1115             vp8_build_intra_predictors_mby_ptr(&x->e_mbd);
   1116             distortion2 = VARIANCE_INVOKE(&cpi->rtcd.variance, get16x16prederror)(x->src.y_buffer, x->src.y_stride, x->e_mbd.predictor, 16, 0x7fffffff);
   1117             rate2  = x->mbmode_cost[x->e_mbd.frame_type][mode];
   1118             this_rd = RD_ESTIMATE(x->rdmult, x->rddiv, rate2, distortion2);
   1119 
   1120             if (Error16x16 > this_rd)
   1121             {
   1122                 Error16x16 = this_rd;
   1123                 best_mode = mode;
   1124             }
   1125         }
   1126 
   1127         vp8_pick_intra4x4mby_modes(IF_RTCD(&cpi->rtcd), x, &rate2, &distortion2);
   1128 
   1129         if (distortion2 == INT_MAX)
   1130             Error4x4 = INT_MAX;
   1131         else
   1132             Error4x4 = RD_ESTIMATE(x->rdmult, x->rddiv, rate2, distortion2);
   1133 
   1134         if (Error4x4 < Error16x16)
   1135         {
   1136             x->e_mbd.mode_info_context->mbmi.mode = B_PRED;
   1137             vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
   1138             cpi->prediction_error += Error4x4;
   1139         }
   1140         else
   1141         {
   1142             x->e_mbd.mode_info_context->mbmi.mode = best_mode;
   1143             vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
   1144             cpi->prediction_error += Error16x16;
   1145         }
   1146 
   1147         vp8_pick_intra_mbuv_mode(x);
   1148         vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
   1149         sum_intra_stats(cpi, x);
   1150         vp8_tokenize_mb(cpi, &x->e_mbd, t);
   1151     }
   1152 
   1153     return rate;
   1154 }
   1155 #ifdef SPEEDSTATS
   1156 extern int cnt_pm;
   1157 #endif
   1158 
   1159 extern void vp8_fix_contexts(MACROBLOCKD *x);
   1160 
   1161 int vp8cx_encode_inter_macroblock
   1162 (
   1163     VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
   1164     int recon_yoffset, int recon_uvoffset
   1165 )
   1166 {
   1167     MACROBLOCKD *const xd = &x->e_mbd;
   1168     int inter_error;
   1169     int intra_error = 0;
   1170     int rate;
   1171     int distortion;
   1172 
   1173     x->skip = 0;
   1174 
   1175     if (xd->segmentation_enabled)
   1176         x->encode_breakout = cpi->segment_encode_breakout[xd->mode_info_context->mbmi.segment_id];
   1177     else
   1178         x->encode_breakout = cpi->oxcf.encode_breakout;
   1179 
   1180 #if !(CONFIG_REALTIME_ONLY)
   1181 
   1182     if (cpi->sf.RD)
   1183     {
   1184         inter_error = vp8_rd_pick_inter_mode(cpi, x, recon_yoffset, recon_uvoffset, &rate, &distortion, &intra_error);
   1185     }
   1186     else
   1187 #endif
   1188         inter_error = vp8_pick_inter_mode(cpi, x, recon_yoffset, recon_uvoffset, &rate, &distortion, &intra_error);
   1189 
   1190 
   1191     cpi->prediction_error += inter_error;
   1192     cpi->intra_error += intra_error;
   1193 
   1194 #if 0
   1195     // Experimental RD code
   1196     cpi->frame_distortion += distortion;
   1197     cpi->last_mb_distortion = distortion;
   1198 #endif
   1199 
   1200     // MB level adjutment to quantizer setup
   1201     if (xd->segmentation_enabled || cpi->zbin_mode_boost_enabled)
   1202     {
   1203         // If cyclic update enabled
   1204         if (cpi->cyclic_refresh_mode_enabled)
   1205         {
   1206             // Clear segment_id back to 0 if not coded (last frame 0,0)
   1207             if ((xd->mode_info_context->mbmi.segment_id == 1) &&
   1208                 ((xd->mode_info_context->mbmi.ref_frame != LAST_FRAME) || (xd->mode_info_context->mbmi.mode != ZEROMV)))
   1209             {
   1210                 xd->mode_info_context->mbmi.segment_id = 0;
   1211             }
   1212         }
   1213 
   1214         // Experimental code. Special case for gf and arf zeromv modes. Increase zbin size to supress noise
   1215         if (cpi->zbin_mode_boost_enabled)
   1216         {
   1217             if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME))
   1218                 cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
   1219             else
   1220                 cpi->zbin_mode_boost = 0;
   1221         }
   1222 
   1223         vp8cx_mb_init_quantizer(cpi,  x);
   1224     }
   1225 
   1226     cpi->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame] ++;
   1227 
   1228     if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
   1229     {
   1230         vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
   1231 
   1232         if (xd->mode_info_context->mbmi.mode == B_PRED)
   1233         {
   1234             vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
   1235         }
   1236         else
   1237         {
   1238             vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
   1239         }
   1240 
   1241         sum_intra_stats(cpi, x);
   1242     }
   1243     else
   1244     {
   1245         MV best_ref_mv;
   1246         MV nearest, nearby;
   1247         int mdcounts[4];
   1248         int ref_fb_idx;
   1249 
   1250         vp8_find_near_mvs(xd, xd->mode_info_context,
   1251                           &nearest, &nearby, &best_ref_mv, mdcounts, xd->mode_info_context->mbmi.ref_frame, cpi->common.ref_frame_sign_bias);
   1252 
   1253         vp8_build_uvmvs(xd, cpi->common.full_pixel);
   1254 
   1255         if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
   1256             ref_fb_idx = cpi->common.lst_fb_idx;
   1257         else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
   1258             ref_fb_idx = cpi->common.gld_fb_idx;
   1259         else
   1260             ref_fb_idx = cpi->common.alt_fb_idx;
   1261 
   1262         xd->pre.y_buffer = cpi->common.yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
   1263         xd->pre.u_buffer = cpi->common.yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
   1264         xd->pre.v_buffer = cpi->common.yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
   1265 
   1266         if (xd->mode_info_context->mbmi.mode == SPLITMV)
   1267         {
   1268             int i;
   1269 
   1270             for (i = 0; i < 16; i++)
   1271             {
   1272                 if (xd->block[i].bmi.mode == NEW4X4)
   1273                 {
   1274                     cpi->MVcount[0][mv_max+((xd->block[i].bmi.mv.as_mv.row - best_ref_mv.row) >> 1)]++;
   1275                     cpi->MVcount[1][mv_max+((xd->block[i].bmi.mv.as_mv.col - best_ref_mv.col) >> 1)]++;
   1276                 }
   1277             }
   1278         }
   1279         else if (xd->mode_info_context->mbmi.mode == NEWMV)
   1280         {
   1281             cpi->MVcount[0][mv_max+((xd->block[0].bmi.mv.as_mv.row - best_ref_mv.row) >> 1)]++;
   1282             cpi->MVcount[1][mv_max+((xd->block[0].bmi.mv.as_mv.col - best_ref_mv.col) >> 1)]++;
   1283         }
   1284 
   1285         if (!x->skip && !x->e_mbd.mode_info_context->mbmi.force_no_skip)
   1286         {
   1287             vp8_encode_inter16x16(IF_RTCD(&cpi->rtcd), x);
   1288 
   1289             // Clear mb_skip_coeff if mb_no_coeff_skip is not set
   1290             if (!cpi->common.mb_no_coeff_skip)
   1291                 xd->mode_info_context->mbmi.mb_skip_coeff = 0;
   1292 
   1293         }
   1294         else
   1295             vp8_stuff_inter16x16(x);
   1296     }
   1297 
   1298     if (!x->skip)
   1299         vp8_tokenize_mb(cpi, xd, t);
   1300     else
   1301     {
   1302         if (cpi->common.mb_no_coeff_skip)
   1303         {
   1304             if (xd->mode_info_context->mbmi.mode != B_PRED && xd->mode_info_context->mbmi.mode != SPLITMV)
   1305                 xd->mode_info_context->mbmi.dc_diff = 0;
   1306             else
   1307                 xd->mode_info_context->mbmi.dc_diff = 1;
   1308 
   1309             xd->mode_info_context->mbmi.mb_skip_coeff = 1;
   1310             cpi->skip_true_count ++;
   1311             vp8_fix_contexts(xd);
   1312         }
   1313         else
   1314         {
   1315             vp8_stuff_mb(cpi, xd, t);
   1316             xd->mode_info_context->mbmi.mb_skip_coeff = 0;
   1317             cpi->skip_false_count ++;
   1318         }
   1319     }
   1320 
   1321     return rate;
   1322 }
   1323