mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Addressed reviews
This commit is contained in:
		
							parent
							
								
									847003cc1c
								
							
						
					
					
						commit
						bd9984b5f8
					
				
					 14 changed files with 282 additions and 225 deletions
				
			
		|  | @ -3,7 +3,7 @@ | |||
| cd /citra | ||||
| 
 | ||||
| mkdir build && cd build | ||||
| cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_FFMPEG=OFF | ||||
| cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON | ||||
| make -j4 | ||||
| 
 | ||||
| ctest -VV -C Release | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ cd /citra | |||
| echo 'max_size = 3.0G' > "$HOME/.ccache/ccache.conf" | ||||
| 
 | ||||
| mkdir build && cd build | ||||
| cmake .. -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DUSE_CCACHE=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON | ||||
| cmake .. -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DUSE_CCACHE=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_FFMPEG=ON | ||||
| make -j4 | ||||
| 
 | ||||
| echo "Tests skipped" | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
| cd /citra | ||||
| 
 | ||||
| mkdir build && cd build | ||||
| cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_FFMPEG=OFF | ||||
| cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON | ||||
| make -j4 | ||||
| 
 | ||||
| ctest -VV -C Release | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ export Qt5_DIR=$(brew --prefix)/opt/qt5 | |||
| export PATH="/usr/local/opt/ccache/libexec:$PATH" | ||||
| 
 | ||||
| mkdir build && cd build | ||||
| cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64;x86_64h" -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON | ||||
| cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64;x86_64h" -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_FFMPEG=ON | ||||
| make -j4 | ||||
| 
 | ||||
| ctest -VV -C Release | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ tx --version | |||
| 
 | ||||
| cd /citra | ||||
| mkdir build && cd build | ||||
| cmake .. -DENABLE_QT_TRANSLATION=ON -DGENERATE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_SDL2=OFF -DENABLE_FFMPEG=OFF | ||||
| cmake .. -DENABLE_QT_TRANSLATION=ON -DGENERATE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_SDL2=OFF | ||||
| make translation | ||||
| cd .. | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON) | |||
| 
 | ||||
| option(ENABLE_CUBEB "Enables the cubeb audio backend" ON) | ||||
| 
 | ||||
| option(ENABLE_FFMPEG "Enable FFmpeg decoder/encoder" ON) | ||||
| option(ENABLE_FFMPEG "Enable FFmpeg decoder/encoder" OFF) | ||||
| 
 | ||||
| option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF) | ||||
| 
 | ||||
|  |  | |||
|  | @ -43,9 +43,9 @@ before_build: | |||
|         $COMPAT = if ($env:ENABLE_COMPATIBILITY_REPORTING -eq $null) {0} else {$env:ENABLE_COMPATIBILITY_REPORTING} | ||||
|         if ($env:BUILD_TYPE -eq 'msvc') { | ||||
|           # redirect stderr and change the exit code to prevent powershell from cancelling the build if cmake prints a warning | ||||
|           cmd /C 'cmake -G "Visual Studio 15 2017 Win64" -DCITRA_USE_BUNDLED_QT=1 -DCITRA_USE_BUNDLED_SDL2=1 -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON .. 2>&1 && exit 0' | ||||
|           cmd /C 'cmake -G "Visual Studio 15 2017 Win64" -DCITRA_USE_BUNDLED_QT=1 -DCITRA_USE_BUNDLED_SDL2=1 -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON  -DENABLE_FFMPEG=ON .. 2>&1 && exit 0' | ||||
|         } else { | ||||
|           C:\msys64\usr\bin\bash.exe -lc "cmake -G 'MSYS Makefiles' -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON .. 2>&1" | ||||
|           C:\msys64\usr\bin\bash.exe -lc "cmake -G 'MSYS Makefiles' -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON  -DENABLE_FFMPEG=ON .. 2>&1" | ||||
|         } | ||||
|   - cd .. | ||||
| 
 | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ add_library(audio_core STATIC | |||
| 
 | ||||
|     $<$<BOOL:${SDL2_FOUND}>:sdl2_sink.cpp sdl2_sink.h> | ||||
|     $<$<BOOL:${ENABLE_CUBEB}>:cubeb_sink.cpp cubeb_sink.h> | ||||
|     $<$<BOOL:${FFMPEG_FOUND}>:hle/aac_decoder.cpp hle/aac_decoder.h hle/ffmpeg_dl.h> | ||||
|     $<$<BOOL:${FFMPEG_FOUND}>:hle/aac_decoder.cpp hle/aac_decoder.h hle/ffmpeg_dl.cpp hle/ffmpeg_dl.h> | ||||
| ) | ||||
| 
 | ||||
