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