2 * Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license and patent
5 * grant that can be found in the LICENSE file in the root of the source
6 * tree. All contributing project authors may be found in the AUTHORS
7 * file in the root of the source tree.
11 #include "vpx_ports/config.h"
12 #include "loopfilter.h"
13 #include "onyxc_int.h"
15 typedef unsigned char uc
;
18 prototype_loopfilter(vp8_loop_filter_horizontal_edge_c
);
19 prototype_loopfilter(vp8_loop_filter_vertical_edge_c
);
20 prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_c
);
21 prototype_loopfilter(vp8_mbloop_filter_vertical_edge_c
);
22 prototype_loopfilter(vp8_loop_filter_simple_horizontal_edge_c
);
23 prototype_loopfilter(vp8_loop_filter_simple_vertical_edge_c
);
25 // Horizontal MB filtering
26 void vp8_loop_filter_mbh_c(unsigned char *y_ptr
, unsigned char *u_ptr
, unsigned char *v_ptr
,
27 int y_stride
, int uv_stride
, loop_filter_info
*lfi
, int simpler_lpf
)
30 vp8_mbloop_filter_horizontal_edge_c(y_ptr
, y_stride
, lfi
->mbflim
, lfi
->lim
, lfi
->mbthr
, 2);
33 vp8_mbloop_filter_horizontal_edge_c(u_ptr
, uv_stride
, lfi
->uvmbflim
, lfi
->uvlim
, lfi
->uvmbthr
, 1);
36 vp8_mbloop_filter_horizontal_edge_c(v_ptr
, uv_stride
, lfi
->uvmbflim
, lfi
->uvlim
, lfi
->uvmbthr
, 1);
39 void vp8_loop_filter_mbhs_c(unsigned char *y_ptr
, unsigned char *u_ptr
, unsigned char *v_ptr
,
40 int y_stride
, int uv_stride
, loop_filter_info
*lfi
, int simpler_lpf
)
46 vp8_loop_filter_simple_horizontal_edge_c(y_ptr
, y_stride
, lfi
->mbflim
, lfi
->lim
, lfi
->mbthr
, 2);
49 // Vertical MB Filtering
50 void vp8_loop_filter_mbv_c(unsigned char *y_ptr
, unsigned char *u_ptr
, unsigned char *v_ptr
,
51 int y_stride
, int uv_stride
, loop_filter_info
*lfi
, int simpler_lpf
)
54 vp8_mbloop_filter_vertical_edge_c(y_ptr
, y_stride
, lfi
->mbflim
, lfi
->lim
, lfi
->mbthr
, 2);
57 vp8_mbloop_filter_vertical_edge_c(u_ptr
, uv_stride
, lfi
->uvmbflim
, lfi
->uvlim
, lfi
->uvmbthr
, 1);
60 vp8_mbloop_filter_vertical_edge_c(v_ptr
, uv_stride
, lfi
->uvmbflim
, lfi
->uvlim
, lfi
->uvmbthr
, 1);
63 void vp8_loop_filter_mbvs_c(unsigned char *y_ptr
, unsigned char *u_ptr
, unsigned char *v_ptr
,
64 int y_stride
, int uv_stride
, loop_filter_info
*lfi
, int simpler_lpf
)
70 vp8_loop_filter_simple_vertical_edge_c(y_ptr
, y_stride
, lfi
->mbflim
, lfi
->lim
, lfi
->mbthr
, 2);
73 // Horizontal B Filtering
74 void vp8_loop_filter_bh_c(unsigned char *y_ptr
, unsigned char *u_ptr
, unsigned char *v_ptr
,
75 int y_stride
, int uv_stride
, loop_filter_info
*lfi
, int simpler_lpf
)
78 vp8_loop_filter_horizontal_edge_c(y_ptr
+ 4 * y_stride
, y_stride
, lfi
->flim
, lfi
->lim
, lfi
->thr
, 2);
79 vp8_loop_filter_horizontal_edge_c(y_ptr
+ 8 * y_stride
, y_stride
, lfi
->flim
, lfi
->lim
, lfi
->thr
, 2);
80 vp8_loop_filter_horizontal_edge_c(y_ptr
+ 12 * y_stride
, y_stride
, lfi
->flim
, lfi
->lim
, lfi
->thr
, 2);
83 vp8_loop_filter_horizontal_edge_c(u_ptr
+ 4 * uv_stride
, uv_stride
, lfi
->uvflim
, lfi
->uvlim
, lfi
->uvthr
, 1);
86 vp8_loop_filter_horizontal_edge_c(v_ptr
+ 4 * uv_stride
, uv_stride
, lfi
->uvflim
, lfi
->uvlim
, lfi
->uvthr
, 1);
89 void vp8_loop_filter_bhs_c(unsigned char *y_ptr
, unsigned char *u_ptr
, unsigned char *v_ptr
,
90 int y_stride
, int uv_stride
, loop_filter_info
*lfi
, int simpler_lpf
)
96 vp8_loop_filter_simple_horizontal_edge_c(y_ptr
+ 4 * y_stride
, y_stride
, lfi
->flim
, lfi
->lim
, lfi
->thr
, 2);
97 vp8_loop_filter_simple_horizontal_edge_c(y_ptr
+ 8 * y_stride
, y_stride
, lfi
->flim
, lfi
->lim
, lfi
->thr
, 2);
98 vp8_loop_filter_simple_horizontal_edge_c(y_ptr
+ 12 * y_stride
, y_stride
, lfi
->flim
, lfi
->lim
, lfi
->thr
, 2);
101 // Vertical B Filtering
102 void vp8_loop_filter_bv_c(unsigned char *y_ptr
, unsigned char *u_ptr
, unsigned char *v_ptr
,
103 int y_stride
, int uv_stride
, loop_filter_info
*lfi
, int simpler_lpf
)
106 vp8_loop_filter_vertical_edge_c(y_ptr
+ 4, y_stride
, lfi
->flim
, lfi
->lim
, lfi
->thr
, 2);
107 vp8_loop_filter_vertical_edge_c(y_ptr
+ 8, y_stride
, lfi
->flim
, lfi
->lim
, lfi
->thr
, 2);
108 vp8_loop_filter_vertical_edge_c(y_ptr
+ 12, y_stride
, lfi
->flim
, lfi
->lim
, lfi
->thr
, 2);
111 vp8_loop_filter_vertical_edge_c(u_ptr
+ 4, uv_stride
, lfi
->uvflim
, lfi
->uvlim
, lfi
->uvthr
, 1);
114 vp8_loop_filter_vertical_edge_c(v_ptr
+ 4, uv_stride
, lfi
->uvflim
, lfi
->uvlim
, lfi
->uvthr
, 1);
117 void vp8_loop_filter_bvs_c(unsigned char *y_ptr
, unsigned char *u_ptr
, unsigned char *v_ptr
,
118 int y_stride
, int uv_stride
, loop_filter_info
*lfi
, int simpler_lpf
)
124 vp8_loop_filter_simple_vertical_edge_c(y_ptr
+ 4, y_stride
, lfi
->flim
, lfi
->lim
, lfi
->thr
, 2);
125 vp8_loop_filter_simple_vertical_edge_c(y_ptr
+ 8, y_stride
, lfi
->flim
, lfi
->lim
, lfi
->thr
, 2);
126 vp8_loop_filter_simple_vertical_edge_c(y_ptr
+ 12, y_stride
, lfi
->flim
, lfi
->lim
, lfi
->thr
, 2);
129 void vp8_init_loop_filter(VP8_COMMON
*cm
)
131 loop_filter_info
*lfi
= cm
->lf_info
;
132 LOOPFILTERTYPE lft
= cm
->filter_type
;
133 int sharpness_lvl
= cm
->sharpness_level
;
134 int frame_type
= cm
->frame_type
;
137 int block_inside_limit
= 0;
139 const int yhedge_boost
= 2;
140 const int uvhedge_boost
= 2;
142 // For each possible value for the loop filter fill out a "loop_filter_info" entry.
143 for (i
= 0; i
<= MAX_LOOP_FILTER
; i
++)
147 if (frame_type
== KEY_FRAME
)
151 else if (filt_lvl
>= 15)
160 else if (filt_lvl
>= 20)
162 else if (filt_lvl
>= 15)
168 // Set loop filter paramaeters that control sharpness.
169 block_inside_limit
= filt_lvl
>> (sharpness_lvl
> 0);
170 block_inside_limit
= block_inside_limit
>> (sharpness_lvl
> 4);
172 if (sharpness_lvl
> 0)
174 if (block_inside_limit
> (9 - sharpness_lvl
))
175 block_inside_limit
= (9 - sharpness_lvl
);
178 if (block_inside_limit
< 1)
179 block_inside_limit
= 1;
181 for (j
= 0; j
< 16; j
++)
183 lfi
[i
].lim
[j
] = block_inside_limit
;
184 lfi
[i
].mbflim
[j
] = filt_lvl
+ yhedge_boost
;
185 lfi
[i
].mbthr
[j
] = HEVThresh
;
186 lfi
[i
].flim
[j
] = filt_lvl
;
187 lfi
[i
].thr
[j
] = HEVThresh
;
188 lfi
[i
].uvlim
[j
] = block_inside_limit
;
189 lfi
[i
].uvmbflim
[j
] = filt_lvl
+ uvhedge_boost
;
190 lfi
[i
].uvmbthr
[j
] = HEVThresh
;
191 lfi
[i
].uvflim
[j
] = filt_lvl
;
192 lfi
[i
].uvthr
[j
] = HEVThresh
;
197 // Set up the function pointers depending on the type of loop filtering selected
198 if (lft
== NORMAL_LOOPFILTER
)
200 cm
->lf_mbv
= LF_INVOKE(&cm
->rtcd
.loopfilter
, normal_mb_v
);
201 cm
->lf_bv
= LF_INVOKE(&cm
->rtcd
.loopfilter
, normal_b_v
);
202 cm
->lf_mbh
= LF_INVOKE(&cm
->rtcd
.loopfilter
, normal_mb_h
);
203 cm
->lf_bh
= LF_INVOKE(&cm
->rtcd
.loopfilter
, normal_b_h
);
207 cm
->lf_mbv
= LF_INVOKE(&cm
->rtcd
.loopfilter
, simple_mb_v
);
208 cm
->lf_bv
= LF_INVOKE(&cm
->rtcd
.loopfilter
, simple_b_v
);
209 cm
->lf_mbh
= LF_INVOKE(&cm
->rtcd
.loopfilter
, simple_mb_h
);
210 cm
->lf_bh
= LF_INVOKE(&cm
->rtcd
.loopfilter
, simple_b_h
);
214 // Put vp8_init_loop_filter() in vp8dx_create_decompressor(). Only call vp8_frame_init_loop_filter() while decoding
215 // each frame. Check last_frame_type to skip the function most of times.
216 void vp8_frame_init_loop_filter(loop_filter_info
*lfi
, int frame_type
)
221 // For each possible value for the loop filter fill out a "loop_filter_info" entry.
222 for (i
= 0; i
<= MAX_LOOP_FILTER
; i
++)
226 if (frame_type
== KEY_FRAME
)
230 else if (filt_lvl
>= 15)
239 else if (filt_lvl
>= 20)
241 else if (filt_lvl
>= 15)
247 for (j
= 0; j
< 16; j
++)
249 //lfi[i].lim[j] = block_inside_limit;
250 //lfi[i].mbflim[j] = filt_lvl+yhedge_boost;
251 lfi
[i
].mbthr
[j
] = HEVThresh
;
252 //lfi[i].flim[j] = filt_lvl;
253 lfi
[i
].thr
[j
] = HEVThresh
;
254 //lfi[i].uvlim[j] = block_inside_limit;
255 //lfi[i].uvmbflim[j] = filt_lvl+uvhedge_boost;
256 lfi
[i
].uvmbthr
[j
] = HEVThresh
;
257 //lfi[i].uvflim[j] = filt_lvl;
258 lfi
[i
].uvthr
[j
] = HEVThresh
;
264 void vp8_adjust_mb_lf_value(MACROBLOCKD
*mbd
, int *filter_level
)
266 MB_MODE_INFO
*mbmi
= &mbd
->mode_info_context
->mbmi
;
268 if (mbd
->mode_ref_lf_delta_enabled
)
270 // Aplly delta for reference frame
271 *filter_level
+= mbd
->ref_lf_deltas
[mbmi
->ref_frame
];
273 // Apply delta for mode
274 if (mbmi
->ref_frame
== INTRA_FRAME
)
276 // Only the split mode BPRED has a further special case
277 if (mbmi
->mode
== B_PRED
)
278 *filter_level
+= mbd
->mode_lf_deltas
[0];
283 if (mbmi
->mode
== ZEROMV
)
284 *filter_level
+= mbd
->mode_lf_deltas
[1];
286 // Split MB motion mode
287 else if (mbmi
->mode
== SPLITMV
)
288 *filter_level
+= mbd
->mode_lf_deltas
[3];
290 // All other inter motion modes (Nearest, Near, New)
292 *filter_level
+= mbd
->mode_lf_deltas
[2];
296 if (*filter_level
> MAX_LOOP_FILTER
)
297 *filter_level
= MAX_LOOP_FILTER
;
298 else if (*filter_level
< 0)
304 void vp8_loop_filter_frame
311 YV12_BUFFER_CONFIG
*post
= cm
->frame_to_show
;
312 loop_filter_info
*lfi
= cm
->lf_info
;
313 int frame_type
= cm
->frame_type
;
319 int baseline_filter_level
[MAX_MB_SEGMENTS
];
321 int alt_flt_enabled
= mbd
->segmentation_enabled
;
324 unsigned char *y_ptr
, *u_ptr
, *v_ptr
;
326 mbd
->mode_info_context
= cm
->mi
; // Point at base of Mb MODE_INFO list
328 // Note the baseline filter values for each segment
331 for (i
= 0; i
< MAX_MB_SEGMENTS
; i
++)
334 if (mbd
->mb_segement_abs_delta
== SEGMENT_ABSDATA
)
335 baseline_filter_level
[i
] = mbd
->segment_feature_data
[MB_LVL_ALT_LF
][i
];
339 baseline_filter_level
[i
] = default_filt_lvl
+ mbd
->segment_feature_data
[MB_LVL_ALT_LF
][i
];
340 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
346 for (i
= 0; i
< MAX_MB_SEGMENTS
; i
++)
347 baseline_filter_level
[i
] = default_filt_lvl
;
350 // Initialize the loop filter for this frame.
351 if ((cm
->last_filter_type
!= cm
->filter_type
) || (cm
->last_sharpness_level
!= cm
->sharpness_level
))
352 vp8_init_loop_filter(cm
);
353 else if (frame_type
!= cm
->last_frame_type
)
354 vp8_frame_init_loop_filter(lfi
, frame_type
);
356 // Set up the buffer pointers
357 y_ptr
= post
->y_buffer
;
358 u_ptr
= post
->u_buffer
;
359 v_ptr
= post
->v_buffer
;
361 // vp8_filter each macro block
362 for (mb_row
= 0; mb_row
< cm
->mb_rows
; mb_row
++)
364 for (mb_col
= 0; mb_col
< cm
->mb_cols
; mb_col
++)
366 int Segment
= (alt_flt_enabled
) ? mbd
->mode_info_context
->mbmi
.segment_id
: 0;
368 filter_level
= baseline_filter_level
[Segment
];
370 // Distance of Mb to the various image edges.
371 // These specified to 8th pel as they are always compared to values that are in 1/8th pel units
372 // Apply any context driven MB level adjustment
373 vp8_adjust_mb_lf_value(mbd
, &filter_level
);
378 cm
->lf_mbv(y_ptr
, u_ptr
, v_ptr
, post
->y_stride
, post
->uv_stride
, &lfi
[filter_level
], cm
->simpler_lpf
);
380 if (mbd
->mode_info_context
->mbmi
.dc_diff
> 0)
381 cm
->lf_bv(y_ptr
, u_ptr
, v_ptr
, post
->y_stride
, post
->uv_stride
, &lfi
[filter_level
], cm
->simpler_lpf
);
383 // don't apply across umv border
385 cm
->lf_mbh(y_ptr
, u_ptr
, v_ptr
, post
->y_stride
, post
->uv_stride
, &lfi
[filter_level
], cm
->simpler_lpf
);
387 if (mbd
->mode_info_context
->mbmi
.dc_diff
> 0)
388 cm
->lf_bh(y_ptr
, u_ptr
, v_ptr
, post
->y_stride
, post
->uv_stride
, &lfi
[filter_level
], cm
->simpler_lpf
);
395 mbd
->mode_info_context
++; // step to next MB
398 y_ptr
+= post
->y_stride
* 16 - post
->y_width
;
399 u_ptr
+= post
->uv_stride
* 8 - post
->uv_width
;
400 v_ptr
+= post
->uv_stride
* 8 - post
->uv_width
;
402 mbd
->mode_info_context
++; // Skip border mb
407 void vp8_loop_filter_frame_yonly
411 int default_filt_lvl
,
415 YV12_BUFFER_CONFIG
*post
= cm
->frame_to_show
;
418 unsigned char *y_ptr
;
422 loop_filter_info
*lfi
= cm
->lf_info
;
423 int baseline_filter_level
[MAX_MB_SEGMENTS
];
425 int alt_flt_enabled
= mbd
->segmentation_enabled
;
426 int frame_type
= cm
->frame_type
;
428 (void) sharpness_lvl
;
430 //MODE_INFO * this_mb_mode_info = cm->mi; // Point at base of Mb MODE_INFO list
431 mbd
->mode_info_context
= cm
->mi
; // Point at base of Mb MODE_INFO list
433 // Note the baseline filter values for each segment
436 for (i
= 0; i
< MAX_MB_SEGMENTS
; i
++)
439 if (mbd
->mb_segement_abs_delta
== SEGMENT_ABSDATA
)
440 baseline_filter_level
[i
] = mbd
->segment_feature_data
[MB_LVL_ALT_LF
][i
];
444 baseline_filter_level
[i
] = default_filt_lvl
+ mbd
->segment_feature_data
[MB_LVL_ALT_LF
][i
];
445 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
451 for (i
= 0; i
< MAX_MB_SEGMENTS
; i
++)
452 baseline_filter_level
[i
] = default_filt_lvl
;
455 // Initialize the loop filter for this frame.
456 if ((cm
->last_filter_type
!= cm
->filter_type
) || (cm
->last_sharpness_level
!= cm
->sharpness_level
))
457 vp8_init_loop_filter(cm
);
458 else if (frame_type
!= cm
->last_frame_type
)
459 vp8_frame_init_loop_filter(lfi
, frame_type
);
461 // Set up the buffer pointers
462 y_ptr
= post
->y_buffer
;
464 // vp8_filter each macro block
465 for (mb_row
= 0; mb_row
< cm
->mb_rows
; mb_row
++)
467 for (mb_col
= 0; mb_col
< cm
->mb_cols
; mb_col
++)
469 int Segment
= (alt_flt_enabled
) ? mbd
->mode_info_context
->mbmi
.segment_id
: 0;
470 filter_level
= baseline_filter_level
[Segment
];
472 // Apply any context driven MB level adjustment
473 vp8_adjust_mb_lf_value(mbd
, &filter_level
);
478 cm
->lf_mbv(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
480 if (mbd
->mode_info_context
->mbmi
.dc_diff
> 0)
481 cm
->lf_bv(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
483 // don't apply across umv border
485 cm
->lf_mbh(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
487 if (mbd
->mode_info_context
->mbmi
.dc_diff
> 0)
488 cm
->lf_bh(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
492 mbd
->mode_info_context
++; // step to next MB
496 y_ptr
+= post
->y_stride
* 16 - post
->y_width
;
497 mbd
->mode_info_context
++; // Skip border mb
503 void vp8_loop_filter_partial_frame
507 int default_filt_lvl
,
512 YV12_BUFFER_CONFIG
*post
= cm
->frame_to_show
;
515 unsigned char *y_ptr
;
518 //int mb_rows = post->y_height >> 4;
519 int mb_cols
= post
->y_width
>> 4;
523 loop_filter_info
*lfi
= cm
->lf_info
;
524 int baseline_filter_level
[MAX_MB_SEGMENTS
];
526 int alt_flt_enabled
= mbd
->segmentation_enabled
;
527 int frame_type
= cm
->frame_type
;
529 (void) sharpness_lvl
;
531 //MODE_INFO * this_mb_mode_info = cm->mi + (post->y_height>>5) * (mb_cols + 1); // Point at base of Mb MODE_INFO list
532 mbd
->mode_info_context
= cm
->mi
+ (post
->y_height
>> 5) * (mb_cols
+ 1); // Point at base of Mb MODE_INFO list
534 linestocopy
= (post
->y_height
>> (4 + Fraction
));
541 // Note the baseline filter values for each segment
544 for (i
= 0; i
< MAX_MB_SEGMENTS
; i
++)
547 if (mbd
->mb_segement_abs_delta
== SEGMENT_ABSDATA
)
548 baseline_filter_level
[i
] = mbd
->segment_feature_data
[MB_LVL_ALT_LF
][i
];
552 baseline_filter_level
[i
] = default_filt_lvl
+ mbd
->segment_feature_data
[MB_LVL_ALT_LF
][i
];
553 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
559 for (i
= 0; i
< MAX_MB_SEGMENTS
; i
++)
560 baseline_filter_level
[i
] = default_filt_lvl
;
563 // Initialize the loop filter for this frame.
564 if ((cm
->last_filter_type
!= cm
->filter_type
) || (cm
->last_sharpness_level
!= cm
->sharpness_level
))
565 vp8_init_loop_filter(cm
);
566 else if (frame_type
!= cm
->last_frame_type
)
567 vp8_frame_init_loop_filter(lfi
, frame_type
);
569 // Set up the buffer pointers
570 y_ptr
= post
->y_buffer
+ (post
->y_height
>> 5) * 16 * post
->y_stride
;
572 // vp8_filter each macro block
573 for (mb_row
= 0; mb_row
<(linestocopy
>> 4); mb_row
++)
575 for (mb_col
= 0; mb_col
< mb_cols
; mb_col
++)
577 int Segment
= (alt_flt_enabled
) ? mbd
->mode_info_context
->mbmi
.segment_id
: 0;
578 filter_level
= baseline_filter_level
[Segment
];
583 cm
->lf_mbv(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
585 if (mbd
->mode_info_context
->mbmi
.dc_diff
> 0)
586 cm
->lf_bv(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
588 cm
->lf_mbh(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
590 if (mbd
->mode_info_context
->mbmi
.dc_diff
> 0)
591 cm
->lf_bh(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
595 mbd
->mode_info_context
+= 1; // step to next MB
598 y_ptr
+= post
->y_stride
* 16 - post
->y_width
;
599 mbd
->mode_info_context
+= 1; // Skip border mb