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->mbthr, 2);
32
33 if (u_ptr)
34 vp8_mbloop_filter_horizontal_edge_c(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
35
36 if (v_ptr)
37 vp8_mbloop_filter_horizontal_edge_c(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 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->mbthr, 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->mbthr, 2);
56
57 if (u_ptr)
58 vp8_mbloop_filter_vertical_edge_c(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
59
60 if (v_ptr)
61 vp8_mbloop_filter_vertical_edge_c(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 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->mbthr, 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->uvflim, lfi->uvlim, lfi->uvthr, 1);
85
86 if (v_ptr)
87 vp8_loop_filter_horizontal_edge_c(v_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 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->uvflim, lfi->uvlim, lfi->uvthr, 1);
113
114 if (v_ptr)
115 vp8_loop_filter_vertical_edge_c(v_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 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 const int yhedge_boost = 2;
141 const int uvhedge_boost = 2;
142
143 /* For each possible value for the loop filter fill out a "loop_filter_info" entry. */
144 for (i = 0; i <= MAX_LOOP_FILTER; i++)
145 {
146 int filt_lvl = i;
147
148 if (frame_type == KEY_FRAME)
149 {
150 if (filt_lvl >= 40)
151 HEVThresh = 2;
152 else if (filt_lvl >= 15)
153 HEVThresh = 1;
154 else
155 HEVThresh = 0;
156 }
157 else
158 {
159 if (filt_lvl >= 40)
160 HEVThresh = 3;
161 else if (filt_lvl >= 20)
162 HEVThresh = 2;
163 else if (filt_lvl >= 15)
164 HEVThresh = 1;
165 else
166 HEVThresh = 0;
167 }
168
169 /* Set loop filter paramaeters that control sharpness. */
170 block_inside_limit = filt_lvl >> (sharpness_lvl > 0);
171 block_inside_limit = block_inside_limit >> (sharpness_lvl > 4);
172
173 if (sharpness_lvl > 0)
174 {
175 if (block_inside_limit > (9 - sharpness_lvl))
176 block_inside_limit = (9 - sharpness_lvl);
177 }
178
179 if (block_inside_limit < 1)
180 block_inside_limit = 1;
181
182 for (j = 0; j < 16; j++)
183 {
184 lfi[i].lim[j] = block_inside_limit;
185 lfi[i].mbflim[j] = filt_lvl + yhedge_boost;
186 lfi[i].mbthr[j] = HEVThresh;
187 lfi[i].flim[j] = filt_lvl;
188 lfi[i].thr[j] = HEVThresh;
189 lfi[i].uvlim[j] = block_inside_limit;
190 lfi[i].uvmbflim[j] = filt_lvl + uvhedge_boost;
191 lfi[i].uvmbthr[j] = HEVThresh;
192 lfi[i].uvflim[j] = filt_lvl;
193 lfi[i].uvthr[j] = HEVThresh;
194 }
195
196 }
197
198 /* Set up the function pointers depending on the type of loop filtering selected */
199 if (lft == NORMAL_LOOPFILTER)
200 {
201 cm->lf_mbv = LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_v);
202 cm->lf_bv = LF_INVOKE(&cm->rtcd.loopfilter, normal_b_v);
203 cm->lf_mbh = LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_h);
204 cm->lf_bh = LF_INVOKE(&cm->rtcd.loopfilter, normal_b_h);
205 }
206 else
207 {
208 cm->lf_mbv = LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_v);
209 cm->lf_bv = LF_INVOKE(&cm->rtcd.loopfilter, simple_b_v);
210 cm->lf_mbh = LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_h);
211 cm->lf_bh = LF_INVOKE(&cm->rtcd.loopfilter, simple_b_h);
212 }
213 }
214
215 /* Put vp8_init_loop_filter() in vp8dx_create_decompressor(). Only call vp8_frame_init_loop_filter() while decoding
216 * each frame. Check last_frame_type to skip the function most of times.
217 */
vp8_frame_init_loop_filter(loop_filter_info * lfi,int frame_type)218 void vp8_frame_init_loop_filter(loop_filter_info *lfi, int frame_type)
219 {
220 int HEVThresh;
221 int i, j;
222
223 /* For each possible value for the loop filter fill out a "loop_filter_info" entry. */
224 for (i = 0; i <= MAX_LOOP_FILTER; i++)
225 {
226 int filt_lvl = i;
227
228 if (frame_type == KEY_FRAME)
229 {
230 if (filt_lvl >= 40)
231 HEVThresh = 2;
232 else if (filt_lvl >= 15)
233 HEVThresh = 1;
234 else
235 HEVThresh = 0;
236 }
237 else
238 {
239 if (filt_lvl >= 40)
240 HEVThresh = 3;
241 else if (filt_lvl >= 20)
242 HEVThresh = 2;
243 else if (filt_lvl >= 15)
244 HEVThresh = 1;
245 else
246 HEVThresh = 0;
247 }
248
249 for (j = 0; j < 16; j++)
250 {
251 /*lfi[i].lim[j] = block_inside_limit;
252 lfi[i].mbflim[j] = filt_lvl+yhedge_boost;*/
253 lfi[i].mbthr[j] = HEVThresh;
254 /*lfi[i].flim[j] = filt_lvl;*/
255 lfi[i].thr[j] = HEVThresh;
256 /*lfi[i].uvlim[j] = block_inside_limit;
257 lfi[i].uvmbflim[j] = filt_lvl+uvhedge_boost;*/
258 lfi[i].uvmbthr[j] = HEVThresh;
259 /*lfi[i].uvflim[j] = filt_lvl;*/
260 lfi[i].uvthr[j] = HEVThresh;
261 }
262 }
263 }
264
265
vp8_adjust_mb_lf_value(MACROBLOCKD * mbd,int * filter_level)266 void vp8_adjust_mb_lf_value(MACROBLOCKD *mbd, int *filter_level)
267 {
268 MB_MODE_INFO *mbmi = &mbd->mode_info_context->mbmi;
269
270 if (mbd->mode_ref_lf_delta_enabled)
271 {
272 /* Apply delta for reference frame */
273 *filter_level += mbd->ref_lf_deltas[mbmi->ref_frame];
274
275 /* Apply delta for mode */
276 if (mbmi->ref_frame == INTRA_FRAME)
277 {
278 /* Only the split mode BPRED has a further special case */
279 if (mbmi->mode == B_PRED)
280 *filter_level += mbd->mode_lf_deltas[0];
281 }
282 else
283 {
284 /* Zero motion mode */
285 if (mbmi->mode == ZEROMV)
286 *filter_level += mbd->mode_lf_deltas[1];
287
288 /* Split MB motion mode */
289 else if (mbmi->mode == SPLITMV)
290 *filter_level += mbd->mode_lf_deltas[3];
291
292 /* All other inter motion modes (Nearest, Near, New) */
293 else
294 *filter_level += mbd->mode_lf_deltas[2];
295 }
296
297 /* Range check */
298 if (*filter_level > MAX_LOOP_FILTER)
299 *filter_level = MAX_LOOP_FILTER;
300 else if (*filter_level < 0)
301 *filter_level = 0;
302 }
303 }
304
305
vp8_loop_filter_frame(VP8_COMMON * cm,MACROBLOCKD * mbd,int default_filt_lvl)306 void vp8_loop_filter_frame
307 (
308 VP8_COMMON *cm,
309 MACROBLOCKD *mbd,
310 int default_filt_lvl
311 )
312 {
313 YV12_BUFFER_CONFIG *post = cm->frame_to_show;
314 loop_filter_info *lfi = cm->lf_info;
315 FRAME_TYPE frame_type = cm->frame_type;
316
317 int mb_row;
318 int mb_col;
319
320
321 int baseline_filter_level[MAX_MB_SEGMENTS];
322 int filter_level;
323 int alt_flt_enabled = mbd->segmentation_enabled;
324
325 int i;
326 unsigned char *y_ptr, *u_ptr, *v_ptr;
327
328 mbd->mode_info_context = cm->mi; /* Point at base of Mb MODE_INFO list */
329
330 /* Note the baseline filter values for each segment */
331 if (alt_flt_enabled)
332 {
333 for (i = 0; i < MAX_MB_SEGMENTS; i++)
334 {
335 /* Abs value */
336 if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
337 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
338 /* Delta Value */
339 else
340 {
341 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
342 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 */
343 }
344 }
345 }
346 else
347 {
348 for (i = 0; i < MAX_MB_SEGMENTS; i++)
349 baseline_filter_level[i] = default_filt_lvl;
350 }
351
352 /* Initialize the loop filter for this frame. */
353 if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
354 vp8_init_loop_filter(cm);
355 else if (frame_type != cm->last_frame_type)
356 vp8_frame_init_loop_filter(lfi, frame_type);
357
358 /* Set up the buffer pointers */
359 y_ptr = post->y_buffer;
360 u_ptr = post->u_buffer;
361 v_ptr = post->v_buffer;
362
363 /* vp8_filter each macro block */
364 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
365 {
366 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
367 {
368 int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
369
370 filter_level = baseline_filter_level[Segment];
371
372 /* Distance of Mb to the various image edges.
373 * These specified to 8th pel as they are always compared to values that are in 1/8th pel units
374 * Apply any context driven MB level adjustment
375 */
376 vp8_adjust_mb_lf_value(mbd, &filter_level);
377
378 if (filter_level)
379 {
380 if (mb_col > 0)
381 cm->lf_mbv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
382
383 if (mbd->mode_info_context->mbmi.dc_diff > 0)
384 cm->lf_bv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
385
386 /* don't apply across umv border */
387 if (mb_row > 0)
388 cm->lf_mbh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
389
390 if (mbd->mode_info_context->mbmi.dc_diff > 0)
391 cm->lf_bh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
392 }
393
394 y_ptr += 16;
395 u_ptr += 8;
396 v_ptr += 8;
397
398 mbd->mode_info_context++; /* step to next MB */
399 }
400
401 y_ptr += post->y_stride * 16 - post->y_width;
402 u_ptr += post->uv_stride * 8 - post->uv_width;
403 v_ptr += post->uv_stride * 8 - post->uv_width;
404
405 mbd->mode_info_context++; /* Skip border mb */
406 }
407 }
408
409
vp8_loop_filter_frame_yonly(VP8_COMMON * cm,MACROBLOCKD * mbd,int default_filt_lvl,int sharpness_lvl)410 void vp8_loop_filter_frame_yonly
411 (
412 VP8_COMMON *cm,
413 MACROBLOCKD *mbd,
414 int default_filt_lvl,
415 int sharpness_lvl
416 )
417 {
418 YV12_BUFFER_CONFIG *post = cm->frame_to_show;
419
420 int i;
421 unsigned char *y_ptr;
422 int mb_row;
423 int mb_col;
424
425 loop_filter_info *lfi = cm->lf_info;
426 int baseline_filter_level[MAX_MB_SEGMENTS];
427 int filter_level;
428 int alt_flt_enabled = mbd->segmentation_enabled;
429 FRAME_TYPE frame_type = cm->frame_type;
430
431 (void) sharpness_lvl;
432
433 /*MODE_INFO * this_mb_mode_info = cm->mi;*/ /* Point at base of Mb MODE_INFO list */
434 mbd->mode_info_context = cm->mi; /* Point at base of Mb MODE_INFO list */
435
436 /* Note the baseline filter values for each segment */
437 if (alt_flt_enabled)
438 {
439 for (i = 0; i < MAX_MB_SEGMENTS; i++)
440 {
441 /* Abs value */
442 if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
443 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
444 /* Delta Value */
445 else
446 {
447 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
448 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 */
449 }
450 }
451 }
452 else
453 {
454 for (i = 0; i < MAX_MB_SEGMENTS; i++)
455 baseline_filter_level[i] = default_filt_lvl;
456 }
457
458 /* Initialize the loop filter for this frame. */
459 if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
460 vp8_init_loop_filter(cm);
461 else if (frame_type != cm->last_frame_type)
462 vp8_frame_init_loop_filter(lfi, frame_type);
463
464 /* Set up the buffer pointers */
465 y_ptr = post->y_buffer;
466
467 /* vp8_filter each macro block */
468 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
469 {
470 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
471 {
472 int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
473 filter_level = baseline_filter_level[Segment];
474
475 /* Apply any context driven MB level adjustment */
476 vp8_adjust_mb_lf_value(mbd, &filter_level);
477
478 if (filter_level)
479 {
480 if (mb_col > 0)
481 cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
482
483 if (mbd->mode_info_context->mbmi.dc_diff > 0)
484 cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
485
486 /* don't apply across umv border */
487 if (mb_row > 0)
488 cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
489
490 if (mbd->mode_info_context->mbmi.dc_diff > 0)
491 cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
492 }
493
494 y_ptr += 16;
495 mbd->mode_info_context ++; /* step to next MB */
496
497 }
498
499 y_ptr += post->y_stride * 16 - post->y_width;
500 mbd->mode_info_context ++; /* Skip border mb */
501 }
502
503 }
504
505
vp8_loop_filter_partial_frame(VP8_COMMON * cm,MACROBLOCKD * mbd,int default_filt_lvl,int sharpness_lvl,int Fraction)506 void vp8_loop_filter_partial_frame
507 (
508 VP8_COMMON *cm,
509 MACROBLOCKD *mbd,
510 int default_filt_lvl,
511 int sharpness_lvl,
512 int Fraction
513 )
514 {
515 YV12_BUFFER_CONFIG *post = cm->frame_to_show;
516
517 int i;
518 unsigned char *y_ptr;
519 int mb_row;
520 int mb_col;
521 /*int mb_rows = post->y_height >> 4;*/
522 int mb_cols = post->y_width >> 4;
523
524 int linestocopy;
525
526 loop_filter_info *lfi = cm->lf_info;
527 int baseline_filter_level[MAX_MB_SEGMENTS];
528 int filter_level;
529 int alt_flt_enabled = mbd->segmentation_enabled;
530 FRAME_TYPE frame_type = cm->frame_type;
531
532 (void) sharpness_lvl;
533
534 /*MODE_INFO * this_mb_mode_info = cm->mi + (post->y_height>>5) * (mb_cols + 1);*/ /* Point at base of Mb MODE_INFO list */
535 mbd->mode_info_context = cm->mi + (post->y_height >> 5) * (mb_cols + 1); /* Point at base of Mb MODE_INFO list */
536
537 linestocopy = (post->y_height >> (4 + Fraction));
538
539 if (linestocopy < 1)
540 linestocopy = 1;
541
542 linestocopy <<= 4;
543
544 /* Note the baseline filter values for each segment */
545 if (alt_flt_enabled)
546 {
547 for (i = 0; i < MAX_MB_SEGMENTS; i++)
548 {
549 /* Abs value */
550 if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
551 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
552 /* Delta Value */
553 else
554 {
555 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
556 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 */
557 }
558 }
559 }
560 else
561 {
562 for (i = 0; i < MAX_MB_SEGMENTS; i++)
563 baseline_filter_level[i] = default_filt_lvl;
564 }
565
566 /* Initialize the loop filter for this frame. */
567 if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
568 vp8_init_loop_filter(cm);
569 else if (frame_type != cm->last_frame_type)
570 vp8_frame_init_loop_filter(lfi, frame_type);
571
572 /* Set up the buffer pointers */
573 y_ptr = post->y_buffer + (post->y_height >> 5) * 16 * post->y_stride;
574
575 /* vp8_filter each macro block */
576 for (mb_row = 0; mb_row<(linestocopy >> 4); mb_row++)
577 {
578 for (mb_col = 0; mb_col < mb_cols; mb_col++)
579 {
580 int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
581 filter_level = baseline_filter_level[Segment];
582
583 if (filter_level)
584 {
585 if (mb_col > 0)
586 cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
587
588 if (mbd->mode_info_context->mbmi.dc_diff > 0)
589 cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
590
591 cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
592
593 if (mbd->mode_info_context->mbmi.dc_diff > 0)
594 cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
595 }
596
597 y_ptr += 16;
598 mbd->mode_info_context += 1; /* step to next MB */
599 }
600
601 y_ptr += post->y_stride * 16 - post->y_width;
602 mbd->mode_info_context += 1; /* Skip border mb */
603 }
604 }
605