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_config.h"
13 #include "vp8_rtcd.h"
14 #include "loopfilter.h"
15 #include "onyxc_int.h"
16 #include "vpx_mem/vpx_mem.h"
17 
18 typedef unsigned char uc;
19 
lf_init_lut(loop_filter_info_n * lfi)20 static void lf_init_lut(loop_filter_info_n *lfi)
21 {
22     int filt_lvl;
23 
24     for (filt_lvl = 0; filt_lvl <= MAX_LOOP_FILTER; filt_lvl++)
25     {
26         if (filt_lvl >= 40)
27         {
28             lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 2;
29             lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 3;
30         }
31         else if (filt_lvl >= 20)
32         {
33             lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 1;
34             lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 2;
35         }
36         else if (filt_lvl >= 15)
37         {
38             lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 1;
39             lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 1;
40         }
41         else
42         {
43             lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 0;
44             lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 0;
45         }
46     }
47 
48     lfi->mode_lf_lut[DC_PRED] = 1;
49     lfi->mode_lf_lut[V_PRED] = 1;
50     lfi->mode_lf_lut[H_PRED] = 1;
51     lfi->mode_lf_lut[TM_PRED] = 1;
52     lfi->mode_lf_lut[B_PRED]  = 0;
53 
54     lfi->mode_lf_lut[ZEROMV]  = 1;
55     lfi->mode_lf_lut[NEARESTMV] = 2;
56     lfi->mode_lf_lut[NEARMV] = 2;
57     lfi->mode_lf_lut[NEWMV] = 2;
58     lfi->mode_lf_lut[SPLITMV] = 3;
59 
60 }
61 
vp8_loop_filter_update_sharpness(loop_filter_info_n * lfi,int sharpness_lvl)62 void vp8_loop_filter_update_sharpness(loop_filter_info_n *lfi,
63                                       int sharpness_lvl)
64 {
65     int i;
66 
67     /* For each possible value for the loop filter fill out limits */
68     for (i = 0; i <= MAX_LOOP_FILTER; i++)
69     {
70         int filt_lvl = i;
71         int block_inside_limit = 0;
72 
73         /* Set loop filter paramaeters that control sharpness. */
74         block_inside_limit = filt_lvl >> (sharpness_lvl > 0);
75         block_inside_limit = block_inside_limit >> (sharpness_lvl > 4);
76 
77         if (sharpness_lvl > 0)
78         {
79             if (block_inside_limit > (9 - sharpness_lvl))
80                 block_inside_limit = (9 - sharpness_lvl);
81         }
82 
83         if (block_inside_limit < 1)
84             block_inside_limit = 1;
85 
86         vpx_memset(lfi->lim[i], block_inside_limit, SIMD_WIDTH);
87         vpx_memset(lfi->blim[i], (2 * filt_lvl + block_inside_limit),
88                 SIMD_WIDTH);
89         vpx_memset(lfi->mblim[i], (2 * (filt_lvl + 2) + block_inside_limit),
90                 SIMD_WIDTH);
91     }
92 }
93 
vp8_loop_filter_init(VP8_COMMON * cm)94 void vp8_loop_filter_init(VP8_COMMON *cm)
95 {
96     loop_filter_info_n *lfi = &cm->lf_info;
97     int i;
98 
99     /* init limits for given sharpness*/
100     vp8_loop_filter_update_sharpness(lfi, cm->sharpness_level);
101     cm->last_sharpness_level = cm->sharpness_level;
102 
103     /* init LUT for lvl  and hev thr picking */
104     lf_init_lut(lfi);
105 
106     /* init hev threshold const vectors */
107     for(i = 0; i < 4 ; i++)
108     {
109         vpx_memset(lfi->hev_thr[i], i, SIMD_WIDTH);
110     }
111 }
112 
vp8_loop_filter_frame_init(VP8_COMMON * cm,MACROBLOCKD * mbd,int default_filt_lvl)113 void vp8_loop_filter_frame_init(VP8_COMMON *cm,
114                                 MACROBLOCKD *mbd,
115                                 int default_filt_lvl)
116 {
117     int seg,  /* segment number */
118         ref,  /* index in ref_lf_deltas */
119         mode; /* index in mode_lf_deltas */
120 
121     loop_filter_info_n *lfi = &cm->lf_info;
122 
123     /* update limits if sharpness has changed */
124     if(cm->last_sharpness_level != cm->sharpness_level)
125     {
126         vp8_loop_filter_update_sharpness(lfi, cm->sharpness_level);
127         cm->last_sharpness_level = cm->sharpness_level;
128     }
129 
130     for(seg = 0; seg < MAX_MB_SEGMENTS; seg++)
131     {
132         int lvl_seg = default_filt_lvl;
133         int lvl_ref, lvl_mode;
134 
135         /* Note the baseline filter values for each segment */
136         if (mbd->segmentation_enabled)
137         {
138             /* Abs value */
139             if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
140             {
141                 lvl_seg = mbd->segment_feature_data[MB_LVL_ALT_LF][seg];
142             }
143             else  /* Delta Value */
144             {
145                 lvl_seg += mbd->segment_feature_data[MB_LVL_ALT_LF][seg];
146                 lvl_seg = (lvl_seg > 0) ? ((lvl_seg > 63) ? 63: lvl_seg) : 0;
147             }
148         }
149 
150         if (!mbd->mode_ref_lf_delta_enabled)
151         {
152             /* we could get rid of this if we assume that deltas are set to
153              * zero when not in use; encoder always uses deltas
154              */
155             vpx_memset(lfi->lvl[seg][0], lvl_seg, 4 * 4 );
156             continue;
157         }
158 
159         /* INTRA_FRAME */
160         ref = INTRA_FRAME;
161 
162         /* Apply delta for reference frame */
163         lvl_ref = lvl_seg + mbd->ref_lf_deltas[ref];
164 
165         /* Apply delta for Intra modes */
166         mode = 0; /* B_PRED */
167         /* Only the split mode BPRED has a further special case */
168         lvl_mode = lvl_ref + mbd->mode_lf_deltas[mode];
169         /* clamp */
170         lvl_mode = (lvl_mode > 0) ? (lvl_mode > 63 ? 63 : lvl_mode) : 0;
171 
172         lfi->lvl[seg][ref][mode] = lvl_mode;
173 
174         mode = 1; /* all the rest of Intra modes */
175         /* clamp */
176         lvl_mode = (lvl_ref > 0) ? (lvl_ref > 63 ? 63 : lvl_ref) : 0;
177         lfi->lvl[seg][ref][mode] = lvl_mode;
178 
179         /* LAST, GOLDEN, ALT */
180         for(ref = 1; ref < MAX_REF_FRAMES; ref++)
181         {
182             /* Apply delta for reference frame */
183             lvl_ref = lvl_seg + mbd->ref_lf_deltas[ref];
184 
185             /* Apply delta for Inter modes */
186             for (mode = 1; mode < 4; mode++)
187             {
188                 lvl_mode = lvl_ref + mbd->mode_lf_deltas[mode];
189                 /* clamp */
190                 lvl_mode = (lvl_mode > 0) ? (lvl_mode > 63 ? 63 : lvl_mode) : 0;
191 
192                 lfi->lvl[seg][ref][mode] = lvl_mode;
193             }
194         }
195     }
196 }
197 
198 
vp8_loop_filter_row_normal(VP8_COMMON * cm,MODE_INFO * mode_info_context,int mb_row,int post_ystride,int post_uvstride,unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr)199 void vp8_loop_filter_row_normal(VP8_COMMON *cm, MODE_INFO *mode_info_context,
200                          int mb_row, int post_ystride, int post_uvstride,
201                          unsigned char *y_ptr, unsigned char *u_ptr,
202                          unsigned char *v_ptr)
203 {
204     int mb_col;
205     int filter_level;
206     loop_filter_info_n *lfi_n = &cm->lf_info;
207     loop_filter_info lfi;
208     FRAME_TYPE frame_type = cm->frame_type;
209 
210     for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
211     {
212         int skip_lf = (mode_info_context->mbmi.mode != B_PRED &&
213                         mode_info_context->mbmi.mode != SPLITMV &&
214                         mode_info_context->mbmi.mb_skip_coeff);
215 
216         const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode];
217         const int seg = mode_info_context->mbmi.segment_id;
218         const int ref_frame = mode_info_context->mbmi.ref_frame;
219 
220         filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
221 
222         if (filter_level)
223         {
224             const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
225             lfi.mblim = lfi_n->mblim[filter_level];
226             lfi.blim = lfi_n->blim[filter_level];
227             lfi.lim = lfi_n->lim[filter_level];
228             lfi.hev_thr = lfi_n->hev_thr[hev_index];
229 
230             if (mb_col > 0)
231                 vp8_loop_filter_mbv
232                 (y_ptr, u_ptr, v_ptr, post_ystride, post_uvstride, &lfi);
233 
234             if (!skip_lf)
235                 vp8_loop_filter_bv
236                 (y_ptr, u_ptr, v_ptr, post_ystride, post_uvstride, &lfi);
237 
238             /* don't apply across umv border */
239             if (mb_row > 0)
240                 vp8_loop_filter_mbh
241                 (y_ptr, u_ptr, v_ptr, post_ystride, post_uvstride, &lfi);
242 
243             if (!skip_lf)
244                 vp8_loop_filter_bh
245                 (y_ptr, u_ptr, v_ptr, post_ystride, post_uvstride, &lfi);
246         }
247 
248         y_ptr += 16;
249         u_ptr += 8;
250         v_ptr += 8;
251 
252         mode_info_context++;     /* step to next MB */
253     }
254 
255 }
256 
vp8_loop_filter_row_simple(VP8_COMMON * cm,MODE_INFO * mode_info_context,int mb_row,int post_ystride,int post_uvstride,unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr)257 void vp8_loop_filter_row_simple(VP8_COMMON *cm, MODE_INFO *mode_info_context,
258                          int mb_row, int post_ystride, int post_uvstride,
259                          unsigned char *y_ptr, unsigned char *u_ptr,
260                          unsigned char *v_ptr)
261 {
262     int mb_col;
263     int filter_level;
264     loop_filter_info_n *lfi_n = &cm->lf_info;
265     (void)post_uvstride;
266 
267     for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
268     {
269         int skip_lf = (mode_info_context->mbmi.mode != B_PRED &&
270                         mode_info_context->mbmi.mode != SPLITMV &&
271                         mode_info_context->mbmi.mb_skip_coeff);
272 
273         const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode];
274         const int seg = mode_info_context->mbmi.segment_id;
275         const int ref_frame = mode_info_context->mbmi.ref_frame;
276 
277         filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
278 
279         if (filter_level)
280         {
281             if (mb_col > 0)
282                 vp8_loop_filter_simple_mbv
283                 (y_ptr, post_ystride, lfi_n->mblim[filter_level]);
284 
285             if (!skip_lf)
286                 vp8_loop_filter_simple_bv
287                 (y_ptr, post_ystride, lfi_n->blim[filter_level]);
288 
289             /* don't apply across umv border */
290             if (mb_row > 0)
291                 vp8_loop_filter_simple_mbh
292                 (y_ptr, post_ystride, lfi_n->mblim[filter_level]);
293 
294             if (!skip_lf)
295                 vp8_loop_filter_simple_bh
296                 (y_ptr, post_ystride, lfi_n->blim[filter_level]);
297         }
298 
299         y_ptr += 16;
300         u_ptr += 8;
301         v_ptr += 8;
302 
303         mode_info_context++;     /* step to next MB */
304     }
305 
306 }
vp8_loop_filter_frame(VP8_COMMON * cm,MACROBLOCKD * mbd,int frame_type)307 void vp8_loop_filter_frame(VP8_COMMON *cm,
308                            MACROBLOCKD *mbd,
309                            int frame_type)
310 {
311     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
312     loop_filter_info_n *lfi_n = &cm->lf_info;
313     loop_filter_info lfi;
314 
315     int mb_row;
316     int mb_col;
317     int mb_rows = cm->mb_rows;
318     int mb_cols = cm->mb_cols;
319 
320     int filter_level;
321 
322     unsigned char *y_ptr, *u_ptr, *v_ptr;
323 
324     /* Point at base of Mb MODE_INFO list */
325     const MODE_INFO *mode_info_context = cm->mi;
326     int post_y_stride = post->y_stride;
327     int post_uv_stride = post->uv_stride;
328 
329     /* Initialize the loop filter for this frame. */
330     vp8_loop_filter_frame_init(cm, mbd, cm->filter_level);
331 
332     /* Set up the buffer pointers */
333     y_ptr = post->y_buffer;
334     u_ptr = post->u_buffer;
335     v_ptr = post->v_buffer;
336 
337     /* vp8_filter each macro block */
338     if (cm->filter_type == NORMAL_LOOPFILTER)
339     {
340         for (mb_row = 0; mb_row < mb_rows; mb_row++)
341         {
342             for (mb_col = 0; mb_col < mb_cols; mb_col++)
343             {
344                 int skip_lf = (mode_info_context->mbmi.mode != B_PRED &&
345                                 mode_info_context->mbmi.mode != SPLITMV &&
346                                 mode_info_context->mbmi.mb_skip_coeff);
347 
348                 const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode];
349                 const int seg = mode_info_context->mbmi.segment_id;
350                 const int ref_frame = mode_info_context->mbmi.ref_frame;
351 
352                 filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
353 
354                 if (filter_level)
355                 {
356                     const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
357                     lfi.mblim = lfi_n->mblim[filter_level];
358                     lfi.blim = lfi_n->blim[filter_level];
359                     lfi.lim = lfi_n->lim[filter_level];
360                     lfi.hev_thr = lfi_n->hev_thr[hev_index];
361 
362                     if (mb_col > 0)
363                         vp8_loop_filter_mbv
364                         (y_ptr, u_ptr, v_ptr, post_y_stride, post_uv_stride, &lfi);
365 
366                     if (!skip_lf)
367                         vp8_loop_filter_bv
368                         (y_ptr, u_ptr, v_ptr, post_y_stride, post_uv_stride, &lfi);
369 
370                     /* don't apply across umv border */
371                     if (mb_row > 0)
372                         vp8_loop_filter_mbh
373                         (y_ptr, u_ptr, v_ptr, post_y_stride, post_uv_stride, &lfi);
374 
375                     if (!skip_lf)
376                         vp8_loop_filter_bh
377                         (y_ptr, u_ptr, v_ptr, post_y_stride, post_uv_stride, &lfi);
378                 }
379 
380                 y_ptr += 16;
381                 u_ptr += 8;
382                 v_ptr += 8;
383 
384                 mode_info_context++;     /* step to next MB */
385             }
386             y_ptr += post_y_stride  * 16 - post->y_width;
387             u_ptr += post_uv_stride *  8 - post->uv_width;
388             v_ptr += post_uv_stride *  8 - post->uv_width;
389 
390             mode_info_context++;         /* Skip border mb */
391 
392         }
393     }
394     else /* SIMPLE_LOOPFILTER */
395     {
396         for (mb_row = 0; mb_row < mb_rows; mb_row++)
397         {
398             for (mb_col = 0; mb_col < mb_cols; mb_col++)
399             {
400                 int skip_lf = (mode_info_context->mbmi.mode != B_PRED &&
401                                 mode_info_context->mbmi.mode != SPLITMV &&
402                                 mode_info_context->mbmi.mb_skip_coeff);
403 
404                 const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode];
405                 const int seg = mode_info_context->mbmi.segment_id;
406                 const int ref_frame = mode_info_context->mbmi.ref_frame;
407 
408                 filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
409                 if (filter_level)
410                 {
411                     const unsigned char * mblim = lfi_n->mblim[filter_level];
412                     const unsigned char * blim = lfi_n->blim[filter_level];
413 
414                     if (mb_col > 0)
415                         vp8_loop_filter_simple_mbv
416                         (y_ptr, post_y_stride, mblim);
417 
418                     if (!skip_lf)
419                         vp8_loop_filter_simple_bv
420                         (y_ptr, post_y_stride, blim);
421 
422                     /* don't apply across umv border */
423                     if (mb_row > 0)
424                         vp8_loop_filter_simple_mbh
425                         (y_ptr, post_y_stride, mblim);
426 
427                     if (!skip_lf)
428                         vp8_loop_filter_simple_bh
429                         (y_ptr, post_y_stride, blim);
430                 }
431 
432                 y_ptr += 16;
433                 u_ptr += 8;
434                 v_ptr += 8;
435 
436                 mode_info_context++;     /* step to next MB */
437             }
438             y_ptr += post_y_stride  * 16 - post->y_width;
439             u_ptr += post_uv_stride *  8 - post->uv_width;
440             v_ptr += post_uv_stride *  8 - post->uv_width;
441 
442             mode_info_context++;         /* Skip border mb */
443 
444         }
445     }
446 }
447 
vp8_loop_filter_frame_yonly(VP8_COMMON * cm,MACROBLOCKD * mbd,int default_filt_lvl)448 void vp8_loop_filter_frame_yonly
449 (
450     VP8_COMMON *cm,
451     MACROBLOCKD *mbd,
452     int default_filt_lvl
453 )
454 {
455     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
456 
457     unsigned char *y_ptr;
458     int mb_row;
459     int mb_col;
460 
461     loop_filter_info_n *lfi_n = &cm->lf_info;
462     loop_filter_info lfi;
463 
464     int filter_level;
465     FRAME_TYPE frame_type = cm->frame_type;
466 
467     /* Point at base of Mb MODE_INFO list */
468     const MODE_INFO *mode_info_context = cm->mi;
469 
470 #if 0
471     if(default_filt_lvl == 0) /* no filter applied */
472         return;
473 #endif
474 
475     /* Initialize the loop filter for this frame. */
476     vp8_loop_filter_frame_init( cm, mbd, default_filt_lvl);
477 
478     /* Set up the buffer pointers */
479     y_ptr = post->y_buffer;
480 
481     /* vp8_filter each macro block */
482     for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
483     {
484         for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
485         {
486             int skip_lf = (mode_info_context->mbmi.mode != B_PRED &&
487                             mode_info_context->mbmi.mode != SPLITMV &&
488                             mode_info_context->mbmi.mb_skip_coeff);
489 
490             const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode];
491             const int seg = mode_info_context->mbmi.segment_id;
492             const int ref_frame = mode_info_context->mbmi.ref_frame;
493 
494             filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
495 
496             if (filter_level)
497             {
498                 if (cm->filter_type == NORMAL_LOOPFILTER)
499                 {
500                     const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
501                     lfi.mblim = lfi_n->mblim[filter_level];
502                     lfi.blim = lfi_n->blim[filter_level];
503                     lfi.lim = lfi_n->lim[filter_level];
504                     lfi.hev_thr = lfi_n->hev_thr[hev_index];
505 
506                     if (mb_col > 0)
507                         vp8_loop_filter_mbv
508                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
509 
510                     if (!skip_lf)
511                         vp8_loop_filter_bv
512                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
513 
514                     /* don't apply across umv border */
515                     if (mb_row > 0)
516                         vp8_loop_filter_mbh
517                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
518 
519                     if (!skip_lf)
520                         vp8_loop_filter_bh
521                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
522                 }
523                 else
524                 {
525                     if (mb_col > 0)
526                         vp8_loop_filter_simple_mbv
527                         (y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
528 
529                     if (!skip_lf)
530                         vp8_loop_filter_simple_bv
531                         (y_ptr, post->y_stride, lfi_n->blim[filter_level]);
532 
533                     /* don't apply across umv border */
534                     if (mb_row > 0)
535                         vp8_loop_filter_simple_mbh
536                         (y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
537 
538                     if (!skip_lf)
539                         vp8_loop_filter_simple_bh
540                         (y_ptr, post->y_stride, lfi_n->blim[filter_level]);
541                 }
542             }
543 
544             y_ptr += 16;
545             mode_info_context ++;        /* step to next MB */
546 
547         }
548 
549         y_ptr += post->y_stride  * 16 - post->y_width;
550         mode_info_context ++;            /* Skip border mb */
551     }
552 
553 }
554 
vp8_loop_filter_partial_frame(VP8_COMMON * cm,MACROBLOCKD * mbd,int default_filt_lvl)555 void vp8_loop_filter_partial_frame
556 (
557     VP8_COMMON *cm,
558     MACROBLOCKD *mbd,
559     int default_filt_lvl
560 )
561 {
562     YV12_BUFFER_CONFIG *post = cm->frame_to_show;
563 
564     unsigned char *y_ptr;
565     int mb_row;
566     int mb_col;
567     int mb_cols = post->y_width >> 4;
568     int mb_rows = post->y_height >> 4;
569 
570     int linestocopy;
571 
572     loop_filter_info_n *lfi_n = &cm->lf_info;
573     loop_filter_info lfi;
574 
575     int filter_level;
576     FRAME_TYPE frame_type = cm->frame_type;
577 
578     const MODE_INFO *mode_info_context;
579 
580 #if 0
581     if(default_filt_lvl == 0) /* no filter applied */
582         return;
583 #endif
584 
585     /* Initialize the loop filter for this frame. */
586     vp8_loop_filter_frame_init( cm, mbd, default_filt_lvl);
587 
588     /* number of MB rows to use in partial filtering */
589     linestocopy = mb_rows / PARTIAL_FRAME_FRACTION;
590     linestocopy = linestocopy ? linestocopy << 4 : 16;     /* 16 lines per MB */
591 
592     /* Set up the buffer pointers; partial image starts at ~middle of frame */
593     y_ptr = post->y_buffer + ((post->y_height >> 5) * 16) * post->y_stride;
594     mode_info_context = cm->mi + (post->y_height >> 5) * (mb_cols + 1);
595 
596     /* vp8_filter each macro block */
597     for (mb_row = 0; mb_row<(linestocopy >> 4); mb_row++)
598     {
599         for (mb_col = 0; mb_col < mb_cols; mb_col++)
600         {
601             int skip_lf = (mode_info_context->mbmi.mode != B_PRED &&
602                            mode_info_context->mbmi.mode != SPLITMV &&
603                            mode_info_context->mbmi.mb_skip_coeff);
604 
605             const int mode_index =
606                 lfi_n->mode_lf_lut[mode_info_context->mbmi.mode];
607             const int seg = mode_info_context->mbmi.segment_id;
608             const int ref_frame = mode_info_context->mbmi.ref_frame;
609 
610             filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
611 
612             if (filter_level)
613             {
614                 if (cm->filter_type == NORMAL_LOOPFILTER)
615                 {
616                     const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
617                     lfi.mblim = lfi_n->mblim[filter_level];
618                     lfi.blim = lfi_n->blim[filter_level];
619                     lfi.lim = lfi_n->lim[filter_level];
620                     lfi.hev_thr = lfi_n->hev_thr[hev_index];
621 
622                     if (mb_col > 0)
623                         vp8_loop_filter_mbv
624                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
625 
626                     if (!skip_lf)
627                         vp8_loop_filter_bv
628                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
629 
630                     vp8_loop_filter_mbh
631                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
632 
633                     if (!skip_lf)
634                         vp8_loop_filter_bh
635                         (y_ptr, 0, 0, post->y_stride, 0, &lfi);
636                 }
637                 else
638                 {
639                     if (mb_col > 0)
640                         vp8_loop_filter_simple_mbv
641                         (y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
642 
643                     if (!skip_lf)
644                         vp8_loop_filter_simple_bv
645                         (y_ptr, post->y_stride, lfi_n->blim[filter_level]);
646 
647                     vp8_loop_filter_simple_mbh
648                         (y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
649 
650                     if (!skip_lf)
651                         vp8_loop_filter_simple_bh
652                         (y_ptr, post->y_stride, lfi_n->blim[filter_level]);
653                 }
654             }
655 
656             y_ptr += 16;
657             mode_info_context += 1;      /* step to next MB */
658         }
659 
660         y_ptr += post->y_stride  * 16 - post->y_width;
661         mode_info_context += 1;          /* Skip border mb */
662     }
663 }
664