summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ameerj2021-11-12 19:28:21 -0500
committerGravatar ameerj2021-11-12 19:49:45 -0500
commitb39b33b1fe1a396bb2f9841d48a1cb45cbfde806 (patch)
tree75517c706c67c3329c0cd6436a2a6397f3dddf24
parentMerge pull request #7320 from OatmealDome/homebrew-capabilities (diff)
downloadyuzu-b39b33b1fe1a396bb2f9841d48a1cb45cbfde806.tar.gz
yuzu-b39b33b1fe1a396bb2f9841d48a1cb45cbfde806.tar.xz
yuzu-b39b33b1fe1a396bb2f9841d48a1cb45cbfde806.zip
codecs: Add VP8 codec class
Diffstat (limited to '')
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/command_classes/codecs/codec.cpp34
-rw-r--r--src/video_core/command_classes/codecs/codec.h2
-rw-r--r--src/video_core/command_classes/codecs/vp8.cpp20
-rw-r--r--src/video_core/command_classes/codecs/vp8.h31
-rw-r--r--src/video_core/command_classes/codecs/vp9.cpp3
-rw-r--r--src/video_core/command_classes/codecs/vp9.h11
-rw-r--r--src/video_core/command_classes/nvdec.cpp3
-rw-r--r--src/video_core/command_classes/nvdec_common.h4
9 files changed, 90 insertions, 20 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 269db21a5..6aac7f305 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -15,6 +15,8 @@ add_library(video_core STATIC
15 command_classes/codecs/codec.h 15 command_classes/codecs/codec.h
16 command_classes/codecs/h264.cpp 16 command_classes/codecs/h264.cpp
17 command_classes/codecs/h264.h 17 command_classes/codecs/h264.h
18 command_classes/codecs/vp8.cpp
19 command_classes/codecs/vp8.h
18 command_classes/codecs/vp9.cpp 20 command_classes/codecs/vp9.cpp
19 command_classes/codecs/vp9.h 21 command_classes/codecs/vp9.h
20 command_classes/codecs/vp9_types.h 22 command_classes/codecs/vp9_types.h
diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp
index 61966cbfe..fc3b8db99 100644
--- a/src/video_core/command_classes/codecs/codec.cpp
+++ b/src/video_core/command_classes/codecs/codec.cpp
@@ -8,6 +8,7 @@
8#include "common/settings.h" 8#include "common/settings.h"
9#include "video_core/command_classes/codecs/codec.h" 9#include "video_core/command_classes/codecs/codec.h"
10#include "video_core/command_classes/codecs/h264.h" 10#include "video_core/command_classes/codecs/h264.h"
11#include "video_core/command_classes/codecs/vp8.h"
11#include "video_core/command_classes/codecs/vp9.h" 12#include "video_core/command_classes/codecs/vp9.h"
12#include "video_core/gpu.h" 13#include "video_core/gpu.h"
13#include "video_core/memory_manager.h" 14#include "video_core/memory_manager.h"
@@ -46,6 +47,7 @@ void AVFrameDeleter(AVFrame* ptr) {
46 47
47Codec::Codec(GPU& gpu_, const NvdecCommon::NvdecRegisters& regs) 48Codec::Codec(GPU& gpu_, const NvdecCommon::NvdecRegisters& regs)
48 : gpu(gpu_), state{regs}, h264_decoder(std::make_unique<Decoder::H264>(gpu)), 49 : gpu(gpu_), state{regs}, h264_decoder(std::make_unique<Decoder::H264>(gpu)),
50 vp8_decoder(std::make_unique<Decoder::VP8>(gpu)),
49 vp9_decoder(std::make_unique<Decoder::VP9>(gpu)) {} 51 vp9_decoder(std::make_unique<Decoder::VP9>(gpu)) {}
50 52
51Codec::~Codec() { 53Codec::~Codec() {
@@ -135,7 +137,9 @@ void Codec::Initialize() {
135 switch (current_codec) { 137 switch (current_codec) {
136 case NvdecCommon::VideoCodec::H264: 138 case NvdecCommon::VideoCodec::H264:
137 return AV_CODEC_ID_H264; 139 return AV_CODEC_ID_H264;
138 case NvdecCommon::VideoCodec::Vp9: 140 case NvdecCommon::VideoCodec::VP8:
141 return AV_CODEC_ID_VP8;
142 case NvdecCommon::VideoCodec::VP9:
139 return AV_CODEC_ID_VP9; 143 return AV_CODEC_ID_VP9;
140 default: 144 default:
141 UNIMPLEMENTED_MSG("Unknown codec {}", current_codec); 145 UNIMPLEMENTED_MSG("Unknown codec {}", current_codec);
@@ -176,19 +180,27 @@ void Codec::Decode() {
176 return; 180 return;
177 } 181 }
178 bool vp9_hidden_frame = false; 182 bool vp9_hidden_frame = false;
179 std::vector<u8> frame_data; 183 const auto& frame_data = [&]() {
180 if (current_codec == NvdecCommon::VideoCodec::H264) { 184 switch (current_codec) {
181 frame_data = h264_decoder->ComposeFrameHeader(state, is_first_frame); 185 case Tegra::NvdecCommon::VideoCodec::H264:
182 } else if (current_codec == NvdecCommon::VideoCodec::Vp9) { 186 return h264_decoder->ComposeFrameHeader(state, is_first_frame);
183 frame_data = vp9_decoder->ComposeFrameHeader(state); 187 case Tegra::NvdecCommon::VideoCodec::VP8:
184 vp9_hidden_frame = vp9_decoder->WasFrameHidden(); 188 return vp8_decoder->ComposeFrameHeader(state, is_first_frame);
185 } 189 case Tegra::NvdecCommon::VideoCodec::VP9:
190 vp9_decoder->ComposeFrameHeader(state);
191 vp9_hidden_frame = vp9_decoder->WasFrameHidden();
192 return vp9_decoder->GetFrameBytes();
193 default:
194 UNREACHABLE();
195 return std::vector<u8>{};
196 }
197 }();
186 AVPacketPtr packet{av_packet_alloc(), AVPacketDeleter}; 198 AVPacketPtr packet{av_packet_alloc(), AVPacketDeleter};
187 if (!packet) { 199 if (!packet) {
188 LOG_ERROR(Service_NVDRV, "av_packet_alloc failed"); 200 LOG_ERROR(Service_NVDRV, "av_packet_alloc failed");
189 return; 201 return;
190 } 202 }
191 packet->data = frame_data.data(); 203 packet->data = const_cast<u8*>(frame_data.data());
192 packet->size = static_cast<s32>(frame_data.size()); 204 packet->size = static_cast<s32>(frame_data.size());
193 if (const int res = avcodec_send_packet(av_codec_ctx, packet.get()); res != 0) { 205 if (const int res = avcodec_send_packet(av_codec_ctx, packet.get()); res != 0) {
194 LOG_DEBUG(Service_NVDRV, "avcodec_send_packet error {}", res); 206 LOG_DEBUG(Service_NVDRV, "avcodec_send_packet error {}", res);
@@ -252,11 +264,11 @@ std::string_view Codec::GetCurrentCodecName() const {
252 return "None"; 264 return "None";
253 case NvdecCommon::VideoCodec::H264: 265 case NvdecCommon::VideoCodec::H264:
254 return "H264"; 266 return "H264";
255 case NvdecCommon::VideoCodec::Vp8: 267 case NvdecCommon::VideoCodec::VP8:
256 return "VP8"; 268 return "VP8";
257 case NvdecCommon::VideoCodec::H265: 269 case NvdecCommon::VideoCodec::H265:
258 return "H265"; 270 return "H265";
259 case NvdecCommon::VideoCodec::Vp9: 271 case NvdecCommon::VideoCodec::VP9:
260 return "VP9"; 272 return "VP9";
261 default: 273 default:
262 return "Unknown"; 274 return "Unknown";
diff --git a/src/video_core/command_classes/codecs/codec.h b/src/video_core/command_classes/codecs/codec.h
index f9a80886f..13ed88382 100644
--- a/src/video_core/command_classes/codecs/codec.h
+++ b/src/video_core/command_classes/codecs/codec.h
@@ -29,6 +29,7 @@ using AVFramePtr = std::unique_ptr<AVFrame, decltype(&AVFrameDeleter)>;
29 29
30namespace Decoder { 30namespace Decoder {
31class H264; 31class H264;
32class VP8;
32class VP9; 33class VP9;
33} // namespace Decoder 34} // namespace Decoder
34 35
@@ -72,6 +73,7 @@ private:
72 GPU& gpu; 73 GPU& gpu;
73 const NvdecCommon::NvdecRegisters& state; 74 const NvdecCommon::NvdecRegisters& state;
74 std::unique_ptr<Decoder::H264> h264_decoder; 75 std::unique_ptr<Decoder::H264> h264_decoder;
76 std::unique_ptr<Decoder::VP8> vp8_decoder;
75 std::unique_ptr<Decoder::VP9> vp9_decoder; 77 std::unique_ptr<Decoder::VP9> vp9_decoder;
76 78
77 std::queue<AVFramePtr> av_frames{}; 79 std::queue<AVFramePtr> av_frames{};
diff --git a/src/video_core/command_classes/codecs/vp8.cpp b/src/video_core/command_classes/codecs/vp8.cpp
new file mode 100644
index 000000000..976e9f9b7
--- /dev/null
+++ b/src/video_core/command_classes/codecs/vp8.cpp
@@ -0,0 +1,20 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <array>
6#include <vector>
7
8#include "video_core/command_classes/codecs/vp8.h"
9
10namespace Tegra::Decoder {
11VP8::VP8(GPU& gpu_) : gpu(gpu_) {}
12
13VP8::~VP8() = default;
14
15const std::vector<u8>& VP8::ComposeFrameHeader(const NvdecCommon::NvdecRegisters& state,
16 bool is_first_frame) {
17 return {};
18}
19
20} // namespace Tegra::Decoder
diff --git a/src/video_core/command_classes/codecs/vp8.h b/src/video_core/command_classes/codecs/vp8.h
new file mode 100644
index 000000000..70c75f414
--- /dev/null
+++ b/src/video_core/command_classes/codecs/vp8.h
@@ -0,0 +1,31 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <vector>
8
9#include "common/common_types.h"
10#include "video_core/command_classes/nvdec_common.h"
11
12namespace Tegra {
13class GPU;
14namespace Decoder {
15
16class VP8 {
17public:
18 explicit VP8(GPU& gpu);
19 ~VP8();
20
21 /// Compose the VP8 header of the frame for FFmpeg decoding
22 [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(
23 const NvdecCommon::NvdecRegisters& state, bool is_first_frame = false);
24
25private:
26 std::vector<u8> frame;
27 GPU& gpu;
28};
29
30} // namespace Decoder
31} // namespace Tegra
diff --git a/src/video_core/command_classes/codecs/vp9.cpp b/src/video_core/command_classes/codecs/vp9.cpp
index d7e749485..269adc3f1 100644
--- a/src/video_core/command_classes/codecs/vp9.cpp
+++ b/src/video_core/command_classes/codecs/vp9.cpp
@@ -770,7 +770,7 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() {
770 return uncomp_writer; 770 return uncomp_writer;
771} 771}
772 772
773const std::vector<u8>& VP9::ComposeFrameHeader(const NvdecCommon::NvdecRegisters& state) { 773void VP9::ComposeFrameHeader(const NvdecCommon::NvdecRegisters& state) {
774 std::vector<u8> bitstream; 774 std::vector<u8> bitstream;
775 { 775 {
776 Vp9FrameContainer curr_frame = GetCurrentFrame(state); 776 Vp9FrameContainer curr_frame = GetCurrentFrame(state);
@@ -792,7 +792,6 @@ const std::vector<u8>& VP9::ComposeFrameHeader(const NvdecCommon::NvdecRegisters
792 frame.begin() + uncompressed_header.size()); 792 frame.begin() + uncompressed_header.size());
793 std::copy(bitstream.begin(), bitstream.end(), 793 std::copy(bitstream.begin(), bitstream.end(),
794 frame.begin() + uncompressed_header.size() + compressed_header.size()); 794 frame.begin() + uncompressed_header.size() + compressed_header.size());
795 return frame;
796} 795}
797 796
798VpxRangeEncoder::VpxRangeEncoder() { 797VpxRangeEncoder::VpxRangeEncoder() {
diff --git a/src/video_core/command_classes/codecs/vp9.h b/src/video_core/command_classes/codecs/vp9.h
index e6e9fc17e..6ab9ef5b5 100644
--- a/src/video_core/command_classes/codecs/vp9.h
+++ b/src/video_core/command_classes/codecs/vp9.h
@@ -116,16 +116,19 @@ public:
116 VP9(VP9&&) = default; 116 VP9(VP9&&) = default;
117 VP9& operator=(VP9&&) = delete; 117 VP9& operator=(VP9&&) = delete;
118 118
119 /// Composes the VP9 frame from the GPU state information. Based on the official VP9 spec 119 /// Composes the VP9 frame from the GPU state information.
120 /// documentation 120 /// Based on the official VP9 spec documentation
121 [[nodiscard]] const std::vector<u8>& ComposeFrameHeader( 121 void ComposeFrameHeader(const NvdecCommon::NvdecRegisters& state);
122 const NvdecCommon::NvdecRegisters& state);
123 122
124 /// Returns true if the most recent frame was a hidden frame. 123 /// Returns true if the most recent frame was a hidden frame.
125 [[nodiscard]] bool WasFrameHidden() const { 124 [[nodiscard]] bool WasFrameHidden() const {
126 return !current_frame_info.show_frame; 125 return !current_frame_info.show_frame;
127 } 126 }
128 127
128 [[nodiscard]] const std::vector<u8>& GetFrameBytes() const {
129 return frame;
130 }
131
129private: 132private:
130 /// Generates compressed header probability updates in the bitstream writer 133 /// Generates compressed header probability updates in the bitstream writer
131 template <typename T, std::size_t N> 134 template <typename T, std::size_t N>
diff --git a/src/video_core/command_classes/nvdec.cpp b/src/video_core/command_classes/nvdec.cpp
index b5c55f14a..9aaf5247e 100644
--- a/src/video_core/command_classes/nvdec.cpp
+++ b/src/video_core/command_classes/nvdec.cpp
@@ -35,7 +35,8 @@ AVFramePtr Nvdec::GetFrame() {
35void Nvdec::Execute() { 35void Nvdec::Execute() {
36 switch (codec->GetCurrentCodec()) { 36 switch (codec->GetCurrentCodec()) {
37 case NvdecCommon::VideoCodec::H264: 37 case NvdecCommon::VideoCodec::H264:
38 case NvdecCommon::VideoCodec::Vp9: 38 case NvdecCommon::VideoCodec::VP8:
39 case NvdecCommon::VideoCodec::VP9:
39 codec->Decode(); 40 codec->Decode();
40 break; 41 break;
41 default: 42 default:
diff --git a/src/video_core/command_classes/nvdec_common.h b/src/video_core/command_classes/nvdec_common.h
index 6a24e00a0..26c974b00 100644
--- a/src/video_core/command_classes/nvdec_common.h
+++ b/src/video_core/command_classes/nvdec_common.h
@@ -13,9 +13,9 @@ namespace Tegra::NvdecCommon {
13enum class VideoCodec : u64 { 13enum class VideoCodec : u64 {
14 None = 0x0, 14 None = 0x0,
15 H264 = 0x3, 15 H264 = 0x3,
16 Vp8 = 0x5, 16 VP8 = 0x5,
17 H265 = 0x7, 17 H265 = 0x7,
18 Vp9 = 0x9, 18 VP9 = 0x9,
19}; 19};
20 20
21// NVDEC should use a 32-bit address space, but is mapped to 64-bit, 21// NVDEC should use a 32-bit address space, but is mapped to 64-bit,