summaryrefslogtreecommitdiff
path: root/media/gmp-clearkey/0.1/AudioDecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/gmp-clearkey/0.1/AudioDecoder.cpp')
-rw-r--r--media/gmp-clearkey/0.1/AudioDecoder.cpp312
1 files changed, 0 insertions, 312 deletions
diff --git a/media/gmp-clearkey/0.1/AudioDecoder.cpp b/media/gmp-clearkey/0.1/AudioDecoder.cpp
deleted file mode 100644
index b02e1a8545..0000000000
--- a/media/gmp-clearkey/0.1/AudioDecoder.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright 2015, 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 <cstdint>
-#include <limits>
-
-#include "AudioDecoder.h"
-#include "ClearKeyDecryptionManager.h"
-#include "ClearKeyUtils.h"
-#include "gmp-task-utils.h"
-
-using namespace wmf;
-
-AudioDecoder::AudioDecoder(GMPAudioHost *aHostAPI)
- : mHostAPI(aHostAPI)
- , mCallback(nullptr)
- , mWorkerThread(nullptr)
- , mMutex(nullptr)
- , mNumInputTasks(0)
- , mHasShutdown(false)
-{
- // We drop the ref in DecodingComplete().
- AddRef();
-}
-
-AudioDecoder::~AudioDecoder()
-{
- if (mMutex) {
- mMutex->Destroy();
- }
-}
-
-void
-AudioDecoder::InitDecode(const GMPAudioCodec& aConfig,
- GMPAudioDecoderCallback* aCallback)
-{
- mCallback = aCallback;
- assert(mCallback);
- mDecoder = new WMFAACDecoder();
- HRESULT hr = mDecoder->Init(aConfig.mChannelCount,
- aConfig.mSamplesPerSecond,
- (BYTE*)aConfig.mExtraData,
- aConfig.mExtraDataLen);
- LOG("[%p] AudioDecoder::InitializeAudioDecoder() hr=0x%x\n", this, hr);
- if (FAILED(hr)) {
- mCallback->Error(GMPGenericErr);
- return;
- }
- auto err = GetPlatform()->createmutex(&mMutex);
- if (GMP_FAILED(err)) {
- mCallback->Error(GMPGenericErr);
- return;
- }
-}
-
-void
-AudioDecoder::EnsureWorker()
-{
- if (!mWorkerThread) {
- GetPlatform()->createthread(&mWorkerThread);
- if (!mWorkerThread) {
- mCallback->Error(GMPAllocErr);
- return;
- }
- }
-}
-
-void
-AudioDecoder::Decode(GMPAudioSamples* aInput)
-{
- EnsureWorker();
- {
- AutoLock lock(mMutex);
- mNumInputTasks++;
- }
- mWorkerThread->Post(WrapTaskRefCounted(this,
- &AudioDecoder::DecodeTask,
- aInput));
-}
-
-void
-AudioDecoder::DecodeTask(GMPAudioSamples* aInput)
-{
- HRESULT hr;
-
- {
- AutoLock lock(mMutex);
- mNumInputTasks--;
- assert(mNumInputTasks >= 0);
- }
-
- if (!aInput || !mHostAPI || !mDecoder) {
- LOG("Decode job not set up correctly!");
- return;
- }
-
- const uint8_t* inBuffer = aInput->Buffer();
- if (!inBuffer) {
- LOG("No buffer for encoded samples!\n");
- return;
- }
-
- const GMPEncryptedBufferMetadata* crypto = aInput->GetDecryptionData();
- std::vector<uint8_t> buffer(inBuffer, inBuffer + aInput->Size());
- if (crypto) {
- // Plugin host should have set up its decryptor/key sessions
- // before trying to decode!
- GMPErr rv =
- ClearKeyDecryptionManager::Get()->Decrypt(buffer, CryptoMetaData(crypto));
-
- if (GMP_FAILED(rv)) {
- CK_LOGE("Failed to decrypt with key id %08x...", *(uint32_t*)crypto->KeyId());
- MaybeRunOnMainThread(WrapTask(mCallback, &GMPAudioDecoderCallback::Error, rv));
- return;
- }
- }
-
- hr = mDecoder->Input(&buffer[0],
- buffer.size(),
- aInput->TimeStamp());
-
- // We must delete the input sample!
- GetPlatform()->runonmainthread(WrapTask(aInput, &GMPAudioSamples::Destroy));
-
- SAMPLE_LOG("AudioDecoder::DecodeTask() Input ret hr=0x%x\n", hr);
- if (FAILED(hr)) {
- LOG("AudioDecoder::DecodeTask() decode failed ret=0x%x%s\n",
- hr,
- ((hr == MF_E_NOTACCEPTING) ? " (MF_E_NOTACCEPTING)" : ""));
- return;
- }
-
- while (hr == S_OK) {
- CComPtr<IMFSample> output;
- hr = mDecoder->Output(&output);
- SAMPLE_LOG("AudioDecoder::DecodeTask() output ret=0x%x\n", hr);
- if (hr == S_OK) {
- ReturnOutput(output);
- }
- if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
- AutoLock lock(mMutex);
- if (mNumInputTasks == 0) {
- // We have run all input tasks. We *must* notify Gecko so that it will
- // send us more data.
- MaybeRunOnMainThread(WrapTask(mCallback, &GMPAudioDecoderCallback::InputDataExhausted));
- }
- } else if (FAILED(hr)) {
- LOG("AudioDecoder::DecodeTask() output failed hr=0x%x\n", hr);
- }
- }
-}
-
-void
-AudioDecoder::ReturnOutput(IMFSample* aSample)
-{
- SAMPLE_LOG("[%p] AudioDecoder::ReturnOutput()\n", this);
- assert(aSample);
-
- HRESULT hr;
-
- GMPAudioSamples* samples = nullptr;
- mHostAPI->CreateSamples(kGMPAudioIS16Samples, &samples);
- if (!samples) {
- LOG("Failed to create i420 frame!\n");
- return;
- }
-
- hr = MFToGMPSample(aSample, samples);
- if (FAILED(hr)) {
- samples->Destroy();
- LOG("Failed to prepare output sample!");
- return;
- }
- ENSURE(SUCCEEDED(hr), /*void*/);
-
- MaybeRunOnMainThread(WrapTask(mCallback, &GMPAudioDecoderCallback::Decoded, samples));
-}
-
-HRESULT
-AudioDecoder::MFToGMPSample(IMFSample* aInput,
- GMPAudioSamples* aOutput)
-{
- ENSURE(aInput != nullptr, E_POINTER);
- ENSURE(aOutput != nullptr, E_POINTER);
-
- HRESULT hr;
- CComPtr<IMFMediaBuffer> mediaBuffer;
-
- hr = aInput->ConvertToContiguousBuffer(&mediaBuffer);
- ENSURE(SUCCEEDED(hr), hr);
-
- BYTE* data = nullptr; // Note: *data will be owned by the IMFMediaBuffer, we don't need to free it.
- DWORD maxLength = 0, currentLength = 0;
- hr = mediaBuffer->Lock(&data, &maxLength, &currentLength);
- ENSURE(SUCCEEDED(hr), hr);
-
- auto err = aOutput->SetBufferSize(currentLength);
- ENSURE(GMP_SUCCEEDED(err), E_FAIL);
-
- memcpy(aOutput->Buffer(), data, currentLength);
-
- mediaBuffer->Unlock();
-
- LONGLONG hns = 0;
- hr = aInput->GetSampleTime(&hns);
- ENSURE(SUCCEEDED(hr), hr);
- aOutput->SetTimeStamp(HNsToUsecs(hns));
- aOutput->SetChannels(mDecoder->Channels());
- aOutput->SetRate(mDecoder->Rate());
-
- return S_OK;
-}
-
-void
-AudioDecoder::Reset()
-{
- if (mDecoder) {
- mDecoder->Reset();
- }
- if (mCallback) {
- mCallback->ResetComplete();
- }
-}
-
-void
-AudioDecoder::DrainTask()
-{
- mDecoder->Drain();
-
- // Return any pending output.
- HRESULT hr = S_OK;
- while (hr == S_OK) {
- CComPtr<IMFSample> output;
- hr = mDecoder->Output(&output);
- SAMPLE_LOG("AudioDecoder::DrainTask() output ret=0x%x\n", hr);
- if (hr == S_OK) {
- ReturnOutput(output);
- }
- }
- MaybeRunOnMainThread(WrapTask(mCallback, &GMPAudioDecoderCallback::DrainComplete));
-}
-
-void
-AudioDecoder::Drain()
-{
- if (!mDecoder) {
- return;
- }
- EnsureWorker();
- mWorkerThread->Post(WrapTaskRefCounted(this,
- &AudioDecoder::DrainTask));
-}
-
-void
-AudioDecoder::DecodingComplete()
-{
- if (mWorkerThread) {
- mWorkerThread->Join();
- }
- mHasShutdown = true;
-
- // Release the reference we added in the constructor. There may be
- // WrapRefCounted tasks that also hold references to us, and keep
- // us alive a little longer.
- Release();
-}
-
-void
-AudioDecoder::MaybeRunOnMainThread(GMPTask* aTask)
-{
- class MaybeRunTask : public GMPTask
- {
- public:
- MaybeRunTask(AudioDecoder* aDecoder, GMPTask* aTask)
- : mDecoder(aDecoder), mTask(aTask)
- { }
-
- virtual void Run(void) {
- if (mDecoder->HasShutdown()) {
- CK_LOGD("Trying to dispatch to main thread after AudioDecoder has shut down");
- return;
- }
-
- mTask->Run();
- }
-
- virtual void Destroy()
- {
- mTask->Destroy();
- delete this;
- }
-
- private:
- RefPtr<AudioDecoder> mDecoder;
- GMPTask* mTask;
- };
-
- GetPlatform()->runonmainthread(new MaybeRunTask(this, aTask));
-}