summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/command_classes/codecs/codec.cpp31
-rw-r--r--src/video_core/command_classes/codecs/codec.h2
2 files changed, 19 insertions, 14 deletions
diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp
index 400834129..18aa40ca3 100644
--- a/src/video_core/command_classes/codecs/codec.cpp
+++ b/src/video_core/command_classes/codecs/codec.cpp
@@ -20,6 +20,12 @@ namespace {
20constexpr AVPixelFormat PREFERRED_GPU_FMT = AV_PIX_FMT_NV12; 20constexpr AVPixelFormat PREFERRED_GPU_FMT = AV_PIX_FMT_NV12;
21constexpr AVPixelFormat PREFERRED_CPU_FMT = AV_PIX_FMT_YUV420P; 21constexpr AVPixelFormat PREFERRED_CPU_FMT = AV_PIX_FMT_YUV420P;
22 22
23void AVPacketDeleter(AVPacket* ptr) {
24 av_packet_free(&ptr);
25}
26
27using AVPacketPtr = std::unique_ptr<AVPacket, decltype(&AVPacketDeleter)>;
28
23AVPixelFormat GetGpuFormat(AVCodecContext* av_codec_ctx, const AVPixelFormat* pix_fmts) { 29AVPixelFormat GetGpuFormat(AVCodecContext* av_codec_ctx, const AVPixelFormat* pix_fmts) {
24 for (const AVPixelFormat* p = pix_fmts; *p != AV_PIX_FMT_NONE; ++p) { 30 for (const AVPixelFormat* p = pix_fmts; *p != AV_PIX_FMT_NONE; ++p) {
25 if (*p == av_codec_ctx->pix_fmt) { 31 if (*p == av_codec_ctx->pix_fmt) {
@@ -46,11 +52,7 @@ Codec::~Codec() {
46 return; 52 return;
47 } 53 }
48 // Free libav memory 54 // Free libav memory
49 avcodec_send_packet(av_codec_ctx, nullptr); 55 avcodec_free_context(&av_codec_ctx);
50 AVFramePtr av_frame{av_frame_alloc(), AVFrameDeleter};
51 avcodec_receive_frame(av_codec_ctx, av_frame.get());
52 avcodec_flush_buffers(av_codec_ctx);
53 avcodec_close(av_codec_ctx);
54 av_buffer_unref(&av_gpu_decoder); 56 av_buffer_unref(&av_gpu_decoder);
55} 57}
56 58
@@ -111,6 +113,11 @@ bool Codec::CreateGpuAvDevice() {
111 return false; 113 return false;
112} 114}
113 115
116void Codec::InitializeAvCodecContext() {
117 av_codec_ctx = avcodec_alloc_context3(av_codec);
118 av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0);
119}
120
114void Codec::InitializeGpuDecoder() { 121void Codec::InitializeGpuDecoder() {
115 if (!CreateGpuAvDevice()) { 122 if (!CreateGpuAvDevice()) {
116 av_buffer_unref(&av_gpu_decoder); 123 av_buffer_unref(&av_gpu_decoder);
@@ -135,13 +142,11 @@ void Codec::Initialize() {
135 } 142 }
136 }(); 143 }();
137 av_codec = avcodec_find_decoder(codec); 144 av_codec = avcodec_find_decoder(codec);
138 av_codec_ctx = avcodec_alloc_context3(av_codec); 145 InitializeAvCodecContext();
139 av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0);
140
141 InitializeGpuDecoder(); 146 InitializeGpuDecoder();
142 if (const int res = avcodec_open2(av_codec_ctx, av_codec, nullptr); res < 0) { 147 if (const int res = avcodec_open2(av_codec_ctx, av_codec, nullptr); res < 0) {
143 LOG_ERROR(Service_NVDRV, "avcodec_open2() Failed with result {}", res); 148 LOG_ERROR(Service_NVDRV, "avcodec_open2() Failed with result {}", res);
144 avcodec_close(av_codec_ctx); 149 avcodec_free_context(&av_codec_ctx);
145 av_buffer_unref(&av_gpu_decoder); 150 av_buffer_unref(&av_gpu_decoder);
146 return; 151 return;
147 } 152 }
@@ -174,17 +179,15 @@ void Codec::Decode() {
174 frame_data = vp9_decoder->ComposeFrameHeader(state); 179 frame_data = vp9_decoder->ComposeFrameHeader(state);
175 vp9_hidden_frame = vp9_decoder->WasFrameHidden(); 180 vp9_hidden_frame = vp9_decoder->WasFrameHidden();
176 } 181 }
177 AVPacket* packet = av_packet_alloc(); 182 AVPacketPtr packet{av_packet_alloc(), AVPacketDeleter};
178 if (!packet) { 183 if (!packet) {
179 LOG_ERROR(Service_NVDRV, "av_packet_alloc failed"); 184 LOG_ERROR(Service_NVDRV, "av_packet_alloc failed");
180 return; 185 return;
181 } 186 }
182 packet->data = frame_data.data(); 187 packet->data = frame_data.data();
183 packet->size = static_cast<s32>(frame_data.size()); 188 packet->size = static_cast<s32>(frame_data.size());
184 const int send_pkt_ret = avcodec_send_packet(av_codec_ctx, packet); 189 if (const int res = avcodec_send_packet(av_codec_ctx, packet.get()); res != 0) {
185 av_packet_free(&packet); 190 LOG_DEBUG(Service_NVDRV, "avcodec_send_packet error {}", res);
186 if (send_pkt_ret != 0) {
187 LOG_DEBUG(Service_NVDRV, "avcodec_send_packet error {}", send_pkt_ret);
188 return; 191 return;
189 } 192 }
190 // Only receive/store visible frames 193 // Only receive/store visible frames
diff --git a/src/video_core/command_classes/codecs/codec.h b/src/video_core/command_classes/codecs/codec.h
index f51ab9df0..1508d36c2 100644
--- a/src/video_core/command_classes/codecs/codec.h
+++ b/src/video_core/command_classes/codecs/codec.h
@@ -55,6 +55,8 @@ public:
55 [[nodiscard]] std::string_view GetCurrentCodecName() const; 55 [[nodiscard]] std::string_view GetCurrentCodecName() const;
56 56
57private: 57private:
58 void InitializeAvCodecContext();
59
58 void InitializeGpuDecoder(); 60 void InitializeGpuDecoder();
59 61
60 bool CreateGpuAvDevice(); 62 bool CreateGpuAvDevice();