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