Addressed reviews
This commit is contained in:
		@@ -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 -DENABLE_SCRIPTING=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_SCRIPTING=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_SCRIPTING=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 -DENABLE_SCRIPTING=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 -DENABLE_SCRIPTING=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_SCRIPTING=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_SCRIPTING=OFF -DENABLE_FFMPEG=OFF
 | 
			
		||||
cmake .. -DENABLE_QT_TRANSLATION=ON -DGENERATE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_SDL2=OFF -DENABLE_SCRIPTING=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 ..
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user