summaryrefslogtreecommitdiffstats
path: root/src/video_core/command_classes/codecs/codec.cpp
diff options
context:
space:
mode:
authorameerj <aj662@drexel.edu>2020-11-25 23:10:44 +0100
committerameerj <aj662@drexel.edu>2020-11-25 23:10:44 +0100
commiteab041866b7c766aa38258aecef8a00c03612459 (patch)
tree7ca30459bcdfb9a277c3afac9d37f7198c01f535 /src/video_core/command_classes/codecs/codec.cpp
parentMerge pull request #4946 from ameerj/alpha-test (diff)
downloadyuzu-eab041866b7c766aa38258aecef8a00c03612459.tar
yuzu-eab041866b7c766aa38258aecef8a00c03612459.tar.gz
yuzu-eab041866b7c766aa38258aecef8a00c03612459.tar.bz2
yuzu-eab041866b7c766aa38258aecef8a00c03612459.tar.lz
yuzu-eab041866b7c766aa38258aecef8a00c03612459.tar.xz
yuzu-eab041866b7c766aa38258aecef8a00c03612459.tar.zst
yuzu-eab041866b7c766aa38258aecef8a00c03612459.zip
Diffstat (limited to 'src/video_core/command_classes/codecs/codec.cpp')
-rw-r--r--src/video_core/command_classes/codecs/codec.cpp30
1 files changed, 20 insertions, 10 deletions
diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp
index 1adf3cd13..1a19341c8 100644
--- a/src/video_core/command_classes/codecs/codec.cpp
+++ b/src/video_core/command_classes/codecs/codec.cpp
@@ -18,6 +18,11 @@ extern "C" {
namespace Tegra {
+void av_frame_deleter(AVFrame* ptr) {
+ av_frame_unref(ptr);
+ av_free(ptr);
+}
+
Codec::Codec(GPU& gpu_)
: gpu(gpu_), h264_decoder(std::make_unique<Decoder::H264>(gpu)),
vp9_decoder(std::make_unique<Decoder::VP9>(gpu)) {}
@@ -27,7 +32,9 @@ Codec::~Codec() {
return;
}
// Free libav memory
+ AVFrame* av_frame{nullptr};
avcodec_send_packet(av_codec_ctx, nullptr);
+ av_frame = av_frame_alloc();
avcodec_receive_frame(av_codec_ctx, av_frame);
avcodec_flush_buffers(av_codec_ctx);
@@ -60,7 +67,7 @@ void Codec::Decode() {
}
av_codec_ctx = avcodec_alloc_context3(av_codec);
- av_frame = av_frame_alloc();
+ av_codec_ctx->refcounted_frames = 1;
av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0);
// TODO(ameerj): libavcodec gpu hw acceleration
@@ -68,8 +75,6 @@ void Codec::Decode() {
const auto av_error = avcodec_open2(av_codec_ctx, av_codec, nullptr);
if (av_error < 0) {
LOG_ERROR(Service_NVDRV, "avcodec_open2() Failed.");
- av_frame_unref(av_frame);
- av_free(av_frame);
avcodec_close(av_codec_ctx);
return;
}
@@ -96,16 +101,21 @@ void Codec::Decode() {
if (!vp9_hidden_frame) {
// Only receive/store visible frames
- avcodec_receive_frame(av_codec_ctx, av_frame);
+ AVFramePtr frame = AVFramePtr{av_frame_alloc(), av_frame_deleter};
+ avcodec_receive_frame(av_codec_ctx, frame.get());
+ av_frames.push(std::move(frame));
}
}
-AVFrame* Codec::GetCurrentFrame() {
- return av_frame;
-}
-
-const AVFrame* Codec::GetCurrentFrame() const {
- return av_frame;
+AVFramePtr Codec::GetCurrentFrame() {
+ // Sometimes VIC will request more frames than have been decoded.
+ // in this case, return a nullptr and don't overwrite previous frame data
+ if (av_frames.size() > 0) {
+ AVFramePtr frame = std::move(av_frames.front());
+ av_frames.pop();
+ return frame;
+ }
+ return AVFramePtr{nullptr, av_frame_deleter};
}
NvdecCommon::VideoCodec Codec::GetCurrentCodec() const {