OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 for (mode = 1; mode < 4; mode++) { | 169 for (mode = 1; mode < 4; mode++) { |
170 lvl_mode = lvl_ref + xd->mode_lf_deltas[mode]; | 170 lvl_mode = lvl_ref + xd->mode_lf_deltas[mode]; |
171 lvl_mode = (lvl_mode > 0) ? (lvl_mode > 63 ? 63 : lvl_mode) : 0; /* clam
p */ | 171 lvl_mode = (lvl_mode > 0) ? (lvl_mode > 63 ? 63 : lvl_mode) : 0; /* clam
p */ |
172 | 172 |
173 lfi->lvl[seg][ref][mode] = lvl_mode; | 173 lfi->lvl[seg][ref][mode] = lvl_mode; |
174 } | 174 } |
175 } | 175 } |
176 } | 176 } |
177 } | 177 } |
178 | 178 |
179 void vp9_loop_filter_frame(VP9_COMMON *cm, MACROBLOCKD *xd) { | 179 // Determine if we should skip inner-MB loop filtering within a MB |
| 180 // The current condition is that the loop filtering is skipped only |
| 181 // the MB uses a prediction size of 16x16 and either 16x16 transform |
| 182 // is used or there is no residue at all. |
| 183 static int mb_lf_skip(const MB_MODE_INFO *const mbmi) { |
| 184 const MB_PREDICTION_MODE mode = mbmi->mode; |
| 185 const int skip_coef = mbmi->mb_skip_coeff; |
| 186 const int tx_size = mbmi->txfm_size; |
| 187 return mode != B_PRED && mode != I8X8_PRED && mode != SPLITMV && |
| 188 (tx_size >= TX_16X16 || skip_coef); |
| 189 } |
| 190 |
| 191 // Determine if we should skip MB loop filtering on a MB edge within |
| 192 // a superblock, the current condition is that MB loop filtering is |
| 193 // skipped only when both MBs do not use inner MB loop filtering, and |
| 194 // same motion vector with same reference frame |
| 195 static int sb_mb_lf_skip(const MODE_INFO *const mip0, |
| 196 const MODE_INFO *const mip1) { |
| 197 const MB_MODE_INFO *mbmi0 = &mip0->mbmi; |
| 198 const MB_MODE_INFO *mbmi1 = &mip0->mbmi; |
| 199 return mb_lf_skip(mbmi0) && mb_lf_skip(mbmi1) && |
| 200 (mbmi0->ref_frame == mbmi1->ref_frame) && |
| 201 (mbmi0->mv[mbmi0->ref_frame].as_int == |
| 202 mbmi1->mv[mbmi1->ref_frame].as_int) && |
| 203 mbmi0->ref_frame != INTRA_FRAME; |
| 204 } |
| 205 void vp9_loop_filter_frame(VP9_COMMON *cm, |
| 206 MACROBLOCKD *xd, |
| 207 int frame_filter_level, |
| 208 int y_only) { |
180 YV12_BUFFER_CONFIG *post = cm->frame_to_show; | 209 YV12_BUFFER_CONFIG *post = cm->frame_to_show; |
181 loop_filter_info_n *lfi_n = &cm->lf_info; | 210 loop_filter_info_n *lfi_n = &cm->lf_info; |
182 struct loop_filter_info lfi; | 211 struct loop_filter_info lfi; |
183 | 212 const FRAME_TYPE frame_type = cm->frame_type; |
184 FRAME_TYPE frame_type = cm->frame_type; | 213 int mb_row, mb_col; |
185 | 214 uint8_t *y_ptr, *u_ptr, *v_ptr; |
186 int mb_row; | |
187 int mb_col; | |
188 | |
189 int filter_level; | |
190 | |
191 unsigned char *y_ptr, *u_ptr, *v_ptr; | |
192 | 215 |
193 /* Point at base of Mb MODE_INFO list */ | 216 /* Point at base of Mb MODE_INFO list */ |
194 const MODE_INFO *mode_info_context = cm->mi; | 217 const MODE_INFO *mode_info_context = cm->mi; |
| 218 const int mis = cm->mode_info_stride; |
195 | 219 |
196 /* Initialize the loop filter for this frame. */ | 220 /* Initialize the loop filter for this frame. */ |
197 vp9_loop_filter_frame_init(cm, xd, cm->filter_level); | 221 vp9_loop_filter_frame_init(cm, xd, frame_filter_level); |
198 | |
199 /* Set up the buffer pointers */ | 222 /* Set up the buffer pointers */ |
200 y_ptr = post->y_buffer; | 223 y_ptr = post->y_buffer; |
201 u_ptr = post->u_buffer; | 224 if (y_only) { |
202 v_ptr = post->v_buffer; | 225 u_ptr = 0; |
| 226 v_ptr = 0; |
| 227 } else { |
| 228 u_ptr = post->u_buffer; |
| 229 v_ptr = post->v_buffer; |
| 230 } |
203 | 231 |
204 /* vp9_filter each macro block */ | 232 /* vp9_filter each macro block */ |
205 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { | 233 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { |
206 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { | 234 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { |
207 int skip_lf = (mode_info_context->mbmi.mode != B_PRED && | 235 const MB_PREDICTION_MODE mode = mode_info_context->mbmi.mode; |
208 mode_info_context->mbmi.mode != I8X8_PRED && | 236 const int mode_index = lfi_n->mode_lf_lut[mode]; |
209 mode_info_context->mbmi.mode != SPLITMV && | |
210 mode_info_context->mbmi.mb_skip_coeff); | |
211 | |
212 const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode]; | |
213 const int seg = mode_info_context->mbmi.segment_id; | 237 const int seg = mode_info_context->mbmi.segment_id; |
214 const int ref_frame = mode_info_context->mbmi.ref_frame; | 238 const int ref_frame = mode_info_context->mbmi.ref_frame; |
215 int tx_type = mode_info_context->mbmi.txfm_size; | 239 const int filter_level = lfi_n->lvl[seg][ref_frame][mode_index]; |
216 filter_level = lfi_n->lvl[seg][ref_frame][mode_index]; | |
217 | |
218 if (filter_level) { | 240 if (filter_level) { |
| 241 const int skip_lf = mb_lf_skip(&mode_info_context->mbmi); |
| 242 const int tx_size = mode_info_context->mbmi.txfm_size; |
219 if (cm->filter_type == NORMAL_LOOPFILTER) { | 243 if (cm->filter_type == NORMAL_LOOPFILTER) { |
220 const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level]; | 244 const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level]; |
221 lfi.mblim = lfi_n->mblim[filter_level]; | 245 lfi.mblim = lfi_n->mblim[filter_level]; |
222 lfi.blim = lfi_n->blim[filter_level]; | 246 lfi.blim = lfi_n->blim[filter_level]; |
223 lfi.lim = lfi_n->lim[filter_level]; | 247 lfi.lim = lfi_n->lim[filter_level]; |
224 lfi.hev_thr = lfi_n->hev_thr[hev_index]; | 248 lfi.hev_thr = lfi_n->hev_thr[hev_index]; |
225 | 249 |
226 if (mb_col > 0 | 250 if (mb_col > 0 && |
227 #if CONFIG_SUPERBLOCKS | 251 !((mb_col & 1) && mode_info_context->mbmi.sb_type && |
228 && !((mb_col & 1) && mode_info_context->mbmi.encoded_as_sb && | 252 (sb_mb_lf_skip(mode_info_context - 1, mode_info_context) || |
229 mode_info_context[0].mbmi.mb_skip_coeff && | 253 tx_size >= TX_32X32)) |
230 mode_info_context[-1].mbmi.mb_skip_coeff) | 254 ) { |
231 #endif | 255 if (tx_size >= TX_16X16) |
232 ) | 256 vp9_lpf_mbv_w(y_ptr, u_ptr, v_ptr, post->y_stride, |
233 vp9_loop_filter_mbv(y_ptr, u_ptr, v_ptr, post->y_stride, | 257 post->uv_stride, &lfi); |
234 post->uv_stride, &lfi); | |
235 | |
236 if (!skip_lf && tx_type != TX_16X16) { | |
237 if (tx_type == TX_8X8) | |
238 vp9_loop_filter_bv8x8(y_ptr, u_ptr, v_ptr, post->y_stride, | |
239 post->uv_stride, &lfi); | |
240 else | 258 else |
| 259 vp9_loop_filter_mbv(y_ptr, u_ptr, v_ptr, post->y_stride, |
| 260 post->uv_stride, &lfi); |
| 261 } |
| 262 if (!skip_lf) { |
| 263 if (tx_size >= TX_8X8) { |
| 264 if (tx_size == TX_8X8 && (mode == I8X8_PRED || mode == SPLITMV)) |
| 265 vp9_loop_filter_bv8x8(y_ptr, u_ptr, v_ptr, post->y_stride, |
| 266 post->uv_stride, &lfi); |
| 267 else |
| 268 vp9_loop_filter_bv8x8(y_ptr, NULL, NULL, post->y_stride, |
| 269 post->uv_stride, &lfi); |
| 270 } else { |
241 vp9_loop_filter_bv(y_ptr, u_ptr, v_ptr, post->y_stride, | 271 vp9_loop_filter_bv(y_ptr, u_ptr, v_ptr, post->y_stride, |
242 post->uv_stride, &lfi); | 272 post->uv_stride, &lfi); |
| 273 } |
243 | 274 |
244 } | 275 } |
245 | |
246 /* don't apply across umv border */ | 276 /* don't apply across umv border */ |
247 if (mb_row > 0 | 277 if (mb_row > 0 && |
248 #if CONFIG_SUPERBLOCKS | 278 !((mb_row & 1) && mode_info_context->mbmi.sb_type && |
249 && !((mb_row & 1) && mode_info_context->mbmi.encoded_as_sb && | 279 (sb_mb_lf_skip(mode_info_context - mis, mode_info_context) || |
250 mode_info_context[0].mbmi.mb_skip_coeff && | 280 tx_size >= TX_32X32)) |
251 mode_info_context[-cm->mode_info_stride].mbmi.mb_skip_coeff) | 281 ) { |
252 #endif | 282 if (tx_size >= TX_16X16) |
253 ) | 283 vp9_lpf_mbh_w(y_ptr, u_ptr, v_ptr, post->y_stride, |
254 vp9_loop_filter_mbh(y_ptr, u_ptr, v_ptr, post->y_stride, | 284 post->uv_stride, &lfi); |
255 post->uv_stride, &lfi); | |
256 | |
257 if (!skip_lf && tx_type != TX_16X16) { | |
258 if (tx_type == TX_8X8) | |
259 vp9_loop_filter_bh8x8(y_ptr, u_ptr, v_ptr, post->y_stride, | |
260 post->uv_stride, &lfi); | |
261 else | 285 else |
| 286 vp9_loop_filter_mbh(y_ptr, u_ptr, v_ptr, post->y_stride, |
| 287 post->uv_stride, &lfi); |
| 288 } |
| 289 if (!skip_lf) { |
| 290 if (tx_size >= TX_8X8) { |
| 291 if (tx_size == TX_8X8 && (mode == I8X8_PRED || mode == SPLITMV)) |
| 292 vp9_loop_filter_bh8x8(y_ptr, u_ptr, v_ptr, post->y_stride, |
| 293 post->uv_stride, &lfi); |
| 294 else |
| 295 vp9_loop_filter_bh8x8(y_ptr, NULL, NULL, post->y_stride, |
| 296 post->uv_stride, &lfi); |
| 297 } else { |
262 vp9_loop_filter_bh(y_ptr, u_ptr, v_ptr, post->y_stride, | 298 vp9_loop_filter_bh(y_ptr, u_ptr, v_ptr, post->y_stride, |
263 post->uv_stride, &lfi); | 299 post->uv_stride, &lfi); |
| 300 } |
264 } | 301 } |
265 } else { | 302 } else { |
266 // FIXME: Not 8x8 aware | 303 // FIXME: Not 8x8 aware |
267 if (mb_col > 0 | 304 if (mb_col > 0 && |
268 #if CONFIG_SUPERBLOCKS | 305 !(skip_lf && mb_lf_skip(&mode_info_context[-1].mbmi)) && |
269 && !((mb_col & 1) && mode_info_context->mbmi.encoded_as_sb && | 306 !((mb_col & 1) && mode_info_context->mbmi.sb_type)) |
270 mode_info_context[0].mbmi.mb_skip_coeff && | |
271 mode_info_context[-1].mbmi.mb_skip_coeff) | |
272 #endif | |
273 ) | |
274 vp9_loop_filter_simple_mbv(y_ptr, post->y_stride, | 307 vp9_loop_filter_simple_mbv(y_ptr, post->y_stride, |
275 lfi_n->mblim[filter_level]); | 308 lfi_n->mblim[filter_level]); |
276 | |
277 if (!skip_lf) | 309 if (!skip_lf) |
278 vp9_loop_filter_simple_bv(y_ptr, post->y_stride, | 310 vp9_loop_filter_simple_bv(y_ptr, post->y_stride, |
279 lfi_n->blim[filter_level]); | 311 lfi_n->blim[filter_level]); |
280 | 312 |
281 /* don't apply across umv border */ | 313 /* don't apply across umv border */ |
282 if (mb_row > 0 | 314 if (mb_row > 0 && |
283 #if CONFIG_SUPERBLOCKS | 315 !(skip_lf && mb_lf_skip(&mode_info_context[-mis].mbmi)) && |
284 && !((mb_row & 1) && mode_info_context->mbmi.encoded_as_sb && | 316 !((mb_row & 1) && mode_info_context->mbmi.sb_type)) |
285 mode_info_context[0].mbmi.mb_skip_coeff && | |
286 mode_info_context[-cm->mode_info_stride].mbmi.mb_skip_coeff) | |
287 #endif | |
288 ) | |
289 vp9_loop_filter_simple_mbh(y_ptr, post->y_stride, | 317 vp9_loop_filter_simple_mbh(y_ptr, post->y_stride, |
290 lfi_n->mblim[filter_level]); | 318 lfi_n->mblim[filter_level]); |
291 | |
292 if (!skip_lf) | 319 if (!skip_lf) |
293 vp9_loop_filter_simple_bh(y_ptr, post->y_stride, | 320 vp9_loop_filter_simple_bh(y_ptr, post->y_stride, |
294 lfi_n->blim[filter_level]); | 321 lfi_n->blim[filter_level]); |
295 } | 322 } |
296 } | 323 } |
297 | |
298 y_ptr += 16; | 324 y_ptr += 16; |
299 u_ptr += 8; | 325 if (!y_only) { |
300 v_ptr += 8; | 326 u_ptr += 8; |
301 | 327 v_ptr += 8; |
| 328 } |
302 mode_info_context++; /* step to next MB */ | 329 mode_info_context++; /* step to next MB */ |
303 } | 330 } |
304 | |
305 y_ptr += post->y_stride * 16 - post->y_width; | 331 y_ptr += post->y_stride * 16 - post->y_width; |
306 u_ptr += post->uv_stride * 8 - post->uv_width; | 332 if (!y_only) { |
307 v_ptr += post->uv_stride * 8 - post->uv_width; | 333 u_ptr += post->uv_stride * 8 - post->uv_width; |
308 | 334 v_ptr += post->uv_stride * 8 - post->uv_width; |
| 335 } |
309 mode_info_context++; /* Skip border mb */ | 336 mode_info_context++; /* Skip border mb */ |
310 } | 337 } |
311 } | 338 } |
312 | 339 |
313 void vp9_loop_filter_frame_yonly(VP9_COMMON *cm, MACROBLOCKD *xd, | |
314 int default_filt_lvl) { | |
315 YV12_BUFFER_CONFIG *post = cm->frame_to_show; | |
316 | |
317 unsigned char *y_ptr; | |
318 int mb_row; | |
319 int mb_col; | |
320 | |
321 loop_filter_info_n *lfi_n = &cm->lf_info; | |
322 struct loop_filter_info lfi; | |
323 | |
324 int filter_level; | |
325 FRAME_TYPE frame_type = cm->frame_type; | |
326 | |
327 /* Point at base of Mb MODE_INFO list */ | |
328 const MODE_INFO *mode_info_context = cm->mi; | |
329 | |
330 #if 0 | |
331 if (default_filt_lvl == 0) /* no filter applied */ | |
332 return; | |
333 #endif | |
334 | |
335 /* Initialize the loop filter for this frame. */ | |
336 vp9_loop_filter_frame_init(cm, xd, default_filt_lvl); | |
337 | |
338 /* Set up the buffer pointers */ | |
339 y_ptr = post->y_buffer; | |
340 | |
341 /* vp9_filter each macro block */ | |
342 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { | |
343 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { | |
344 int skip_lf = (mode_info_context->mbmi.mode != B_PRED && | |
345 mode_info_context->mbmi.mode != I8X8_PRED && | |
346 mode_info_context->mbmi.mode != SPLITMV && | |
347 mode_info_context->mbmi.mb_skip_coeff); | |
348 | |
349 const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode]; | |
350 const int seg = mode_info_context->mbmi.segment_id; | |
351 const int ref_frame = mode_info_context->mbmi.ref_frame; | |
352 int tx_type = mode_info_context->mbmi.txfm_size; | |
353 filter_level = lfi_n->lvl[seg][ref_frame][mode_index]; | |
354 | |
355 if (filter_level) { | |
356 if (cm->filter_type == NORMAL_LOOPFILTER) { | |
357 const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level]; | |
358 lfi.mblim = lfi_n->mblim[filter_level]; | |
359 lfi.blim = lfi_n->blim[filter_level]; | |
360 lfi.lim = lfi_n->lim[filter_level]; | |
361 lfi.hev_thr = lfi_n->hev_thr[hev_index]; | |
362 | |
363 if (mb_col > 0) | |
364 vp9_loop_filter_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi); | |
365 | |
366 if (!skip_lf && tx_type != TX_16X16) { | |
367 if (tx_type == TX_8X8) | |
368 vp9_loop_filter_bv8x8(y_ptr, 0, 0, post->y_stride, 0, &lfi); | |
369 else | |
370 vp9_loop_filter_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi); | |
371 } | |
372 | |
373 /* don't apply across umv border */ | |
374 if (mb_row > 0) | |
375 vp9_loop_filter_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi); | |
376 | |
377 if (!skip_lf && tx_type != TX_16X16) { | |
378 if (tx_type == TX_8X8) | |
379 vp9_loop_filter_bh8x8(y_ptr, 0, 0, post->y_stride, 0, &lfi); | |
380 else | |
381 vp9_loop_filter_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi); | |
382 } | |
383 } else { | |
384 // FIXME: Not 8x8 aware | |
385 if (mb_col > 0) | |
386 vp9_loop_filter_simple_mbv(y_ptr, post->y_stride, | |
387 lfi_n->mblim[filter_level]); | |
388 | |
389 if (!skip_lf) | |
390 vp9_loop_filter_simple_bv(y_ptr, post->y_stride, | |
391 lfi_n->blim[filter_level]); | |
392 | |
393 /* don't apply across umv border */ | |
394 if (mb_row > 0) | |
395 vp9_loop_filter_simple_mbh(y_ptr, post->y_stride, | |
396 lfi_n->mblim[filter_level]); | |
397 | |
398 if (!skip_lf) | |
399 vp9_loop_filter_simple_bh(y_ptr, post->y_stride, | |
400 lfi_n->blim[filter_level]); | |
401 } | |
402 } | |
403 | |
404 y_ptr += 16; | |
405 mode_info_context++; /* step to next MB */ | |
406 } | |
407 | |
408 y_ptr += post->y_stride * 16 - post->y_width; | |
409 mode_info_context++; /* Skip border mb */ | |
410 } | |
411 } | |
412 | 340 |
413 void vp9_loop_filter_partial_frame(VP9_COMMON *cm, MACROBLOCKD *xd, | 341 void vp9_loop_filter_partial_frame(VP9_COMMON *cm, MACROBLOCKD *xd, |
414 int default_filt_lvl) { | 342 int default_filt_lvl) { |
415 YV12_BUFFER_CONFIG *post = cm->frame_to_show; | 343 YV12_BUFFER_CONFIG *post = cm->frame_to_show; |
416 | 344 |
417 unsigned char *y_ptr; | 345 uint8_t *y_ptr; |
418 int mb_row; | 346 int mb_row; |
419 int mb_col; | 347 int mb_col; |
420 int mb_cols = post->y_width >> 4; | 348 int mb_cols = post->y_width >> 4; |
421 | 349 |
422 int linestocopy, i; | 350 int linestocopy, i; |
423 | 351 |
424 loop_filter_info_n *lfi_n = &cm->lf_info; | 352 loop_filter_info_n *lfi_n = &cm->lf_info; |
425 struct loop_filter_info lfi; | 353 struct loop_filter_info lfi; |
426 | 354 |
427 int filter_level; | 355 int filter_level; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 } | 443 } |
516 | 444 |
517 y_ptr += 16; | 445 y_ptr += 16; |
518 mode_info_context += 1; /* step to next MB */ | 446 mode_info_context += 1; /* step to next MB */ |
519 } | 447 } |
520 | 448 |
521 y_ptr += post->y_stride * 16 - post->y_width; | 449 y_ptr += post->y_stride * 16 - post->y_width; |
522 mode_info_context += 1; /* Skip border mb */ | 450 mode_info_context += 1; /* Skip border mb */ |
523 } | 451 } |
524 } | 452 } |
OLD | NEW |