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_config.h"
14 #include "loopfilter.h"
15 #include "onyxc_int.h"
16 #include "vpx_mem/vpx_mem.h"
19 static void lf_init_lut(loop_filter_info_n
*lfi
)
23 for (filt_lvl
= 0; filt_lvl
<= MAX_LOOP_FILTER
; filt_lvl
++)
27 lfi
->hev_thr_lut
[KEY_FRAME
][filt_lvl
] = 2;
28 lfi
->hev_thr_lut
[INTER_FRAME
][filt_lvl
] = 3;
30 else if (filt_lvl
>= 20)
32 lfi
->hev_thr_lut
[KEY_FRAME
][filt_lvl
] = 1;
33 lfi
->hev_thr_lut
[INTER_FRAME
][filt_lvl
] = 2;
35 else if (filt_lvl
>= 15)
37 lfi
->hev_thr_lut
[KEY_FRAME
][filt_lvl
] = 1;
38 lfi
->hev_thr_lut
[INTER_FRAME
][filt_lvl
] = 1;
42 lfi
->hev_thr_lut
[KEY_FRAME
][filt_lvl
] = 0;
43 lfi
->hev_thr_lut
[INTER_FRAME
][filt_lvl
] = 0;
47 lfi
->mode_lf_lut
[DC_PRED
] = 1;
48 lfi
->mode_lf_lut
[V_PRED
] = 1;
49 lfi
->mode_lf_lut
[H_PRED
] = 1;
50 lfi
->mode_lf_lut
[TM_PRED
] = 1;
51 lfi
->mode_lf_lut
[B_PRED
] = 0;
53 lfi
->mode_lf_lut
[ZEROMV
] = 1;
54 lfi
->mode_lf_lut
[NEARESTMV
] = 2;
55 lfi
->mode_lf_lut
[NEARMV
] = 2;
56 lfi
->mode_lf_lut
[NEWMV
] = 2;
57 lfi
->mode_lf_lut
[SPLITMV
] = 3;
61 void vp8_loop_filter_update_sharpness(loop_filter_info_n
*lfi
,
66 /* For each possible value for the loop filter fill out limits */
67 for (i
= 0; i
<= MAX_LOOP_FILTER
; i
++)
70 int block_inside_limit
= 0;
72 /* Set loop filter paramaeters that control sharpness. */
73 block_inside_limit
= filt_lvl
>> (sharpness_lvl
> 0);
74 block_inside_limit
= block_inside_limit
>> (sharpness_lvl
> 4);
76 if (sharpness_lvl
> 0)
78 if (block_inside_limit
> (9 - sharpness_lvl
))
79 block_inside_limit
= (9 - sharpness_lvl
);
82 if (block_inside_limit
< 1)
83 block_inside_limit
= 1;
85 memset(lfi
->lim
[i
], block_inside_limit
, SIMD_WIDTH
);
86 memset(lfi
->blim
[i
], (2 * filt_lvl
+ block_inside_limit
), SIMD_WIDTH
);
87 memset(lfi
->mblim
[i
], (2 * (filt_lvl
+ 2) + block_inside_limit
),
92 void vp8_loop_filter_init(VP8_COMMON
*cm
)
94 loop_filter_info_n
*lfi
= &cm
->lf_info
;
97 /* init limits for given sharpness*/
98 vp8_loop_filter_update_sharpness(lfi
, cm
->sharpness_level
);
99 cm
->last_sharpness_level
= cm
->sharpness_level
;
101 /* init LUT for lvl and hev thr picking */
104 /* init hev threshold const vectors */
105 for(i
= 0; i
< 4 ; i
++)
107 memset(lfi
->hev_thr
[i
], i
, SIMD_WIDTH
);
111 void vp8_loop_filter_frame_init(VP8_COMMON
*cm
,
113 int default_filt_lvl
)
115 int seg
, /* segment number */
116 ref
, /* index in ref_lf_deltas */
117 mode
; /* index in mode_lf_deltas */
119 loop_filter_info_n
*lfi
= &cm
->lf_info
;
121 /* update limits if sharpness has changed */
122 if(cm
->last_sharpness_level
!= cm
->sharpness_level
)
124 vp8_loop_filter_update_sharpness(lfi
, cm
->sharpness_level
);
125 cm
->last_sharpness_level
= cm
->sharpness_level
;
128 for(seg
= 0; seg
< MAX_MB_SEGMENTS
; seg
++)
130 int lvl_seg
= default_filt_lvl
;
131 int lvl_ref
, lvl_mode
;
133 /* Note the baseline filter values for each segment */
134 if (mbd
->segmentation_enabled
)
137 if (mbd
->mb_segement_abs_delta
== SEGMENT_ABSDATA
)
139 lvl_seg
= mbd
->segment_feature_data
[MB_LVL_ALT_LF
][seg
];
141 else /* Delta Value */
143 lvl_seg
+= mbd
->segment_feature_data
[MB_LVL_ALT_LF
][seg
];
145 lvl_seg
= (lvl_seg
> 0) ? ((lvl_seg
> 63) ? 63: lvl_seg
) : 0;
148 if (!mbd
->mode_ref_lf_delta_enabled
)
150 /* we could get rid of this if we assume that deltas are set to
151 * zero when not in use; encoder always uses deltas
153 memset(lfi
->lvl
[seg
][0], lvl_seg
, 4 * 4 );
160 /* Apply delta for reference frame */
161 lvl_ref
= lvl_seg
+ mbd
->ref_lf_deltas
[ref
];
163 /* Apply delta for Intra modes */
164 mode
= 0; /* B_PRED */
165 /* Only the split mode BPRED has a further special case */
166 lvl_mode
= lvl_ref
+ mbd
->mode_lf_deltas
[mode
];
168 lvl_mode
= (lvl_mode
> 0) ? (lvl_mode
> 63 ? 63 : lvl_mode
) : 0;
170 lfi
->lvl
[seg
][ref
][mode
] = lvl_mode
;
172 mode
= 1; /* all the rest of Intra modes */
174 lvl_mode
= (lvl_ref
> 0) ? (lvl_ref
> 63 ? 63 : lvl_ref
) : 0;
175 lfi
->lvl
[seg
][ref
][mode
] = lvl_mode
;
177 /* LAST, GOLDEN, ALT */
178 for(ref
= 1; ref
< MAX_REF_FRAMES
; ref
++)
180 /* Apply delta for reference frame */
181 lvl_ref
= lvl_seg
+ mbd
->ref_lf_deltas
[ref
];
183 /* Apply delta for Inter modes */
184 for (mode
= 1; mode
< 4; mode
++)
186 lvl_mode
= lvl_ref
+ mbd
->mode_lf_deltas
[mode
];
188 lvl_mode
= (lvl_mode
> 0) ? (lvl_mode
> 63 ? 63 : lvl_mode
) : 0;
190 lfi
->lvl
[seg
][ref
][mode
] = lvl_mode
;
197 void vp8_loop_filter_row_normal(VP8_COMMON
*cm
, MODE_INFO
*mode_info_context
,
198 int mb_row
, int post_ystride
, int post_uvstride
,
199 unsigned char *y_ptr
, unsigned char *u_ptr
,
200 unsigned char *v_ptr
)
204 loop_filter_info_n
*lfi_n
= &cm
->lf_info
;
205 loop_filter_info lfi
;
206 FRAME_TYPE frame_type
= cm
->frame_type
;
208 for (mb_col
= 0; mb_col
< cm
->mb_cols
; mb_col
++)
210 int skip_lf
= (mode_info_context
->mbmi
.mode
!= B_PRED
&&
211 mode_info_context
->mbmi
.mode
!= SPLITMV
&&
212 mode_info_context
->mbmi
.mb_skip_coeff
);
214 const int mode_index
= lfi_n
->mode_lf_lut
[mode_info_context
->mbmi
.mode
];
215 const int seg
= mode_info_context
->mbmi
.segment_id
;
216 const int ref_frame
= mode_info_context
->mbmi
.ref_frame
;
218 filter_level
= lfi_n
->lvl
[seg
][ref_frame
][mode_index
];
222 const int hev_index
= lfi_n
->hev_thr_lut
[frame_type
][filter_level
];
223 lfi
.mblim
= lfi_n
->mblim
[filter_level
];
224 lfi
.blim
= lfi_n
->blim
[filter_level
];
225 lfi
.lim
= lfi_n
->lim
[filter_level
];
226 lfi
.hev_thr
= lfi_n
->hev_thr
[hev_index
];
230 (y_ptr
, u_ptr
, v_ptr
, post_ystride
, post_uvstride
, &lfi
);
234 (y_ptr
, u_ptr
, v_ptr
, post_ystride
, post_uvstride
, &lfi
);
236 /* don't apply across umv border */
239 (y_ptr
, u_ptr
, v_ptr
, post_ystride
, post_uvstride
, &lfi
);
243 (y_ptr
, u_ptr
, v_ptr
, post_ystride
, post_uvstride
, &lfi
);
250 mode_info_context
++; /* step to next MB */
255 void vp8_loop_filter_row_simple(VP8_COMMON
*cm
, MODE_INFO
*mode_info_context
,
256 int mb_row
, int post_ystride
, int post_uvstride
,
257 unsigned char *y_ptr
, unsigned char *u_ptr
,
258 unsigned char *v_ptr
)
262 loop_filter_info_n
*lfi_n
= &cm
->lf_info
;
265 for (mb_col
= 0; mb_col
< cm
->mb_cols
; mb_col
++)
267 int skip_lf
= (mode_info_context
->mbmi
.mode
!= B_PRED
&&
268 mode_info_context
->mbmi
.mode
!= SPLITMV
&&
269 mode_info_context
->mbmi
.mb_skip_coeff
);
271 const int mode_index
= lfi_n
->mode_lf_lut
[mode_info_context
->mbmi
.mode
];
272 const int seg
= mode_info_context
->mbmi
.segment_id
;
273 const int ref_frame
= mode_info_context
->mbmi
.ref_frame
;
275 filter_level
= lfi_n
->lvl
[seg
][ref_frame
][mode_index
];
280 vp8_loop_filter_simple_mbv
281 (y_ptr
, post_ystride
, lfi_n
->mblim
[filter_level
]);
284 vp8_loop_filter_simple_bv
285 (y_ptr
, post_ystride
, lfi_n
->blim
[filter_level
]);
287 /* don't apply across umv border */
289 vp8_loop_filter_simple_mbh
290 (y_ptr
, post_ystride
, lfi_n
->mblim
[filter_level
]);
293 vp8_loop_filter_simple_bh
294 (y_ptr
, post_ystride
, lfi_n
->blim
[filter_level
]);
301 mode_info_context
++; /* step to next MB */
305 void vp8_loop_filter_frame(VP8_COMMON
*cm
,
309 YV12_BUFFER_CONFIG
*post
= cm
->frame_to_show
;
310 loop_filter_info_n
*lfi_n
= &cm
->lf_info
;
311 loop_filter_info lfi
;
315 int mb_rows
= cm
->mb_rows
;
316 int mb_cols
= cm
->mb_cols
;
320 unsigned char *y_ptr
, *u_ptr
, *v_ptr
;
322 /* Point at base of Mb MODE_INFO list */
323 const MODE_INFO
*mode_info_context
= cm
->mi
;
324 int post_y_stride
= post
->y_stride
;
325 int post_uv_stride
= post
->uv_stride
;
327 /* Initialize the loop filter for this frame. */
328 vp8_loop_filter_frame_init(cm
, mbd
, cm
->filter_level
);
330 /* Set up the buffer pointers */
331 y_ptr
= post
->y_buffer
;
332 u_ptr
= post
->u_buffer
;
333 v_ptr
= post
->v_buffer
;
335 /* vp8_filter each macro block */
336 if (cm
->filter_type
== NORMAL_LOOPFILTER
)
338 for (mb_row
= 0; mb_row
< mb_rows
; mb_row
++)
340 for (mb_col
= 0; mb_col
< mb_cols
; mb_col
++)
342 int skip_lf
= (mode_info_context
->mbmi
.mode
!= B_PRED
&&
343 mode_info_context
->mbmi
.mode
!= SPLITMV
&&
344 mode_info_context
->mbmi
.mb_skip_coeff
);
346 const int mode_index
= lfi_n
->mode_lf_lut
[mode_info_context
->mbmi
.mode
];
347 const int seg
= mode_info_context
->mbmi
.segment_id
;
348 const int ref_frame
= mode_info_context
->mbmi
.ref_frame
;
350 filter_level
= lfi_n
->lvl
[seg
][ref_frame
][mode_index
];
354 const int hev_index
= lfi_n
->hev_thr_lut
[frame_type
][filter_level
];
355 lfi
.mblim
= lfi_n
->mblim
[filter_level
];
356 lfi
.blim
= lfi_n
->blim
[filter_level
];
357 lfi
.lim
= lfi_n
->lim
[filter_level
];
358 lfi
.hev_thr
= lfi_n
->hev_thr
[hev_index
];
362 (y_ptr
, u_ptr
, v_ptr
, post_y_stride
, post_uv_stride
, &lfi
);
366 (y_ptr
, u_ptr
, v_ptr
, post_y_stride
, post_uv_stride
, &lfi
);
368 /* don't apply across umv border */
371 (y_ptr
, u_ptr
, v_ptr
, post_y_stride
, post_uv_stride
, &lfi
);
375 (y_ptr
, u_ptr
, v_ptr
, post_y_stride
, post_uv_stride
, &lfi
);
382 mode_info_context
++; /* step to next MB */
384 y_ptr
+= post_y_stride
* 16 - post
->y_width
;
385 u_ptr
+= post_uv_stride
* 8 - post
->uv_width
;
386 v_ptr
+= post_uv_stride
* 8 - post
->uv_width
;
388 mode_info_context
++; /* Skip border mb */
392 else /* SIMPLE_LOOPFILTER */
394 for (mb_row
= 0; mb_row
< mb_rows
; mb_row
++)
396 for (mb_col
= 0; mb_col
< mb_cols
; mb_col
++)
398 int skip_lf
= (mode_info_context
->mbmi
.mode
!= B_PRED
&&
399 mode_info_context
->mbmi
.mode
!= SPLITMV
&&
400 mode_info_context
->mbmi
.mb_skip_coeff
);
402 const int mode_index
= lfi_n
->mode_lf_lut
[mode_info_context
->mbmi
.mode
];
403 const int seg
= mode_info_context
->mbmi
.segment_id
;
404 const int ref_frame
= mode_info_context
->mbmi
.ref_frame
;
406 filter_level
= lfi_n
->lvl
[seg
][ref_frame
][mode_index
];
409 const unsigned char * mblim
= lfi_n
->mblim
[filter_level
];
410 const unsigned char * blim
= lfi_n
->blim
[filter_level
];
413 vp8_loop_filter_simple_mbv
414 (y_ptr
, post_y_stride
, mblim
);
417 vp8_loop_filter_simple_bv
418 (y_ptr
, post_y_stride
, blim
);
420 /* don't apply across umv border */
422 vp8_loop_filter_simple_mbh
423 (y_ptr
, post_y_stride
, mblim
);
426 vp8_loop_filter_simple_bh
427 (y_ptr
, post_y_stride
, blim
);
434 mode_info_context
++; /* step to next MB */
436 y_ptr
+= post_y_stride
* 16 - post
->y_width
;
437 u_ptr
+= post_uv_stride
* 8 - post
->uv_width
;
438 v_ptr
+= post_uv_stride
* 8 - post
->uv_width
;
440 mode_info_context
++; /* Skip border mb */
446 void vp8_loop_filter_frame_yonly
453 YV12_BUFFER_CONFIG
*post
= cm
->frame_to_show
;
455 unsigned char *y_ptr
;
459 loop_filter_info_n
*lfi_n
= &cm
->lf_info
;
460 loop_filter_info lfi
;
463 FRAME_TYPE frame_type
= cm
->frame_type
;
465 /* Point at base of Mb MODE_INFO list */
466 const MODE_INFO
*mode_info_context
= cm
->mi
;
469 if(default_filt_lvl
== 0) /* no filter applied */
473 /* Initialize the loop filter for this frame. */
474 vp8_loop_filter_frame_init( cm
, mbd
, default_filt_lvl
);
476 /* Set up the buffer pointers */
477 y_ptr
= post
->y_buffer
;
479 /* vp8_filter each macro block */
480 for (mb_row
= 0; mb_row
< cm
->mb_rows
; mb_row
++)
482 for (mb_col
= 0; mb_col
< cm
->mb_cols
; mb_col
++)
484 int skip_lf
= (mode_info_context
->mbmi
.mode
!= B_PRED
&&
485 mode_info_context
->mbmi
.mode
!= SPLITMV
&&
486 mode_info_context
->mbmi
.mb_skip_coeff
);
488 const int mode_index
= lfi_n
->mode_lf_lut
[mode_info_context
->mbmi
.mode
];
489 const int seg
= mode_info_context
->mbmi
.segment_id
;
490 const int ref_frame
= mode_info_context
->mbmi
.ref_frame
;
492 filter_level
= lfi_n
->lvl
[seg
][ref_frame
][mode_index
];
496 if (cm
->filter_type
== NORMAL_LOOPFILTER
)
498 const int hev_index
= lfi_n
->hev_thr_lut
[frame_type
][filter_level
];
499 lfi
.mblim
= lfi_n
->mblim
[filter_level
];
500 lfi
.blim
= lfi_n
->blim
[filter_level
];
501 lfi
.lim
= lfi_n
->lim
[filter_level
];
502 lfi
.hev_thr
= lfi_n
->hev_thr
[hev_index
];
506 (y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
);
510 (y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
);
512 /* don't apply across umv border */
515 (y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
);
519 (y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
);
524 vp8_loop_filter_simple_mbv
525 (y_ptr
, post
->y_stride
, lfi_n
->mblim
[filter_level
]);
528 vp8_loop_filter_simple_bv
529 (y_ptr
, post
->y_stride
, lfi_n
->blim
[filter_level
]);
531 /* don't apply across umv border */
533 vp8_loop_filter_simple_mbh
534 (y_ptr
, post
->y_stride
, lfi_n
->mblim
[filter_level
]);
537 vp8_loop_filter_simple_bh
538 (y_ptr
, post
->y_stride
, lfi_n
->blim
[filter_level
]);
543 mode_info_context
++; /* step to next MB */
547 y_ptr
+= post
->y_stride
* 16 - post
->y_width
;
548 mode_info_context
++; /* Skip border mb */
553 void vp8_loop_filter_partial_frame
560 YV12_BUFFER_CONFIG
*post
= cm
->frame_to_show
;
562 unsigned char *y_ptr
;
565 int mb_cols
= post
->y_width
>> 4;
566 int mb_rows
= post
->y_height
>> 4;
570 loop_filter_info_n
*lfi_n
= &cm
->lf_info
;
571 loop_filter_info lfi
;
574 FRAME_TYPE frame_type
= cm
->frame_type
;
576 const MODE_INFO
*mode_info_context
;
579 if(default_filt_lvl
== 0) /* no filter applied */
583 /* Initialize the loop filter for this frame. */
584 vp8_loop_filter_frame_init( cm
, mbd
, default_filt_lvl
);
586 /* number of MB rows to use in partial filtering */
587 linestocopy
= mb_rows
/ PARTIAL_FRAME_FRACTION
;
588 linestocopy
= linestocopy
? linestocopy
<< 4 : 16; /* 16 lines per MB */
590 /* Set up the buffer pointers; partial image starts at ~middle of frame */
591 y_ptr
= post
->y_buffer
+ ((post
->y_height
>> 5) * 16) * post
->y_stride
;
592 mode_info_context
= cm
->mi
+ (post
->y_height
>> 5) * (mb_cols
+ 1);
594 /* vp8_filter each macro block */
595 for (mb_row
= 0; mb_row
<(linestocopy
>> 4); mb_row
++)
597 for (mb_col
= 0; mb_col
< mb_cols
; mb_col
++)
599 int skip_lf
= (mode_info_context
->mbmi
.mode
!= B_PRED
&&
600 mode_info_context
->mbmi
.mode
!= SPLITMV
&&
601 mode_info_context
->mbmi
.mb_skip_coeff
);
603 const int mode_index
=
604 lfi_n
->mode_lf_lut
[mode_info_context
->mbmi
.mode
];
605 const int seg
= mode_info_context
->mbmi
.segment_id
;
606 const int ref_frame
= mode_info_context
->mbmi
.ref_frame
;
608 filter_level
= lfi_n
->lvl
[seg
][ref_frame
][mode_index
];
612 if (cm
->filter_type
== NORMAL_LOOPFILTER
)
614 const int hev_index
= lfi_n
->hev_thr_lut
[frame_type
][filter_level
];
615 lfi
.mblim
= lfi_n
->mblim
[filter_level
];
616 lfi
.blim
= lfi_n
->blim
[filter_level
];
617 lfi
.lim
= lfi_n
->lim
[filter_level
];
618 lfi
.hev_thr
= lfi_n
->hev_thr
[hev_index
];
622 (y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
);
626 (y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
);
629 (y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
);
633 (y_ptr
, 0, 0, post
->y_stride
, 0, &lfi
);
638 vp8_loop_filter_simple_mbv
639 (y_ptr
, post
->y_stride
, lfi_n
->mblim
[filter_level
]);
642 vp8_loop_filter_simple_bv
643 (y_ptr
, post
->y_stride
, lfi_n
->blim
[filter_level
]);
645 vp8_loop_filter_simple_mbh
646 (y_ptr
, post
->y_stride
, lfi_n
->mblim
[filter_level
]);
649 vp8_loop_filter_simple_bh
650 (y_ptr
, post
->y_stride
, lfi_n
->blim
[filter_level
]);
655 mode_info_context
+= 1; /* step to next MB */
658 y_ptr
+= post
->y_stride
* 16 - post
->y_width
;
659 mode_info_context
+= 1; /* Skip border mb */