vp9.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // Copyright 2020 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <vector>
  7. #include "common/common_types.h"
  8. #include "common/stream.h"
  9. #include "video_core/command_classes/codecs/vp9_types.h"
  10. #include "video_core/command_classes/nvdec_common.h"
  11. namespace Tegra {
  12. class GPU;
  13. enum class FrameType { KeyFrame = 0, InterFrame = 1 };
  14. namespace Decoder {
  15. /// The VpxRangeEncoder, and VpxBitStreamWriter classes are used to compose the
  16. /// VP9 header bitstreams.
  17. class VpxRangeEncoder {
  18. public:
  19. VpxRangeEncoder();
  20. ~VpxRangeEncoder();
  21. VpxRangeEncoder(const VpxRangeEncoder&) = delete;
  22. VpxRangeEncoder& operator=(const VpxRangeEncoder&) = delete;
  23. VpxRangeEncoder(VpxRangeEncoder&&) = default;
  24. VpxRangeEncoder& operator=(VpxRangeEncoder&&) = default;
  25. /// Writes the rightmost value_size bits from value into the stream
  26. void Write(s32 value, s32 value_size);
  27. /// Writes a single bit with half probability
  28. void Write(bool bit);
  29. /// Writes a bit to the base_stream encoded with probability
  30. void Write(bool bit, s32 probability);
  31. /// Signal the end of the bitstream
  32. void End();
  33. [[nodiscard]] std::vector<u8>& GetBuffer() {
  34. return base_stream.GetBuffer();
  35. }
  36. [[nodiscard]] const std::vector<u8>& GetBuffer() const {
  37. return base_stream.GetBuffer();
  38. }
  39. private:
  40. u8 PeekByte();
  41. Common::Stream base_stream{};
  42. u32 low_value{};
  43. u32 range{0xff};
  44. s32 count{-24};
  45. s32 half_probability{128};
  46. };
  47. class VpxBitStreamWriter {
  48. public:
  49. VpxBitStreamWriter();
  50. ~VpxBitStreamWriter();
  51. VpxBitStreamWriter(const VpxBitStreamWriter&) = delete;
  52. VpxBitStreamWriter& operator=(const VpxBitStreamWriter&) = delete;
  53. VpxBitStreamWriter(VpxBitStreamWriter&&) = default;
  54. VpxBitStreamWriter& operator=(VpxBitStreamWriter&&) = default;
  55. /// Write an unsigned integer value
  56. void WriteU(u32 value, u32 value_size);
  57. /// Write a signed integer value
  58. void WriteS(s32 value, u32 value_size);
  59. /// Based on 6.2.10 of VP9 Spec, writes a delta coded value
  60. void WriteDeltaQ(u32 value);
  61. /// Write a single bit.
  62. void WriteBit(bool state);
  63. /// Pushes current buffer into buffer_array, resets buffer
  64. void Flush();
  65. /// Returns byte_array
  66. [[nodiscard]] std::vector<u8>& GetByteArray();
  67. /// Returns const byte_array
  68. [[nodiscard]] const std::vector<u8>& GetByteArray() const;
  69. private:
  70. /// Write bit_count bits from value into buffer
  71. void WriteBits(u32 value, u32 bit_count);
  72. /// Gets next available position in buffer, invokes Flush() if buffer is full
  73. s32 GetFreeBufferBits();
  74. s32 buffer_size{8};
  75. s32 buffer{};
  76. s32 buffer_pos{};
  77. std::vector<u8> byte_array;
  78. };
  79. class VP9 {
  80. public:
  81. explicit VP9(GPU& gpu_);
  82. ~VP9();
  83. VP9(const VP9&) = delete;
  84. VP9& operator=(const VP9&) = delete;
  85. VP9(VP9&&) = default;
  86. VP9& operator=(VP9&&) = delete;
  87. /// Composes the VP9 frame from the GPU state information. Based on the official VP9 spec
  88. /// documentation
  89. [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(
  90. const NvdecCommon::NvdecRegisters& state);
  91. /// Returns true if the most recent frame was a hidden frame.
  92. [[nodiscard]] bool WasFrameHidden() const {
  93. return hidden;
  94. }
  95. private:
  96. /// Generates compressed header probability updates in the bitstream writer
  97. template <typename T, std::size_t N>
  98. void WriteProbabilityUpdate(VpxRangeEncoder& writer, const std::array<T, N>& new_prob,
  99. const std::array<T, N>& old_prob);
  100. /// Generates compressed header probability updates in the bitstream writer
  101. /// If probs are not equal, WriteProbabilityDelta is invoked
  102. void WriteProbabilityUpdate(VpxRangeEncoder& writer, u8 new_prob, u8 old_prob);
  103. /// Generates compressed header probability deltas in the bitstream writer
  104. void WriteProbabilityDelta(VpxRangeEncoder& writer, u8 new_prob, u8 old_prob);
  105. /// Inverse of 6.3.4 Decode term subexp
  106. void EncodeTermSubExp(VpxRangeEncoder& writer, s32 value);
  107. /// Writes if the value is less than the test value
  108. bool WriteLessThan(VpxRangeEncoder& writer, s32 value, s32 test);
  109. /// Writes probability updates for the Coef probabilities
  110. void WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode,
  111. const std::array<u8, 1728>& new_prob,
  112. const std::array<u8, 1728>& old_prob);
  113. /// Write probabilities for 4-byte aligned structures
  114. template <typename T, std::size_t N>
  115. void WriteProbabilityUpdateAligned4(VpxRangeEncoder& writer, const std::array<T, N>& new_prob,
  116. const std::array<T, N>& old_prob);
  117. /// Write motion vector probability updates. 6.3.17 in the spec
  118. void WriteMvProbabilityUpdate(VpxRangeEncoder& writer, u8 new_prob, u8 old_prob);
  119. /// Returns VP9 information from NVDEC provided offset and size
  120. [[nodiscard]] Vp9PictureInfo GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state);
  121. /// Read and convert NVDEC provided entropy probs to Vp9EntropyProbs struct
  122. void InsertEntropy(u64 offset, Vp9EntropyProbs& dst);
  123. /// Returns frame to be decoded after buffering
  124. [[nodiscard]] Vp9FrameContainer GetCurrentFrame(const NvdecCommon::NvdecRegisters& state);
  125. /// Use NVDEC providied information to compose the headers for the current frame
  126. [[nodiscard]] std::vector<u8> ComposeCompressedHeader();
  127. [[nodiscard]] VpxBitStreamWriter ComposeUncompressedHeader();
  128. GPU& gpu;
  129. std::vector<u8> frame;
  130. std::array<s8, 4> loop_filter_ref_deltas{};
  131. std::array<s8, 2> loop_filter_mode_deltas{};
  132. bool hidden = false;
  133. s64 current_frame_number = -2; // since we buffer 2 frames
  134. s32 grace_period = 6; // frame offsets need to stabilize
  135. std::array<FrameContexts, 4> frame_ctxs{};
  136. Vp9FrameContainer next_frame{};
  137. Vp9FrameContainer next_next_frame{};
  138. bool swap_ref_indices{};
  139. Vp9PictureInfo current_frame_info{};
  140. Vp9EntropyProbs prev_frame_probs{};
  141. s32 diff_update_probability = 252;
  142. s32 frame_sync_code = 0x498342;
  143. };
  144. } // namespace Decoder
  145. } // namespace Tegra