| create_target_directory_groups(audio_core) | ||||
|  |  | |||
|  | @ -20,28 +20,47 @@ private: | |||
| 
 | ||||
|     std::optional<BinaryResponse> Decode(const BinaryRequest& request); | ||||
| 
 | ||||
|     bool initalized; | ||||
|     struct AVPacketDeleter { | ||||
|         void operator()(AVPacket* packet) const { | ||||
|             av_packet_free_dl(&packet); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     struct AVCodecContextDeleter { | ||||
|         void operator()(AVCodecContext* context) const { | ||||
|             avcodec_free_context_dl(&context); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     struct AVCodecParserContextDeleter { | ||||
|         void operator()(AVCodecParserContext* parser) const { | ||||
|             av_parser_close_dl(parser); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     struct AVFrameDeleter { | ||||
|         void operator()(AVFrame* frame) const { | ||||
|             av_frame_free_dl(&frame); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     bool initalized = false; | ||||
|     bool have_ffmpeg_dl; | ||||
| 
 | ||||
|     Memory::MemorySystem& memory; | ||||
| 
 | ||||
|     AVCodec* codec; | ||||
|     AVCodecContext* av_context = nullptr; | ||||
|     AVCodecParserContext* parser = nullptr; | ||||
|     AVPacket* av_packet; | ||||
|     AVFrame* decoded_frame = nullptr; | ||||
|     std::unique_ptr<AVCodecContext, AVCodecContextDeleter> av_context; | ||||
|     std::unique_ptr<AVCodecParserContext, AVCodecParserContextDeleter> parser; | ||||
|     std::unique_ptr<AVPacket, AVPacketDeleter> av_packet; | ||||
|     std::unique_ptr<AVFrame, AVFrameDeleter> decoded_frame; | ||||
| }; | ||||
| 
 | ||||
| AACDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) { | ||||
|     initalized = false; | ||||
| 
 | ||||
|     have_ffmpeg_dl = InitFFmpegDL(); | ||||
| } | ||||
| 
 | ||||
| AACDecoder::Impl::~Impl() { | ||||
|     if (initalized) | ||||
|         Clear(); | ||||
| } | ||||
| AACDecoder::Impl::~Impl() = default; | ||||
| 
 | ||||
| std::optional<BinaryResponse> AACDecoder::Impl::ProcessRequest(const BinaryRequest& request) { | ||||
|     if (request.codec != DecoderCodec::AAC) { | ||||
|  | @ -52,23 +71,19 @@ std::optional<BinaryResponse> AACDecoder::Impl::ProcessRequest(const BinaryReque | |||
|     switch (request.cmd) { | ||||
|     case DecoderCommand::Init: { | ||||
|         return Initalize(request); | ||||
|         break; | ||||
|     } | ||||
|     case DecoderCommand::Decode: { | ||||
|         return Decode(request); | ||||
|         break; | ||||
|     } | ||||
|     case DecoderCommand::Unknown: { | ||||
|         BinaryResponse response; | ||||
|         std::memcpy(&response, &request, sizeof(response)); | ||||
|         response.unknown1 = 0x0; | ||||
|         return response; | ||||
|         break; | ||||
|     } | ||||
|     default: | ||||
|         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", static_cast<u16>(request.cmd)); | ||||
|         return {}; | ||||
|         break; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -85,7 +100,7 @@ std::optional<BinaryResponse> AACDecoder::Impl::Initalize(const BinaryRequest& r | |||
|         return response; | ||||
|     } | ||||
| 
 | ||||
|     av_packet = av_packet_alloc_dl(); | ||||
|     av_packet.reset(av_packet_alloc_dl()); | ||||
| 
 | ||||
|     codec = avcodec_find_decoder_dl(AV_CODEC_ID_AAC); | ||||
|     if (!codec) { | ||||
|  | @ -93,19 +108,19 @@ std::optional<BinaryResponse> AACDecoder::Impl::Initalize(const BinaryRequest& r | |||
|         return response; | ||||
|     } | ||||
| 
 | ||||
|     parser = av_parser_init_dl(codec->id); | ||||
|     parser.reset(av_parser_init_dl(codec->id)); | ||||
|     if (!parser) { | ||||
|         LOG_ERROR(Audio_DSP, "Parser not found\n"); | ||||
|         return response; | ||||
|     } | ||||
| 
 | ||||
|     av_context = avcodec_alloc_context3_dl(codec); | ||||
|     av_context.reset(avcodec_alloc_context3_dl(codec)); | ||||
|     if (!av_context) { | ||||
|         LOG_ERROR(Audio_DSP, "Could not allocate audio codec context\n"); | ||||
|         return response; | ||||
|     } | ||||
| 
 | ||||
|     if (avcodec_open2_dl(av_context, codec, NULL) < 0) { | ||||
|     if (avcodec_open2_dl(av_context.get(), codec, nullptr) < 0) { | ||||
|         LOG_ERROR(Audio_DSP, "Could not open codec\n"); | ||||
|         return response; | ||||
|     } | ||||
|  | @ -119,23 +134,23 @@ void AACDecoder::Impl::Clear() { | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     avcodec_free_context_dl(&av_context); | ||||
|     av_parser_close_dl(parser); | ||||
|     av_frame_free_dl(&decoded_frame); | ||||
|     av_packet_free_dl(&av_packet); | ||||
|     av_context.reset(); | ||||
|     parser.reset(); | ||||
|     decoded_frame.reset(); | ||||
|     av_packet.reset(); | ||||
| } | ||||
| 
 | ||||
| std::optional<BinaryResponse> AACDecoder::Impl::Decode(const BinaryRequest& request) { | ||||
|     BinaryResponse response; | ||||
|     response.codec = request.codec; | ||||
|     response.cmd = request.cmd; | ||||
|     response.size = request.size; | ||||
| 
 | ||||
|     if (!initalized) { | ||||
|         LOG_DEBUG(Audio_DSP, "Decoder not initalized"); | ||||
| 
 | ||||
|         // This is a hack to continue games that are not compiled with the aac codec
 | ||||
|         BinaryResponse response; | ||||
|         response.codec = request.codec; | ||||
|         response.cmd = request.cmd; | ||||
|         response.num_channels = 2; | ||||
|         response.num_samples = 1024; | ||||
|         response.size = request.size; | ||||
|         return response; | ||||
|     } | ||||
| 
 | ||||
|  | @ -151,14 +166,16 @@ std::optional<BinaryResponse> AACDecoder::Impl::Decode(const BinaryRequest& requ | |||
|     std::size_t data_size = request.size; | ||||
|     while (data_size > 0) { | ||||
|         if (!decoded_frame) { | ||||
|             if (!(decoded_frame = av_frame_alloc_dl())) { | ||||
|             decoded_frame.reset(av_frame_alloc_dl()); | ||||
|             if (!decoded_frame) { | ||||
|                 LOG_ERROR(Audio_DSP, "Could not allocate audio frame"); | ||||
|                 return {}; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         int ret = av_parser_parse2_dl(parser, av_context, &av_packet->data, &av_packet->size, data, | ||||
|                                       data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0); | ||||
|         int ret = | ||||
|             av_parser_parse2_dl(parser.get(), av_context.get(), &av_packet->data, &av_packet->size, | ||||
|                                 data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0); | ||||
|         if (ret < 0) { | ||||
|             LOG_ERROR(Audio_DSP, "Error while parsing"); | ||||
|             return {}; | ||||
|  | @ -166,7 +183,7 @@ std::optional<BinaryResponse> AACDecoder::Impl::Decode(const BinaryRequest& requ | |||
|         data += ret; | ||||
|         data_size -= ret; | ||||
| 
 | ||||
|         ret = avcodec_send_packet_dl(av_context, av_packet); | ||||
|         ret = avcodec_send_packet_dl(av_context.get(), av_packet.get()); | ||||
|         if (ret < 0) { | ||||
|             LOG_ERROR(Audio_DSP, "Error submitting the packet to the decoder"); | ||||
|             return {}; | ||||
|  | @ -174,7 +191,7 @@ std::optional<BinaryResponse> AACDecoder::Impl::Decode(const BinaryRequest& requ | |||
| 
 | ||||
|         if (av_packet->size) { | ||||
|             while (ret >= 0) { | ||||
|                 ret = avcodec_receive_frame_dl(av_context, decoded_frame); | ||||
|                 ret = avcodec_receive_frame_dl(av_context.get(), decoded_frame.get()); | ||||
|                 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) | ||||
|                     break; | ||||
|                 else if (ret < 0) { | ||||
|  | @ -187,16 +204,19 @@ std::optional<BinaryResponse> AACDecoder::Impl::Decode(const BinaryRequest& requ | |||
|                     return {}; | ||||
|                 } | ||||
| 
 | ||||
|                 ASSERT(decoded_frame->channels == out_streams.size()); | ||||
|                 ASSERT(decoded_frame->channels <= out_streams.size()); | ||||
| 
 | ||||
|                 std::size_t size = bytes_per_sample * (decoded_frame->nb_samples); | ||||
| 
 | ||||
|                 response.num_channels = decoded_frame->channels; | ||||
|                 response.num_samples += decoded_frame->nb_samples; | ||||
| 
 | ||||
|                 // 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;) { | ||||
|                     for (std::size_t channel(0); channel < out_streams.size(); channel++) { | ||||
|                         std::memcpy(&val_float, decoded_frame->data[0] + current_pos, | ||||
|                     for (std::size_t channel(0); channel < decoded_frame->channels; channel++) { | ||||
|                         std::memcpy(&val_float, decoded_frame->data[channel] + current_pos, | ||||
|                                     sizeof(val_float)); | ||||
|                         s16 val = static_cast<s16>(0x7FFF * val_float); | ||||
|                         out_streams[channel].push_back(val & 0xFF); | ||||
|  | @ -208,28 +228,27 @@ std::optional<BinaryResponse> AACDecoder::Impl::Decode(const BinaryRequest& requ | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     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 {}; | ||||
|     if (out_streams[0].size() != 0) { | ||||
|         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()); | ||||
|     } | ||||
|     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 || | ||||
|         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 {}; | ||||
|     if (out_streams[1].size() != 0) { | ||||
|         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 {}; | ||||
|         } | ||||
|         std::memcpy(memory.GetFCRAMPointer(request.dst_addr_ch1 - Memory::FCRAM_PADDR), | ||||
|                     out_streams[1].data(), out_streams[1].size()); | ||||
|     } | ||||
|     std::memcpy(memory.GetFCRAMPointer(request.dst_addr_ch1 - Memory::FCRAM_PADDR), | ||||
|                 out_streams[1].data(), out_streams[1].size()); | ||||
| 
 | ||||
|     BinaryResponse response; | ||||
|     response.codec = request.codec; | ||||
|     response.cmd = request.cmd; | ||||
|     response.num_channels = 2; | ||||
|     response.num_samples = decoded_frame->nb_samples; | ||||
|     response.size = request.size; | ||||
|     return response; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ namespace AudioCore::HLE { | |||
| 
 | ||||
| class AACDecoder final : public DecoderBase { | ||||
| public: | ||||
|     AACDecoder(Memory::MemorySystem& memory); | ||||
|     explicit AACDecoder(Memory::MemorySystem& memory); | ||||
|     ~AACDecoder() override; | ||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override; | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,7 +6,9 @@ | |||
| 
 | ||||
| namespace AudioCore::HLE { | ||||
| 
 | ||||
| NullDecoder::NullDecoder() {} | ||||
| DecoderBase::~DecoderBase(){}; | ||||
| 
 | ||||
| NullDecoder::NullDecoder() = default; | ||||
| 
 | ||||
| NullDecoder::~NullDecoder() = default; | ||||
| 
 | ||||
|  |  | |||
|  | @ -54,7 +54,7 @@ static_assert(sizeof(BinaryResponse) == 32, "Unexpected struct size for BinaryRe | |||
| 
 | ||||
| class DecoderBase { | ||||
| public: | ||||
|     virtual ~DecoderBase(){}; | ||||
|     virtual ~DecoderBase(); | ||||
|     virtual std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) = 0; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										173
									
								
								src/audio_core/hle/ffmpeg_dl.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								src/audio_core/hle/ffmpeg_dl.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,173 @@ | |||
| // Copyright 2018 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| 
 | ||||
| #include <memory> | ||||
| #include "audio_core/hle/ffmpeg_dl.h" | ||||
| #include "common/file_util.h" | ||||
| #include "common/logging/log.h" | ||||
| 
 | ||||
| struct LibraryDeleter { | ||||
|     typedef HMODULE pointer; | ||||
|     void operator()(HMODULE h) { | ||||
|         if (h != nullptr) | ||||
|             FreeLibrary(h); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| std::unique_ptr<HMODULE, LibraryDeleter> dll_util{nullptr}; | ||||
| std::unique_ptr<HMODULE, LibraryDeleter> dll_codec{nullptr}; | ||||
| 
 | ||||
| FuncDL<int(AVSampleFormat)> av_get_bytes_per_sample_dl; | ||||
| FuncDL<AVFrame*(void)> av_frame_alloc_dl; | ||||
| FuncDL<void(AVFrame**)> av_frame_free_dl; | ||||
| FuncDL<AVCodecContext*(const AVCodec*)> avcodec_alloc_context3_dl; | ||||
| FuncDL<void(AVCodecContext**)> avcodec_free_context_dl; | ||||
| FuncDL<int(AVCodecContext*, const AVCodec*, AVDictionary**)> avcodec_open2_dl; | ||||
| FuncDL<AVPacket*(void)> av_packet_alloc_dl; | ||||
| FuncDL<void(AVPacket**)> av_packet_free_dl; | ||||
| FuncDL<AVCodec*(AVCodecID)> avcodec_find_decoder_dl; | ||||
| FuncDL<int(AVCodecContext*, const AVPacket*)> avcodec_send_packet_dl; | ||||
| FuncDL<int(AVCodecContext*, AVFrame*)> avcodec_receive_frame_dl; | ||||
| FuncDL<AVCodecParserContext*(int)> av_parser_init_dl; | ||||
| FuncDL<int(AVCodecParserContext*, AVCodecContext*, uint8_t**, int*, const uint8_t*, int, int64_t, | ||||
|            int64_t, int64_t)> | ||||
|     av_parser_parse2_dl; | ||||
| FuncDL<void(AVCodecParserContext*)> av_parser_close_dl; | ||||
| 
 | ||||
| bool InitFFmpegDL() { | ||||
|     std::string dll_path = FileUtil::GetUserPath(FileUtil::UserPath::DLLDir); | ||||
|     FileUtil::CreateDir(dll_path); | ||||
|     std::wstring w_dll_path = std::wstring(dll_path.begin(), dll_path.end()); | ||||
|     SetDllDirectoryW(w_dll_path.c_str()); | ||||
| 
 | ||||
|     dll_util.reset(LoadLibrary("avutil-56.dll")); | ||||
|     if (!dll_util) { | ||||
|         DWORD error_message_id = GetLastError(); | ||||
|         LPSTR message_buffer = nullptr; | ||||
|         size_t size = | ||||
|             FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | | ||||
|                                FORMAT_MESSAGE_IGNORE_INSERTS, | ||||
|                            nullptr, error_message_id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||||
|                            reinterpret_cast<LPSTR>(&message_buffer), 0, nullptr); | ||||
| 
 | ||||
|         std::string message(message_buffer, size); | ||||
| 
 | ||||
|         LocalFree(message_buffer); | ||||
|         LOG_ERROR(Audio_DSP, "Could not load avutil-56.dll: {}", message); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     dll_codec.reset(LoadLibrary("avcodec-58.dll")); | ||||
|     if (!dll_codec) { | ||||
|         DWORD error_message_id = GetLastError(); | ||||
|         LPSTR message_buffer = nullptr; | ||||
|         size_t size = | ||||
|             FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | | ||||
|                                FORMAT_MESSAGE_IGNORE_INSERTS, | ||||
|                            nullptr, error_message_id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||||
|                            reinterpret_cast<LPSTR>(&message_buffer), 0, nullptr); | ||||
| 
 | ||||
|         std::string message(message_buffer, size); | ||||
| 
 | ||||
|         LocalFree(message_buffer); | ||||
|         LOG_ERROR(Audio_DSP, "Could not load avcodec-58.dll: {}", message); | ||||
|         return false; | ||||
|     } | ||||
|     av_get_bytes_per_sample_dl = | ||||
|         FuncDL<int(AVSampleFormat)>(dll_util.get(), "av_get_bytes_per_sample"); | ||||
|     if (!av_get_bytes_per_sample_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_get_bytes_per_sample"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     av_frame_alloc_dl = FuncDL<AVFrame*()>(dll_util.get(), "av_frame_alloc"); | ||||
|     if (!av_frame_alloc_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_frame_alloc"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     av_frame_free_dl = FuncDL<void(AVFrame**)>(dll_util.get(), "av_frame_free"); | ||||
|     if (!av_frame_free_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_frame_free"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     avcodec_alloc_context3_dl = | ||||
|         FuncDL<AVCodecContext*(const AVCodec*)>(dll_codec.get(), "avcodec_alloc_context3"); | ||||
|     if (!avcodec_alloc_context3_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function avcodec_alloc_context3"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     avcodec_free_context_dl = | ||||
|         FuncDL<void(AVCodecContext**)>(dll_codec.get(), "avcodec_free_context"); | ||||
|     if (!av_get_bytes_per_sample_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function avcodec_free_context"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     avcodec_open2_dl = FuncDL<int(AVCodecContext*, const AVCodec*, AVDictionary**)>( | ||||
|         dll_codec.get(), "avcodec_open2"); | ||||
|     if (!avcodec_open2_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function avcodec_open2"); | ||||
|         return false; | ||||
|     } | ||||
|     av_packet_alloc_dl = FuncDL<AVPacket*(void)>(dll_codec.get(), "av_packet_alloc"); | ||||
|     if (!av_packet_alloc_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_packet_alloc"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     av_packet_free_dl = FuncDL<void(AVPacket**)>(dll_codec.get(), "av_packet_free"); | ||||
|     if (!av_packet_free_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_packet_free"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     avcodec_find_decoder_dl = FuncDL<AVCodec*(AVCodecID)>(dll_codec.get(), "avcodec_find_decoder"); | ||||
|     if (!avcodec_find_decoder_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function avcodec_find_decoder"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     avcodec_send_packet_dl = | ||||
|         FuncDL<int(AVCodecContext*, const AVPacket*)>(dll_codec.get(), "avcodec_send_packet"); | ||||
|     if (!avcodec_send_packet_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function avcodec_send_packet"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     avcodec_receive_frame_dl = | ||||
|         FuncDL<int(AVCodecContext*, AVFrame*)>(dll_codec.get(), "avcodec_receive_frame"); | ||||
|     if (!avcodec_receive_frame_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function avcodec_receive_frame"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     av_parser_init_dl = FuncDL<AVCodecParserContext*(int)>(dll_codec.get(), "av_parser_init"); | ||||
|     if (!av_parser_init_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_parser_init"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     av_parser_parse2_dl = | ||||
|         FuncDL<int(AVCodecParserContext*, AVCodecContext*, uint8_t**, int*, const uint8_t*, int, | ||||
|                    int64_t, int64_t, int64_t)>(dll_codec.get(), "av_parser_parse2"); | ||||
|     if (!av_parser_parse2_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_parser_parse2"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     av_parser_close_dl = FuncDL<void(AVCodecParserContext*)>(dll_codec.get(), "av_parser_close"); | ||||
|     if (!av_parser_close_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_parser_close"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| #endif // _Win32
 | ||||
|  | @ -8,9 +8,6 @@ | |||
| #include <windows.h> | ||||
| #endif // _WIN32
 | ||||
| 
 | ||||
| #include "common/file_util.h" | ||||
| #include "common/logging/log.h" | ||||
| 
 | ||||
| extern "C" { | ||||
| #include "libavcodec/avcodec.h" | ||||
| } | ||||
|  | @ -20,9 +17,9 @@ extern "C" { | |||
| template <typename T> | ||||
| struct FuncDL { | ||||
|     FuncDL() = default; | ||||
|     FuncDL(HMODULE dll, const char* name) { | ||||
|     FuncDL(void* dll, const char* name) { | ||||
|         if (dll) { | ||||
|             ptr_function = reinterpret_cast<T*>(GetProcAddress(dll, name)); | ||||
|             ptr_function = reinterpret_cast<T*>(GetProcAddress((HMODULE)dll, name)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -30,167 +27,33 @@ struct FuncDL { | |||
|         return ptr_function; | ||||
|     } | ||||
| 
 | ||||
|     operator bool() const { | ||||
|     explicit operator bool() const { | ||||
|         return ptr_function != nullptr; | ||||
|     } | ||||
| 
 | ||||
|     T* ptr_function = nullptr; | ||||
| }; | ||||
| 
 | ||||
| FuncDL<int(AVSampleFormat)> av_get_bytes_per_sample_dl; | ||||
| FuncDL<AVFrame*(void)> av_frame_alloc_dl; | ||||
| FuncDL<void(AVFrame**)> av_frame_free_dl; | ||||
| FuncDL<AVCodecContext*(const AVCodec*)> avcodec_alloc_context3_dl; | ||||
| FuncDL<void(AVCodecContext**)> avcodec_free_context_dl; | ||||
| FuncDL<int(AVCodecContext*, const AVCodec*, AVDictionary**)> avcodec_open2_dl; | ||||
| FuncDL<AVPacket*(void)> av_packet_alloc_dl; | ||||
| FuncDL<void(AVPacket**)> av_packet_free_dl; | ||||
| FuncDL<AVCodec*(AVCodecID)> avcodec_find_decoder_dl; | ||||
| FuncDL<int(AVCodecContext*, const AVPacket*)> avcodec_send_packet_dl; | ||||
| FuncDL<int(AVCodecContext*, AVFrame*)> avcodec_receive_frame_dl; | ||||
| FuncDL<AVCodecParserContext*(int)> av_parser_init_dl; | ||||
| FuncDL<int(AVCodecParserContext*, AVCodecContext*, uint8_t**, int*, const uint8_t*, int, int64_t, | ||||
|            int64_t, int64_t)> | ||||
| extern FuncDL<int(AVSampleFormat)> av_get_bytes_per_sample_dl; | ||||
| extern FuncDL<AVFrame*(void)> av_frame_alloc_dl; | ||||
| extern FuncDL<void(AVFrame**)> av_frame_free_dl; | ||||
| extern FuncDL<AVCodecContext*(const AVCodec*)> avcodec_alloc_context3_dl; | ||||
| extern FuncDL<void(AVCodecContext**)> avcodec_free_context_dl; | ||||
| extern FuncDL<int(AVCodecContext*, const AVCodec*, AVDictionary**)> avcodec_open2_dl; | ||||
| extern FuncDL<AVPacket*(void)> av_packet_alloc_dl; | ||||
| extern FuncDL<void(AVPacket**)> av_packet_free_dl; | ||||
| extern FuncDL<AVCodec*(AVCodecID)> avcodec_find_decoder_dl; | ||||
| extern FuncDL<int(AVCodecContext*, const AVPacket*)> avcodec_send_packet_dl; | ||||
| extern FuncDL<int(AVCodecContext*, AVFrame*)> avcodec_receive_frame_dl; | ||||
| extern FuncDL<AVCodecParserContext*(int)> av_parser_init_dl; | ||||
| extern FuncDL<int(AVCodecParserContext*, AVCodecContext*, uint8_t**, int*, const uint8_t*, int, | ||||
|                   int64_t, int64_t, int64_t)> | ||||
|     av_parser_parse2_dl; | ||||
| FuncDL<void(AVCodecParserContext*)> av_parser_close_dl; | ||||
| extern FuncDL<void(AVCodecParserContext*)> av_parser_close_dl; | ||||
| 
 | ||||
| bool InitFFmpegDL() { | ||||
| 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) { | ||||
|         DWORD errorMessageID = GetLastError(); | ||||
|         LPSTR messageBuffer = nullptr; | ||||
|         size_t size = | ||||
|             FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | | ||||
|                                FORMAT_MESSAGE_IGNORE_INSERTS, | ||||
|                            NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||||
|                            (LPSTR)&messageBuffer, 0, NULL); | ||||
| 
 | ||||
|         std::string message(messageBuffer, size); | ||||
| 
 | ||||
|         // Free the buffer.
 | ||||
|         LocalFree(messageBuffer); | ||||
|         LOG_ERROR(Audio_DSP, "Could not load avutil-56.dll: {}", message); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     HMODULE dll_codec = nullptr; | ||||
|     dll_codec = LoadLibrary("avcodec-58.dll"); | ||||
|     if (!dll_codec) { | ||||
|         DWORD errorMessageID = GetLastError(); | ||||
|         LPSTR messageBuffer = nullptr; | ||||
|         size_t size = | ||||
|             FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | | ||||
|                                FORMAT_MESSAGE_IGNORE_INSERTS, | ||||
|                            NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||||
|                            (LPSTR)&messageBuffer, 0, NULL); | ||||
| 
 | ||||
|         std::string message(messageBuffer, size); | ||||
| 
 | ||||
|         // Free the buffer.
 | ||||
|         LocalFree(messageBuffer); | ||||
|         LOG_ERROR(Audio_DSP, "Could not load avcodec-58.dll: {}", message); | ||||
|         return false; | ||||
|     } | ||||
|     av_get_bytes_per_sample_dl = FuncDL<int(AVSampleFormat)>(dll_util, "av_get_bytes_per_sample"); | ||||
|     if (!av_get_bytes_per_sample_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_get_bytes_per_sample"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     av_frame_alloc_dl = FuncDL<AVFrame*()>(dll_util, "av_frame_alloc"); | ||||
|     if (!av_frame_alloc_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_frame_alloc"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     av_frame_free_dl = FuncDL<void(AVFrame**)>(dll_util, "av_frame_free"); | ||||
|     if (!av_frame_free_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_frame_free"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     avcodec_alloc_context3_dl = | ||||
|         FuncDL<AVCodecContext*(const AVCodec*)>(dll_codec, "avcodec_alloc_context3"); | ||||
|     if (!avcodec_alloc_context3_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function avcodec_alloc_context3"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     avcodec_free_context_dl = FuncDL<void(AVCodecContext**)>(dll_codec, "avcodec_free_context"); | ||||
|     if (!av_get_bytes_per_sample_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function avcodec_free_context"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     avcodec_open2_dl = | ||||
|         FuncDL<int(AVCodecContext*, const AVCodec*, AVDictionary**)>(dll_codec, "avcodec_open2"); | ||||
|     if (!avcodec_open2_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function avcodec_open2"); | ||||
|         return false; | ||||
|     } | ||||
|     av_packet_alloc_dl = FuncDL<AVPacket*(void)>(dll_codec, "av_packet_alloc"); | ||||
|     if (!av_packet_alloc_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_packet_alloc"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     av_packet_free_dl = FuncDL<void(AVPacket**)>(dll_codec, "av_packet_free"); | ||||
|     if (!av_packet_free_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_packet_free"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     avcodec_find_decoder_dl = FuncDL<AVCodec*(AVCodecID)>(dll_codec, "avcodec_find_decoder"); | ||||
|     if (!avcodec_find_decoder_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function avcodec_find_decoder"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     avcodec_send_packet_dl = | ||||
|         FuncDL<int(AVCodecContext*, const AVPacket*)>(dll_codec, "avcodec_send_packet"); | ||||
|     if (!avcodec_send_packet_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function avcodec_send_packet"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     avcodec_receive_frame_dl = | ||||
|         FuncDL<int(AVCodecContext*, AVFrame*)>(dll_codec, "avcodec_receive_frame"); | ||||
|     if (!avcodec_receive_frame_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function avcodec_receive_frame"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     av_parser_init_dl = FuncDL<AVCodecParserContext*(int)>(dll_codec, "av_parser_init"); | ||||
|     if (!av_parser_init_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_parser_init"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     av_parser_parse2_dl = | ||||
|         FuncDL<int(AVCodecParserContext*, AVCodecContext*, uint8_t**, int*, const uint8_t*, int, | ||||
|                    int64_t, int64_t, int64_t)>(dll_codec, "av_parser_parse2"); | ||||
|     if (!av_parser_parse2_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_parser_parse2"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     av_parser_close_dl = FuncDL<void(AVCodecParserContext*)>(dll_codec, "av_parser_close"); | ||||
|     if (!av_parser_close_dl) { | ||||
|         LOG_ERROR(Audio_DSP, "Can not load function av_parser_close"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| #endif // _Win32
 | ||||
| 
 | ||||
| #if defined(__APPLE__) || defined(__linux__) | ||||
| #else // _Win32
 | ||||
| 
 | ||||
| // No dynamic loading for Unix and Apple
 | ||||
| 
 | ||||
|  | @ -213,4 +76,4 @@ bool InitFFmpegDL() { | |||
|     return true; | ||||
| } | ||||
| 
 | ||||
| #endif // defined(__APPLE__) || defined(__linux__)
 | ||||
| #endif // _Win32
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue