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