From 6332e570696762cefe8020e279fedd887b5bc5e3 Mon Sep 17 00:00:00 2001 From: liushuyu Date: Tue, 5 Feb 2019 21:13:40 -0700 Subject: [PATCH] audio_core: hle: mf: return values as std::optional --- src/audio_core/hle/adts.h | 2 +- src/audio_core/hle/adts_reader.cpp | 27 +++++++++++---------- src/audio_core/hle/wmf_decoder.cpp | 13 ++++------ src/audio_core/hle/wmf_decoder_utils.cpp | 30 ++++++++++++++++-------- src/audio_core/hle/wmf_decoder_utils.h | 6 +++-- 5 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/audio_core/hle/adts.h b/src/audio_core/hle/adts.h index d662c221c..fd11555a9 100644 --- a/src/audio_core/hle/adts.h +++ b/src/audio_core/hle/adts.h @@ -16,7 +16,7 @@ struct ADTSData { u32 samplerate; }; -u32 ParseADTS(char* buffer, ADTSData* out); +ADTSData ParseADTS(char* buffer); // last two bytes of MF AAC decoder user data // see https://docs.microsoft.com/en-us/windows/desktop/medfound/aac-decoder#example-media-types diff --git a/src/audio_core/hle/adts_reader.cpp b/src/audio_core/hle/adts_reader.cpp index 58201d162..42ac4afa2 100644 --- a/src/audio_core/hle/adts_reader.cpp +++ b/src/audio_core/hle/adts_reader.cpp @@ -8,36 +8,39 @@ constexpr std::array freq_table = {96000, 88200, 64000, 48000, 44100, 3 16000, 12000, 11025, 8000, 7350, 0, 0, 0}; constexpr std::array channel_table = {0, 1, 2, 3, 4, 5, 6, 8}; -u32 ParseADTS(char* buffer, ADTSData* out) { +ADTSData ParseADTS(char* buffer) { u32 tmp = 0; + ADTSData out; // sync word 0xfff tmp = (buffer[0] << 8) | (buffer[1] & 0xf0); - if ((tmp & 0xffff) != 0xfff0) - return 0; - out->MPEG2 = (buffer[1] >> 3) & 0x1; + if ((tmp & 0xffff) != 0xfff0) { + out.length = 0; + return out; + } + out.MPEG2 = (buffer[1] >> 3) & 0x1; // bit 17 to 18 - out->profile = (buffer[2] >> 6) + 1; + out.profile = (buffer[2] >> 6) + 1; // bit 19 to 22 tmp = (buffer[2] >> 2) & 0xf; - out->samplerate_idx = tmp; - out->samplerate = (tmp > 15) ? 0 : freq_table[tmp]; + out.samplerate_idx = tmp; + out.samplerate = (tmp > 15) ? 0 : freq_table[tmp]; // bit 24 to 26 tmp = ((buffer[2] & 0x1) << 2) | ((buffer[3] >> 6) & 0x3); - out->channel_idx = tmp; - out->channels = (tmp > 7) ? 0 : channel_table[tmp]; + out.channel_idx = tmp; + out.channels = (tmp > 7) ? 0 : channel_table[tmp]; // bit 55 to 56 - out->framecount = (buffer[6] & 0x3) + 1; + out.framecount = (buffer[6] & 0x3) + 1; // bit 31 to 43 tmp = (buffer[3] & 0x3) << 11; tmp |= (buffer[4] << 3) & 0x7f8; tmp |= (buffer[5] >> 5) & 0x7; - out->length = tmp; + out.length = tmp; - return tmp; + return out; } // last two bytes of MF AAC decoder user data diff --git a/src/audio_core/hle/wmf_decoder.cpp b/src/audio_core/hle/wmf_decoder.cpp index 7440049f4..2d448a216 100644 --- a/src/audio_core/hle/wmf_decoder.cpp +++ b/src/audio_core/hle/wmf_decoder.cpp @@ -104,8 +104,7 @@ void WMFDecoder::Impl::Clear() { MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header, std::array, 2>& out_streams) { MFOutputState output_status = MFOutputState::OK; - char* output_buffer = nullptr; - DWORD output_len = 0; + std::optional> output_buffer; unique_mfptr output; while (true) { @@ -113,22 +112,18 @@ MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header, // 0 -> okay; 3 -> okay but more data available (buffer too small) if (output_status == MFOutputState::OK || output_status == MFOutputState::HaveMoreData) { - CopySampleToBuffer(output.get(), (void**)&output_buffer, &output_len); + output_buffer = CopySampleToBuffer(output.get()); // the following was taken from ffmpeg version of the decoder f32 val_f32; - for (size_t i = 0; i < output_len;) { + for (size_t i = 0; i < output_buffer->size(); i++) { for (std::size_t channel = 0; channel < adts_header.channels; channel++) { - std::memcpy(&val_f32, output_buffer + i, sizeof(val_f32)); + val_f32 = output_buffer->at(i); s16 val = static_cast(0x7FFF * val_f32); out_streams[channel].push_back(val & 0xFF); out_streams[channel].push_back(val >> 8); - i += sizeof(val_f32); } } - - if (output_buffer) - free(output_buffer); } // in case of "ok" only, just return quickly diff --git a/src/audio_core/hle/wmf_decoder_utils.cpp b/src/audio_core/hle/wmf_decoder_utils.cpp index 8ecfae1af..8f0147a2c 100644 --- a/src/audio_core/hle/wmf_decoder_utils.cpp +++ b/src/audio_core/hle/wmf_decoder_utils.cpp @@ -25,6 +25,12 @@ void ReportError(std::string msg, HRESULT hr) { bool MFCoInit() { HRESULT hr = S_OK; + hr = CoInitialize(NULL); + // S_FALSE will be returned when COM has already been initialized + if (hr != S_OK && hr != S_FALSE) { + ReportError("Failed to start COM components", hr); + return false; + } // lite startup is faster and all what we need is included hr = MFStartup(MF_VERSION, MFSTARTUP_LITE); @@ -216,8 +222,8 @@ int DetectMediaType(char* buffer, size_t len, ADTSData* output, char** aac_tag) UINT8 aac_tmp[] = {0x01, 0x00, 0xfe, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x00, 0x00}; uint16_t tag = 0; - uint32_t result = ParseADTS(buffer, &tmp); - if (result == 0) { + tmp = ParseADTS(buffer); + if (tmp.length == 0) { return -1; } @@ -325,33 +331,37 @@ std::tuple> ReceiveSample(IMFTransform* t return std::make_tuple(MFOutputState::OK, std::move(sample)); } -int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len) { +std::optional> CopySampleToBuffer(IMFSample* sample) { unique_mfptr buffer; HRESULT hr = S_OK; + std::optional> output; + std::vector output_buffer; BYTE* data; + DWORD len = 0; - hr = sample->GetTotalLength(len); + hr = sample->GetTotalLength(&len); if (FAILED(hr)) { ReportError("Failed to get the length of sample buffer", hr); - return -1; + return std::nullopt; } hr = sample->ConvertToContiguousBuffer(Amp(buffer)); if (FAILED(hr)) { ReportError("Failed to get sample buffer", hr); - return -1; + return std::nullopt; } hr = buffer->Lock(&data, nullptr, nullptr); if (FAILED(hr)) { ReportError("Failed to lock the buffer", hr); - return -1; + return std::nullopt; } - *output = malloc(*len); - std::memcpy(*output, data, *len); + output_buffer.resize(len / sizeof(f32)); + std::memcpy(output_buffer.data(), data, len); + output = output_buffer; // if buffer unlock fails, then... whatever, we have already got data buffer->Unlock(); - return 0; + return output; } diff --git a/src/audio_core/hle/wmf_decoder_utils.h b/src/audio_core/hle/wmf_decoder_utils.h index 79514c19c..187ec68d7 100644 --- a/src/audio_core/hle/wmf_decoder_utils.h +++ b/src/audio_core/hle/wmf_decoder_utils.h @@ -6,8 +6,10 @@ // AAC decoder related APIs are only available with WIN7+ #define WINVER _WIN32_WINNT_WIN7 +#include #include #include +#include #include #include #include @@ -45,7 +47,7 @@ public: private: SmartPtr& smart_ptr; - RawPtr raw_ptr; + RawPtr raw_ptr = nullptr; }; template @@ -72,4 +74,4 @@ void MFFlush(IMFTransform* transform); MFInputState SendSample(IMFTransform* transform, DWORD in_stream_id, IMFSample* in_sample); std::tuple> ReceiveSample(IMFTransform* transform, DWORD out_stream_id); -int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len); +std::optional> CopySampleToBuffer(IMFSample* sample);