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 void vp8_frame_init_loop_filter(loop_filter_info *lfi, int frame_type) 218 { 219 int HEVThresh; 220 int i, j; 221 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++) 224 { 225 int filt_lvl = i; 226 227 if (frame_type == KEY_FRAME) 228 { 229 if (filt_lvl >= 40) 230 HEVThresh = 2; 231 else if (filt_lvl >= 15) 232 HEVThresh = 1; 233 else 234 HEVThresh = 0; 235 } 236 else 237 { 238 if (filt_lvl >= 40) 239 HEVThresh = 3; 240 else if (filt_lvl >= 20) 241 HEVThresh = 2; 242 else if (filt_lvl >= 15) 243 HEVThresh = 1; 244 else 245 HEVThresh = 0; 246 } 247 248 for (j = 0; j < 16; j++) 249 { 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; 260 } 261 } 262 } 263 264 265 void vp8_adjust_mb_lf_value(MACROBLOCKD *mbd, int *filter_level) 266 { 267 MB_MODE_INFO *mbmi = &mbd->mode_info_context->mbmi; 268 269 if (mbd->mode_ref_lf_delta_enabled) 270 { 271 // Aplly delta for reference frame 272 *filter_level += mbd->ref_lf_deltas[mbmi->ref_frame]; 273 274 // Apply delta for mode 275 if (mbmi->ref_frame == INTRA_FRAME) 276 { 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]; 280 } 281 else 282 { 283 // Zero motion mode 284 if (mbmi->mode == ZEROMV) 285 *filter_level += mbd->mode_lf_deltas[1]; 286 287 // Split MB motion mode 288 else if (mbmi->mode == SPLITMV) 289 *filter_level += mbd->mode_lf_deltas[3]; 290 291 // All other inter motion modes (Nearest, Near, New) 292 else 293 *filter_level += mbd->mode_lf_deltas[2]; 294 } 295 296 // Range check 297 if (*filter_level > MAX_LOOP_FILTER) 298 *filter_level = MAX_LOOP_FILTER; 299 else if (*filter_level < 0) 300 *filter_level = 0; 301 } 302 } 303 304 305 void vp8_loop_filter_frame 306 ( 307 VP8_COMMON *cm, 308 MACROBLOCKD *mbd, 309 int default_filt_lvl 310 ) 311 { 312 YV12_BUFFER_CONFIG *post = cm->frame_to_show; 313 loop_filter_info *lfi = cm->lf_info; 314 int frame_type = cm->frame_type; 315 316 int mb_row; 317 int mb_col; 318 319 320 int baseline_filter_level[MAX_MB_SEGMENTS]; 321 int filter_level; 322 int alt_flt_enabled = mbd->segmentation_enabled; 323 324 int i; 325 unsigned char *y_ptr, *u_ptr, *v_ptr; 326 327 mbd->mode_info_context = cm->mi; // Point at base of Mb MODE_INFO list 328 329 // Note the baseline filter values for each segment 330 if (alt_flt_enabled) 331 { 332 for (i = 0; i < MAX_MB_SEGMENTS; i++) 333 { 334 // Abs value 335 if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA) 336 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i]; 337 // Delta Value 338 else 339 { 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 342 } 343 } 344 } 345 else 346 { 347 for (i = 0; i < MAX_MB_SEGMENTS; i++) 348 baseline_filter_level[i] = default_filt_lvl; 349 } 350 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); 356 357 // Set up the buffer pointers 358 y_ptr = post->y_buffer; 359 u_ptr = post->u_buffer; 360 v_ptr = post->v_buffer; 361 362 // vp8_filter each macro block 363 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) 364 { 365 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) 366 { 367 int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0; 368 369 filter_level = baseline_filter_level[Segment]; 370 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); 375 376 if (filter_level) 377 { 378 if (mb_col > 0) 379 cm->lf_mbv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf); 380 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); 383 384 // don't apply across umv border 385 if (mb_row > 0) 386 cm->lf_mbh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf); 387 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); 390 } 391 392 y_ptr += 16; 393 u_ptr += 8; 394 v_ptr += 8; 395 396 mbd->mode_info_context++; // step to next MB 397 } 398 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; 402 403 mbd->mode_info_context++; // Skip border mb 404 } 405 } 406 407 408 void vp8_loop_filter_frame_yonly 409 ( 410 VP8_COMMON *cm, 411 MACROBLOCKD *mbd, 412 int default_filt_lvl, 413 int sharpness_lvl 414 ) 415 { 416 YV12_BUFFER_CONFIG *post = cm->frame_to_show; 417 418 int i; 419 unsigned char *y_ptr; 420 int mb_row; 421 int mb_col; 422 423 loop_filter_info *lfi = cm->lf_info; 424 int baseline_filter_level[MAX_MB_SEGMENTS]; 425 int filter_level; 426 int alt_flt_enabled = mbd->segmentation_enabled; 427 int frame_type = cm->frame_type; 428 429 (void) sharpness_lvl; 430 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 433 434 // Note the baseline filter values for each segment 435 if (alt_flt_enabled) 436 { 437 for (i = 0; i < MAX_MB_SEGMENTS; i++) 438 { 439 // Abs value 440 if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA) 441 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i]; 442 // Delta Value 443 else 444 { 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 447 } 448 } 449 } 450 else 451 { 452 for (i = 0; i < MAX_MB_SEGMENTS; i++) 453 baseline_filter_level[i] = default_filt_lvl; 454 } 455 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); 461 462 // Set up the buffer pointers 463 y_ptr = post->y_buffer; 464 465 // vp8_filter each macro block 466 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) 467 { 468 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) 469 { 470 int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0; 471 filter_level = baseline_filter_level[Segment]; 472 473 // Apply any context driven MB level adjustment 474 vp8_adjust_mb_lf_value(mbd, &filter_level); 475 476 if (filter_level) 477 { 478 if (mb_col > 0) 479 cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0); 480 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); 483 484 // don't apply across umv border 485 if (mb_row > 0) 486 cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0); 487 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); 490 } 491 492 y_ptr += 16; 493 mbd->mode_info_context ++; // step to next MB 494 495 } 496 497 y_ptr += post->y_stride * 16 - post->y_width; 498 mbd->mode_info_context ++; // Skip border mb 499 } 500 501 } 502 503 504 void vp8_loop_filter_partial_frame 505 ( 506 VP8_COMMON *cm, 507 MACROBLOCKD *mbd, 508 int default_filt_lvl, 509 int sharpness_lvl, 510 int Fraction 511 ) 512 { 513 YV12_BUFFER_CONFIG *post = cm->frame_to_show; 514 515 int i; 516 unsigned char *y_ptr; 517 int mb_row; 518 int mb_col; 519 //int mb_rows = post->y_height >> 4; 520 int mb_cols = post->y_width >> 4; 521 522 int linestocopy; 523 524 loop_filter_info *lfi = cm->lf_info; 525 int baseline_filter_level[MAX_MB_SEGMENTS]; 526 int filter_level; 527 int alt_flt_enabled = mbd->segmentation_enabled; 528 int frame_type = cm->frame_type; 529 530 (void) sharpness_lvl; 531 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 534 535 linestocopy = (post->y_height >> (4 + Fraction)); 536 537 if (linestocopy < 1) 538 linestocopy = 1; 539 540 linestocopy <<= 4; 541 542 // Note the baseline filter values for each segment 543 if (alt_flt_enabled) 544 { 545 for (i = 0; i < MAX_MB_SEGMENTS; i++) 546 { 547 // Abs value 548 if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA) 549 baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i]; 550 // Delta Value 551 else 552 { 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 555 } 556 } 557 } 558 else 559 { 560 for (i = 0; i < MAX_MB_SEGMENTS; i++) 561 baseline_filter_level[i] = default_filt_lvl; 562 } 563 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); 569 570 // Set up the buffer pointers 571 y_ptr = post->y_buffer + (post->y_height >> 5) * 16 * post->y_stride; 572 573 // vp8_filter each macro block 574 for (mb_row = 0; mb_row<(linestocopy >> 4); mb_row++) 575 { 576 for (mb_col = 0; mb_col < mb_cols; mb_col++) 577 { 578 int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0; 579 filter_level = baseline_filter_level[Segment]; 580 581 if (filter_level) 582 { 583 if (mb_col > 0) 584 cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0); 585 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); 588 589 cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0); 590 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); 593 } 594 595 y_ptr += 16; 596 mbd->mode_info_context += 1; // step to next MB 597 } 598 599 y_ptr += post->y_stride * 16 - post->y_width; 600 mbd->mode_info_context += 1; // Skip border mb 601 } 602 } 603