diff options
Diffstat (limited to 'media/gmp-clearkey/0.1/WMFAACDecoder.cpp')
-rw-r--r-- | media/gmp-clearkey/0.1/WMFAACDecoder.cpp | 366 |
1 files changed, 0 insertions, 366 deletions
diff --git a/media/gmp-clearkey/0.1/WMFAACDecoder.cpp b/media/gmp-clearkey/0.1/WMFAACDecoder.cpp deleted file mode 100644 index 495f840e8d..0000000000 --- a/media/gmp-clearkey/0.1/WMFAACDecoder.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright 2013, Mozilla Foundation and contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "WMFAACDecoder.h" -#include <algorithm> -#include <stdint.h> -#include <vector> - -using std::vector; - -namespace wmf { - -WMFAACDecoder::WMFAACDecoder() - : mDecoder(nullptr) - , mChannels(0) - , mRate(0) -{ - memset(&mInputStreamInfo, 0, sizeof(MFT_INPUT_STREAM_INFO)); - memset(&mOutputStreamInfo, 0, sizeof(MFT_OUTPUT_STREAM_INFO)); -} - -WMFAACDecoder::~WMFAACDecoder() -{ - Reset(); -} - -HRESULT -AACAudioSpecificConfigToUserData(BYTE* aAudioSpecConfig, UINT32 aConfigLength, - BYTE** aOutUserData, UINT32* aOutUserDataLength) -{ - // For MFAudioFormat_AAC, MF_MT_USER_DATA - // Contains the portion of the HEAACWAVEINFO structure that appears - // after the WAVEFORMATEX structure (that is, after the wfx member). - // This is followed by the AudioSpecificConfig() data, as defined - // by ISO/IEC 14496-3. - // ... - // The length of the AudioSpecificConfig() data is 2 bytes for AAC-LC - // or HE-AAC with implicit signaling of SBR/PS. It is more than 2 bytes - // for HE-AAC with explicit signaling of SBR/PS. - // - // The value of audioObjectType as defined in AudioSpecificConfig() - // must be 2, indicating AAC-LC. The value of extensionAudioObjectType - // must be 5 for SBR or 29 for PS. - // - // See: - // http://msdn.microsoft.com/en-us/library/windows/desktop/dd742784%28v=vs.85%29.aspx - // - // HEAACWAVEINFO structure: - // typedef struct heaacwaveinfo_tag { - // WAVEFORMATEX wfx; - // WORD wPayloadType; - // WORD wAudioProfileLevelIndication; - // WORD wStructType; - // WORD wReserved1; - // DWORD dwReserved2; - // } - const UINT32 heeInfoLen = 4 * sizeof(WORD) + sizeof(DWORD); - BYTE heeInfo[heeInfoLen] = {0}; - WORD* w = (WORD*)heeInfo; - w[0] = 0x0; // Payload type raw AAC - w[1] = 0; // Profile level unspecified - - const UINT32 len = heeInfoLen + aConfigLength; - BYTE* data = new BYTE[len]; - memcpy(data, heeInfo, heeInfoLen); - memcpy(data+heeInfoLen, aAudioSpecConfig, aConfigLength); - *aOutUserData = data; - *aOutUserDataLength = len; - return S_OK; -} - -HRESULT -WMFAACDecoder::Init(int32_t aChannelCount, - int32_t aSampleRate, - BYTE* aAACAudioSpecificConfig, - UINT32 aAudioConfigLength) -{ - HRESULT hr; - - // AAC decoder is in msauddecmft on Win8, and msmpeg2adec in earlier versions. - hr = CreateMFT(CLSID_CMSAACDecMFT, - WMFDecoderDllNameFor(AAC), - mDecoder); - if (FAILED(hr)) { - hr = CreateMFT(CLSID_CMSAACDecMFT, - WMFDecoderDllNameFor(AAC), - mDecoder); - if (FAILED(hr)) { - LOG("Failed to create AAC decoder\n"); - return E_FAIL; - } - } - - BYTE* userData = nullptr; - UINT32 userDataLength; - hr = AACAudioSpecificConfigToUserData(aAACAudioSpecificConfig, - aAudioConfigLength, - &userData, - &userDataLength); - ENSURE(SUCCEEDED(hr), hr); - hr = SetDecoderInputType(aChannelCount, aSampleRate, userData, userDataLength); - delete userData; - ENSURE(SUCCEEDED(hr), hr); - - hr = SetDecoderOutputType(); - ENSURE(SUCCEEDED(hr), hr); - - hr = SendMFTMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0); - ENSURE(SUCCEEDED(hr), hr); - - hr = SendMFTMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0); - ENSURE(SUCCEEDED(hr), hr); - - hr = mDecoder->GetInputStreamInfo(0, &mInputStreamInfo); - ENSURE(SUCCEEDED(hr), hr); - - hr = mDecoder->GetOutputStreamInfo(0, &mOutputStreamInfo); - ENSURE(SUCCEEDED(hr), hr); - - return S_OK; -} - -HRESULT -WMFAACDecoder::SetDecoderInputType(int32_t aChannelCount, - int32_t aSampleRate, - BYTE* aUserData, - UINT32 aUserDataLength) -{ - HRESULT hr; - - CComPtr<IMFMediaType> type; - hr = MFCreateMediaType(&type); - ENSURE(SUCCEEDED(hr), hr); - - hr = type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio); - ENSURE(SUCCEEDED(hr), hr); - - hr = type->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC); - ENSURE(SUCCEEDED(hr), hr); - - mRate = aSampleRate; - hr = type->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, mRate); - ENSURE(SUCCEEDED(hr), hr); - - mChannels = aChannelCount; - hr = type->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, mChannels); - ENSURE(SUCCEEDED(hr), hr); - - hr = type->SetBlob(MF_MT_USER_DATA, aUserData, aUserDataLength); - ENSURE(SUCCEEDED(hr), hr); - - hr = mDecoder->SetInputType(0, type, 0); - ENSURE(SUCCEEDED(hr), hr); - - return S_OK; -} - -HRESULT -WMFAACDecoder::SetDecoderOutputType() -{ - HRESULT hr; - - CComPtr<IMFMediaType> type; - - UINT32 typeIndex = 0; - while (type = nullptr, SUCCEEDED(mDecoder->GetOutputAvailableType(0, typeIndex++, &type))) { - GUID subtype; - hr = type->GetGUID(MF_MT_SUBTYPE, &subtype); - if (FAILED(hr)) { - continue; - } - if (subtype == MFAudioFormat_PCM) { - hr = mDecoder->SetOutputType(0, type, 0); - ENSURE(SUCCEEDED(hr), hr); - - hr = type->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &mChannels); - ENSURE(SUCCEEDED(hr), hr); - - hr = type->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, &mRate); - ENSURE(SUCCEEDED(hr), hr); - - return S_OK; - } - } - - return E_FAIL; -} - -HRESULT -WMFAACDecoder::SendMFTMessage(MFT_MESSAGE_TYPE aMsg, UINT32 aData) -{ - ENSURE(mDecoder != nullptr, E_POINTER); - HRESULT hr = mDecoder->ProcessMessage(aMsg, aData); - ENSURE(SUCCEEDED(hr), hr); - return S_OK; -} - -HRESULT -WMFAACDecoder::CreateInputSample(const uint8_t* aData, - uint32_t aDataSize, - Microseconds aTimestamp, - IMFSample** aOutSample) -{ - HRESULT hr; - CComPtr<IMFSample> sample = nullptr; - hr = MFCreateSample(&sample); - ENSURE(SUCCEEDED(hr), hr); - - CComPtr<IMFMediaBuffer> buffer = nullptr; - int32_t bufferSize = std::max<uint32_t>(uint32_t(mInputStreamInfo.cbSize), aDataSize); - UINT32 alignment = (mInputStreamInfo.cbAlignment > 1) ? mInputStreamInfo.cbAlignment - 1 : 0; - hr = MFCreateAlignedMemoryBuffer(bufferSize, alignment, &buffer); - ENSURE(SUCCEEDED(hr), hr); - - DWORD maxLength = 0; - DWORD currentLength = 0; - BYTE* dst = nullptr; - hr = buffer->Lock(&dst, &maxLength, ¤tLength); - ENSURE(SUCCEEDED(hr), hr); - - // Copy data into sample's buffer. - memcpy(dst, aData, aDataSize); - - hr = buffer->Unlock(); - ENSURE(SUCCEEDED(hr), hr); - - hr = buffer->SetCurrentLength(aDataSize); - ENSURE(SUCCEEDED(hr), hr); - - hr = sample->AddBuffer(buffer); - ENSURE(SUCCEEDED(hr), hr); - - hr = sample->SetSampleTime(UsecsToHNs(aTimestamp)); - ENSURE(SUCCEEDED(hr), hr); - - *aOutSample = sample.Detach(); - - return S_OK; -} - -HRESULT -WMFAACDecoder::CreateOutputSample(IMFSample** aOutSample) -{ - HRESULT hr; - CComPtr<IMFSample> sample = nullptr; - hr = MFCreateSample(&sample); - ENSURE(SUCCEEDED(hr), hr); - - CComPtr<IMFMediaBuffer> buffer = nullptr; - int32_t bufferSize = mOutputStreamInfo.cbSize; - UINT32 alignment = (mOutputStreamInfo.cbAlignment > 1) ? mOutputStreamInfo.cbAlignment - 1 : 0; - hr = MFCreateAlignedMemoryBuffer(bufferSize, alignment, &buffer); - ENSURE(SUCCEEDED(hr), hr); - - hr = sample->AddBuffer(buffer); - ENSURE(SUCCEEDED(hr), hr); - - *aOutSample = sample.Detach(); - - return S_OK; -} - - -HRESULT -WMFAACDecoder::GetOutputSample(IMFSample** aOutSample) -{ - HRESULT hr; - // We allocate samples for MFT output. - MFT_OUTPUT_DATA_BUFFER output = {0}; - - CComPtr<IMFSample> sample = nullptr; - hr = CreateOutputSample(&sample); - ENSURE(SUCCEEDED(hr), hr); - - output.pSample = sample; - - DWORD status = 0; - hr = mDecoder->ProcessOutput(0, 1, &output, &status); - CComPtr<IMFCollection> events = output.pEvents; // Ensure this is released. - - if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { - // Type change. Probably geometric apperature change. - hr = SetDecoderOutputType(); - ENSURE(SUCCEEDED(hr), hr); - - return GetOutputSample(aOutSample); - } else if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT || !sample) { - return MF_E_TRANSFORM_NEED_MORE_INPUT; - } - // Treat other errors as fatal. - ENSURE(SUCCEEDED(hr), hr); - - assert(sample); - - *aOutSample = sample.Detach(); - return S_OK; -} - -HRESULT -WMFAACDecoder::Input(const uint8_t* aData, - uint32_t aDataSize, - Microseconds aTimestamp) -{ - CComPtr<IMFSample> input = nullptr; - HRESULT hr = CreateInputSample(aData, aDataSize, aTimestamp, &input); - ENSURE(SUCCEEDED(hr) && input!=nullptr, hr); - - hr = mDecoder->ProcessInput(0, input, 0); - if (hr == MF_E_NOTACCEPTING) { - // MFT *already* has enough data to produce a sample. Retrieve it. - LOG("ProcessInput returned MF_E_NOTACCEPTING\n"); - return MF_E_NOTACCEPTING; - } - ENSURE(SUCCEEDED(hr), hr); - - return S_OK; -} - -HRESULT -WMFAACDecoder::Output(IMFSample** aOutput) -{ - CComPtr<IMFSample> outputSample = nullptr; - HRESULT hr = GetOutputSample(&outputSample); - if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { - return MF_E_TRANSFORM_NEED_MORE_INPUT; - } - // Treat other errors as fatal. - ENSURE(SUCCEEDED(hr) && outputSample, hr); - - *aOutput = outputSample.Detach(); - - return S_OK; -} - -HRESULT -WMFAACDecoder::Reset() -{ - HRESULT hr = SendMFTMessage(MFT_MESSAGE_COMMAND_FLUSH, 0); - ENSURE(SUCCEEDED(hr), hr); - - return S_OK; -} - -HRESULT -WMFAACDecoder::Drain() -{ - HRESULT hr = SendMFTMessage(MFT_MESSAGE_COMMAND_DRAIN, 0); - ENSURE(SUCCEEDED(hr), hr); - - return S_OK; -} - -} |