| 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 |