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