h264.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // MIT License
  2. //
  3. // Copyright (c) Ryujinx Team and Contributors
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
  6. // associated documentation files (the "Software"), to deal in the Software without restriction,
  7. // including without limitation the rights to use, copy, modify, merge, publish, distribute,
  8. // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in all copies or
  12. // substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
  15. // NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  17. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. #pragma once
  21. #include <span>
  22. #include <vector>
  23. #include "common/bit_field.h"
  24. #include "common/common_funcs.h"
  25. #include "common/common_types.h"
  26. #include "video_core/command_classes/nvdec_common.h"
  27. namespace Tegra {
  28. class GPU;
  29. namespace Decoder {
  30. class H264BitWriter {
  31. public:
  32. H264BitWriter();
  33. ~H264BitWriter();
  34. /// The following Write methods are based on clause 9.1 in the H.264 specification.
  35. /// WriteSe and WriteUe write in the Exp-Golomb-coded syntax
  36. void WriteU(s32 value, s32 value_sz);
  37. void WriteSe(s32 value);
  38. void WriteUe(u32 value);
  39. /// Finalize the bitstream
  40. void End();
  41. /// append a bit to the stream, equivalent value to the state parameter
  42. void WriteBit(bool state);
  43. /// Based on section 7.3.2.1.1.1 and Table 7-4 in the H.264 specification
  44. /// Writes the scaling matrices of the sream
  45. void WriteScalingList(std::span<const u8> list, s32 start, s32 count);
  46. /// Return the bitstream as a vector.
  47. [[nodiscard]] std::vector<u8>& GetByteArray();
  48. [[nodiscard]] const std::vector<u8>& GetByteArray() const;
  49. private:
  50. void WriteBits(s32 value, s32 bit_count);
  51. void WriteExpGolombCodedInt(s32 value);
  52. void WriteExpGolombCodedUInt(u32 value);
  53. [[nodiscard]] s32 GetFreeBufferBits();
  54. void Flush();
  55. s32 buffer_size{8};
  56. s32 buffer{};
  57. s32 buffer_pos{};
  58. std::vector<u8> byte_array;
  59. };
  60. class H264 {
  61. public:
  62. explicit H264(GPU& gpu);
  63. ~H264();
  64. /// Compose the H264 header of the frame for FFmpeg decoding
  65. [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(
  66. const NvdecCommon::NvdecRegisters& state, bool is_first_frame = false);
  67. private:
  68. std::vector<u8> frame;
  69. GPU& gpu;
  70. struct H264ParameterSet {
  71. s32 log2_max_pic_order_cnt_lsb_minus4; ///< 0x00
  72. s32 delta_pic_order_always_zero_flag; ///< 0x04
  73. s32 frame_mbs_only_flag; ///< 0x08
  74. u32 pic_width_in_mbs; ///< 0x0C
  75. u32 frame_height_in_map_units; ///< 0x10
  76. union { ///< 0x14
  77. BitField<0, 2, u32> tile_format;
  78. BitField<2, 3, u32> gob_height;
  79. };
  80. u32 entropy_coding_mode_flag; ///< 0x18
  81. s32 pic_order_present_flag; ///< 0x1C
  82. s32 num_refidx_l0_default_active; ///< 0x20
  83. s32 num_refidx_l1_default_active; ///< 0x24
  84. s32 deblocking_filter_control_present_flag; ///< 0x28
  85. s32 redundant_pic_cnt_present_flag; ///< 0x2C
  86. u32 transform_8x8_mode_flag; ///< 0x30
  87. u32 pitch_luma; ///< 0x34
  88. u32 pitch_chroma; ///< 0x38
  89. u32 luma_top_offset; ///< 0x3C
  90. u32 luma_bot_offset; ///< 0x40
  91. u32 luma_frame_offset; ///< 0x44
  92. u32 chroma_top_offset; ///< 0x48
  93. u32 chroma_bot_offset; ///< 0x4C
  94. u32 chroma_frame_offset; ///< 0x50
  95. u32 hist_buffer_size; ///< 0x54
  96. union { ///< 0x58
  97. union {
  98. BitField<0, 1, u64> mbaff_frame;
  99. BitField<1, 1, u64> direct_8x8_inference;
  100. BitField<2, 1, u64> weighted_pred;
  101. BitField<3, 1, u64> constrained_intra_pred;
  102. BitField<4, 1, u64> ref_pic;
  103. BitField<5, 1, u64> field_pic;
  104. BitField<6, 1, u64> bottom_field;
  105. BitField<7, 1, u64> second_field;
  106. } flags;
  107. BitField<8, 4, u64> log2_max_frame_num_minus4;
  108. BitField<12, 2, u64> chroma_format_idc;
  109. BitField<14, 2, u64> pic_order_cnt_type;
  110. BitField<16, 6, s64> pic_init_qp_minus26;
  111. BitField<22, 5, s64> chroma_qp_index_offset;
  112. BitField<27, 5, s64> second_chroma_qp_index_offset;
  113. BitField<32, 2, u64> weighted_bipred_idc;
  114. BitField<34, 7, u64> curr_pic_idx;
  115. BitField<41, 5, u64> curr_col_idx;
  116. BitField<46, 16, u64> frame_number;
  117. BitField<62, 1, u64> frame_surfaces;
  118. BitField<63, 1, u64> output_memory_layout;
  119. };
  120. };
  121. static_assert(sizeof(H264ParameterSet) == 0x60, "H264ParameterSet is an invalid size");
  122. struct H264DecoderContext {
  123. INSERT_PADDING_WORDS_NOINIT(18); ///< 0x0000
  124. u32 stream_len; ///< 0x0048
  125. INSERT_PADDING_WORDS_NOINIT(3); ///< 0x004C
  126. H264ParameterSet h264_parameter_set; ///< 0x0058
  127. INSERT_PADDING_WORDS_NOINIT(66); ///< 0x00B8
  128. std::array<u8, 0x60> weight_scale; ///< 0x01C0
  129. std::array<u8, 0x80> weight_scale_8x8; ///< 0x0220
  130. };
  131. static_assert(sizeof(H264DecoderContext) == 0x2A0, "H264DecoderContext is an invalid size");
  132. #define ASSERT_POSITION(field_name, position) \
  133. static_assert(offsetof(H264ParameterSet, field_name) == position, \
  134. "Field " #field_name " has invalid position")
  135. ASSERT_POSITION(log2_max_pic_order_cnt_lsb_minus4, 0x00);
  136. ASSERT_POSITION(delta_pic_order_always_zero_flag, 0x04);
  137. ASSERT_POSITION(frame_mbs_only_flag, 0x08);
  138. ASSERT_POSITION(pic_width_in_mbs, 0x0C);
  139. ASSERT_POSITION(frame_height_in_map_units, 0x10);
  140. ASSERT_POSITION(tile_format, 0x14);
  141. ASSERT_POSITION(entropy_coding_mode_flag, 0x18);
  142. ASSERT_POSITION(pic_order_present_flag, 0x1C);
  143. ASSERT_POSITION(num_refidx_l0_default_active, 0x20);
  144. ASSERT_POSITION(num_refidx_l1_default_active, 0x24);
  145. ASSERT_POSITION(deblocking_filter_control_present_flag, 0x28);
  146. ASSERT_POSITION(redundant_pic_cnt_present_flag, 0x2C);
  147. ASSERT_POSITION(transform_8x8_mode_flag, 0x30);
  148. ASSERT_POSITION(pitch_luma, 0x34);
  149. ASSERT_POSITION(pitch_chroma, 0x38);
  150. ASSERT_POSITION(luma_top_offset, 0x3C);
  151. ASSERT_POSITION(luma_bot_offset, 0x40);
  152. ASSERT_POSITION(luma_frame_offset, 0x44);
  153. ASSERT_POSITION(chroma_top_offset, 0x48);
  154. ASSERT_POSITION(chroma_bot_offset, 0x4C);
  155. ASSERT_POSITION(chroma_frame_offset, 0x50);
  156. ASSERT_POSITION(hist_buffer_size, 0x54);
  157. ASSERT_POSITION(flags, 0x58);
  158. #undef ASSERT_POSITION
  159. #define ASSERT_POSITION(field_name, position) \
  160. static_assert(offsetof(H264DecoderContext, field_name) == position, \
  161. "Field " #field_name " has invalid position")
  162. ASSERT_POSITION(stream_len, 0x48);
  163. ASSERT_POSITION(h264_parameter_set, 0x58);
  164. ASSERT_POSITION(weight_scale, 0x1C0);
  165. #undef ASSERT_POSITION
  166. };
  167. } // namespace Decoder
  168. } // namespace Tegra