From a832aa699f783f6ae0a6a1468b0aa6bc7d68c5d2 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 7 Aug 2021 23:57:22 -0400 Subject: codec: Improve libav memory alloc and cleanup --- src/video_core/command_classes/codecs/codec.cpp | 31 ++++++++++++++----------- src/video_core/command_classes/codecs/codec.h | 2 ++ 2 files changed, 19 insertions(+), 14 deletions(-) (limited to 'src') 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 { constexpr AVPixelFormat PREFERRED_GPU_FMT = AV_PIX_FMT_NV12; constexpr AVPixelFormat PREFERRED_CPU_FMT = AV_PIX_FMT_YUV420P; +void AVPacketDeleter(AVPacket* ptr) { + av_packet_free(&ptr); +} + +using AVPacketPtr = std::unique_ptr; + AVPixelFormat GetGpuFormat(AVCodecContext* av_codec_ctx, const AVPixelFormat* pix_fmts) { for (const AVPixelFormat* p = pix_fmts; *p != AV_PIX_FMT_NONE; ++p) { if (*p == av_codec_ctx->pix_fmt) { @@ -46,11 +52,7 @@ Codec::~Codec() { return; } // Free libav memory - avcodec_send_packet(av_codec_ctx, nullptr); - AVFramePtr av_frame{av_frame_alloc(), AVFrameDeleter}; - avcodec_receive_frame(av_codec_ctx, av_frame.get()); - avcodec_flush_buffers(av_codec_ctx); - avcodec_close(av_codec_ctx); + avcodec_free_context(&av_codec_ctx); av_buffer_unref(&av_gpu_decoder); } @@ -111,6 +113,11 @@ bool Codec::CreateGpuAvDevice() { return false; } +void Codec::InitializeAvCodecContext() { + av_codec_ctx = avcodec_alloc_context3(av_codec); + av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0); +} + void Codec::InitializeGpuDecoder() { if (!CreateGpuAvDevice()) { av_buffer_unref(&av_gpu_decoder); @@ -135,13 +142,11 @@ void Codec::Initialize() { } }(); av_codec = avcodec_find_decoder(codec); - av_codec_ctx = avcodec_alloc_context3(av_codec); - av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0); - + InitializeAvCodecContext(); InitializeGpuDecoder(); if (const int res = avcodec_open2(av_codec_ctx, av_codec, nullptr); res < 0) { LOG_ERROR(Service_NVDRV, "avcodec_open2() Failed with result {}", res); - avcodec_close(av_codec_ctx); + avcodec_free_context(&av_codec_ctx); av_buffer_unref(&av_gpu_decoder); return; } @@ -174,17 +179,15 @@ void Codec::Decode() { frame_data = vp9_decoder->ComposeFrameHeader(state); vp9_hidden_frame = vp9_decoder->WasFrameHidden(); } - AVPacket* packet = av_packet_alloc(); + AVPacketPtr packet{av_packet_alloc(), AVPacketDeleter}; if (!packet) { LOG_ERROR(Service_NVDRV, "av_packet_alloc failed"); return; } packet->data = frame_data.data(); packet->size = static_cast(frame_data.size()); - const int send_pkt_ret = avcodec_send_packet(av_codec_ctx, packet); - av_packet_free(&packet); - if (send_pkt_ret != 0) { - LOG_DEBUG(Service_NVDRV, "avcodec_send_packet error {}", send_pkt_ret); + if (const int res = avcodec_send_packet(av_codec_ctx, packet.get()); res != 0) { + LOG_DEBUG(Service_NVDRV, "avcodec_send_packet error {}", res); return; } // 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: [[nodiscard]] std::string_view GetCurrentCodecName() const; private: + void InitializeAvCodecContext(); + void InitializeGpuDecoder(); bool CreateGpuAvDevice(); -- cgit v1.2.3