|
|
|
@ -9,7 +9,7 @@
|
|
|
|
|
#include "video_core/memory_manager.h"
|
|
|
|
|
|
|
|
|
|
namespace Tegra::Decoder {
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
// Default compressed header probabilities once frame context resets
|
|
|
|
|
constexpr Vp9EntropyProbs default_probs{
|
|
|
|
|
.y_mode_prob{
|
|
|
|
@ -170,6 +170,35 @@ constexpr Vp9EntropyProbs default_probs{
|
|
|
|
|
.high_precision{128, 128},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
constexpr std::array<s32, 256> norm_lut{
|
|
|
|
|
0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
|
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
constexpr std::array<s32, 254> map_lut{
|
|
|
|
|
20, 21, 22, 23, 24, 25, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
|
|
|
|
|
1, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 2, 50, 51, 52, 53, 54,
|
|
|
|
|
55, 56, 57, 58, 59, 60, 61, 3, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
|
|
|
|
|
73, 4, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 5, 86, 87, 88, 89,
|
|
|
|
|
90, 91, 92, 93, 94, 95, 96, 97, 6, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
|
|
|
|
|
108, 109, 7, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 8, 122, 123, 124,
|
|
|
|
|
125, 126, 127, 128, 129, 130, 131, 132, 133, 9, 134, 135, 136, 137, 138, 139, 140, 141, 142,
|
|
|
|
|
143, 144, 145, 10, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 11, 158, 159,
|
|
|
|
|
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 12, 170, 171, 172, 173, 174, 175, 176, 177,
|
|
|
|
|
178, 179, 180, 181, 13, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 14, 194,
|
|
|
|
|
195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 15, 206, 207, 208, 209, 210, 211, 212,
|
|
|
|
|
213, 214, 215, 216, 217, 16, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 17,
|
|
|
|
|
230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 18, 242, 243, 244, 245, 246, 247,
|
|
|
|
|
248, 249, 250, 251, 252, 253, 19,
|
|
|
|
|
};
|
|
|
|
|
} // Anonymous namespace
|
|
|
|
|
|
|
|
|
|
VP9::VP9(GPU& gpu) : gpu(gpu) {}
|
|
|
|
|
|
|
|
|
|
VP9::~VP9() = default;
|
|
|
|
@ -379,14 +408,14 @@ Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state)
|
|
|
|
|
Vp9FrameContainer frame{};
|
|
|
|
|
{
|
|
|
|
|
gpu.SyncGuestHost();
|
|
|
|
|
frame.info = std::move(GetVp9PictureInfo(state));
|
|
|
|
|
frame.info = GetVp9PictureInfo(state);
|
|
|
|
|
|
|
|
|
|
frame.bit_stream.resize(frame.info.bitstream_size);
|
|
|
|
|
gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.bit_stream.data(),
|
|
|
|
|
frame.info.bitstream_size);
|
|
|
|
|
}
|
|
|
|
|
// Buffer two frames, saving the last show frame info
|
|
|
|
|
if (next_next_frame.bit_stream.size() != 0) {
|
|
|
|
|
if (!next_next_frame.bit_stream.empty()) {
|
|
|
|
|
Vp9FrameContainer temp{
|
|
|
|
|
.info = frame.info,
|
|
|
|
|
.bit_stream = frame.bit_stream,
|
|
|
|
@ -396,15 +425,15 @@ Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state)
|
|
|
|
|
frame.bit_stream = next_next_frame.bit_stream;
|
|
|
|
|
next_next_frame = std::move(temp);
|
|
|
|
|
|
|
|
|
|
if (next_frame.bit_stream.size() != 0) {
|
|
|
|
|
Vp9FrameContainer temp{
|
|
|
|
|
if (!next_frame.bit_stream.empty()) {
|
|
|
|
|
Vp9FrameContainer temp2{
|
|
|
|
|
.info = frame.info,
|
|
|
|
|
.bit_stream = frame.bit_stream,
|
|
|
|
|
};
|
|
|
|
|
next_frame.info.show_frame = frame.info.last_frame_shown;
|
|
|
|
|
frame.info = next_frame.info;
|
|
|
|
|
frame.bit_stream = next_frame.bit_stream;
|
|
|
|
|
next_frame = std::move(temp);
|
|
|
|
|
next_frame = std::move(temp2);
|
|
|
|
|
} else {
|
|
|
|
|
next_frame.info = frame.info;
|
|
|
|
|
next_frame.bit_stream = frame.bit_stream;
|
|
|
|
@ -605,12 +634,6 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
|
|
|
|
|
|
|
|
|
|
writer.End();
|
|
|
|
|
return writer.GetBuffer();
|
|
|
|
|
|
|
|
|
|
const auto writer_bytearray = writer.GetBuffer();
|
|
|
|
|
|
|
|
|
|
std::vector<u8> compressed_header(writer_bytearray.size());
|
|
|
|
|
std::memcpy(compressed_header.data(), writer_bytearray.data(), writer_bytearray.size());
|
|
|
|
|
return compressed_header;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VpxBitStreamWriter VP9::ComposeUncompressedHeader() {
|
|
|
|
@ -648,7 +671,6 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() {
|
|
|
|
|
current_frame_info.intra_only = true;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
std::array<s32, 3> ref_frame_index;
|
|
|
|
|
|
|
|
|
|
if (!current_frame_info.show_frame) {
|
|
|
|
|
uncomp_writer.WriteBit(current_frame_info.intra_only);
|
|
|
|
@ -663,9 +685,9 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Last, Golden, Altref frames
|
|
|
|
|
ref_frame_index = std::array<s32, 3>{0, 1, 2};
|
|
|
|
|
std::array<s32, 3> ref_frame_index{0, 1, 2};
|
|
|
|
|
|
|
|
|
|
// set when next frame is hidden
|
|
|
|
|
// Set when next frame is hidden
|
|
|
|
|
// altref and golden references are swapped
|
|
|
|
|
if (swap_next_golden) {
|
|
|
|
|
ref_frame_index = std::array<s32, 3>{0, 2, 1};
|
|
|
|
@ -754,17 +776,19 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() {
|
|
|
|
|
for (std::size_t index = 0; index < current_frame_info.ref_deltas.size(); index++) {
|
|
|
|
|
const s8 old_deltas = loop_filter_ref_deltas[index];
|
|
|
|
|
const s8 new_deltas = current_frame_info.ref_deltas[index];
|
|
|
|
|
const bool differing_delta = old_deltas != new_deltas;
|
|
|
|
|
|
|
|
|
|
loop_filter_delta_update |=
|
|
|
|
|
(update_loop_filter_ref_deltas[index] = old_deltas != new_deltas);
|
|
|
|
|
update_loop_filter_ref_deltas[index] = differing_delta;
|
|
|
|
|
loop_filter_delta_update |= differing_delta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (std::size_t index = 0; index < current_frame_info.mode_deltas.size(); index++) {
|
|
|
|
|
const s8 old_deltas = loop_filter_mode_deltas[index];
|
|
|
|
|
const s8 new_deltas = current_frame_info.mode_deltas[index];
|
|
|
|
|
const bool differing_delta = old_deltas != new_deltas;
|
|
|
|
|
|
|
|
|
|
loop_filter_delta_update |=
|
|
|
|
|
(update_loop_filter_mode_deltas[index] = old_deltas != new_deltas);
|
|
|
|
|
update_loop_filter_mode_deltas[index] = differing_delta;
|
|
|
|
|
loop_filter_delta_update |= differing_delta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uncomp_writer.WriteBit(loop_filter_delta_update);
|
|
|
|
@ -829,7 +853,7 @@ std::vector<u8>& VP9::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state) {
|
|
|
|
|
{
|
|
|
|
|
Vp9FrameContainer curr_frame = GetCurrentFrame(state);
|
|
|
|
|
current_frame_info = curr_frame.info;
|
|
|
|
|
bitstream = curr_frame.bit_stream;
|
|
|
|
|
bitstream = std::move(curr_frame.bit_stream);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The uncompressed header routine sets PrevProb parameters needed for the compressed header
|
|
|
|
|