Home | History | Annotate | Download | only in common
      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 "loopfilter.h"
     14 #include "onyxc_int.h"
     15 
     16 typedef unsigned char uc;
     17 
     18 
     19 prototype_loopfilter(vp8_loop_filter_horizontal_edge_c);
     20 prototype_loopfilter(vp8_loop_filter_vertical_edge_c);
     21 prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_c);
     22 prototype_loopfilter(vp8_mbloop_filter_vertical_edge_c);
     23 prototype_loopfilter(vp8_loop_filter_simple_horizontal_edge_c);
     24 prototype_loopfilter(vp8_loop_filter_simple_vertical_edge_c);
     25 
     26 // Horizontal MB filtering
     27 void vp8_loop_filter_mbh_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
     28                            int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
     29 {
     30     (void) simpler_lpf;
     31     vp8_mbloop_filter_horizontal_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
     32 
     33     if (u_ptr)
     34         vp8_mbloop_filter_horizontal_edge_c(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
     35 
     36     if (v_ptr)
     37         vp8_mbloop_filter_horizontal_edge_c(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
     38 }
     39 
     40 void vp8_loop_filter_mbhs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
     41                             int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
     42 {
     43     (void) u_ptr;
     44     (void) v_ptr;
     45     (void) uv_stride;
     46     (void) simpler_lpf;
     47     vp8_loop_filter_simple_horizontal_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
     48 }
     49 
     50 // Vertical MB Filtering
     51 void vp8_loop_filter_mbv_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
     52                            int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
     53 {
     54     (void) simpler_lpf;
     55     vp8_mbloop_filter_vertical_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
     56 
     57     if (u_ptr)
     58         vp8_mbloop_filter_vertical_edge_c(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
     59 
     60     if (v_ptr)
     61         vp8_mbloop_filter_vertical_edge_c(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
     62 }
     63 
     64 void vp8_loop_filter_mbvs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
     65                             int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
     66 {
     67     (void) u_ptr;
     68     (void) v_ptr;
     69     (void) uv_stride;
     70     (void) simpler_lpf;
     71     vp8_loop_filter_simple_vertical_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
     72 }
     73 
     74 // Horizontal B Filtering
     75 void vp8_loop_filter_bh_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
     76                           int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
     77 {
     78     (void) simpler_lpf;
     79     vp8_loop_filter_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
     80     vp8_loop_filter_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
     81     vp8_loop_filter_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
     82 
     83     if (u_ptr)
     84         vp8_loop_filter_horizontal_edge_c(u_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
     85 
     86     if (v_ptr)
     87         vp8_loop_filter_horizontal_edge_c(v_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
     88 }
     89 
     90 void vp8_loop_filter_bhs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
     91                            int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
     92 {
     93     (void) u_ptr;
     94     (void) v_ptr;
     95     (void) uv_stride;
     96     (void) simpler_lpf;
     97     vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
     98     vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
     99     vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    100 }
    101 
    102 // Vertical B Filtering
    103 void vp8_loop_filter_bv_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
    104                           int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
    105 {
    106     (void) simpler_lpf;
    107     vp8_loop_filter_vertical_edge_c(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    108     vp8_loop_filter_vertical_edge_c(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    109     vp8_loop_filter_vertical_edge_c(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    110 
    111     if (u_ptr)
    112         vp8_loop_filter_vertical_edge_c(u_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
    113 
    114     if (v_ptr)
    115         vp8_loop_filter_vertical_edge_c(v_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
    116 }
    117 
    118 void vp8_loop_filter_bvs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
    119                            int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
    120 {
    121     (void) u_ptr;
    122     (void) v_ptr;
    123     (void) uv_stride;
    124     (void) simpler_lpf;
    125     vp8_loop_filter_simple_vertical_edge_c(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    126     vp8_loop_filter_simple_vertical_edge_c(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    127     vp8_loop_filter_simple_vertical_edge_c(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
    128 }
    129 
    130 void vp8_init_loop_filter(VP8_COMMON *cm)
    131 {
    132     loop_filter_info *lfi = cm->lf_info;
    133     LOOPFILTERTYPE lft = cm->filter_type;
    134     int sharpness_lvl = cm->sharpness_level;
    135     int frame_type = cm->frame_type;
    136     int i, j;
    137 
    138     int block_inside_limit = 0;
    139     int HEVThresh;
    140     const int yhedge_boost  = 2;
    141     const int uvhedge_boost = 2;
    142 
    143     // For each possible value for the loop filter fill out a "loop_filter_info" entry.
    144     for (i = 0; i <= MAX_LOOP_FILTER; i++)
    145     {
    146         int filt_lvl = i;
    147 
    148         if (frame_type == KEY_FRAME)
    149         {
    150             if (filt_lvl >= 40)
    151                 HEVThresh = 2;
    152             else if (filt_lvl >= 15)
    153                 HEVThresh = 1;
    154             else
    155                 HEVThresh = 0;
    156         }
    157         else
    158         {
    159             if (filt_lvl >= 40)
    160                 HEVThresh = 3;
    161             else if (filt_lvl >= 20)
    162                 HEVThresh = 2;
    163             else if (filt_lvl >= 15)
    164                 HEVThresh = 1;
    165             else
    166                 HEVThresh = 0;
    167         }
    168 
    169         // Set loop filter paramaeters that control sharpness.
    170         block_inside_limit = filt_lvl >> (sharpness_lvl > 0);
    171         block_inside_limit = block_inside_limit >> (sharpness_lvl > 4);
    172 
    173         if (sharpness_lvl > 0)
    174         {
    175             if (block_inside_limit > (9 - sharpness_lvl))
    176                 block_inside_limit = (9 - sharpness_lvl);
    177         }
    178 
    179         if (block_inside_limit < 1)
    180             block_inside_limit = 1;
    181 
    182         for (j = 0; j < 16; j++)
    183         {
    184             lfi[i].lim[j] = block_inside_limit;
    185             lfi[i].mbflim[j] = filt_lvl + yhedge_boost;
    186             lfi[i].mbthr[j] = HEVThresh;
    187             lfi[i].flim[j] = filt_lvl;
    188             lfi[i].thr[j] = HEVThresh;
    189             lfi[i].uvlim[j] = block_inside_limit;
    190             lfi[i].uvmbflim[j] = filt_lvl + uvhedge_boost;
    191             lfi[i].uvmbthr[j] = HEVThresh;
    192             lfi[i].uvflim[j] = filt_lvl;
    193             lfi[i].uvthr[j] = HEVThresh;
    194         }
    195 
    196     }
    197 
    198     // Set up the function pointers depending on the type of loop filtering selected
    199     if (lft == NORMAL_LOOPFILTER)
    200     {
    201         cm->lf_mbv = LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_v);
    202         cm->lf_bv  = LF_INVOKE(&cm->rtcd.loopfilter, normal_b_v);
    203         cm->lf_mbh = LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_h);
    204         cm->lf_bh  = LF_INVOKE(&cm->rtcd.loopfilter, normal_b_h);
    205     }
    206     else
    207     {
    208         cm->lf_mbv = LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_v);
    209         cm->lf_bv  = LF_INVOKE(&cm->rtcd.loopfilter, simple_b_v);
    210         cm->lf_mbh = LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_h);
    211         cm->lf_bh  = LF_INVOKE(&cm->rtcd.loopfilter, simple_b_h);
    212     }
    213 }
    214 
    215 // Put vp8_init_loop_filter() in vp8dx_create_decompressor(). Only call vp8_frame_init_loop_filter() while decoding
    216 // each frame. Check last_frame_type to skip the function most of times.
    217 void vp8_frame_init_loop_filter(loop_filter_info *lfi, int frame_type)
    218 {
    219     int HEVThresh;
    220     int i, j;
    221 
    222     // For each possible value for the loop filter fill out a "loop_filter_info" entry.
    223     for (i = 0; i <= MAX_LOOP_FILTER; i++)
    224     {
    225         int filt_lvl = i;
    226 
    227         if (frame_type == KEY_FRAME)
    228         {
    229             if (filt_lvl >= 40)
    230                 HEVThresh = 2;
    231             else if (filt_lvl >= 15)
    232                 HEVThresh = 1;
    233             else
    234                 HEVThresh = 0;
    235         }
    236         else
    237         {
    238             if (filt_lvl >= 40)
    239                 HEVThresh = 3;
    240             else if (filt_lvl >= 20)
    241                 HEVThresh = 2;
    242             else if (filt_lvl >= 15)
    243                 HEVThresh = 1;
    244             else
    245                 HEVThresh = 0;
    246         }
    247 
    248         for (j = 0; j < 16; j++)
    249         {
    250             //lfi[i].lim[j] = block_inside_limit;
    251             //lfi[i].mbflim[j] = filt_lvl+yhedge_boost;
    252             lfi[i].mbthr[j] = HEVThresh;
    253             //lfi[i].flim[j] = filt_lvl;
    254             lfi[i].thr[j] = HEVThresh;
    255             //lfi[i].uvlim[j] = block_inside_limit;
    256             //lfi[i].uvmbflim[j] = filt_lvl+uvhedge_boost;
    257             lfi[i].uvmbthr[j] = HEVThresh;
    258             //lfi[i].uvflim[j] = filt_lvl;
    259             lfi[i].uvthr[j] = HEVThresh;
    260         }
    261     }
    262 }
    263 
    264 
    265 void vp8_adjust_mb_lf_value(MACROBLOCKD *mbd, int *filter_level)
    266 {
    267     MB_MODE_INFO *mbmi = &mbd->mode_info_context->mbmi;
    268 
    269     if (mbd->mode_ref_lf_delta_enabled)
    270     {
    271         // Aplly delta for reference frame
    272         *filter_level += mbd->ref_lf_deltas[mbmi->ref_frame];
    273 
    274         // Apply delta for mode
    275         if (mbmi->ref_frame == INTRA_FRAME)
    276         {
    277             // Only the split mode BPRED has a further special case
    278             if (mbmi->mode == B_PRED)
    279                 *filter_level +=  mbd->mode_lf_deltas[0];
    280         }
    281         else
    282         {
    283             // Zero motion mode
    284             if (mbmi->mode == ZEROMV)
    285                 *filter_level +=  mbd->mode_lf_deltas[1];
    286 
    287             // Split MB motion mode
    288             else if (mbmi->mode == SPLITMV)
    289                 *filter_level +=  mbd->mode_lf_deltas[3];
    290 
    291             // All other inter motion modes (Nearest, Near, New)
    292             else
    293                 *filter_level +=  mbd->mode_lf_deltas[2];
    294         }
    295 
    296         // Range check
    297         if (*filter_level > MAX_LOOP_FILTER)
    298             *filter_level = MAX_LOOP_FILTER;
    299         else if (*filter_level < 0)
    300             *filter_level = 0;
    301     }
    302 }
    303 
    304 
    305 void vp8_loop_filter_frame
    306 (
    307     VP8_COMMON *cm,
    308     MACROBLOCKD *mbd,
    309     int default_filt_lvl
    310 )
    311 {
    312     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
    313     loop_filter_info *lfi = cm->lf_info;
    314     int frame_type = cm->frame_type;
    315 
    316     int mb_row;
    317     int mb_col;
    318 
    319 
    320     int baseline_filter_level[MAX_MB_SEGMENTS];
    321     int filter_level;
    322     int alt_flt_enabled = mbd->segmentation_enabled;
    323 
    324     int i;
    325     unsigned char *y_ptr, *u_ptr, *v_ptr;
    326 
    327     mbd->mode_info_context = cm->mi;          // Point at base of Mb MODE_INFO list
    328 
    329     // Note the baseline filter values for each segment
    330     if (alt_flt_enabled)
    331     {
    332         for (i = 0; i < MAX_MB_SEGMENTS; i++)
    333         {
    334             // Abs value
    335             if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
    336                 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
    337             // Delta Value
    338             else
    339             {
    340                 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
    341                 baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0;  // Clamp to valid range
    342             }
    343         }
    344     }
    345     else
    346     {
    347         for (i = 0; i < MAX_MB_SEGMENTS; i++)
    348             baseline_filter_level[i] = default_filt_lvl;
    349     }
    350 
    351     // Initialize the loop filter for this frame.
    352     if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
    353         vp8_init_loop_filter(cm);
    354     else if (frame_type != cm->last_frame_type)
    355         vp8_frame_init_loop_filter(lfi, frame_type);
    356 
    357     // Set up the buffer pointers
    358     y_ptr = post->y_buffer;
    359     u_ptr = post->u_buffer;
    360     v_ptr = post->v_buffer;
    361 
    362     // vp8_filter each macro block
    363     for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
    364     {
    365         for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
    366         {
    367             int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
    368 
    369             filter_level = baseline_filter_level[Segment];
    370 
    371             // Distance of Mb to the various image edges.
    372             // These specified to 8th pel as they are always compared to values that are in 1/8th pel units
    373             // Apply any context driven MB level adjustment
    374             vp8_adjust_mb_lf_value(mbd, &filter_level);
    375 
    376             if (filter_level)
    377             {
    378                 if (mb_col > 0)
    379                     cm->lf_mbv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
    380 
    381                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
    382                     cm->lf_bv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
    383 
    384                 // don't apply across umv border
    385                 if (mb_row > 0)
    386                     cm->lf_mbh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
    387 
    388                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
    389                     cm->lf_bh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
    390             }
    391 
    392             y_ptr += 16;
    393             u_ptr += 8;
    394             v_ptr += 8;
    395 
    396             mbd->mode_info_context++;     // step to next MB
    397         }
    398 
    399         y_ptr += post->y_stride  * 16 - post->y_width;
    400         u_ptr += post->uv_stride *  8 - post->uv_width;
    401         v_ptr += post->uv_stride *  8 - post->uv_width;
    402 
    403         mbd->mode_info_context++;         // Skip border mb
    404     }
    405 }
    406 
    407 
    408 void vp8_loop_filter_frame_yonly
    409 (
    410     VP8_COMMON *cm,
    411     MACROBLOCKD *mbd,
    412     int default_filt_lvl,
    413     int sharpness_lvl
    414 )
    415 {
    416     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
    417 
    418     int i;
    419     unsigned char *y_ptr;
    420     int mb_row;
    421     int mb_col;
    422 
    423     loop_filter_info *lfi = cm->lf_info;
    424     int baseline_filter_level[MAX_MB_SEGMENTS];
    425     int filter_level;
    426     int alt_flt_enabled = mbd->segmentation_enabled;
    427     int frame_type = cm->frame_type;
    428 
    429     (void) sharpness_lvl;
    430 
    431     //MODE_INFO * this_mb_mode_info = cm->mi;  // Point at base of Mb MODE_INFO list
    432     mbd->mode_info_context = cm->mi;          // Point at base of Mb MODE_INFO list
    433 
    434     // Note the baseline filter values for each segment
    435     if (alt_flt_enabled)
    436     {
    437         for (i = 0; i < MAX_MB_SEGMENTS; i++)
    438         {
    439             // Abs value
    440             if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
    441                 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
    442             // Delta Value
    443             else
    444             {
    445                 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
    446                 baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0;  // Clamp to valid range
    447             }
    448         }
    449     }
    450     else
    451     {
    452         for (i = 0; i < MAX_MB_SEGMENTS; i++)
    453             baseline_filter_level[i] = default_filt_lvl;
    454     }
    455 
    456     // Initialize the loop filter for this frame.
    457     if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
    458         vp8_init_loop_filter(cm);
    459     else if (frame_type != cm->last_frame_type)
    460         vp8_frame_init_loop_filter(lfi, frame_type);
    461 
    462     // Set up the buffer pointers
    463     y_ptr = post->y_buffer;
    464 
    465     // vp8_filter each macro block
    466     for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
    467     {
    468         for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
    469         {
    470             int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
    471             filter_level = baseline_filter_level[Segment];
    472 
    473             // Apply any context driven MB level adjustment
    474             vp8_adjust_mb_lf_value(mbd, &filter_level);
    475 
    476             if (filter_level)
    477             {
    478                 if (mb_col > 0)
    479                     cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    480 
    481                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
    482                     cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    483 
    484                 // don't apply across umv border
    485                 if (mb_row > 0)
    486                     cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    487 
    488                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
    489                     cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    490             }
    491 
    492             y_ptr += 16;
    493             mbd->mode_info_context ++;        // step to next MB
    494 
    495         }
    496 
    497         y_ptr += post->y_stride  * 16 - post->y_width;
    498         mbd->mode_info_context ++;            // Skip border mb
    499     }
    500 
    501 }
    502 
    503 
    504 void vp8_loop_filter_partial_frame
    505 (
    506     VP8_COMMON *cm,
    507     MACROBLOCKD *mbd,
    508     int default_filt_lvl,
    509     int sharpness_lvl,
    510     int Fraction
    511 )
    512 {
    513     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
    514 
    515     int i;
    516     unsigned char *y_ptr;
    517     int mb_row;
    518     int mb_col;
    519     //int mb_rows = post->y_height >> 4;
    520     int mb_cols = post->y_width  >> 4;
    521 
    522     int linestocopy;
    523 
    524     loop_filter_info *lfi = cm->lf_info;
    525     int baseline_filter_level[MAX_MB_SEGMENTS];
    526     int filter_level;
    527     int alt_flt_enabled = mbd->segmentation_enabled;
    528     int frame_type = cm->frame_type;
    529 
    530     (void) sharpness_lvl;
    531 
    532     //MODE_INFO * this_mb_mode_info = cm->mi + (post->y_height>>5) * (mb_cols + 1);  // Point at base of Mb MODE_INFO list
    533     mbd->mode_info_context = cm->mi + (post->y_height >> 5) * (mb_cols + 1);        // Point at base of Mb MODE_INFO list
    534 
    535     linestocopy = (post->y_height >> (4 + Fraction));
    536 
    537     if (linestocopy < 1)
    538         linestocopy = 1;
    539 
    540     linestocopy <<= 4;
    541 
    542     // Note the baseline filter values for each segment
    543     if (alt_flt_enabled)
    544     {
    545         for (i = 0; i < MAX_MB_SEGMENTS; i++)
    546         {
    547             // Abs value
    548             if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
    549                 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
    550             // Delta Value
    551             else
    552             {
    553                 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
    554                 baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0;  // Clamp to valid range
    555             }
    556         }
    557     }
    558     else
    559     {
    560         for (i = 0; i < MAX_MB_SEGMENTS; i++)
    561             baseline_filter_level[i] = default_filt_lvl;
    562     }
    563 
    564     // Initialize the loop filter for this frame.
    565     if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
    566         vp8_init_loop_filter(cm);
    567     else if (frame_type != cm->last_frame_type)
    568         vp8_frame_init_loop_filter(lfi, frame_type);
    569 
    570     // Set up the buffer pointers
    571     y_ptr = post->y_buffer + (post->y_height >> 5) * 16 * post->y_stride;
    572 
    573     // vp8_filter each macro block
    574     for (mb_row = 0; mb_row<(linestocopy >> 4); mb_row++)
    575     {
    576         for (mb_col = 0; mb_col < mb_cols; mb_col++)
    577         {
    578             int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
    579             filter_level = baseline_filter_level[Segment];
    580 
    581             if (filter_level)
    582             {
    583                 if (mb_col > 0)
    584                     cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    585 
    586                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
    587                     cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    588 
    589                 cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    590 
    591                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
    592                     cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    593             }
    594 
    595             y_ptr += 16;
    596             mbd->mode_info_context += 1;      // step to next MB
    597         }
    598 
    599         y_ptr += post->y_stride  * 16 - post->y_width;
    600         mbd->mode_info_context += 1;          // Skip border mb
    601     }
    602 }
    603