| 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 : read_segment_id(r, seg); | 170 : read_segment_id(r, seg); |
| 171 } else { | 171 } else { |
| 172 segment_id = read_segment_id(r, seg); | 172 segment_id = read_segment_id(r, seg); |
| 173 } | 173 } |
| 174 set_segment_id(cm, bsize, mi_row, mi_col, segment_id); | 174 set_segment_id(cm, bsize, mi_row, mi_col, segment_id); |
| 175 return segment_id; | 175 return segment_id; |
| 176 } | 176 } |
| 177 | 177 |
| 178 static int read_skip(VP9_COMMON *cm, const MACROBLOCKD *xd, | 178 static int read_skip(VP9_COMMON *cm, const MACROBLOCKD *xd, |
| 179 int segment_id, vp9_reader *r) { | 179 int segment_id, vp9_reader *r) { |
| 180 if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) { | 180 if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) { |
| 181 return 1; | 181 return 1; |
| 182 } else { | 182 } else { |
| 183 const int ctx = vp9_get_skip_context(xd); | 183 const int ctx = vp9_get_skip_context(xd); |
| 184 const int skip = vp9_read(r, cm->fc->skip_probs[ctx]); | 184 const int skip = vp9_read(r, cm->fc->skip_probs[ctx]); |
| 185 FRAME_COUNTS *counts = xd->counts; | 185 FRAME_COUNTS *counts = xd->counts; |
| 186 if (counts) | 186 if (counts) |
| 187 ++counts->skip[ctx][skip]; | 187 ++counts->skip[ctx][skip]; |
| 188 return skip; | 188 return skip; |
| 189 } | 189 } |
| 190 } | 190 } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 } | 300 } |
| 301 } | 301 } |
| 302 | 302 |
| 303 // Read the referncence frame | 303 // Read the referncence frame |
| 304 static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd, | 304 static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd, |
| 305 vp9_reader *r, | 305 vp9_reader *r, |
| 306 int segment_id, MV_REFERENCE_FRAME ref_frame[2]) { | 306 int segment_id, MV_REFERENCE_FRAME ref_frame[2]) { |
| 307 FRAME_CONTEXT *const fc = cm->fc; | 307 FRAME_CONTEXT *const fc = cm->fc; |
| 308 FRAME_COUNTS *counts = xd->counts; | 308 FRAME_COUNTS *counts = xd->counts; |
| 309 | 309 |
| 310 if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { | 310 if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { |
| 311 ref_frame[0] = (MV_REFERENCE_FRAME)vp9_get_segdata(&cm->seg, segment_id, | 311 ref_frame[0] = (MV_REFERENCE_FRAME)get_segdata(&cm->seg, segment_id, |
| 312 SEG_LVL_REF_FRAME); | 312 SEG_LVL_REF_FRAME); |
| 313 ref_frame[1] = NONE; | 313 ref_frame[1] = NONE; |
| 314 } else { | 314 } else { |
| 315 const REFERENCE_MODE mode = read_block_reference_mode(cm, xd, r); | 315 const REFERENCE_MODE mode = read_block_reference_mode(cm, xd, r); |
| 316 // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding | 316 // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding |
| 317 if (mode == COMPOUND_REFERENCE) { | 317 if (mode == COMPOUND_REFERENCE) { |
| 318 const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref]; | 318 const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref]; |
| 319 const int ctx = vp9_get_pred_context_comp_ref_p(cm, xd); | 319 const int ctx = vp9_get_pred_context_comp_ref_p(cm, xd); |
| 320 const int bit = vp9_read(r, fc->comp_ref_prob[ctx]); | 320 const int bit = vp9_read(r, fc->comp_ref_prob[ctx]); |
| 321 if (counts) | 321 if (counts) |
| 322 ++counts->comp_ref[ctx][bit]; | 322 ++counts->comp_ref[ctx][bit]; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 } | 437 } |
| 438 default: { | 438 default: { |
| 439 return 0; | 439 return 0; |
| 440 } | 440 } |
| 441 } | 441 } |
| 442 return ret; | 442 return ret; |
| 443 } | 443 } |
| 444 | 444 |
| 445 static int read_is_inter_block(VP9_COMMON *const cm, MACROBLOCKD *const xd, | 445 static int read_is_inter_block(VP9_COMMON *const cm, MACROBLOCKD *const xd, |
| 446 int segment_id, vp9_reader *r) { | 446 int segment_id, vp9_reader *r) { |
| 447 if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { | 447 if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { |
| 448 return vp9_get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME) != | 448 return get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME) != INTRA_FRAME; |
| 449 INTRA_FRAME; | |
| 450 } else { | 449 } else { |
| 451 const int ctx = vp9_get_intra_inter_context(xd); | 450 const int ctx = vp9_get_intra_inter_context(xd); |
| 452 const int is_inter = vp9_read(r, cm->fc->intra_inter_prob[ctx]); | 451 const int is_inter = vp9_read(r, cm->fc->intra_inter_prob[ctx]); |
| 453 FRAME_COUNTS *counts = xd->counts; | 452 FRAME_COUNTS *counts = xd->counts; |
| 454 if (counts) | 453 if (counts) |
| 455 ++counts->intra_inter[ctx][is_inter]; | 454 ++counts->intra_inter[ctx][is_inter]; |
| 456 return is_inter; | 455 return is_inter; |
| 457 } | 456 } |
| 458 } | 457 } |
| 459 | 458 |
| 460 static void fpm_sync(void *const data, int mi_row) { | 459 static void fpm_sync(void *const data, int mi_row) { |
| 461 VP9Decoder *const pbi = (VP9Decoder *)data; | 460 VP9Decoder *const pbi = (VP9Decoder *)data; |
| 462 vp9_frameworker_wait(pbi->frame_worker_owner, pbi->common.prev_frame, | 461 vp9_frameworker_wait(pbi->frame_worker_owner, pbi->common.prev_frame, |
| 463 mi_row << MI_BLOCK_SIZE_LOG2); | 462 mi_row << MI_BLOCK_SIZE_LOG2); |
| 464 } | 463 } |
| 465 | 464 |
| 466 static void read_inter_block_mode_info(VP9Decoder *const pbi, | 465 static void read_inter_block_mode_info(VP9Decoder *const pbi, |
| 467 MACROBLOCKD *const xd, | 466 MACROBLOCKD *const xd, |
| 468 const TileInfo *const tile, | 467 const TileInfo *const tile, |
| 469 MODE_INFO *const mi, | 468 MODE_INFO *const mi, |
| 470 int mi_row, int mi_col, vp9_reader *r) { | 469 int mi_row, int mi_col, vp9_reader *r) { |
| 471 VP9_COMMON *const cm = &pbi->common; | 470 VP9_COMMON *const cm = &pbi->common; |
| 472 MB_MODE_INFO *const mbmi = &mi->mbmi; | 471 MB_MODE_INFO *const mbmi = &mi->mbmi; |
| 473 const BLOCK_SIZE bsize = mbmi->sb_type; | 472 const BLOCK_SIZE bsize = mbmi->sb_type; |
| 474 const int allow_hp = cm->allow_high_precision_mv; | 473 const int allow_hp = cm->allow_high_precision_mv; |
| 475 int_mv nearestmv[2], nearmv[2]; | 474 int_mv nearestmv[2], nearmv[2]; |
| 476 int inter_mode_ctx, ref, is_compound; | 475 int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES]; |
| 476 int ref, is_compound; |
| 477 uint8_t inter_mode_ctx[MAX_REF_FRAMES]; |
| 477 | 478 |
| 478 read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame); | 479 read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame); |
| 479 is_compound = has_second_ref(mbmi); | 480 is_compound = has_second_ref(mbmi); |
| 480 | 481 |
| 481 for (ref = 0; ref < 1 + is_compound; ++ref) { | 482 for (ref = 0; ref < 1 + is_compound; ++ref) { |
| 482 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref]; | 483 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref]; |
| 483 RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME]; | 484 RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME]; |
| 484 xd->block_refs[ref] = ref_buf; | 485 xd->block_refs[ref] = ref_buf; |
| 485 if ((!vp9_is_valid_scale(&ref_buf->sf))) | 486 if ((!vp9_is_valid_scale(&ref_buf->sf))) |
| 486 vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM, | 487 vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM, |
| 487 "Reference frame has invalid dimensions"); | 488 "Reference frame has invalid dimensions"); |
| 488 vp9_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col, | 489 vp9_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col, |
| 489 &ref_buf->sf); | 490 &ref_buf->sf); |
| 490 vp9_find_mv_refs(cm, xd, tile, mi, frame, mbmi->ref_mvs[frame], | 491 vp9_find_mv_refs(cm, xd, tile, mi, frame, ref_mvs[frame], |
| 491 mi_row, mi_col, fpm_sync, (void *)pbi); | 492 mi_row, mi_col, fpm_sync, (void *)pbi, inter_mode_ctx); |
| 492 } | 493 } |
| 493 | 494 |
| 494 inter_mode_ctx = mbmi->mode_context[mbmi->ref_frame[0]]; | 495 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) { |
| 495 | |
| 496 if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) { | |
| 497 mbmi->mode = ZEROMV; | 496 mbmi->mode = ZEROMV; |
| 498 if (bsize < BLOCK_8X8) { | 497 if (bsize < BLOCK_8X8) { |
| 499 vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM, | 498 vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM, |
| 500 "Invalid usage of segement feature on small blocks"); | 499 "Invalid usage of segement feature on small blocks"); |
| 501 return; | 500 return; |
| 502 } | 501 } |
| 503 } else { | 502 } else { |
| 504 if (bsize >= BLOCK_8X8) | 503 if (bsize >= BLOCK_8X8) |
| 505 mbmi->mode = read_inter_mode(cm, xd, r, inter_mode_ctx); | 504 mbmi->mode = read_inter_mode(cm, xd, r, |
| 505 inter_mode_ctx[mbmi->ref_frame[0]]); |
| 506 } | 506 } |
| 507 | 507 |
| 508 if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) { | 508 if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) { |
| 509 for (ref = 0; ref < 1 + is_compound; ++ref) { | 509 for (ref = 0; ref < 1 + is_compound; ++ref) { |
| 510 vp9_find_best_ref_mvs(xd, allow_hp, mbmi->ref_mvs[mbmi->ref_frame[ref]], | 510 vp9_find_best_ref_mvs(xd, allow_hp, ref_mvs[mbmi->ref_frame[ref]], |
| 511 &nearestmv[ref], &nearmv[ref]); | 511 &nearestmv[ref], &nearmv[ref]); |
| 512 } | 512 } |
| 513 } | 513 } |
| 514 | 514 |
| 515 mbmi->interp_filter = (cm->interp_filter == SWITCHABLE) | 515 mbmi->interp_filter = (cm->interp_filter == SWITCHABLE) |
| 516 ? read_switchable_interp_filter(cm, xd, r) | 516 ? read_switchable_interp_filter(cm, xd, r) |
| 517 : cm->interp_filter; | 517 : cm->interp_filter; |
| 518 | 518 |
| 519 if (bsize < BLOCK_8X8) { | 519 if (bsize < BLOCK_8X8) { |
| 520 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; // 1 or 2 | 520 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; // 1 or 2 |
| 521 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; // 1 or 2 | 521 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; // 1 or 2 |
| 522 int idx, idy; | 522 int idx, idy; |
| 523 PREDICTION_MODE b_mode; | 523 PREDICTION_MODE b_mode; |
| 524 int_mv nearest_sub8x8[2], near_sub8x8[2]; | 524 int_mv nearest_sub8x8[2], near_sub8x8[2]; |
| 525 for (idy = 0; idy < 2; idy += num_4x4_h) { | 525 for (idy = 0; idy < 2; idy += num_4x4_h) { |
| 526 for (idx = 0; idx < 2; idx += num_4x4_w) { | 526 for (idx = 0; idx < 2; idx += num_4x4_w) { |
| 527 int_mv block[2]; | 527 int_mv block[2]; |
| 528 const int j = idy * 2 + idx; | 528 const int j = idy * 2 + idx; |
| 529 b_mode = read_inter_mode(cm, xd, r, inter_mode_ctx); | 529 b_mode = read_inter_mode(cm, xd, r, inter_mode_ctx[mbmi->ref_frame[0]]); |
| 530 | 530 |
| 531 if (b_mode == NEARESTMV || b_mode == NEARMV) | 531 if (b_mode == NEARESTMV || b_mode == NEARMV) { |
| 532 uint8_t dummy_mode_ctx[MAX_REF_FRAMES]; |
| 532 for (ref = 0; ref < 1 + is_compound; ++ref) | 533 for (ref = 0; ref < 1 + is_compound; ++ref) |
| 533 vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, j, ref, mi_row, mi_col, | 534 vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, j, ref, mi_row, mi_col, |
| 534 &nearest_sub8x8[ref], | 535 &nearest_sub8x8[ref], |
| 535 &near_sub8x8[ref]); | 536 &near_sub8x8[ref], |
| 537 dummy_mode_ctx); |
| 538 } |
| 536 | 539 |
| 537 if (!assign_mv(cm, xd, b_mode, block, nearestmv, | 540 if (!assign_mv(cm, xd, b_mode, block, nearestmv, |
| 538 nearest_sub8x8, near_sub8x8, | 541 nearest_sub8x8, near_sub8x8, |
| 539 is_compound, allow_hp, r)) { | 542 is_compound, allow_hp, r)) { |
| 540 xd->corrupted |= 1; | 543 xd->corrupted |= 1; |
| 541 break; | 544 break; |
| 542 }; | 545 }; |
| 543 | 546 |
| 544 mi->bmi[j].as_mv[0].as_int = block[0].as_int; | 547 mi->bmi[j].as_mv[0].as_int = block[0].as_int; |
| 545 if (is_compound) | 548 if (is_compound) |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 int mi_row, int mi_col, vp9_reader *r) { | 592 int mi_row, int mi_col, vp9_reader *r) { |
| 590 VP9_COMMON *const cm = &pbi->common; | 593 VP9_COMMON *const cm = &pbi->common; |
| 591 MODE_INFO *const mi = xd->mi[0]; | 594 MODE_INFO *const mi = xd->mi[0]; |
| 592 const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type]; | 595 const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type]; |
| 593 const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type]; | 596 const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type]; |
| 594 const int x_mis = MIN(bw, cm->mi_cols - mi_col); | 597 const int x_mis = MIN(bw, cm->mi_cols - mi_col); |
| 595 const int y_mis = MIN(bh, cm->mi_rows - mi_row); | 598 const int y_mis = MIN(bh, cm->mi_rows - mi_row); |
| 596 MV_REF* frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col; | 599 MV_REF* frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col; |
| 597 int w, h; | 600 int w, h; |
| 598 | 601 |
| 599 if (frame_is_intra_only(cm)) | 602 if (frame_is_intra_only(cm)) { |
| 600 read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r); | 603 read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r); |
| 601 else | 604 } else { |
| 602 read_inter_frame_mode_info(pbi, xd, tile, mi_row, mi_col, r); | 605 read_inter_frame_mode_info(pbi, xd, tile, mi_row, mi_col, r); |
| 603 | 606 |
| 604 for (h = 0; h < y_mis; ++h) { | 607 for (h = 0; h < y_mis; ++h) { |
| 605 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols; | 608 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols; |
| 606 for (w = 0; w < x_mis; ++w) { | 609 for (w = 0; w < x_mis; ++w) { |
| 607 MV_REF *const mv = frame_mv + w; | 610 MV_REF *const mv = frame_mv + w; |
| 608 mv->ref_frame[0] = mi->mbmi.ref_frame[0]; | 611 mv->ref_frame[0] = mi->mbmi.ref_frame[0]; |
| 609 mv->ref_frame[1] = mi->mbmi.ref_frame[1]; | 612 mv->ref_frame[1] = mi->mbmi.ref_frame[1]; |
| 610 mv->mv[0].as_int = mi->mbmi.mv[0].as_int; | 613 mv->mv[0].as_int = mi->mbmi.mv[0].as_int; |
| 611 mv->mv[1].as_int = mi->mbmi.mv[1].as_int; | 614 mv->mv[1].as_int = mi->mbmi.mv[1].as_int; |
| 615 } |
| 612 } | 616 } |
| 613 } | 617 } |
| 614 } | 618 } |
| OLD | NEW |