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 */
vp8_loop_filter_mbh_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)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
vp8_loop_filter_mbhs_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)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 */
vp8_loop_filter_mbv_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)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
vp8_loop_filter_mbvs_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)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 */
vp8_loop_filter_bh_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)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
vp8_loop_filter_bhs_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)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 */
vp8_loop_filter_bv_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)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
vp8_loop_filter_bvs_c(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi,int simpler_lpf)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
vp8_init_loop_filter(VP8_COMMON * cm)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 */
vp8_frame_init_loop_filter(loop_filter_info * lfi,int frame_type)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
vp8_adjust_mb_lf_value(MACROBLOCKD * mbd,int filter_level)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
vp8_loop_filter_frame(VP8_COMMON * cm,MACROBLOCKD * mbd,int default_filt_lvl)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
vp8_loop_filter_frame_yonly(VP8_COMMON * cm,MACROBLOCKD * mbd,int default_filt_lvl,int sharpness_lvl)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
vp8_loop_filter_partial_frame(VP8_COMMON * cm,MACROBLOCKD * mbd,int default_filt_lvl,int sharpness_lvl,int Fraction)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