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  */
    218 void vp8_frame_init_loop_filter(loop_filter_info *lfi, int frame_type)
    219 {
    220     int HEVThresh;
    221     int i, j;
    222 
    223     /* For each possible value for the loop filter fill out a "loop_filter_info" entry. */
    224     for (i = 0; i <= MAX_LOOP_FILTER; i++)
    225     {
    226         int filt_lvl = i;
    227 
    228         if (frame_type == KEY_FRAME)
    229         {
    230             if (filt_lvl >= 40)
    231                 HEVThresh = 2;
    232             else if (filt_lvl >= 15)
    233                 HEVThresh = 1;
    234             else
    235                 HEVThresh = 0;
    236         }
    237         else
    238         {
    239             if (filt_lvl >= 40)
    240                 HEVThresh = 3;
    241             else if (filt_lvl >= 20)
    242                 HEVThresh = 2;
    243             else if (filt_lvl >= 15)
    244                 HEVThresh = 1;
    245             else
    246                 HEVThresh = 0;
    247         }
    248 
    249         for (j = 0; j < 16; j++)
    250         {
    251             /*lfi[i].lim[j] = block_inside_limit;
    252             lfi[i].mbflim[j] = filt_lvl+yhedge_boost;*/
    253             lfi[i].mbthr[j] = HEVThresh;
    254             /*lfi[i].flim[j] = filt_lvl;*/
    255             lfi[i].thr[j] = HEVThresh;
    256             /*lfi[i].uvlim[j] = block_inside_limit;
    257             lfi[i].uvmbflim[j] = filt_lvl+uvhedge_boost;*/
    258             lfi[i].uvmbthr[j] = HEVThresh;
    259             /*lfi[i].uvflim[j] = filt_lvl;*/
    260             lfi[i].uvthr[j] = HEVThresh;
    261         }
    262     }
    263 }
    264 
    265 
    266 void vp8_adjust_mb_lf_value(MACROBLOCKD *mbd, int *filter_level)
    267 {
    268     MB_MODE_INFO *mbmi = &mbd->mode_info_context->mbmi;
    269 
    270     if (mbd->mode_ref_lf_delta_enabled)
    271     {
    272         /* Apply delta for reference frame */
    273         *filter_level += mbd->ref_lf_deltas[mbmi->ref_frame];
    274 
    275         /* Apply delta for mode */
    276         if (mbmi->ref_frame == INTRA_FRAME)
    277         {
    278             /* Only the split mode BPRED has a further special case */
    279             if (mbmi->mode == B_PRED)
    280                 *filter_level +=  mbd->mode_lf_deltas[0];
    281         }
    282         else
    283         {
    284             /* Zero motion mode */
    285             if (mbmi->mode == ZEROMV)
    286                 *filter_level +=  mbd->mode_lf_deltas[1];
    287 
    288             /* Split MB motion mode */
    289             else if (mbmi->mode == SPLITMV)
    290                 *filter_level +=  mbd->mode_lf_deltas[3];
    291 
    292             /* All other inter motion modes (Nearest, Near, New) */
    293             else
    294                 *filter_level +=  mbd->mode_lf_deltas[2];
    295         }
    296 
    297         /* Range check */
    298         if (*filter_level > MAX_LOOP_FILTER)
    299             *filter_level = MAX_LOOP_FILTER;
    300         else if (*filter_level < 0)
    301             *filter_level = 0;
    302     }
    303 }
    304 
    305 
    306 void vp8_loop_filter_frame
    307 (
    308     VP8_COMMON *cm,
    309     MACROBLOCKD *mbd,
    310     int default_filt_lvl
    311 )
    312 {
    313     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
    314     loop_filter_info *lfi = cm->lf_info;
    315     FRAME_TYPE frame_type = cm->frame_type;
    316 
    317     int mb_row;
    318     int mb_col;
    319 
    320 
    321     int baseline_filter_level[MAX_MB_SEGMENTS];
    322     int filter_level;
    323     int alt_flt_enabled = mbd->segmentation_enabled;
    324 
    325     int i;
    326     unsigned char *y_ptr, *u_ptr, *v_ptr;
    327 
    328     mbd->mode_info_context = cm->mi;          /* Point at base of Mb MODE_INFO list */
    329 
    330     /* Note the baseline filter values for each segment */
    331     if (alt_flt_enabled)
    332     {
    333         for (i = 0; i < MAX_MB_SEGMENTS; i++)
    334         {
    335             /* Abs value */
    336             if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
    337                 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
    338             /* Delta Value */
    339             else
    340             {
    341                 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
    342                 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 */
    343             }
    344         }
    345     }
    346     else
    347     {
    348         for (i = 0; i < MAX_MB_SEGMENTS; i++)
    349             baseline_filter_level[i] = default_filt_lvl;
    350     }
    351 
    352     /* Initialize the loop filter for this frame. */
    353     if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
    354         vp8_init_loop_filter(cm);
    355     else if (frame_type != cm->last_frame_type)
    356         vp8_frame_init_loop_filter(lfi, frame_type);
    357 
    358     /* Set up the buffer pointers */
    359     y_ptr = post->y_buffer;
    360     u_ptr = post->u_buffer;
    361     v_ptr = post->v_buffer;
    362 
    363     /* vp8_filter each macro block */
    364     for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
    365     {
    366         for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
    367         {
    368             int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
    369 
    370             filter_level = baseline_filter_level[Segment];
    371 
    372             /* Distance of Mb to the various image edges.
    373              * These specified to 8th pel as they are always compared to values that are in 1/8th pel units
    374              * Apply any context driven MB level adjustment
    375              */
    376             vp8_adjust_mb_lf_value(mbd, &filter_level);
    377 
    378             if (filter_level)
    379             {
    380                 if (mb_col > 0)
    381                     cm->lf_mbv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
    382 
    383                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
    384                     cm->lf_bv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
    385 
    386                 /* don't apply across umv border */
    387                 if (mb_row > 0)
    388                     cm->lf_mbh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
    389 
    390                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
    391                     cm->lf_bh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
    392             }
    393 
    394             y_ptr += 16;
    395             u_ptr += 8;
    396             v_ptr += 8;
    397 
    398             mbd->mode_info_context++;     /* step to next MB */
    399         }
    400 
    401         y_ptr += post->y_stride  * 16 - post->y_width;
    402         u_ptr += post->uv_stride *  8 - post->uv_width;
    403         v_ptr += post->uv_stride *  8 - post->uv_width;
    404 
    405         mbd->mode_info_context++;         /* Skip border mb */
    406     }
    407 }
    408 
    409 
    410 void vp8_loop_filter_frame_yonly
    411 (
    412     VP8_COMMON *cm,
    413     MACROBLOCKD *mbd,
    414     int default_filt_lvl,
    415     int sharpness_lvl
    416 )
    417 {
    418     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
    419 
    420     int i;
    421     unsigned char *y_ptr;
    422     int mb_row;
    423     int mb_col;
    424 
    425     loop_filter_info *lfi = cm->lf_info;
    426     int baseline_filter_level[MAX_MB_SEGMENTS];
    427     int filter_level;
    428     int alt_flt_enabled = mbd->segmentation_enabled;
    429     FRAME_TYPE frame_type = cm->frame_type;
    430 
    431     (void) sharpness_lvl;
    432 
    433     /*MODE_INFO * this_mb_mode_info = cm->mi;*/ /* Point at base of Mb MODE_INFO list */
    434     mbd->mode_info_context = cm->mi;          /* Point at base of Mb MODE_INFO list */
    435 
    436     /* Note the baseline filter values for each segment */
    437     if (alt_flt_enabled)
    438     {
    439         for (i = 0; i < MAX_MB_SEGMENTS; i++)
    440         {
    441             /* Abs value */
    442             if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
    443                 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
    444             /* Delta Value */
    445             else
    446             {
    447                 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
    448                 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 */
    449             }
    450         }
    451     }
    452     else
    453     {
    454         for (i = 0; i < MAX_MB_SEGMENTS; i++)
    455             baseline_filter_level[i] = default_filt_lvl;
    456     }
    457 
    458     /* Initialize the loop filter for this frame. */
    459     if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
    460         vp8_init_loop_filter(cm);
    461     else if (frame_type != cm->last_frame_type)
    462         vp8_frame_init_loop_filter(lfi, frame_type);
    463 
    464     /* Set up the buffer pointers */
    465     y_ptr = post->y_buffer;
    466 
    467     /* vp8_filter each macro block */
    468     for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
    469     {
    470         for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
    471         {
    472             int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
    473             filter_level = baseline_filter_level[Segment];
    474 
    475             /* Apply any context driven MB level adjustment */
    476             vp8_adjust_mb_lf_value(mbd, &filter_level);
    477 
    478             if (filter_level)
    479             {
    480                 if (mb_col > 0)
    481                     cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    482 
    483                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
    484                     cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    485 
    486                 /* don't apply across umv border */
    487                 if (mb_row > 0)
    488                     cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    489 
    490                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
    491                     cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    492             }
    493 
    494             y_ptr += 16;
    495             mbd->mode_info_context ++;        /* step to next MB */
    496 
    497         }
    498 
    499         y_ptr += post->y_stride  * 16 - post->y_width;
    500         mbd->mode_info_context ++;            /* Skip border mb */
    501     }
    502 
    503 }
    504 
    505 
    506 void vp8_loop_filter_partial_frame
    507 (
    508     VP8_COMMON *cm,
    509     MACROBLOCKD *mbd,
    510     int default_filt_lvl,
    511     int sharpness_lvl,
    512     int Fraction
    513 )
    514 {
    515     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
    516 
    517     int i;
    518     unsigned char *y_ptr;
    519     int mb_row;
    520     int mb_col;
    521     /*int mb_rows = post->y_height >> 4;*/
    522     int mb_cols = post->y_width  >> 4;
    523 
    524     int linestocopy;
    525 
    526     loop_filter_info *lfi = cm->lf_info;
    527     int baseline_filter_level[MAX_MB_SEGMENTS];
    528     int filter_level;
    529     int alt_flt_enabled = mbd->segmentation_enabled;
    530     FRAME_TYPE frame_type = cm->frame_type;
    531 
    532     (void) sharpness_lvl;
    533 
    534     /*MODE_INFO * this_mb_mode_info = cm->mi + (post->y_height>>5) * (mb_cols + 1);*/ /* Point at base of Mb MODE_INFO list */
    535     mbd->mode_info_context = cm->mi + (post->y_height >> 5) * (mb_cols + 1);        /* Point at base of Mb MODE_INFO list */
    536 
    537     linestocopy = (post->y_height >> (4 + Fraction));
    538 
    539     if (linestocopy < 1)
    540         linestocopy = 1;
    541 
    542     linestocopy <<= 4;
    543 
    544     /* Note the baseline filter values for each segment */
    545     if (alt_flt_enabled)
    546     {
    547         for (i = 0; i < MAX_MB_SEGMENTS; i++)
    548         {
    549             /* Abs value */
    550             if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
    551                 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
    552             /* Delta Value */
    553             else
    554             {
    555                 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
    556                 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 */
    557             }
    558         }
    559     }
    560     else
    561     {
    562         for (i = 0; i < MAX_MB_SEGMENTS; i++)
    563             baseline_filter_level[i] = default_filt_lvl;
    564     }
    565 
    566     /* Initialize the loop filter for this frame. */
    567     if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
    568         vp8_init_loop_filter(cm);
    569     else if (frame_type != cm->last_frame_type)
    570         vp8_frame_init_loop_filter(lfi, frame_type);
    571 
    572     /* Set up the buffer pointers */
    573     y_ptr = post->y_buffer + (post->y_height >> 5) * 16 * post->y_stride;
    574 
    575     /* vp8_filter each macro block */
    576     for (mb_row = 0; mb_row<(linestocopy >> 4); mb_row++)
    577     {
    578         for (mb_col = 0; mb_col < mb_cols; mb_col++)
    579         {
    580             int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
    581             filter_level = baseline_filter_level[Segment];
    582 
    583             if (filter_level)
    584             {
    585                 if (mb_col > 0)
    586                     cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    587 
    588                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
    589                     cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    590 
    591                 cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    592 
    593                 if (mbd->mode_info_context->mbmi.dc_diff > 0)
    594                     cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
    595             }
    596 
    597             y_ptr += 16;
    598             mbd->mode_info_context += 1;      /* step to next MB */
    599         }
    600 
    601         y_ptr += post->y_stride  * 16 - post->y_width;
    602         mbd->mode_info_context += 1;          /* Skip border mb */
    603     }
    604 }
    605