From 847003cc1c2de0802608eebae6774fedee041b8c Mon Sep 17 00:00:00 2001
From: B3N30 <benediktthomas@gmail.com>
Date: Sat, 15 Dec 2018 21:33:33 +0100
Subject: [PATCH] FFmpegDL: Added external_dlls folder to user folder
 AACDecoder: addressed reviews

---
 src/audio_core/hle/aac_decoder.cpp | 31 ++++++++++++++++--------------
 src/audio_core/hle/ffmpeg_dl.h     | 11 +++++++----
 src/common/common_paths.h          |  1 +
 src/common/file_util.cpp           |  1 +
 src/common/file_util.h             |  1 +
 5 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/src/audio_core/hle/aac_decoder.cpp b/src/audio_core/hle/aac_decoder.cpp
index 1e8c56163..db8a09065 100644
--- a/src/audio_core/hle/aac_decoder.cpp
+++ b/src/audio_core/hle/aac_decoder.cpp
@@ -9,7 +9,7 @@ namespace AudioCore::HLE {
 
 class AACDecoder::Impl {
 public:
-    Impl(Memory::MemorySystem& memory);
+    explicit Impl(Memory::MemorySystem& memory);
     ~Impl();
     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request);
 
@@ -77,8 +77,12 @@ std::optional<BinaryResponse> AACDecoder::Impl::Initalize(const BinaryRequest& r
         Clear();
     }
 
+    BinaryResponse response;
+    std::memcpy(&response, &request, sizeof(response));
+    response.unknown1 = 0x0;
+
     if (!have_ffmpeg_dl) {
-        return {};
+        return response;
     }
 
     av_packet = av_packet_alloc_dl();
@@ -86,31 +90,27 @@ std::optional<BinaryResponse> AACDecoder::Impl::Initalize(const BinaryRequest& r
     codec = avcodec_find_decoder_dl(AV_CODEC_ID_AAC);
     if (!codec) {
         LOG_ERROR(Audio_DSP, "Codec not found\n");
-        return {};
+        return response;
     }
 
     parser = av_parser_init_dl(codec->id);
     if (!parser) {
         LOG_ERROR(Audio_DSP, "Parser not found\n");
-        return {};
+        return response;
     }
 
     av_context = avcodec_alloc_context3_dl(codec);
     if (!av_context) {
         LOG_ERROR(Audio_DSP, "Could not allocate audio codec context\n");
-        return {};
+        return response;
     }
 
     if (avcodec_open2_dl(av_context, codec, NULL) < 0) {
         LOG_ERROR(Audio_DSP, "Could not open codec\n");
-        return {};
+        return response;
     }
 
     initalized = true;
-
-    BinaryResponse response;
-    std::memcpy(&response, &request, sizeof(response));
-    response.unknown1 = 0x0;
     return response;
 }
 
@@ -139,7 +139,8 @@ std::optional<BinaryResponse> AACDecoder::Impl::Decode(const BinaryRequest& requ
         return response;
     }
 
-    if (request.src_addr < Memory::FCRAM_PADDR) {
+    if (request.src_addr < Memory::FCRAM_PADDR ||
+        request.src_addr + request.size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) {
         LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", request.src_addr);
         return {};
     }
@@ -190,7 +191,7 @@ std::optional<BinaryResponse> AACDecoder::Impl::Decode(const BinaryRequest& requ
 
                 std::size_t size = bytes_per_sample * (decoded_frame->nb_samples);
 
-                // FFmpeg converts to 32 signed floating point PCM, we need s32 PCM so we need to
+                // FFmpeg converts to 32 signed floating point PCM, we need s16 PCM so we need to
                 // convert it
                 f32 val_float;
                 for (std::size_t current_pos(0); current_pos < size;) {
@@ -207,14 +208,16 @@ std::optional<BinaryResponse> AACDecoder::Impl::Decode(const BinaryRequest& requ
         }
     }
 
-    if (request.dst_addr_ch0 < Memory::FCRAM_PADDR) {
+    if (request.dst_addr_ch0 < Memory::FCRAM_PADDR ||
+        request.dst_addr_ch0 + out_streams[0].size() > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) {
         LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch0 {:08x}", request.dst_addr_ch0);
         return {};
     }
     std::memcpy(memory.GetFCRAMPointer(request.dst_addr_ch0 - Memory::FCRAM_PADDR),
                 out_streams[0].data(), out_streams[0].size());
 
-    if (request.dst_addr_ch1 < Memory::FCRAM_PADDR) {
+    if (request.dst_addr_ch1 < Memory::FCRAM_PADDR ||
+        request.dst_addr_ch1 + out_streams[1].size() > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) {
         LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch1 {:08x}", request.dst_addr_ch1);
         return {};
     }
diff --git a/src/audio_core/hle/ffmpeg_dl.h b/src/audio_core/hle/ffmpeg_dl.h
index df787f160..61af403b9 100644
--- a/src/audio_core/hle/ffmpeg_dl.h
+++ b/src/audio_core/hle/ffmpeg_dl.h
@@ -6,8 +6,9 @@
 
 #ifdef _WIN32
 #include <windows.h>
-#endif  // _WIN32
+#endif // _WIN32
 
+#include "common/file_util.h"
 #include "common/logging/log.h"
 
 extern "C" {
@@ -20,9 +21,8 @@ template <typename T>
 struct FuncDL {
     FuncDL() = default;
     FuncDL(HMODULE dll, const char* name) {
-        ptr_function = nullptr;
         if (dll) {
-            *(void**)&ptr_function = (void*)GetProcAddress(dll, name);
+            ptr_function = reinterpret_cast<T*>(GetProcAddress(dll, name));
         }
     }
 
@@ -35,7 +35,6 @@ struct FuncDL {
     }
 
     T* ptr_function = nullptr;
-    ;
 };
 
 FuncDL<int(AVSampleFormat)> av_get_bytes_per_sample_dl;
@@ -56,6 +55,10 @@ FuncDL<int(AVCodecParserContext*, AVCodecContext*, uint8_t**, int*, const uint8_
 FuncDL<void(AVCodecParserContext*)> av_parser_close_dl;
 
 bool InitFFmpegDL() {
+
+    FileUtil::CreateDir(FileUtil::GetUserPath(FileUtil::UserPath::DLLDir));
+    SetDllDirectoryA(FileUtil::GetUserPath(FileUtil::UserPath::DLLDir).c_str());
+
     HMODULE dll_util = nullptr;
     dll_util = LoadLibrary("avutil-56.dll");
     if (!dll_util) {
diff --git a/src/common/common_paths.h b/src/common/common_paths.h
index 908225ac8..4942c02ab 100644
--- a/src/common/common_paths.h
+++ b/src/common/common_paths.h
@@ -38,6 +38,7 @@
 #define SYSDATA_DIR "sysdata"
 #define LOG_DIR "log"
 #define CHEATS_DIR "cheats"
+#define DLL_DIR "external_dlls"
 
 // Filenames
 // Files in the directory returned by GetUserPath(UserPath::LogDir)
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index 4b95174d6..0ae9e2c5f 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -711,6 +711,7 @@ const std::string& GetUserPath(UserPath path, const std::string& new_path) {
         // TODO: Put the logs in a better location for each OS
         paths.emplace(UserPath::LogDir, user_path + LOG_DIR DIR_SEP);
         paths.emplace(UserPath::CheatsDir, user_path + CHEATS_DIR DIR_SEP);
+        paths.emplace(UserPath::DLLDir, user_path + DLL_DIR DIR_SEP);
     }
 
     if (!new_path.empty()) {
diff --git a/src/common/file_util.h b/src/common/file_util.h
index 96a30675c..d30780b97 100644
--- a/src/common/file_util.h
+++ b/src/common/file_util.h
@@ -24,6 +24,7 @@ enum class UserPath {
     CacheDir,
     CheatsDir,
     ConfigDir,
+    DLLDir,
     LogDir,
     NANDDir,
     RootDir,