audio_core: hle: mf: transition to use smart pointers

This commit is contained in:
liushuyu 2019-01-07 16:57:20 -07:00 committed by B3N30
parent bee5ba3e33
commit 10f876653d
3 changed files with 29 additions and 22 deletions

View file

@ -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

View file

@ -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;
} }

View file

@ -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);