summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/command_classes/codecs/vp9.cpp77
-rw-r--r--src/video_core/command_classes/codecs/vp9.h2
2 files changed, 31 insertions, 48 deletions
diff --git a/src/video_core/command_classes/codecs/vp9.cpp b/src/video_core/command_classes/codecs/vp9.cpp
index 902bc2a98..b3e3462d6 100644
--- a/src/video_core/command_classes/codecs/vp9.cpp
+++ b/src/video_core/command_classes/codecs/vp9.cpp
@@ -613,7 +613,7 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() {
613 613
614 // Reset context 614 // Reset context
615 prev_frame_probs = default_probs; 615 prev_frame_probs = default_probs;
616 swap_next_golden = false; 616 swap_ref_indices = false;
617 loop_filter_ref_deltas.fill(0); 617 loop_filter_ref_deltas.fill(0);
618 loop_filter_mode_deltas.fill(0); 618 loop_filter_mode_deltas.fill(0);
619 619
@@ -626,73 +626,57 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() {
626 626
627 // intra only, meaning the frame can be recreated with no other references 627 // intra only, meaning the frame can be recreated with no other references
628 current_frame_info.intra_only = true; 628 current_frame_info.intra_only = true;
629
630 } else { 629 } else {
631
632 if (!current_frame_info.show_frame) { 630 if (!current_frame_info.show_frame) {
633 uncomp_writer.WriteBit(current_frame_info.intra_only); 631 uncomp_writer.WriteBit(current_frame_info.intra_only);
634 if (!current_frame_info.last_frame_was_key) {
635 swap_next_golden = !swap_next_golden;
636 }
637 } else { 632 } else {
638 current_frame_info.intra_only = false; 633 current_frame_info.intra_only = false;
639 } 634 }
640 if (!current_frame_info.error_resilient_mode) { 635 if (!current_frame_info.error_resilient_mode) {
641 uncomp_writer.WriteU(0, 2); // Reset frame context. 636 uncomp_writer.WriteU(0, 2); // Reset frame context.
642 } 637 }
643 638 const auto& curr_offsets = current_frame_info.frame_offsets;
644 // Last, Golden, Altref frames 639 const auto& next_offsets = next_frame.info.frame_offsets;
645 std::array<s32, 3> ref_frame_index{0, 1, 2}; 640 const bool ref_frames_different = curr_offsets[1] != curr_offsets[2];
646 641 const bool next_references_swap =
647 // Set when next frame is hidden 642 (next_offsets[1] == curr_offsets[2]) || (next_offsets[2] == curr_offsets[1]);
648 // altref and golden references are swapped 643 const bool needs_ref_swap = ref_frames_different && next_references_swap;
649 if (swap_next_golden) { 644 if (needs_ref_swap) {
650 ref_frame_index = std::array<s32, 3>{0, 2, 1}; 645 swap_ref_indices = !swap_ref_indices;
651 } 646 }
652 647 union {
653 // update Last Frame 648 u32 raw;
654 u64 refresh_frame_flags = 1; 649 BitField<0, 1, u32> refresh_last;
655 650 BitField<1, 2, u32> refresh_golden;
656 // golden frame may refresh, determined if the next golden frame offset is changed 651 BitField<2, 1, u32> refresh_alt;
657 bool golden_refresh = false; 652 } refresh_frame_flags;
658 if (grace_period <= 0) { 653
659 for (s32 index = 1; index < 3; ++index) { 654 refresh_frame_flags.raw = 0;
660 if (current_frame_info.frame_offsets[index] != 655 for (u32 index = 0; index < 3; ++index) {
661 next_frame.info.frame_offsets[index]) { 656 // Refresh indices that use the current frame as an index
662 current_frame_info.refresh_frame[index] = true; 657 if (curr_offsets[3] == next_offsets[index]) {
663 golden_refresh = true; 658 refresh_frame_flags.raw |= 1u << index;
664 grace_period = 3;
665 }
666 } 659 }
667 } 660 }
668 661 if (swap_ref_indices) {
669 if (current_frame_info.show_frame && 662 const u32 temp = refresh_frame_flags.refresh_golden;
670 (!next_frame.info.show_frame || next_frame.info.is_key_frame)) { 663 refresh_frame_flags.refresh_golden.Assign(refresh_frame_flags.refresh_alt.Value());
671 // Update golden frame 664 refresh_frame_flags.refresh_alt.Assign(temp);
672 refresh_frame_flags = swap_next_golden ? 2 : 4;
673 } 665 }
674
675 if (!current_frame_info.show_frame) {
676 // Update altref
677 refresh_frame_flags = swap_next_golden ? 2 : 4;
678 } else if (golden_refresh) {
679 refresh_frame_flags = 3;
680 }
681
682 if (current_frame_info.intra_only) { 666 if (current_frame_info.intra_only) {
683 uncomp_writer.WriteU(frame_sync_code, 24); 667 uncomp_writer.WriteU(frame_sync_code, 24);
684 uncomp_writer.WriteU(static_cast<s32>(refresh_frame_flags), 8); 668 uncomp_writer.WriteU(refresh_frame_flags.raw, 8);
685 uncomp_writer.WriteU(current_frame_info.frame_size.width - 1, 16); 669 uncomp_writer.WriteU(current_frame_info.frame_size.width - 1, 16);
686 uncomp_writer.WriteU(current_frame_info.frame_size.height - 1, 16); 670 uncomp_writer.WriteU(current_frame_info.frame_size.height - 1, 16);
687 uncomp_writer.WriteBit(false); // Render and frame size different. 671 uncomp_writer.WriteBit(false); // Render and frame size different.
688 } else { 672 } else {
689 uncomp_writer.WriteU(static_cast<s32>(refresh_frame_flags), 8); 673 const bool swap_indices = needs_ref_swap ^ swap_ref_indices;
690 674 const auto ref_frame_index = swap_indices ? std::array{0, 2, 1} : std::array{0, 1, 2};
691 for (s32 index = 1; index < 4; index++) { 675 uncomp_writer.WriteU(refresh_frame_flags.raw, 8);
676 for (size_t index = 1; index < 4; index++) {
692 uncomp_writer.WriteU(ref_frame_index[index - 1], 3); 677 uncomp_writer.WriteU(ref_frame_index[index - 1], 3);
693 uncomp_writer.WriteU(current_frame_info.ref_frame_sign_bias[index], 1); 678 uncomp_writer.WriteU(current_frame_info.ref_frame_sign_bias[index], 1);
694 } 679 }
695
696 uncomp_writer.WriteBit(true); // Frame size with refs. 680 uncomp_writer.WriteBit(true); // Frame size with refs.
697 uncomp_writer.WriteBit(false); // Render and frame size different. 681 uncomp_writer.WriteBit(false); // Render and frame size different.
698 uncomp_writer.WriteBit(current_frame_info.allow_high_precision_mv); 682 uncomp_writer.WriteBit(current_frame_info.allow_high_precision_mv);
@@ -812,7 +796,6 @@ const std::vector<u8>& VP9::ComposeFrameHeader(const NvdecCommon::NvdecRegisters
812 current_frame_info = curr_frame.info; 796 current_frame_info = curr_frame.info;
813 bitstream = std::move(curr_frame.bit_stream); 797 bitstream = std::move(curr_frame.bit_stream);
814 } 798 }
815
816 // The uncompressed header routine sets PrevProb parameters needed for the compressed header 799 // The uncompressed header routine sets PrevProb parameters needed for the compressed header
817 auto uncomp_writer = ComposeUncompressedHeader(); 800 auto uncomp_writer = ComposeUncompressedHeader();
818 std::vector<u8> compressed_header = ComposeCompressedHeader(); 801 std::vector<u8> compressed_header = ComposeCompressedHeader();
diff --git a/src/video_core/command_classes/codecs/vp9.h b/src/video_core/command_classes/codecs/vp9.h
index 8396c8105..bb4d0d972 100644
--- a/src/video_core/command_classes/codecs/vp9.h
+++ b/src/video_core/command_classes/codecs/vp9.h
@@ -184,7 +184,7 @@ private:
184 std::array<FrameContexts, 4> frame_ctxs{}; 184 std::array<FrameContexts, 4> frame_ctxs{};
185 Vp9FrameContainer next_frame{}; 185 Vp9FrameContainer next_frame{};
186 Vp9FrameContainer next_next_frame{}; 186 Vp9FrameContainer next_next_frame{};
187 bool swap_next_golden{}; 187 bool swap_ref_indices{};
188 188
189 Vp9PictureInfo current_frame_info{}; 189 Vp9PictureInfo current_frame_info{};
190 Vp9EntropyProbs prev_frame_probs{}; 190 Vp9EntropyProbs prev_frame_probs{};