Mercurial > libavcodec.hg
comparison vp8.c @ 12217:f6b229456bdf libavcodec
Much faster VP8 mv and mode prediction
author | darkshikari |
---|---|
date | Thu, 22 Jul 2010 04:26:41 +0000 |
parents | 58d828f9810f |
children | 1696e915ae2e |
comparison
equal
deleted
inserted
replaced
12216:160eceee6c3d | 12217:f6b229456bdf |
---|---|
518 dst->y = av_clip(src->y, -((mb_y << 6) + MARGIN), | 518 dst->y = av_clip(src->y, -((mb_y << 6) + MARGIN), |
519 ((s->mb_height - 1 - mb_y) << 6) + MARGIN); | 519 ((s->mb_height - 1 - mb_y) << 6) + MARGIN); |
520 } | 520 } |
521 | 521 |
522 static void find_near_mvs(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, | 522 static void find_near_mvs(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, |
523 VP56mv near[2], VP56mv *best, int cnt[4]) | 523 VP56mv near[2], VP56mv *best, uint8_t cnt[4]) |
524 { | 524 { |
525 VP8Macroblock *mb_edge[3] = { mb - s->mb_stride /* top */, | 525 int mb_stride = s->mb_stride; |
526 mb - 1 /* left */, | 526 VP8Macroblock *mb_edge[3] = { mb - mb_stride /* top */, |
527 mb - s->mb_stride - 1 /* top-left */ }; | 527 mb - 1 /* left */, |
528 mb - mb_stride - 1 /* top-left */ }; | |
528 enum { EDGE_TOP, EDGE_LEFT, EDGE_TOPLEFT }; | 529 enum { EDGE_TOP, EDGE_LEFT, EDGE_TOPLEFT }; |
529 VP56mv near_mv[4] = {{ 0 }}; | 530 VP56mv near_mv[4] = {{ 0 }}; |
530 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV }; | 531 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV }; |
531 int idx = CNT_ZERO, n; | 532 int idx = CNT_ZERO; |
532 int best_idx = CNT_ZERO; | 533 int best_idx = CNT_ZERO; |
534 int cur_sign_bias = s->sign_bias[mb->ref_frame]; | |
535 int *sign_bias = s->sign_bias; | |
533 | 536 |
534 /* Process MB on top, left and top-left */ | 537 /* Process MB on top, left and top-left */ |
535 for (n = 0; n < 3; n++) { | 538 #define MV_EDGE_CHECK(n)\ |
536 VP8Macroblock *edge = mb_edge[n]; | 539 {\ |
537 if (edge->ref_frame != VP56_FRAME_CURRENT) { | 540 VP8Macroblock *edge = mb_edge[n];\ |
538 if (edge->mv.x | edge->mv.y) { | 541 int edge_ref = edge->ref_frame;\ |
539 VP56mv tmp = edge->mv; | 542 if (edge_ref != VP56_FRAME_CURRENT) {\ |
540 if (s->sign_bias[mb->ref_frame] != s->sign_bias[edge->ref_frame]) { | 543 uint32_t mv = AV_RN32A(&edge->mv);\ |
541 tmp.x *= -1; | 544 if (mv) {\ |
542 tmp.y *= -1; | 545 if (cur_sign_bias != sign_bias[edge_ref]) {\ |
543 } | 546 /* SWAR negate of the values in mv. */\ |
544 if ((tmp.x ^ near_mv[idx].x) | (tmp.y ^ near_mv[idx].y)) | 547 mv = ((mv&0x80008000) + 0x00010001) ^ (mv&0x7fff7fff);\ |
545 near_mv[++idx] = tmp; | 548 }\ |
546 cnt[idx] += 1 + (n != 2); | 549 if (!n || mv != AV_RN32A(&near_mv[idx]))\ |
547 } else | 550 AV_WN32A(&near_mv[++idx], mv);\ |
548 cnt[CNT_ZERO] += 1 + (n != 2); | 551 cnt[idx] += 1 + (n != 2);\ |
549 } | 552 } else\ |
550 } | 553 cnt[CNT_ZERO] += 1 + (n != 2);\ |
551 | 554 }\ |
552 /* If we have three distinct MV's, merge first and last if they're the same */ | 555 } |
553 if (cnt[CNT_SPLITMV] && | 556 MV_EDGE_CHECK(0) |
554 !((near_mv[1+EDGE_TOP].x ^ near_mv[1+EDGE_TOPLEFT].x) | | 557 MV_EDGE_CHECK(1) |
555 (near_mv[1+EDGE_TOP].y ^ near_mv[1+EDGE_TOPLEFT].y))) | 558 MV_EDGE_CHECK(2) |
559 | |
560 /* If we have three distinct MVs, merge first and last if they're the same */ | |
561 if (cnt[CNT_SPLITMV] && AV_RN32A(&near_mv[1+EDGE_TOP]) == AV_RN32A(&near_mv[1+EDGE_TOPLEFT])) | |
556 cnt[CNT_NEAREST] += 1; | 562 cnt[CNT_NEAREST] += 1; |
557 | 563 |
558 cnt[CNT_SPLITMV] = ((mb_edge[EDGE_LEFT]->mode == VP8_MVMODE_SPLIT) + | 564 cnt[CNT_SPLITMV] = ((mb_edge[EDGE_LEFT]->mode == VP8_MVMODE_SPLIT) + |
559 (mb_edge[EDGE_TOP]->mode == VP8_MVMODE_SPLIT)) * 2 + | 565 (mb_edge[EDGE_TOP]->mode == VP8_MVMODE_SPLIT)) * 2 + |
560 (mb_edge[EDGE_TOPLEFT]->mode == VP8_MVMODE_SPLIT); | 566 (mb_edge[EDGE_TOPLEFT]->mode == VP8_MVMODE_SPLIT); |
561 | 567 |
562 /* Swap near and nearest if necessary */ | 568 /* Swap near and nearest if necessary */ |
563 if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) { | 569 if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) { |
564 FFSWAP(int, cnt[CNT_NEAREST], cnt[CNT_NEAR]); | 570 FFSWAP(uint8_t, cnt[CNT_NEAREST], cnt[CNT_NEAR]); |
565 FFSWAP(VP56mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR]); | 571 FFSWAP( VP56mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR]); |
566 } | 572 } |
567 | 573 |
568 /* Choose the best mv out of 0,0 and the nearest mv */ | 574 /* Choose the best mv out of 0,0 and the nearest mv */ |
569 if (cnt[CNT_NEAREST] >= cnt[CNT_ZERO]) | 575 if (cnt[CNT_NEAREST] >= cnt[CNT_ZERO]) |
570 best_idx = CNT_NEAREST; | 576 best_idx = CNT_NEAREST; |
682 | 688 |
683 static void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, | 689 static void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, |
684 uint8_t *intra4x4) | 690 uint8_t *intra4x4) |
685 { | 691 { |
686 VP56RangeCoder *c = &s->c; | 692 VP56RangeCoder *c = &s->c; |
687 int n; | |
688 | 693 |
689 if (s->segmentation.update_map) | 694 if (s->segmentation.update_map) |
690 mb->segment = vp8_rac_get_tree(c, vp8_segmentid_tree, s->prob->segmentid); | 695 mb->segment = vp8_rac_get_tree(c, vp8_segmentid_tree, s->prob->segmentid); |
691 | 696 |
692 mb->skip = s->mbskip_enabled ? vp56_rac_get_prob(c, s->prob->mbskip) : 0; | 697 mb->skip = s->mbskip_enabled ? vp56_rac_get_prob(c, s->prob->mbskip) : 0; |
701 | 706 |
702 s->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree, vp8_pred8x8c_prob_intra); | 707 s->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree, vp8_pred8x8c_prob_intra); |
703 mb->ref_frame = VP56_FRAME_CURRENT; | 708 mb->ref_frame = VP56_FRAME_CURRENT; |
704 } else if (vp56_rac_get_prob(c, s->prob->intra)) { | 709 } else if (vp56_rac_get_prob(c, s->prob->intra)) { |
705 VP56mv near[2], best; | 710 VP56mv near[2], best; |
706 int cnt[4] = { 0 }; | 711 uint8_t cnt[4] = { 0 }; |
707 uint8_t p[4]; | 712 uint8_t p[4]; |
708 | 713 |
709 // inter MB, 16.2 | 714 // inter MB, 16.2 |
710 if (vp56_rac_get_prob(c, s->prob->last)) | 715 if (vp56_rac_get_prob(c, s->prob->last)) |
711 mb->ref_frame = vp56_rac_get_prob(c, s->prob->golden) ? | 716 mb->ref_frame = vp56_rac_get_prob(c, s->prob->golden) ? |
713 else | 718 else |
714 mb->ref_frame = VP56_FRAME_PREVIOUS; | 719 mb->ref_frame = VP56_FRAME_PREVIOUS; |
715 | 720 |
716 // motion vectors, 16.3 | 721 // motion vectors, 16.3 |
717 find_near_mvs(s, mb, mb_x, mb_y, near, &best, cnt); | 722 find_near_mvs(s, mb, mb_x, mb_y, near, &best, cnt); |
718 for (n = 0; n < 4; n++) | 723 p[0] = vp8_mode_contexts[cnt[0]][0]; |
719 p[n] = vp8_mode_contexts[cnt[n]][n]; | 724 p[1] = vp8_mode_contexts[cnt[1]][1]; |
725 p[2] = vp8_mode_contexts[cnt[2]][2]; | |
726 p[3] = vp8_mode_contexts[cnt[3]][3]; | |
720 mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_mvinter, p); | 727 mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_mvinter, p); |
721 switch (mb->mode) { | 728 switch (mb->mode) { |
722 case VP8_MVMODE_SPLIT: | 729 case VP8_MVMODE_SPLIT: |
723 mb->mv = mb->bmv[decode_splitmvs(s, c, mb, &best) - 1]; | 730 mb->mv = mb->bmv[decode_splitmvs(s, c, mb, &best) - 1]; |
724 break; | 731 break; |