// Copyright 2018 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #ifdef _WIN32 #include #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 dll_util{nullptr}; std::unique_ptr dll_codec{nullptr}; FuncDL av_get_bytes_per_sample_dl; FuncDL av_frame_alloc_dl; FuncDL av_frame_free_dl; FuncDL avcodec_alloc_context3_dl; FuncDL avcodec_free_context_dl; FuncDL avcodec_open2_dl; FuncDL av_packet_alloc_dl; FuncDL av_packet_free_dl; FuncDL avcodec_find_decoder_dl; FuncDL avcodec_send_packet_dl; FuncDL avcodec_receive_frame_dl; FuncDL av_parser_init_dl; FuncDL av_parser_parse2_dl; FuncDL 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(&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(&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(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(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(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(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(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( 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(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(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(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(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(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(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(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(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