SamplesWaitingForKey.cpp (2392B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "SamplesWaitingForKey.h" 8 9 #include "MediaData.h" 10 #include "MediaEventSource.h" 11 #include "mozilla/CDMCaps.h" 12 #include "mozilla/CDMProxy.h" 13 #include "mozilla/TaskQueue.h" 14 15 namespace mozilla { 16 17 SamplesWaitingForKey::SamplesWaitingForKey( 18 CDMProxy* aProxy, TrackInfo::TrackType aType, 19 const std::function<MediaEventProducer<TrackInfo::TrackType>*()>& 20 aOnWaitingForKeyEvent) 21 : mMutex("SamplesWaitingForKey"), 22 mProxy(aProxy), 23 mType(aType), 24 mOnWaitingForKeyEvent(aOnWaitingForKeyEvent) {} 25 26 SamplesWaitingForKey::~SamplesWaitingForKey() { Flush(); } 27 28 RefPtr<SamplesWaitingForKey::WaitForKeyPromise> 29 SamplesWaitingForKey::WaitIfKeyNotUsable(MediaRawData* aSample) { 30 if (!aSample || !aSample->mCrypto.IsEncrypted() || !mProxy) { 31 return WaitForKeyPromise::CreateAndResolve(aSample, __func__); 32 } 33 auto caps = mProxy->Capabilites().Lock(); 34 const auto& keyid = aSample->mCrypto.mKeyId; 35 if (caps->IsKeyUsable(keyid)) { 36 return WaitForKeyPromise::CreateAndResolve(aSample, __func__); 37 } 38 SampleEntry entry; 39 entry.mSample = aSample; 40 RefPtr<WaitForKeyPromise> p = entry.mPromise.Ensure(__func__); 41 { 42 MutexAutoLock lock(mMutex); 43 mSamples.AppendElement(std::move(entry)); 44 } 45 if (mOnWaitingForKeyEvent && mOnWaitingForKeyEvent()) { 46 mOnWaitingForKeyEvent()->Notify(mType); 47 } 48 caps->NotifyWhenKeyIdUsable(aSample->mCrypto.mKeyId, this); 49 return p; 50 } 51 52 void SamplesWaitingForKey::NotifyUsable(const CencKeyId& aKeyId) { 53 MutexAutoLock lock(mMutex); 54 size_t i = 0; 55 while (i < mSamples.Length()) { 56 auto& entry = mSamples[i]; 57 if (aKeyId == entry.mSample->mCrypto.mKeyId) { 58 entry.mPromise.Resolve(entry.mSample, __func__); 59 mSamples.RemoveElementAt(i); 60 } else { 61 i++; 62 } 63 } 64 } 65 66 void SamplesWaitingForKey::Flush() { 67 MutexAutoLock lock(mMutex); 68 for (auto& sample : mSamples) { 69 sample.mPromise.Reject(true, __func__); 70 } 71 mSamples.Clear(); 72 } 73 74 void SamplesWaitingForKey::BreakCycles() { 75 MutexAutoLock lock(mMutex); 76 mProxy = nullptr; 77 } 78 79 } // namespace mozilla