diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/command_classes/codecs/vp9.cpp | 57 | ||||
| -rw-r--r-- | src/video_core/command_classes/codecs/vp9.h | 12 | ||||
| -rw-r--r-- | src/video_core/command_classes/codecs/vp9_types.h | 6 |
3 files changed, 17 insertions, 58 deletions
diff --git a/src/video_core/command_classes/codecs/vp9.cpp b/src/video_core/command_classes/codecs/vp9.cpp index b3e3462d6..7eecb3991 100644 --- a/src/video_core/command_classes/codecs/vp9.cpp +++ b/src/video_core/command_classes/codecs/vp9.cpp | |||
| @@ -11,6 +11,9 @@ | |||
| 11 | 11 | ||
| 12 | namespace Tegra::Decoder { | 12 | namespace Tegra::Decoder { |
| 13 | namespace { | 13 | namespace { |
| 14 | constexpr u32 diff_update_probability = 252; | ||
| 15 | constexpr u32 frame_sync_code = 0x498342; | ||
| 16 | |||
| 14 | // Default compressed header probabilities once frame context resets | 17 | // Default compressed header probabilities once frame context resets |
| 15 | constexpr Vp9EntropyProbs default_probs{ | 18 | constexpr Vp9EntropyProbs default_probs{ |
| 16 | .y_mode_prob{ | 19 | .y_mode_prob{ |
| @@ -361,8 +364,7 @@ Vp9PictureInfo VP9::GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state) | |||
| 361 | InsertEntropy(state.vp9_entropy_probs_offset, vp9_info.entropy); | 364 | InsertEntropy(state.vp9_entropy_probs_offset, vp9_info.entropy); |
| 362 | 365 | ||
| 363 | // surface_luma_offset[0:3] contains the address of the reference frame offsets in the following | 366 | // surface_luma_offset[0:3] contains the address of the reference frame offsets in the following |
| 364 | // order: last, golden, altref, current. It may be worthwhile to track the updates done here | 367 | // order: last, golden, altref, current. |
| 365 | // to avoid buffering frame data needed for reference frame updating in the header composition. | ||
| 366 | std::copy(state.surface_luma_offset.begin(), state.surface_luma_offset.begin() + 4, | 368 | std::copy(state.surface_luma_offset.begin(), state.surface_luma_offset.begin() + 4, |
| 367 | vp9_info.frame_offsets.begin()); | 369 | vp9_info.frame_offsets.begin()); |
| 368 | 370 | ||
| @@ -384,33 +386,18 @@ Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state) | |||
| 384 | gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset, current_frame.bit_stream.data(), | 386 | gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset, current_frame.bit_stream.data(), |
| 385 | current_frame.info.bitstream_size); | 387 | current_frame.info.bitstream_size); |
| 386 | } | 388 | } |
| 387 | // Buffer two frames, saving the last show frame info | 389 | if (!next_frame.bit_stream.empty()) { |
| 388 | if (!next_next_frame.bit_stream.empty()) { | ||
| 389 | Vp9FrameContainer temp{ | 390 | Vp9FrameContainer temp{ |
| 390 | .info = current_frame.info, | 391 | .info = current_frame.info, |
| 391 | .bit_stream = std::move(current_frame.bit_stream), | 392 | .bit_stream = std::move(current_frame.bit_stream), |
| 392 | }; | 393 | }; |
| 393 | next_next_frame.info.show_frame = current_frame.info.last_frame_shown; | 394 | next_frame.info.show_frame = current_frame.info.last_frame_shown; |
| 394 | current_frame.info = next_next_frame.info; | 395 | current_frame.info = next_frame.info; |
| 395 | current_frame.bit_stream = std::move(next_next_frame.bit_stream); | 396 | current_frame.bit_stream = std::move(next_frame.bit_stream); |
| 396 | next_next_frame = std::move(temp); | 397 | next_frame = std::move(temp); |
| 397 | |||
| 398 | if (!next_frame.bit_stream.empty()) { | ||
| 399 | Vp9FrameContainer temp2{ | ||
| 400 | .info = current_frame.info, | ||
| 401 | .bit_stream = std::move(current_frame.bit_stream), | ||
| 402 | }; | ||
| 403 | next_frame.info.show_frame = current_frame.info.last_frame_shown; | ||
| 404 | current_frame.info = next_frame.info; | ||
| 405 | current_frame.bit_stream = std::move(next_frame.bit_stream); | ||
| 406 | next_frame = std::move(temp2); | ||
| 407 | } else { | ||
| 408 | next_frame.info = current_frame.info; | ||
| 409 | next_frame.bit_stream = std::move(current_frame.bit_stream); | ||
| 410 | } | ||
| 411 | } else { | 398 | } else { |
| 412 | next_next_frame.info = current_frame.info; | 399 | next_frame.info = current_frame.info; |
| 413 | next_next_frame.bit_stream = std::move(current_frame.bit_stream); | 400 | next_frame.bit_stream = std::move(current_frame.bit_stream); |
| 414 | } | 401 | } |
| 415 | return current_frame; | 402 | return current_frame; |
| 416 | } | 403 | } |
| @@ -616,13 +603,7 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() { | |||
| 616 | swap_ref_indices = false; | 603 | swap_ref_indices = false; |
| 617 | loop_filter_ref_deltas.fill(0); | 604 | loop_filter_ref_deltas.fill(0); |
| 618 | loop_filter_mode_deltas.fill(0); | 605 | loop_filter_mode_deltas.fill(0); |
| 619 | 606 | frame_ctxs.fill(default_probs); | |
| 620 | // allow frames offsets to stabilize before checking for golden frames | ||
| 621 | grace_period = 4; | ||
| 622 | |||
| 623 | // On key frames, all frame slots are set to the current frame, | ||
| 624 | // so the value of the selected slot doesn't really matter. | ||
| 625 | frame_ctxs.fill({current_frame_number, false, default_probs}); | ||
| 626 | 607 | ||
| 627 | // intra only, meaning the frame can be recreated with no other references | 608 | // intra only, meaning the frame can be recreated with no other references |
| 628 | current_frame_info.intra_only = true; | 609 | current_frame_info.intra_only = true; |
| @@ -698,10 +679,9 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() { | |||
| 698 | frame_ctx_idx = 1; | 679 | frame_ctx_idx = 1; |
| 699 | } | 680 | } |
| 700 | 681 | ||
| 701 | uncomp_writer.WriteU(frame_ctx_idx, 2); // Frame context index. | 682 | uncomp_writer.WriteU(frame_ctx_idx, 2); // Frame context index. |
| 702 | prev_frame_probs = | 683 | prev_frame_probs = frame_ctxs[frame_ctx_idx]; // reference probabilities for compressed header |
| 703 | frame_ctxs[frame_ctx_idx].probs; // reference probabilities for compressed header | 684 | frame_ctxs[frame_ctx_idx] = current_frame_info.entropy; |
| 704 | frame_ctxs[frame_ctx_idx] = {current_frame_number, false, current_frame_info.entropy}; | ||
| 705 | 685 | ||
| 706 | uncomp_writer.WriteU(current_frame_info.first_level, 6); | 686 | uncomp_writer.WriteU(current_frame_info.first_level, 6); |
| 707 | uncomp_writer.WriteU(current_frame_info.sharpness_level, 3); | 687 | uncomp_writer.WriteU(current_frame_info.sharpness_level, 3); |
| @@ -811,13 +791,6 @@ const std::vector<u8>& VP9::ComposeFrameHeader(const NvdecCommon::NvdecRegisters | |||
| 811 | frame.begin() + uncompressed_header.size()); | 791 | frame.begin() + uncompressed_header.size()); |
| 812 | std::copy(bitstream.begin(), bitstream.end(), | 792 | std::copy(bitstream.begin(), bitstream.end(), |
| 813 | frame.begin() + uncompressed_header.size() + compressed_header.size()); | 793 | frame.begin() + uncompressed_header.size() + compressed_header.size()); |
| 814 | |||
| 815 | // keep track of frame number | ||
| 816 | current_frame_number++; | ||
| 817 | grace_period--; | ||
| 818 | |||
| 819 | // don't display hidden frames | ||
| 820 | hidden = !current_frame_info.show_frame; | ||
| 821 | return frame; | 794 | return frame; |
| 822 | } | 795 | } |
| 823 | 796 | ||
diff --git a/src/video_core/command_classes/codecs/vp9.h b/src/video_core/command_classes/codecs/vp9.h index bb4d0d972..e6e9fc17e 100644 --- a/src/video_core/command_classes/codecs/vp9.h +++ b/src/video_core/command_classes/codecs/vp9.h | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | 14 | ||
| 15 | namespace Tegra { | 15 | namespace Tegra { |
| 16 | class GPU; | 16 | class GPU; |
| 17 | enum class FrameType { KeyFrame = 0, InterFrame = 1 }; | ||
| 18 | namespace Decoder { | 17 | namespace Decoder { |
| 19 | 18 | ||
| 20 | /// The VpxRangeEncoder, and VpxBitStreamWriter classes are used to compose the | 19 | /// The VpxRangeEncoder, and VpxBitStreamWriter classes are used to compose the |
| @@ -124,7 +123,7 @@ public: | |||
| 124 | 123 | ||
| 125 | /// Returns true if the most recent frame was a hidden frame. | 124 | /// Returns true if the most recent frame was a hidden frame. |
| 126 | [[nodiscard]] bool WasFrameHidden() const { | 125 | [[nodiscard]] bool WasFrameHidden() const { |
| 127 | return hidden; | 126 | return !current_frame_info.show_frame; |
| 128 | } | 127 | } |
| 129 | 128 | ||
| 130 | private: | 129 | private: |
| @@ -178,19 +177,12 @@ private: | |||
| 178 | std::array<s8, 4> loop_filter_ref_deltas{}; | 177 | std::array<s8, 4> loop_filter_ref_deltas{}; |
| 179 | std::array<s8, 2> loop_filter_mode_deltas{}; | 178 | std::array<s8, 2> loop_filter_mode_deltas{}; |
| 180 | 179 | ||
| 181 | bool hidden = false; | ||
| 182 | s64 current_frame_number = -2; // since we buffer 2 frames | ||
| 183 | s32 grace_period = 6; // frame offsets need to stabilize | ||
| 184 | std::array<FrameContexts, 4> frame_ctxs{}; | ||
| 185 | Vp9FrameContainer next_frame{}; | 180 | Vp9FrameContainer next_frame{}; |
| 186 | Vp9FrameContainer next_next_frame{}; | 181 | std::array<Vp9EntropyProbs, 4> frame_ctxs{}; |
| 187 | bool swap_ref_indices{}; | 182 | bool swap_ref_indices{}; |
| 188 | 183 | ||
| 189 | Vp9PictureInfo current_frame_info{}; | 184 | Vp9PictureInfo current_frame_info{}; |
| 190 | Vp9EntropyProbs prev_frame_probs{}; | 185 | Vp9EntropyProbs prev_frame_probs{}; |
| 191 | |||
| 192 | s32 diff_update_probability = 252; | ||
| 193 | s32 frame_sync_code = 0x498342; | ||
| 194 | }; | 186 | }; |
| 195 | 187 | ||
| 196 | } // namespace Decoder | 188 | } // namespace Decoder |
diff --git a/src/video_core/command_classes/codecs/vp9_types.h b/src/video_core/command_classes/codecs/vp9_types.h index 2da14f3ca..6820afa26 100644 --- a/src/video_core/command_classes/codecs/vp9_types.h +++ b/src/video_core/command_classes/codecs/vp9_types.h | |||
| @@ -296,12 +296,6 @@ struct RefPoolElement { | |||
| 296 | bool refresh{}; | 296 | bool refresh{}; |
| 297 | }; | 297 | }; |
| 298 | 298 | ||
| 299 | struct FrameContexts { | ||
| 300 | s64 from; | ||
| 301 | bool adapted; | ||
| 302 | Vp9EntropyProbs probs; | ||
| 303 | }; | ||
| 304 | |||
| 305 | #define ASSERT_POSITION(field_name, position) \ | 299 | #define ASSERT_POSITION(field_name, position) \ |
| 306 | static_assert(offsetof(Vp9EntropyProbs, field_name) == position, \ | 300 | static_assert(offsetof(Vp9EntropyProbs, field_name) == position, \ |
| 307 | "Field " #field_name " has invalid position") | 301 | "Field " #field_name " has invalid position") |