summaryrefslogtreecommitdiff
path: root/media/gmp-clearkey/0.1/WMFAACDecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/gmp-clearkey/0.1/WMFAACDecoder.cpp')
-rw-r--r--media/gmp-clearkey/0.1/WMFAACDecoder.cpp366
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, &currentLength);
- 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;
-}
-
-}