1 /* 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3 * 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. 9 */ 10 11 12 #include "vpx_ports/config.h" 13 #include "loopfilter.h" 14 #include "onyxc_int.h" 15 16 typedef unsigned char uc; 17 18 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); 25 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) 29 { 30 (void) simpler_lpf; 31 vp8_mbloop_filter_horizontal_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2); 32 33 if (u_ptr) 34 vp8_mbloop_filter_horizontal_edge_c(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1); 35 36 if (v_ptr) 37 vp8_mbloop_filter_horizontal_edge_c(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1); 38 } 39 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) 42 { 43 (void) u_ptr; 44 (void) v_ptr; 45 (void) uv_stride; 46 (void) simpler_lpf; 47 vp8_loop_filter_simple_horizontal_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2); 48 } 49 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) 53 { 54 (void) simpler_lpf; 55 vp8_mbloop_filter_vertical_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2); 56 57 if (u_ptr) 58 vp8_mbloop_filter_vertical_edge_c(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1); 59 60 if (v_ptr) 61 vp8_mbloop_filter_vertical_edge_c(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1); 62 } 63 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) 66 { 67 (void) u_ptr; 68 (void) v_ptr; 69 (void) uv_stride; 70 (void) simpler_lpf; 71 vp8_loop_filter_simple_vertical_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2); 72 } 73 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) 77 { 78 (void) 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); 82 83 if (u_ptr) 84 vp8_loop_filter_horizontal_edge_c(u_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1); 85 86 if (v_ptr) 87 vp8_loop_filter_horizontal_edge_c(v_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1); 88 } 89 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) 92 { 93 (void) u_ptr; 94 (void) v_ptr; 95 (void) uv_stride; 96 (void) 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); 100 } 101 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) 105 { 106 (void) 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); 110 111 if (u_ptr) 112 vp8_loop_filter_vertical_edge_c(u_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1); 113 114 if (v_ptr) 115 vp8_loop_filter_vertical_edge_c(v_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1); 116 } 117 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) 120 { 121 (void) u_ptr; 122 (void) v_ptr; 123 (void) uv_stride; 124 (void) 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); 128 } 129 130 void vp8_init_loop_filter(VP8_COMMON *cm) 131 { 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; 136 int i, j; 137 138 int block_inside_limit = 0; 139 int HEVThresh; 140 const int yhedge_boost = 2; 141 const int uvhedge_boost = 2; 142 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++) 145 { 146 int filt_lvl = i; 147 148 if (frame_type == KEY_FRAME) 149 { 150 if (filt_lvl >= 40) 151 HEVThresh = 2; 152 else if (filt_lvl >= 15) 153 HEVThresh = 1; 154 else 155 HEVThresh = 0; 156 } 157 else 158 { 159 if (filt_lvl >= 40) 160 HEVThresh = 3; 161 else if (filt_lvl >= 20) 162 HEVThresh = 2; 163 else if (filt_lvl >= 15) 164 HEVThresh = 1; 165 else 166 HEVThresh = 0; 167 } 168 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); 172 173 if (sharpness_lvl > 0) 174 { 175 if (block_inside_limit > (9 - sharpness_lvl)) 176 block_inside_limit = (9 - sharpness_lvl); 177 } 178 179 if (block_inside_limit < 1) 180 block_inside_limit = 1; 181 182 for (j = 0; j < 16; j++) 183 { 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; 194 } 195 196 } 197 198 /* Set up the function pointers depending on the type of loop filtering selected */ 199 if (lft == NORMAL_LOOPFILTER) 200 { 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); 205 } 206 else 207 { 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); 212 } 213 } 214 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 */ 218 void vp8_frame_init_loop_filter(loop_filter_info *lfi, int frame_type) 219 { 220 int HEVThresh; 221 int i, j; 222 223 /* For each possible value for the loop filter fill out a "loop_filter_info" entry. */ 224 for (i = 0; i <= MAX_LOOP_FILTER; i++) 225 { 226 int filt_lvl = i; 227 228 if (frame_type == KEY_FRAME) 229 { 230 if (filt_lvl >= 40) 231 HEVThresh = 2; 232 else if (filt_lvl >= 15) 233 HEVThresh = 1; 234 else 235 HEVThresh = 0; 236 } 237 else 238 { 239 if (filt_lvl >= 40) 240 HEVThresh = 3; 241 else if (filt_lvl >= 20) 242 HEVThresh = 2; 243 else if (filt_lvl >= 15) 244 HEVThresh = 1; 245 else 246 HEVThresh = 0; 247 } 248 249 for (j = 0; j < 16; j++) 250 { 251 /*lfi[i].lim[j] = block_inside_limit; 252 lfi[i].mbflim[j] = filt_lvl+yhedge_boost;*/ 253 lfi[i].mbthr[j] = HEVThresh; 254 /*lfi[i].flim[j] = filt_lvl;*/ 255 lfi[i].thr[j] = HEVThresh; 256 /*lfi[i].uvlim[j] = block_inside_limit; 257 lfi[i].uvmbflim[j] = filt_lvl+uvhedge_boost;*/ 258 lfi[i].uvmbthr[j] = HEVThresh; 259 /*lfi[i].uvflim[j] = filt_lvl;*/ 260 lfi[i].uvthr[j] = HEVThresh; 261 } 262 } 263 } 264 265 266 void vp8_adjust_mb_lf_value(MACROBLOCKD *mbd, int *filter_level) 267 { 268 MB_MODE_INFO *mbmi = &mbd->mode_info_context->mbmi; 269 270 if (mbd->mode_ref_lf_delta_enabled) 271 { 272 /* Apply delta for reference frame */ 273 *filter_level += mbd->ref_lf_deltas[mbmi->ref_frame]; 274 275 /* Apply delta for mode */ 276 if (mbmi->ref_frame == INTRA_FRAME) 277 { 278 /* Only the split mode BPRED has a further special case */ 279 if (mbmi->mode == B_PRED) 280 *filter_level += mbd->mode_lf_deltas[0]; 281 } 282 else 283 { 284 /* Zero motion mode */ 285 if (mbmi->mode == ZEROMV) 286 *filter_level += mbd->mode_lf_deltas[1]; 287 288 /* Split MB motion mode */ 289 else if (mbmi->mode == SPLITMV) 290 *filter_level += mbd->mode_lf_deltas[3]; 291 292 /* All other inter motion modes (Nearest, Near, New) */ 293 else 294 *filter_level += mbd->mode_lf_deltas[2]; 295 } 296 297 /* Range check */ 298 if (*filter_level > MAX_LOOP_FILTER) 299 *filter_level = MAX_LOOP_FILTER; 300 else if (*filter_level < 0) 301 *filter_level = 0; 302 } 303 } 304 305 306 void vp8_loop_filter_frame 307 ( 308 VP8_COMMON *cm, 309 MACROBLOCKD *mbd, 310 int default_filt_lvl 311 ) 312 { 313 YV12_BUFFER_CONFIG *post = cm->frame_to_show; 314 loop_filter_info *lfi = cm->lf_info; 315 FRAME_TYPE frame_type = cm->frame_type; 316 317 int mb_row; 318 int mb_col; 319 320 321 int baseline_filter_level[MAX_MB_SEGMENTS]; 322 int filter_level; 323 int alt_flt_enabled = mbd->segmentation_enabled; 324 325 int i; 326 unsigned char *y_ptr, *u_ptr, *v_ptr; 327 328 mbd->mode_info_context = cm->mi; /* Point at base of Mb MODE_INFO list */ 329 330 /* Note the baseline filter values for each segment */ 331 if (alt_flt_enabled) 332 { 333 for (i = 0; i < MAX_MB_SEGMENTS; i++) 334 { 335 /* Abs value */ 336 if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA) 337 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i]; 338 /* Delta Value */ 339 else 340 { 341 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i]; 342 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 */ 343 } 344 } 345 } 346 else 347 { 348 for (i = 0; i < MAX_MB_SEGMENTS; i++) 349 baseline_filter_level[i] = default_filt_lvl; 350 } 351 352 /* Initialize the loop filter for this frame. */ 353 if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level)) 354 vp8_init_loop_filter(cm); 355 else if (frame_type != cm->last_frame_type) 356 vp8_frame_init_loop_filter(lfi, frame_type); 357 358 /* Set up the buffer pointers */ 359 y_ptr = post->y_buffer; 360 u_ptr = post->u_buffer; 361 v_ptr = post->v_buffer; 362 363 /* vp8_filter each macro block */ 364 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) 365 { 366 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) 367 { 368 int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0; 369 370 filter_level = baseline_filter_level[Segment]; 371 372 /* Distance of Mb to the various image edges. 373 * These specified to 8th pel as they are always compared to values that are in 1/8th pel units 374 * Apply any context driven MB level adjustment 375 */ 376 vp8_adjust_mb_lf_value(mbd, &filter_level); 377 378 if (filter_level) 379 { 380 if (mb_col > 0) 381 cm->lf_mbv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf); 382 383 if (mbd->mode_info_context->mbmi.dc_diff > 0) 384 cm->lf_bv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf); 385 386 /* don't apply across umv border */ 387 if (mb_row > 0) 388 cm->lf_mbh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf); 389 390 if (mbd->mode_info_context->mbmi.dc_diff > 0) 391 cm->lf_bh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf); 392 } 393 394 y_ptr += 16; 395 u_ptr += 8; 396 v_ptr += 8; 397 398 mbd->mode_info_context++; /* step to next MB */ 399 } 400 401 y_ptr += post->y_stride * 16 - post->y_width; 402 u_ptr += post->uv_stride * 8 - post->uv_width; 403 v_ptr += post->uv_stride * 8 - post->uv_width; 404 405 mbd->mode_info_context++; /* Skip border mb */ 406 } 407 } 408 409 410 void vp8_loop_filter_frame_yonly 411 ( 412 VP8_COMMON *cm, 413 MACROBLOCKD *mbd, 414 int default_filt_lvl, 415 int sharpness_lvl 416 ) 417 { 418 YV12_BUFFER_CONFIG *post = cm->frame_to_show; 419 420 int i; 421 unsigned char *y_ptr; 422 int mb_row; 423 int mb_col; 424 425 loop_filter_info *lfi = cm->lf_info; 426 int baseline_filter_level[MAX_MB_SEGMENTS]; 427 int filter_level; 428 int alt_flt_enabled = mbd->segmentation_enabled; 429 FRAME_TYPE frame_type = cm->frame_type; 430 431 (void) sharpness_lvl; 432 433 /*MODE_INFO * this_mb_mode_info = cm->mi;*/ /* Point at base of Mb MODE_INFO list */ 434 mbd->mode_info_context = cm->mi; /* Point at base of Mb MODE_INFO list */ 435 436 /* Note the baseline filter values for each segment */ 437 if (alt_flt_enabled) 438 { 439 for (i = 0; i < MAX_MB_SEGMENTS; i++) 440 { 441 /* Abs value */ 442 if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA) 443 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i]; 444 /* Delta Value */ 445 else 446 { 447 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i]; 448 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 */ 449 } 450 } 451 } 452 else 453 { 454 for (i = 0; i < MAX_MB_SEGMENTS; i++) 455 baseline_filter_level[i] = default_filt_lvl; 456 } 457 458 /* Initialize the loop filter for this frame. */ 459 if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level)) 460 vp8_init_loop_filter(cm); 461 else if (frame_type != cm->last_frame_type) 462 vp8_frame_init_loop_filter(lfi, frame_type); 463 464 /* Set up the buffer pointers */ 465 y_ptr = post->y_buffer; 466 467 /* vp8_filter each macro block */ 468 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) 469 { 470 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) 471 { 472 int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0; 473 filter_level = baseline_filter_level[Segment]; 474 475 /* Apply any context driven MB level adjustment */ 476 vp8_adjust_mb_lf_value(mbd, &filter_level); 477 478 if (filter_level) 479 { 480 if (mb_col > 0) 481 cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0); 482 483 if (mbd->mode_info_context->mbmi.dc_diff > 0) 484 cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0); 485 486 /* don't apply across umv border */ 487 if (mb_row > 0) 488 cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0); 489 490 if (mbd->mode_info_context->mbmi.dc_diff > 0) 491 cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0); 492 } 493 494 y_ptr += 16; 495 mbd->mode_info_context ++; /* step to next MB */ 496 497 } 498 499 y_ptr += post->y_stride * 16 - post->y_width; 500 mbd->mode_info_context ++; /* Skip border mb */ 501 } 502 503 } 504 505 506 void vp8_loop_filter_partial_frame 507 ( 508 VP8_COMMON *cm, 509 MACROBLOCKD *mbd, 510 int default_filt_lvl, 511 int sharpness_lvl, 512 int Fraction 513 ) 514 { 515 YV12_BUFFER_CONFIG *post = cm->frame_to_show; 516 517 int i; 518 unsigned char *y_ptr; 519 int mb_row; 520 int mb_col; 521 /*int mb_rows = post->y_height >> 4;*/ 522 int mb_cols = post->y_width >> 4; 523 524 int linestocopy; 525 526 loop_filter_info *lfi = cm->lf_info; 527 int baseline_filter_level[MAX_MB_SEGMENTS]; 528 int filter_level; 529 int alt_flt_enabled = mbd->segmentation_enabled; 530 FRAME_TYPE frame_type = cm->frame_type; 531 532 (void) sharpness_lvl; 533 534 /*MODE_INFO * this_mb_mode_info = cm->mi + (post->y_height>>5) * (mb_cols + 1);*/ /* Point at base of Mb MODE_INFO list */ 535 mbd->mode_info_context = cm->mi + (post->y_height >> 5) * (mb_cols + 1); /* Point at base of Mb MODE_INFO list */ 536 537 linestocopy = (post->y_height >> (4 + Fraction)); 538 539 if (linestocopy < 1) 540 linestocopy = 1; 541 542 linestocopy <<= 4; 543 544 /* Note the baseline filter values for each segment */ 545 if (alt_flt_enabled) 546 { 547 for (i = 0; i < MAX_MB_SEGMENTS; i++) 548 { 549 /* Abs value */ 550 if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA) 551 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i]; 552 /* Delta Value */ 553 else 554 { 555 baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i]; 556 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 */ 557 } 558 } 559 } 560 else 561 { 562 for (i = 0; i < MAX_MB_SEGMENTS; i++) 563 baseline_filter_level[i] = default_filt_lvl; 564 } 565 566 /* Initialize the loop filter for this frame. */ 567 if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level)) 568 vp8_init_loop_filter(cm); 569 else if (frame_type != cm->last_frame_type) 570 vp8_frame_init_loop_filter(lfi, frame_type); 571 572 /* Set up the buffer pointers */ 573 y_ptr = post->y_buffer + (post->y_height >> 5) * 16 * post->y_stride; 574 575 /* vp8_filter each macro block */ 576 for (mb_row = 0; mb_row<(linestocopy >> 4); mb_row++) 577 { 578 for (mb_col = 0; mb_col < mb_cols; mb_col++) 579 { 580 int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0; 581 filter_level = baseline_filter_level[Segment]; 582 583 if (filter_level) 584 { 585 if (mb_col > 0) 586 cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0); 587 588 if (mbd->mode_info_context->mbmi.dc_diff > 0) 589 cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0); 590 591 cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0); 592 593 if (mbd->mode_info_context->mbmi.dc_diff > 0) 594 cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0); 595 } 596 597 y_ptr += 16; 598 mbd->mode_info_context += 1; /* step to next MB */ 599 } 600 601 y_ptr += post->y_stride * 16 - post->y_width; 602 mbd->mode_info_context += 1; /* Skip border mb */ 603 } 604 } 605