audio_core: hle: mf: transition to use smart pointers
This commit is contained in:
parent
bee5ba3e33
commit
10f876653d
|
@ -27,7 +27,7 @@ private:
|
||||||
|
|
||||||
Memory::MemorySystem& memory;
|
Memory::MemorySystem& memory;
|
||||||
|
|
||||||
IMFTransform* transform = nullptr;
|
std::unique_ptr<IMFTransform, MFRelease<IMFTransform>> transform;
|
||||||
DWORD in_stream_id = 0;
|
DWORD in_stream_id = 0;
|
||||||
DWORD out_stream_id = 0;
|
DWORD out_stream_id = 0;
|
||||||
};
|
};
|
||||||
|
@ -70,13 +70,15 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Initalize(const BinaryRequest& r
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryResponse response;
|
BinaryResponse response;
|
||||||
|
IMFTransform* tmp = nullptr;
|
||||||
std::memcpy(&response, &request, sizeof(response));
|
std::memcpy(&response, &request, sizeof(response));
|
||||||
response.unknown1 = 0x0;
|
response.unknown1 = 0x0;
|
||||||
|
|
||||||
if (!MFDecoderInit(&transform)) {
|
if (!MFDecoderInit(&tmp)) {
|
||||||
LOG_CRITICAL(Audio_DSP, "Can't init decoder");
|
LOG_CRITICAL(Audio_DSP, "Can't init decoder");
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
transform.reset(tmp);
|
||||||
|
|
||||||
HRESULT hr = transform->GetStreamIDs(1, &in_stream_id, 1, &out_stream_id);
|
HRESULT hr = transform->GetStreamIDs(1, &in_stream_id, 1, &out_stream_id);
|
||||||
if (hr == E_NOTIMPL) {
|
if (hr == E_NOTIMPL) {
|
||||||
|
@ -85,7 +87,6 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Initalize(const BinaryRequest& r
|
||||||
out_stream_id = 0;
|
out_stream_id = 0;
|
||||||
} else if (FAILED(hr)) {
|
} else if (FAILED(hr)) {
|
||||||
ReportError("Decoder failed to initialize the stream ID", hr);
|
ReportError("Decoder failed to initialize the stream ID", hr);
|
||||||
SafeRelease(&transform);
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,8 +96,8 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Initalize(const BinaryRequest& r
|
||||||
|
|
||||||
void WMFDecoder::Impl::Clear() {
|
void WMFDecoder::Impl::Clear() {
|
||||||
if (initalized) {
|
if (initalized) {
|
||||||
MFFlush(&transform);
|
MFFlush(transform.get());
|
||||||
MFDeInit(&transform);
|
MFDeInit(transform.get());
|
||||||
}
|
}
|
||||||
initalized = false;
|
initalized = false;
|
||||||
selected = false;
|
selected = false;
|
||||||
|
@ -110,7 +111,7 @@ int WMFDecoder::Impl::DecodingLoop(ADTSData adts_header,
|
||||||
IMFSample* output = nullptr;
|
IMFSample* output = nullptr;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
output_status = ReceiveSample(transform, out_stream_id, &output);
|
output_status = ReceiveSample(transform.get(), out_stream_id, &output);
|
||||||
|
|
||||||
// 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 == OK || output_status == HAVE_MORE_DATA) {
|
||||||
|
@ -192,9 +193,9 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
LOG_DEBUG(Audio_DSP, "New ADTS stream: channels = {}, sample rate = {}",
|
LOG_DEBUG(Audio_DSP, "New ADTS stream: channels = {}, sample rate = {}",
|
||||||
adts_header.channels, adts_header.samplerate);
|
adts_header.channels, adts_header.samplerate);
|
||||||
SelectInputMediaType(transform, in_stream_id, adts_header, (UINT8*)aac_tag, 14);
|
SelectInputMediaType(transform.get(), in_stream_id, adts_header, (UINT8*)aac_tag, 14);
|
||||||
SelectOutputMediaType(transform, out_stream_id);
|
SelectOutputMediaType(transform.get(), out_stream_id);
|
||||||
SendSample(transform, in_stream_id, nullptr);
|
SendSample(transform.get(), in_stream_id, nullptr);
|
||||||
// cache the result from detect_mediatype and call select_*_mediatype only once
|
// cache the result from detect_mediatype and call select_*_mediatype only once
|
||||||
// This could increase performance very slightly
|
// This could increase performance very slightly
|
||||||
transform->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
|
transform->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
|
||||||
|
@ -205,7 +206,7 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ
|
||||||
sample->SetUINT32(MFSampleExtension_CleanPoint, 1);
|
sample->SetUINT32(MFSampleExtension_CleanPoint, 1);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
input_status = SendSample(transform, in_stream_id, sample);
|
input_status = SendSample(transform.get(), in_stream_id, sample);
|
||||||
|
|
||||||
if (DecodingLoop(adts_header, out_streams) < 0) {
|
if (DecodingLoop(adts_header, out_streams) < 0) {
|
||||||
// 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
|
||||||
|
|
|
@ -72,9 +72,8 @@ bool MFDecoderInit(IMFTransform** transform, GUID audio_format) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MFDeInit(IMFTransform** transform) {
|
void MFDeInit(IMFTransform* transform) {
|
||||||
MFShutdownObject(*transform);
|
MFShutdownObject(transform);
|
||||||
SafeRelease(transform);
|
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,12 +226,12 @@ int DetectMediaType(char* buffer, size_t len, ADTSData* output, char** aac_tag)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MFFlush(IMFTransform** transform) {
|
void MFFlush(IMFTransform* transform) {
|
||||||
HRESULT hr = (*transform)->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0);
|
HRESULT hr = (transform)->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
ReportError("MFT: Flush command failed", hr);
|
ReportError("MFT: Flush command failed", hr);
|
||||||
}
|
}
|
||||||
hr = (*transform)->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, 0);
|
hr = (transform)->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, 0);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
ReportError("Failed to end streaming for MFT", hr);
|
ReportError("Failed to end streaming for MFT", hr);
|
||||||
}
|
}
|
||||||
|
@ -333,7 +332,8 @@ MFOutputState ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSam
|
||||||
}
|
}
|
||||||
|
|
||||||
int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len) {
|
int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len) {
|
||||||
IMFMediaBuffer* buffer;
|
std::unique_ptr<IMFMediaBuffer, MFRelease<IMFMediaBuffer>> buffer;
|
||||||
|
IMFMediaBuffer* tmp;
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
BYTE* data;
|
BYTE* data;
|
||||||
|
|
||||||
|
@ -343,16 +343,16 @@ int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sample->ConvertToContiguousBuffer(&buffer);
|
sample->ConvertToContiguousBuffer(&tmp);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
ReportError("Failed to get sample buffer", hr);
|
ReportError("Failed to get sample buffer", hr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
buffer.reset(tmp);
|
||||||
|
|
||||||
hr = buffer->Lock(&data, nullptr, nullptr);
|
hr = buffer->Lock(&data, nullptr, nullptr);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
ReportError("Failed to lock the buffer", hr);
|
ReportError("Failed to lock the buffer", hr);
|
||||||
SafeRelease(&buffer);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,6 +361,5 @@ int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len) {
|
||||||
|
|
||||||
// if buffer unlock fails, then... whatever, we have already got data
|
// if buffer unlock fails, then... whatever, we have already got data
|
||||||
buffer->Unlock();
|
buffer->Unlock();
|
||||||
SafeRelease(&buffer);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,12 +30,19 @@ void SafeRelease(T** ppT) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct MFRelease {
|
||||||
|
void operator()(T* pointer) const {
|
||||||
|
pointer->Release();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
void ReportError(std::string msg, HRESULT hr);
|
void ReportError(std::string msg, HRESULT hr);
|
||||||
|
|
||||||
// exported functions
|
// exported functions
|
||||||
bool MFCoInit();
|
bool MFCoInit();
|
||||||
bool MFDecoderInit(IMFTransform** transform, GUID audio_format = MFAudioFormat_AAC);
|
bool MFDecoderInit(IMFTransform** transform, GUID audio_format = MFAudioFormat_AAC);
|
||||||
void MFDeInit(IMFTransform** transform);
|
void MFDeInit(IMFTransform* transform);
|
||||||
IMFSample* CreateSample(void* data, DWORD len, DWORD alignment = 1, LONGLONG duration = 0);
|
IMFSample* CreateSample(void* data, DWORD len, DWORD alignment = 1, LONGLONG duration = 0);
|
||||||
bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts,
|
bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts,
|
||||||
UINT8* user_data, UINT32 user_data_len,
|
UINT8* user_data, UINT32 user_data_len,
|
||||||
|
@ -43,7 +50,7 @@ bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSD
|
||||||
int DetectMediaType(char* buffer, size_t len, ADTSData* output, char** aac_tag);
|
int DetectMediaType(char* buffer, size_t len, ADTSData* output, char** aac_tag);
|
||||||
bool SelectOutputMediaType(IMFTransform* transform, int out_stream_id,
|
bool SelectOutputMediaType(IMFTransform* transform, int out_stream_id,
|
||||||
GUID audio_format = MFAudioFormat_PCM);
|
GUID audio_format = MFAudioFormat_PCM);
|
||||||
void MFFlush(IMFTransform** transform);
|
void MFFlush(IMFTransform* transform);
|
||||||
int SendSample(IMFTransform* transform, DWORD in_stream_id, IMFSample* in_sample);
|
int SendSample(IMFTransform* transform, DWORD in_stream_id, IMFSample* in_sample);
|
||||||
MFOutputState ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_sample);
|
MFOutputState ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_sample);
|
||||||
int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len);
|
int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len);
|
||||||
|
|
Reference in New Issue