2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
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.
12 #include "vpx_ports/config.h"
13 #include "loopfilter.h"
14 #include "onyxc_int.h"
16 typedef unsigned char uc
;
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
);
26 // Horizontal MB filtering
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
)
31 vp8_mbloop_filter_horizontal_edge_c(y_ptr
, y_stride
, lfi
->mbflim
, lfi
->lim
, lfi
->mbthr
, 2);
34 vp8_mbloop_filter_horizontal_edge_c(u_ptr
, uv_stride
, lfi
->uvmbflim
, lfi
->uvlim
, lfi
->uvmbthr
, 1);
37 vp8_mbloop_filter_horizontal_edge_c(v_ptr
, uv_stride
, lfi
->uvmbflim
, lfi
->uvlim
, lfi
->uvmbthr
, 1);
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
)
47 vp8_loop_filter_simple_horizontal_edge_c(y_ptr
, y_stride
, lfi
->mbflim
, lfi
->lim
, lfi
->mbthr
, 2);
50 // Vertical MB Filtering
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
)
55 vp8_mbloop_filter_vertical_edge_c(y_ptr
, y_stride
, lfi
->mbflim
, lfi
->lim
, lfi
->mbthr
, 2);
58 vp8_mbloop_filter_vertical_edge_c(u_ptr
, uv_stride
, lfi
->uvmbflim
, lfi
->uvlim
, lfi
->uvmbthr
, 1);
61 vp8_mbloop_filter_vertical_edge_c(v_ptr
, uv_stride
, lfi
->uvmbflim
, lfi
->uvlim
, lfi
->uvmbthr
, 1);
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
)
71 vp8_loop_filter_simple_vertical_edge_c(y_ptr
, y_stride
, lfi
->mbflim
, lfi
->lim
, lfi
->mbthr
, 2);
74 // Horizontal B Filtering
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
)
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);
84 vp8_loop_filter_horizontal_edge_c(u_ptr
+ 4 * uv_stride
, uv_stride
, lfi
->uvflim
, lfi
->uvlim
, lfi
->uvthr
, 1);
87 vp8_loop_filter_horizontal_edge_c(v_ptr
+ 4 * uv_stride
, uv_stride
, lfi
->uvflim
, lfi
->uvlim
, lfi
->uvthr
, 1);
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
)
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);
102 // Vertical B Filtering
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
)
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);
112 vp8_loop_filter_vertical_edge_c(u_ptr
+ 4, uv_stride
, lfi
->uvflim
, lfi
->uvlim
, lfi
->uvthr
, 1);
115 vp8_loop_filter_vertical_edge_c(v_ptr
+ 4, uv_stride
, lfi
->uvflim
, lfi
->uvlim
, lfi
->uvthr
, 1);
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
)
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);
130 void vp8_init_loop_filter(VP8_COMMON
*cm
)
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
;
138 int block_inside_limit
= 0;
140 const int yhedge_boost
= 2;
141 const int uvhedge_boost
= 2;
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
++)
148 if (frame_type
== KEY_FRAME
)
152 else if (filt_lvl
>= 15)
161 else if (filt_lvl
>= 20)
163 else if (filt_lvl
>= 15)
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);
173 if (sharpness_lvl
> 0)
175 if (block_inside_limit
> (9 - sharpness_lvl
))
176 block_inside_limit
= (9 - sharpness_lvl
);
179 if (block_inside_limit
< 1)
180 block_inside_limit
= 1;
182 for (j
= 0; j
< 16; j
++)
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
;
198 // Set up the function pointers depending on the type of loop filtering selected
199 if (lft
== NORMAL_LOOPFILTER
)
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
);
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
);
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 void vp8_frame_init_loop_filter(loop_filter_info
*lfi
, int frame_type
)
222 // For each possible value for the loop filter fill out a "loop_filter_info" entry.
223 for (i
= 0; i
<= MAX_LOOP_FILTER
; i
++)
227 if (frame_type
== KEY_FRAME
)
231 else if (filt_lvl
>= 15)
240 else if (filt_lvl
>= 20)
242 else if (filt_lvl
>= 15)
248 for (j
= 0; j
< 16; j
++)
250 //lfi[i].lim[j] = block_inside_limit;
251 //lfi[i].mbflim[j] = filt_lvl+yhedge_boost;
252 lfi
[i
].mbthr
[j
] = HEVThresh
;
253 //lfi[i].flim[j] = filt_lvl;
254 lfi
[i
].thr
[j
] = HEVThresh
;
255 //lfi[i].uvlim[j] = block_inside_limit;
256 //lfi[i].uvmbflim[j] = filt_lvl+uvhedge_boost;
257 lfi
[i
].uvmbthr
[j
] = HEVThresh
;
258 //lfi[i].uvflim[j] = filt_lvl;
259 lfi
[i
].uvthr
[j
] = HEVThresh
;
265 void vp8_adjust_mb_lf_value(MACROBLOCKD
*mbd
, int *filter_level
)
267 MB_MODE_INFO
*mbmi
= &mbd
->mode_info_context
->mbmi
;
269 if (mbd
->mode_ref_lf_delta_enabled
)
271 // Aplly delta for reference frame
272 *filter_level
+= mbd
->ref_lf_deltas
[mbmi
->ref_frame
];
274 // Apply delta for mode
275 if (mbmi
->ref_frame
== INTRA_FRAME
)
277 // Only the split mode BPRED has a further special case
278 if (mbmi
->mode
== B_PRED
)
279 *filter_level
+= mbd
->mode_lf_deltas
[0];
284 if (mbmi
->mode
== ZEROMV
)
285 *filter_level
+= mbd
->mode_lf_deltas
[1];
287 // Split MB motion mode
288 else if (mbmi
->mode
== SPLITMV
)
289 *filter_level
+= mbd
->mode_lf_deltas
[3];
291 // All other inter motion modes (Nearest, Near, New)
293 *filter_level
+= mbd
->mode_lf_deltas
[2];
297 if (*filter_level
> MAX_LOOP_FILTER
)
298 *filter_level
= MAX_LOOP_FILTER
;
299 else if (*filter_level
< 0)
305 void vp8_loop_filter_frame
312 YV12_BUFFER_CONFIG
*post
= cm
->frame_to_show
;
313 loop_filter_info
*lfi
= cm
->lf_info
;
314 int frame_type
= cm
->frame_type
;
320 int baseline_filter_level
[MAX_MB_SEGMENTS
];
322 int alt_flt_enabled
= mbd
->segmentation_enabled
;
325 unsigned char *y_ptr
, *u_ptr
, *v_ptr
;
327 mbd
->mode_info_context
= cm
->mi
; // Point at base of Mb MODE_INFO list
329 // Note the baseline filter values for each segment
332 for (i
= 0; i
< MAX_MB_SEGMENTS
; i
++)
335 if (mbd
->mb_segement_abs_delta
== SEGMENT_ABSDATA
)
336 baseline_filter_level
[i
] = mbd
->segment_feature_data
[MB_LVL_ALT_LF
][i
];
340 baseline_filter_level
[i
] = default_filt_lvl
+ mbd
->segment_feature_data
[MB_LVL_ALT_LF
][i
];
341 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
347 for (i
= 0; i
< MAX_MB_SEGMENTS
; i
++)
348 baseline_filter_level
[i
] = default_filt_lvl
;
351 // Initialize the loop filter for this frame.
352 if ((cm
->last_filter_type
!= cm
->filter_type
) || (cm
->last_sharpness_level
!= cm
->sharpness_level
))
353 vp8_init_loop_filter(cm
);
354 else if (frame_type
!= cm
->last_frame_type
)
355 vp8_frame_init_loop_filter(lfi
, frame_type
);
357 // Set up the buffer pointers
358 y_ptr
= post
->y_buffer
;
359 u_ptr
= post
->u_buffer
;
360 v_ptr
= post
->v_buffer
;
362 // vp8_filter each macro block
363 for (mb_row
= 0; mb_row
< cm
->mb_rows
; mb_row
++)
365 for (mb_col
= 0; mb_col
< cm
->mb_cols
; mb_col
++)
367 int Segment
= (alt_flt_enabled
) ? mbd
->mode_info_context
->mbmi
.segment_id
: 0;
369 filter_level
= baseline_filter_level
[Segment
];
371 // Distance of Mb to the various image edges.
372 // These specified to 8th pel as they are always compared to values that are in 1/8th pel units
373 // Apply any context driven MB level adjustment
374 vp8_adjust_mb_lf_value(mbd
, &filter_level
);
379 cm
->lf_mbv(y_ptr
, u_ptr
, v_ptr
, post
->y_stride
, post
->uv_stride
, &lfi
[filter_level
], cm
->simpler_lpf
);
381 if (mbd
->mode_info_context
->mbmi
.dc_diff
> 0)
382 cm
->lf_bv(y_ptr
, u_ptr
, v_ptr
, post
->y_stride
, post
->uv_stride
, &lfi
[filter_level
], cm
->simpler_lpf
);
384 // don't apply across umv border
386 cm
->lf_mbh(y_ptr
, u_ptr
, v_ptr
, post
->y_stride
, post
->uv_stride
, &lfi
[filter_level
], cm
->simpler_lpf
);
388 if (mbd
->mode_info_context
->mbmi
.dc_diff
> 0)
389 cm
->lf_bh(y_ptr
, u_ptr
, v_ptr
, post
->y_stride
, post
->uv_stride
, &lfi
[filter_level
], cm
->simpler_lpf
);
396 mbd
->mode_info_context
++; // step to next MB
399 y_ptr
+= post
->y_stride
* 16 - post
->y_width
;
400 u_ptr
+= post
->uv_stride
* 8 - post
->uv_width
;
401 v_ptr
+= post
->uv_stride
* 8 - post
->uv_width
;
403 mbd
->mode_info_context
++; // Skip border mb
408 void vp8_loop_filter_frame_yonly
412 int default_filt_lvl
,
416 YV12_BUFFER_CONFIG
*post
= cm
->frame_to_show
;
419 unsigned char *y_ptr
;
423 loop_filter_info
*lfi
= cm
->lf_info
;
424 int baseline_filter_level
[MAX_MB_SEGMENTS
];
426 int alt_flt_enabled
= mbd
->segmentation_enabled
;
427 int frame_type
= cm
->frame_type
;
429 (void) sharpness_lvl
;
431 //MODE_INFO * this_mb_mode_info = cm->mi; // Point at base of Mb MODE_INFO list
432 mbd
->mode_info_context
= cm
->mi
; // Point at base of Mb MODE_INFO list
434 // Note the baseline filter values for each segment
437 for (i
= 0; i
< MAX_MB_SEGMENTS
; i
++)
440 if (mbd
->mb_segement_abs_delta
== SEGMENT_ABSDATA
)
441 baseline_filter_level
[i
] = mbd
->segment_feature_data
[MB_LVL_ALT_LF
][i
];
445 baseline_filter_level
[i
] = default_filt_lvl
+ mbd
->segment_feature_data
[MB_LVL_ALT_LF
][i
];
446 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
452 for (i
= 0; i
< MAX_MB_SEGMENTS
; i
++)
453 baseline_filter_level
[i
] = default_filt_lvl
;
456 // Initialize the loop filter for this frame.
457 if ((cm
->last_filter_type
!= cm
->filter_type
) || (cm
->last_sharpness_level
!= cm
->sharpness_level
))
458 vp8_init_loop_filter(cm
);
459 else if (frame_type
!= cm
->last_frame_type
)
460 vp8_frame_init_loop_filter(lfi
, frame_type
);
462 // Set up the buffer pointers
463 y_ptr
= post
->y_buffer
;
465 // vp8_filter each macro block
466 for (mb_row
= 0; mb_row
< cm
->mb_rows
; mb_row
++)
468 for (mb_col
= 0; mb_col
< cm
->mb_cols
; mb_col
++)
470 int Segment
= (alt_flt_enabled
) ? mbd
->mode_info_context
->mbmi
.segment_id
: 0;
471 filter_level
= baseline_filter_level
[Segment
];
473 // Apply any context driven MB level adjustment
474 vp8_adjust_mb_lf_value(mbd
, &filter_level
);
479 cm
->lf_mbv(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
481 if (mbd
->mode_info_context
->mbmi
.dc_diff
> 0)
482 cm
->lf_bv(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
484 // don't apply across umv border
486 cm
->lf_mbh(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
488 if (mbd
->mode_info_context
->mbmi
.dc_diff
> 0)
489 cm
->lf_bh(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
493 mbd
->mode_info_context
++; // step to next MB
497 y_ptr
+= post
->y_stride
* 16 - post
->y_width
;
498 mbd
->mode_info_context
++; // Skip border mb
504 void vp8_loop_filter_partial_frame
508 int default_filt_lvl
,
513 YV12_BUFFER_CONFIG
*post
= cm
->frame_to_show
;
516 unsigned char *y_ptr
;
519 //int mb_rows = post->y_height >> 4;
520 int mb_cols
= post
->y_width
>> 4;
524 loop_filter_info
*lfi
= cm
->lf_info
;
525 int baseline_filter_level
[MAX_MB_SEGMENTS
];
527 int alt_flt_enabled
= mbd
->segmentation_enabled
;
528 int frame_type
= cm
->frame_type
;
530 (void) sharpness_lvl
;
532 //MODE_INFO * this_mb_mode_info = cm->mi + (post->y_height>>5) * (mb_cols + 1); // Point at base of Mb MODE_INFO list
533 mbd
->mode_info_context
= cm
->mi
+ (post
->y_height
>> 5) * (mb_cols
+ 1); // Point at base of Mb MODE_INFO list
535 linestocopy
= (post
->y_height
>> (4 + Fraction
));
542 // Note the baseline filter values for each segment
545 for (i
= 0; i
< MAX_MB_SEGMENTS
; i
++)
548 if (mbd
->mb_segement_abs_delta
== SEGMENT_ABSDATA
)
549 baseline_filter_level
[i
] = mbd
->segment_feature_data
[MB_LVL_ALT_LF
][i
];
553 baseline_filter_level
[i
] = default_filt_lvl
+ mbd
->segment_feature_data
[MB_LVL_ALT_LF
][i
];
554 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
560 for (i
= 0; i
< MAX_MB_SEGMENTS
; i
++)
561 baseline_filter_level
[i
] = default_filt_lvl
;
564 // Initialize the loop filter for this frame.
565 if ((cm
->last_filter_type
!= cm
->filter_type
) || (cm
->last_sharpness_level
!= cm
->sharpness_level
))
566 vp8_init_loop_filter(cm
);
567 else if (frame_type
!= cm
->last_frame_type
)
568 vp8_frame_init_loop_filter(lfi
, frame_type
);
570 // Set up the buffer pointers
571 y_ptr
= post
->y_buffer
+ (post
->y_height
>> 5) * 16 * post
->y_stride
;
573 // vp8_filter each macro block
574 for (mb_row
= 0; mb_row
<(linestocopy
>> 4); mb_row
++)
576 for (mb_col
= 0; mb_col
< mb_cols
; mb_col
++)
578 int Segment
= (alt_flt_enabled
) ? mbd
->mode_info_context
->mbmi
.segment_id
: 0;
579 filter_level
= baseline_filter_level
[Segment
];
584 cm
->lf_mbv(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
586 if (mbd
->mode_info_context
->mbmi
.dc_diff
> 0)
587 cm
->lf_bv(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
589 cm
->lf_mbh(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
591 if (mbd
->mode_info_context
->mbmi
.dc_diff
> 0)
592 cm
->lf_bh(y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
[filter_level
], 0);
596 mbd
->mode_info_context
+= 1; // step to next MB
599 y_ptr
+= post
->y_stride
* 16 - post
->y_width
;
600 mbd
->mode_info_context
+= 1; // Skip border mb