audio_core: hle: mf: wrap enum in class
This commit is contained in:
parent
633f02b9b2
commit
26b3b41788
|
@ -105,7 +105,7 @@ void WMFDecoder::Impl::Clear() {
|
||||||
|
|
||||||
MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header,
|
MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header,
|
||||||
std::array<std::vector<u8>, 2>& out_streams) {
|
std::array<std::vector<u8>, 2>& out_streams) {
|
||||||
MFOutputState output_status = OK;
|
MFOutputState output_status = MFOutputState::OK;
|
||||||
char* output_buffer = nullptr;
|
char* output_buffer = nullptr;
|
||||||
DWORD output_len = 0;
|
DWORD output_len = 0;
|
||||||
DWORD tmp = 0;
|
DWORD tmp = 0;
|
||||||
|
@ -117,7 +117,7 @@ MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header,
|
||||||
auto [output_status, output] = ReceiveSample(transform.get(), out_stream_id);
|
auto [output_status, output] = ReceiveSample(transform.get(), out_stream_id);
|
||||||
|
|
||||||
// 0 -> okay; 3 -> okay but more data available (buffer too small)
|
// 0 -> okay; 3 -> okay but more data available (buffer too small)
|
||||||
if (output_status == OK || output_status == HAVE_MORE_DATA) {
|
if (output_status == MFOutputState::OK || output_status == MFOutputState::HaveMoreData) {
|
||||||
CopySampleToBuffer(output.get(), (void**)&output_buffer, &output_len);
|
CopySampleToBuffer(output.get(), (void**)&output_buffer, &output_len);
|
||||||
|
|
||||||
// the following was taken from ffmpeg version of the decoder
|
// the following was taken from ffmpeg version of the decoder
|
||||||
|
@ -137,26 +137,26 @@ MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header,
|
||||||
}
|
}
|
||||||
|
|
||||||
// in case of "ok" only, just return quickly
|
// in case of "ok" only, just return quickly
|
||||||
if (output_status == OK)
|
if (output_status == MFOutputState::OK)
|
||||||
return OK;
|
return MFOutputState::OK;
|
||||||
|
|
||||||
// for status = 2, reset MF
|
// for status = 2, reset MF
|
||||||
if (output_status == NEED_RECONFIG) {
|
if (output_status == MFOutputState::NeedReconfig) {
|
||||||
Clear();
|
Clear();
|
||||||
return FATAL_ERROR;
|
return MFOutputState::FatalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for status = 3, try again with new buffer
|
// for status = 3, try again with new buffer
|
||||||
if (output_status == HAVE_MORE_DATA)
|
if (output_status == MFOutputState::HaveMoreData)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (output_status == NEED_MORE_INPUT) // according to MS document, this is not an error (?!)
|
if (output_status == MFOutputState::NeedMoreInput) // according to MS document, this is not an error (?!)
|
||||||
return NEED_MORE_INPUT;
|
return MFOutputState::NeedMoreInput;
|
||||||
|
|
||||||
return FATAL_ERROR; // return on other status
|
return MFOutputState::FatalError; // return on other status
|
||||||
}
|
}
|
||||||
|
|
||||||
return FATAL_ERROR;
|
return MFOutputState::FatalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& request) {
|
std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& request) {
|
||||||
|
@ -184,7 +184,7 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ
|
||||||
unique_mfptr<IMFSample> sample;
|
unique_mfptr<IMFSample> sample;
|
||||||
ADTSData adts_header;
|
ADTSData adts_header;
|
||||||
char* aac_tag = (char*)calloc(1, 14);
|
char* aac_tag = (char*)calloc(1, 14);
|
||||||
MFInputState input_status = INPUT_OK;
|
MFInputState input_status = MFInputState::OK;
|
||||||
|
|
||||||
if (DetectMediaType((char*)data, request.size, &adts_header, &aac_tag) != 0) {
|
if (DetectMediaType((char*)data, request.size, &adts_header, &aac_tag) != 0) {
|
||||||
LOG_ERROR(Audio_DSP, "Unable to deduce decoding parameters from ADTS stream");
|
LOG_ERROR(Audio_DSP, "Unable to deduce decoding parameters from ADTS stream");
|
||||||
|
@ -211,11 +211,11 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ
|
||||||
while (true) {
|
while (true) {
|
||||||
input_status = SendSample(transform.get(), in_stream_id, sample.get());
|
input_status = SendSample(transform.get(), in_stream_id, sample.get());
|
||||||
|
|
||||||
if (DecodingLoop(adts_header, out_streams) == FATAL_ERROR) {
|
if (DecodingLoop(adts_header, out_streams) == MFOutputState::FatalError) {
|
||||||
// if the decode issues are caused by MFT not accepting new samples, try again
|
// if the decode issues are caused by MFT not accepting new samples, try again
|
||||||
// NOTICE: you are required to check the output even if you already knew/guessed
|
// NOTICE: you are required to check the output even if you already knew/guessed
|
||||||
// MFT didn't accept the input sample
|
// MFT didn't accept the input sample
|
||||||
if (input_status == NOT_ACCEPTED) {
|
if (input_status == MFInputState::NotAccepted) {
|
||||||
// try again
|
// try again
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,10 +250,10 @@ MFInputState SendSample(IMFTransform* transform, DWORD in_stream_id, IMFSample*
|
||||||
if (in_sample) {
|
if (in_sample) {
|
||||||
hr = transform->ProcessInput(in_stream_id, in_sample, 0);
|
hr = transform->ProcessInput(in_stream_id, in_sample, 0);
|
||||||
if (hr == MF_E_NOTACCEPTING) {
|
if (hr == MF_E_NOTACCEPTING) {
|
||||||
return NOT_ACCEPTED; // try again
|
return MFInputState::NotAccepted; // try again
|
||||||
} else if (FAILED(hr)) {
|
} else if (FAILED(hr)) {
|
||||||
ReportError("MFT: Failed to process input", hr);
|
ReportError("MFT: Failed to process input", hr);
|
||||||
return INPUT_ERROR;
|
return MFInputState::FatalError;
|
||||||
} // FAILED(hr)
|
} // FAILED(hr)
|
||||||
} else {
|
} else {
|
||||||
hr = transform->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, 0);
|
hr = transform->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, 0);
|
||||||
|
@ -262,7 +262,7 @@ MFInputState SendSample(IMFTransform* transform, DWORD in_stream_id, IMFSample*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return INPUT_OK;
|
return MFInputState::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<MFOutputState, unique_mfptr<IMFSample>> ReceiveSample(IMFTransform* transform,
|
std::tuple<MFOutputState, unique_mfptr<IMFSample>> ReceiveSample(IMFTransform* transform,
|
||||||
|
@ -278,7 +278,7 @@ std::tuple<MFOutputState, unique_mfptr<IMFSample>> ReceiveSample(IMFTransform* t
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
ReportError("MFT: Failed to get stream info", hr);
|
ReportError("MFT: Failed to get stream info", hr);
|
||||||
return std::make_tuple(FATAL_ERROR, std::move(sample));
|
return std::make_tuple(MFOutputState::FatalError, std::move(sample));
|
||||||
}
|
}
|
||||||
mft_create_sample = (out_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) ||
|
mft_create_sample = (out_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) ||
|
||||||
(out_info.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES);
|
(out_info.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES);
|
||||||
|
@ -290,7 +290,7 @@ std::tuple<MFOutputState, unique_mfptr<IMFSample>> ReceiveSample(IMFTransform* t
|
||||||
sample = CreateSample(nullptr, out_info.cbSize, out_info.cbAlignment);
|
sample = CreateSample(nullptr, out_info.cbSize, out_info.cbAlignment);
|
||||||
if (!sample.get()) {
|
if (!sample.get()) {
|
||||||
ReportError("MFT: Unable to allocate memory for samples", hr);
|
ReportError("MFT: Unable to allocate memory for samples", hr);
|
||||||
return std::make_tuple(FATAL_ERROR, std::move(sample));
|
return std::make_tuple(MFOutputState::FatalError, std::move(sample));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,12 +305,12 @@ std::tuple<MFOutputState, unique_mfptr<IMFSample>> ReceiveSample(IMFTransform* t
|
||||||
|
|
||||||
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
|
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
|
||||||
// Most likely reasons: data corrupted; your actions not expected by MFT
|
// Most likely reasons: data corrupted; your actions not expected by MFT
|
||||||
return std::make_tuple(NEED_MORE_INPUT, std::move(sample));
|
return std::make_tuple(MFOutputState::NeedMoreInput, std::move(sample));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
|
if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
|
||||||
ReportError("MFT: stream format changed, re-configuration required", hr);
|
ReportError("MFT: stream format changed, re-configuration required", hr);
|
||||||
return std::make_tuple(NEED_RECONFIG, std::move(sample));
|
return std::make_tuple(MFOutputState::NeedReconfig, std::move(sample));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -318,15 +318,15 @@ std::tuple<MFOutputState, unique_mfptr<IMFSample>> ReceiveSample(IMFTransform* t
|
||||||
|
|
||||||
if (out_buffers.dwStatus & MFT_OUTPUT_DATA_BUFFER_INCOMPLETE) {
|
if (out_buffers.dwStatus & MFT_OUTPUT_DATA_BUFFER_INCOMPLETE) {
|
||||||
// this status is also unreliable but whatever
|
// this status is also unreliable but whatever
|
||||||
return std::make_tuple(HAVE_MORE_DATA, std::move(sample));
|
return std::make_tuple(MFOutputState::HaveMoreData, std::move(sample));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out_buffers.pSample == nullptr) {
|
if (out_buffers.pSample == nullptr) {
|
||||||
ReportError("MFT: decoding failure", hr);
|
ReportError("MFT: decoding failure", hr);
|
||||||
return std::make_tuple(FATAL_ERROR, std::move(sample));
|
return std::make_tuple(MFOutputState::FatalError, std::move(sample));
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_tuple(OK, std::move(sample));
|
return std::make_tuple(MFOutputState::OK, std::move(sample));
|
||||||
}
|
}
|
||||||
|
|
||||||
int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len) {
|
int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len) {
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
// AAC decoder related APIs are only available with WIN7+
|
// AAC decoder related APIs are only available with WIN7+
|
||||||
#define WINVER _WIN32_WINNT_WIN7
|
#define WINVER _WIN32_WINNT_WIN7
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <comdef.h>
|
#include <comdef.h>
|
||||||
|
@ -17,10 +16,10 @@
|
||||||
|
|
||||||
#include "adts.h"
|
#include "adts.h"
|
||||||
|
|
||||||
enum MFOutputState { FATAL_ERROR, OK, NEED_MORE_INPUT, NEED_RECONFIG, HAVE_MORE_DATA };
|
enum class MFOutputState { FatalError, OK, NeedMoreInput, NeedReconfig, HaveMoreData };
|
||||||
enum MFInputState { INPUT_ERROR, INPUT_OK, NOT_ACCEPTED };
|
enum class MFInputState { FatalError, OK, NotAccepted };
|
||||||
|
|
||||||
// utility functions
|
// utility functions / templates
|
||||||
template <class T>
|
template <class T>
|
||||||
struct MFRelease {
|
struct MFRelease {
|
||||||
void operator()(T* pointer) const {
|
void operator()(T* pointer) const {
|
||||||
|
@ -28,6 +27,7 @@ struct MFRelease {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// wrapper facilities for dealing with pointers
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using unique_mfptr = std::unique_ptr<T, MFRelease<T>>;
|
using unique_mfptr = std::unique_ptr<T, MFRelease<T>>;
|
||||||
|
|
||||||
|
|
Reference in New Issue