--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -238,16 +238,28 @@ public:
return mTimedMetadataEvent;
}
MediaEventProducer<void>& MediaNotSeekableProducer()
{
return mOnMediaNotSeekable;
}
+ // Notified if the reader can't decode a sample due to a missing decryption
+ // key.
+ MediaEventSource<TrackInfo::TrackType>& OnTrackWaitingForKey()
+ {
+ return mOnTrackWaitingForKey;
+ }
+
+ MediaEventProducer<TrackInfo::TrackType>& OnTrackWaitingForKeyProducer()
+ {
+ return mOnTrackWaitingForKey;
+ }
+
// Switch the video decoder to BlankDecoderModule. It might takes effective
// since a few samples later depends on how much demuxed samples are already
// queued in the original video decoder.
virtual void SetVideoBlankDecode(bool aIsBlankDecode) {}
protected:
virtual ~MediaDecoderReader();
@@ -301,16 +313,19 @@ protected:
bool mShutdown;
// Used to send TimedMetadata to the listener.
TimedMetadataEventProducer mTimedMetadataEvent;
// Notify if this media is not seekable.
MediaEventProducer<void> mOnMediaNotSeekable;
+ // Notify if we are waiting for a decryption key.
+ MediaEventProducer<TrackInfo::TrackType> mOnTrackWaitingForKey;
+
private:
virtual nsresult InitInternal() { return NS_OK; }
// Does any spinup that needs to happen on this task queue. This runs on a
// different thread than Init, and there should not be ordering dependencies
// between the two (even though in practice, Init will always run first right
// now thanks to the tail dispatcher).
void InitializationTask();
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -384,34 +384,38 @@ MediaFormatReader::DecoderFactory::DoCre
case TrackInfo::kAudioTrack: {
data.mDecoder = mOwner->mPlatform->CreateDecoder({
ownerData.mInfo
? *ownerData.mInfo->GetAsAudioInfo()
: *ownerData.mOriginalInfo->GetAsAudioInfo(),
ownerData.mTaskQueue,
mOwner->mCrashHelper,
ownerData.mIsBlankDecode,
- &result
+ &result,
+ aTrack,
+ &mOwner->OnTrackWaitingForKeyProducer()
});
break;
}
case TrackType::kVideoTrack: {
// Decoders use the layers backend to decide if they can use hardware decoding,
// so specify LAYERS_NONE if we want to forcibly disable it.
data.mDecoder = mOwner->mPlatform->CreateDecoder({
ownerData.mInfo
? *ownerData.mInfo->GetAsVideoInfo()
: *ownerData.mOriginalInfo->GetAsVideoInfo(),
ownerData.mTaskQueue,
mOwner->mKnowsCompositor,
mOwner->GetImageContainer(),
mOwner->mCrashHelper,
ownerData.mIsBlankDecode,
- &result
+ &result,
+ aTrack,
+ &mOwner->OnTrackWaitingForKeyProducer()
});
break;
}
default:
break;
}
@@ -842,16 +846,18 @@ MediaFormatReader::MediaFormatReader(Abs
MOZ_ASSERT(aDemuxer);
MOZ_COUNT_CTOR(MediaFormatReader);
if (aDecoder && aDecoder->CompositorUpdatedEvent()) {
mCompositorUpdatedListener =
aDecoder->CompositorUpdatedEvent()->Connect(
mTaskQueue, this, &MediaFormatReader::NotifyCompositorUpdated);
}
+ mOnTrackWaitingForKeyListener = OnTrackWaitingForKey().Connect(
+ mTaskQueue, this, &MediaFormatReader::NotifyWaitingForKey);
}
MediaFormatReader::~MediaFormatReader()
{
MOZ_COUNT_DTOR(MediaFormatReader);
}
RefPtr<ShutdownPromise>
@@ -890,16 +896,17 @@ MediaFormatReader::Shutdown()
mVideo.ResetState();
promises.AppendElement(ShutdownDecoderWithPromise(TrackInfo::kVideoTrack));
}
promises.AppendElement(mDemuxer->Shutdown());
mDemuxer = nullptr;
mCompositorUpdatedListener.DisconnectIfExists();
+ mOnTrackWaitingForKeyListener.Disconnect();
RefPtr<ShutdownPromise> p = mShutdownPromise.Ensure(__func__);
ShutdownPromise::All(OwnerThread(), promises)
->Then(OwnerThread(), __func__, this,
&MediaFormatReader::TearDownDecoders,
&MediaFormatReader::TearDownDecoders);
mShutdown = true;
@@ -1519,16 +1526,31 @@ MediaFormatReader::NotifyWaitingForData(
decoder.mWaitingForData = true;
if (decoder.mTimeThreshold) {
decoder.mTimeThreshold.ref().mWaiting = true;
}
ScheduleUpdate(aTrack);
}
void
+MediaFormatReader::NotifyWaitingForKey(TrackType aTrack)
+{
+ MOZ_ASSERT(OnTaskQueue());
+ auto& decoder = GetDecoderData(aTrack);
+ if (mDecoder) {
+ mDecoder->NotifyWaitingForKey();
+ }
+ if (!decoder.mDecodeRequest.Exists()) {
+ LOGV("WaitingForKey received while no pending decode. Ignoring");
+ }
+ decoder.mWaitingForKey = true;
+ ScheduleUpdate(aTrack);
+}
+
+void
MediaFormatReader::NotifyEndOfStream(TrackType aTrack)
{
MOZ_ASSERT(OnTaskQueue());
auto& decoder = GetDecoderData(aTrack);
decoder.mDemuxEOS = true;
ScheduleUpdate(aTrack);
}
@@ -2008,16 +2030,20 @@ MediaFormatReader::Update(TrackType aTra
} else if (decoder.mDemuxEOS && !decoder.mNeedDraining &&
!decoder.HasPendingDrain() && decoder.mQueuedSamples.IsEmpty()) {
// It is possible to transition from WAITING_FOR_DATA directly to EOS
// state during the internal seek; in which case no draining would occur.
// There is no more samples left to be decoded and we are already in
// EOS state. We can immediately reject the data promise.
LOG("Rejecting %s promise: EOS", TrackTypeToStr(aTrack));
decoder.RejectPromise(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
+ } else if (decoder.mWaitingForKey) {
+ LOG("Rejecting %s promise: WAITING_FOR_DATA due to waiting for key",
+ TrackTypeToStr(aTrack));
+ decoder.RejectPromise(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA, __func__);
}
}
if (decoder.mNeedDraining) {
DrainDecoder(aTrack);
return;
}
@@ -2049,23 +2075,33 @@ MediaFormatReader::Update(TrackType aTra
"shutdown:%d pending:%u waiting:%d promise:%d sid:%u",
TrackTypeToStr(aTrack), needInput, needOutput, decoder.mNumSamplesInput,
decoder.mNumSamplesOutput, uint32_t(size_t(decoder.mSizeOfQueue)),
decoder.mDecodeRequest.Exists(), decoder.mFlushRequest.Exists(),
decoder.mShutdownRequest.Exists(), uint32_t(decoder.mOutput.Length()),
decoder.mWaitingForData, decoder.HasPromise(),
decoder.mLastStreamSourceID);
- if ((decoder.mWaitingForData &&
- (!decoder.mTimeThreshold || decoder.mTimeThreshold.ref().mWaiting))) {
+ if ((decoder.mWaitingForData
+ && (!decoder.mTimeThreshold || decoder.mTimeThreshold.ref().mWaiting))
+ || (decoder.mWaitingForKey && decoder.mDecodeRequest.Exists())) {
// Nothing more we can do at present.
LOGV("Still waiting for data or key.");
return;
}
+ if (decoder.mWaitingForKey) {
+ decoder.mWaitingForKey = false;
+ if (decoder.HasWaitingPromise() && !decoder.IsWaiting()) {
+ LOGV("No longer waiting for key. Resolving waiting promise");
+ decoder.mWaitingPromise.Resolve(decoder.mType, __func__);
+ return;
+ }
+ }
+
if (!needInput) {
LOGV("No need for additional input (pending:%u)",
uint32_t(decoder.mOutput.Length()));
return;
}
// Demux samples if we don't have some.
RequestDemuxSamples(aTrack);
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -136,16 +136,17 @@ private:
// Drain the current decoder.
void DrainDecoder(TrackType aTrack);
void NotifyNewOutput(TrackType aTrack,
const MediaDataDecoder::DecodedData& aResults);
void NotifyDrainComplete(TrackType aTrack);
void NotifyError(TrackType aTrack, const MediaResult& aError);
void NotifyWaitingForData(TrackType aTrack);
+ void NotifyWaitingForKey(TrackType aTrack);
void NotifyEndOfStream(TrackType aTrack);
void ExtractCryptoInitData(nsTArray<uint8_t>& aInitData);
// Initializes mLayersBackendType if possible.
void InitLayersBackendType();
void Reset(TrackType aTrack);
@@ -165,16 +166,17 @@ private:
uint32_t aNumOfMaxError)
: mOwner(aOwner)
, mType(aType)
, mMutex("DecoderData")
, mDescription("shutdown")
, mUpdateScheduled(false)
, mDemuxEOS(false)
, mWaitingForData(false)
+ , mWaitingForKey(false)
, mReceivedNewData(false)
, mNeedDraining(false)
, mDraining(false)
, mDrainComplete(false)
, mFlushed(true)
, mNumOfConsecutiveError(0)
, mMaxConsecutiveError(aNumOfMaxError)
, mNumSamplesInput(0)
@@ -221,16 +223,17 @@ private:
mDescription = "shutdown";
mDecoder = nullptr;
}
// Only accessed from reader's task queue.
bool mUpdateScheduled;
bool mDemuxEOS;
bool mWaitingForData;
+ bool mWaitingForKey;
bool mReceivedNewData;
// Pending seek.
MozPromiseRequestHolder<MediaTrackDemuxer::SeekPromise> mSeekRequest;
// Queued demux samples waiting to be decoded.
nsTArray<RefPtr<MediaRawData>> mQueuedSamples;
MozPromiseRequestHolder<MediaTrackDemuxer::SamplesPromise> mDemuxRequest;
@@ -240,17 +243,17 @@ private:
bool HasWaitingPromise() const
{
MOZ_ASSERT(mOwner->OnTaskQueue());
return !mWaitingPromise.IsEmpty();
}
bool IsWaiting() const
{
MOZ_ASSERT(mOwner->OnTaskQueue());
- return mWaitingForData;
+ return mWaitingForData || mWaitingForKey;
}
// MediaDataDecoder handler's variables.
MozPromiseRequestHolder<MediaDataDecoder::DecodePromise> mDecodeRequest;
bool mNeedDraining;
MozPromiseRequestHolder<MediaDataDecoder::DecodePromise> mDrainRequest;
bool mDraining;
bool mDrainComplete;
@@ -368,16 +371,17 @@ private:
// Reset the state of the DecoderData, clearing all queued frames
// (pending demuxed and decoded).
// The track demuxer is *not* reset.
void ResetState()
{
MOZ_ASSERT(mOwner->OnTaskQueue());
mDemuxEOS = false;
mWaitingForData = false;
+ mWaitingForKey = false;
mQueuedSamples.Clear();
mNeedDraining = false;
mDecodeRequest.DisconnectIfExists();
mDrainRequest.DisconnectIfExists();
mDraining = false;
mDrainComplete = false;
mTimeThreshold.reset();
mLastSampleTime.reset();
@@ -555,16 +559,17 @@ private:
RefPtr<GMPCrashHelper> mCrashHelper;
void SetBlankDecode(TrackType aTrack, bool aIsBlankDecode);
class DecoderFactory;
UniquePtr<DecoderFactory> mDecoderFactory;
MediaEventListener mCompositorUpdatedListener;
+ MediaEventListener mOnTrackWaitingForKeyListener;
void OnFirstDemuxCompleted(TrackInfo::TrackType aType,
RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
void OnFirstDemuxFailed(TrackInfo::TrackType aType, const MediaResult& aError);
void MaybeResolveMetadataPromise();
--- a/dom/media/platforms/PlatformDecoderModule.h
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -76,16 +76,18 @@ struct MOZ_STACK_CLASS CreateDecoderPara
const TrackInfo& mConfig;
TaskQueue* mTaskQueue = nullptr;
DecoderDoctorDiagnostics* mDiagnostics = nullptr;
layers::ImageContainer* mImageContainer = nullptr;
MediaResult* mError = nullptr;
RefPtr<layers::KnowsCompositor> mKnowsCompositor;
RefPtr<GMPCrashHelper> mCrashHelper;
bool mUseBlankDecoder = false;
+ TrackInfo::TrackType mType = TrackInfo::kUndefinedTrack;
+ MediaEventProducer<TrackInfo::TrackType>* mOnWaitingForKeyEvent = nullptr;
private:
void Set(TaskQueue* aTaskQueue) { mTaskQueue = aTaskQueue; }
void Set(DecoderDoctorDiagnostics* aDiagnostics)
{
mDiagnostics = aDiagnostics;
}
void Set(layers::ImageContainer* aImageContainer)
@@ -94,16 +96,24 @@ private:
}
void Set(MediaResult* aError) { mError = aError; }
void Set(GMPCrashHelper* aCrashHelper) { mCrashHelper = aCrashHelper; }
void Set(bool aUseBlankDecoder) { mUseBlankDecoder = aUseBlankDecoder; }
void Set(layers::KnowsCompositor* aKnowsCompositor)
{
mKnowsCompositor = aKnowsCompositor;
}
+ void Set(TrackInfo::TrackType aType)
+ {
+ mType = aType;
+ }
+ void Set(MediaEventProducer<TrackInfo::TrackType>* aOnWaitingForKey)
+ {
+ mOnWaitingForKeyEvent = aOnWaitingForKey;
+ }
template <typename T1, typename T2, typename... Ts>
void Set(T1&& a1, T2&& a2, Ts&&... args)
{
Set(mozilla::Forward<T1>(a1));
Set(mozilla::Forward<T2>(a2), mozilla::Forward<Ts>(args)...);
}
};
--- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
@@ -22,23 +22,24 @@
namespace mozilla {
typedef MozPromiseRequestHolder<CDMProxy::DecryptPromise> DecryptPromiseRequestHolder;
extern already_AddRefed<PlatformDecoderModule> CreateBlankDecoderModule();
class EMEDecryptor : public MediaDataDecoder
{
public:
- EMEDecryptor(MediaDataDecoder* aDecoder,
- CDMProxy* aProxy,
- TaskQueue* aDecodeTaskQueue)
+ EMEDecryptor(MediaDataDecoder* aDecoder, CDMProxy* aProxy,
+ TaskQueue* aDecodeTaskQueue, TrackInfo::TrackType aType,
+ MediaEventProducer<TrackInfo::TrackType>* aOnWaitingForKey)
: mDecoder(aDecoder)
, mTaskQueue(aDecodeTaskQueue)
, mProxy(aProxy)
- , mSamplesWaitingForKey(new SamplesWaitingForKey(mProxy))
+ , mSamplesWaitingForKey(
+ new SamplesWaitingForKey(mProxy, aType, aOnWaitingForKey))
, mIsShutdown(false)
{
}
RefPtr<InitPromise> Init() override
{
MOZ_ASSERT(!mIsShutdown);
return mDecoder->Init();
@@ -199,22 +200,25 @@ private:
MozPromiseRequestHolder<DecodePromise> mDecodeRequest;
bool mIsShutdown;
};
class EMEMediaDataDecoderProxy : public MediaDataDecoderProxy
{
public:
- EMEMediaDataDecoderProxy(already_AddRefed<AbstractThread> aProxyThread,
- CDMProxy* aProxy)
- : MediaDataDecoderProxy(Move(aProxyThread))
- , mTaskQueue(AbstractThread::GetCurrent()->AsTaskQueue())
- , mSamplesWaitingForKey(new SamplesWaitingForKey(aProxy))
- , mProxy(aProxy)
+ EMEMediaDataDecoderProxy(
+ already_AddRefed<AbstractThread> aProxyThread, CDMProxy* aProxy,
+ TrackInfo::TrackType aType,
+ MediaEventProducer<TrackInfo::TrackType>* aOnWaitingForKey)
+ : MediaDataDecoderProxy(Move(aProxyThread))
+ , mTaskQueue(AbstractThread::GetCurrent()->AsTaskQueue())
+ , mSamplesWaitingForKey(
+ new SamplesWaitingForKey(aProxy, aType, aOnWaitingForKey))
+ , mProxy(aProxy)
{
}
RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
RefPtr<FlushPromise> Flush() override;
RefPtr<ShutdownPromise> Shutdown() override;
private:
@@ -284,58 +288,60 @@ EMEDecoderModule::EMEDecoderModule(CDMPr
{
}
EMEDecoderModule::~EMEDecoderModule()
{
}
static already_AddRefed<MediaDataDecoderProxy>
-CreateDecoderWrapper(CDMProxy* aProxy)
+CreateDecoderWrapper(CDMProxy* aProxy, const CreateDecoderParams& aParams)
{
RefPtr<gmp::GeckoMediaPluginService> s(gmp::GeckoMediaPluginService::GetGeckoMediaPluginService());
if (!s) {
return nullptr;
}
RefPtr<AbstractThread> thread(s->GetAbstractGMPThread());
if (!thread) {
return nullptr;
}
- RefPtr<MediaDataDecoderProxy> decoder(
- new EMEMediaDataDecoderProxy(thread.forget(), aProxy));
+ RefPtr<MediaDataDecoderProxy> decoder(new EMEMediaDataDecoderProxy(
+ thread.forget(), aProxy, aParams.mType, aParams.mOnWaitingForKeyEvent));
return decoder.forget();
}
already_AddRefed<MediaDataDecoder>
EMEDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
{
MOZ_ASSERT(aParams.mConfig.mCrypto.mValid);
if (MediaPrefs::EMEBlankVideo()) {
EME_LOG("EMEDecoderModule::CreateVideoDecoder() creating a blank decoder.");
RefPtr<PlatformDecoderModule> m(CreateBlankDecoderModule());
return m->CreateVideoDecoder(aParams);
}
if (SupportsMimeType(aParams.mConfig.mMimeType, nullptr)) {
// GMP decodes. Assume that means it can decrypt too.
- RefPtr<MediaDataDecoderProxy> wrapper = CreateDecoderWrapper(mProxy);
+ RefPtr<MediaDataDecoderProxy> wrapper =
+ CreateDecoderWrapper(mProxy, aParams);
auto params = GMPVideoDecoderParams(aParams);
wrapper->SetProxyTarget(new EMEVideoDecoder(mProxy, params));
return wrapper.forget();
}
MOZ_ASSERT(mPDM);
RefPtr<MediaDataDecoder> decoder(mPDM->CreateDecoder(aParams));
if (!decoder) {
return nullptr;
}
RefPtr<MediaDataDecoder> emeDecoder(new EMEDecryptor(
- decoder, mProxy, AbstractThread::GetCurrent()->AsTaskQueue()));
+ decoder, mProxy, AbstractThread::GetCurrent()->AsTaskQueue(),
+ aParams.mType, aParams.mOnWaitingForKeyEvent));
return emeDecoder.forget();
}
already_AddRefed<MediaDataDecoder>
EMEDecoderModule::CreateAudioDecoder(const CreateDecoderParams& aParams)
{
MOZ_ASSERT(aParams.mConfig.mCrypto.mValid);
@@ -350,17 +356,18 @@ EMEDecoderModule::CreateAudioDecoder(con
}
RefPtr<MediaDataDecoder> decoder(mPDM->CreateDecoder(aParams));
if (!decoder) {
return nullptr;
}
RefPtr<MediaDataDecoder> emeDecoder(new EMEDecryptor(
- decoder, mProxy, AbstractThread::GetCurrent()->AsTaskQueue()));
+ decoder, mProxy, AbstractThread::GetCurrent()->AsTaskQueue(),
+ aParams.mType, aParams.mOnWaitingForKeyEvent));
return emeDecoder.forget();
}
PlatformDecoderModule::ConversionRequired
EMEDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const
{
if (aConfig.IsVideo() && MP4Decoder::IsH264(aConfig.mMimeType)) {
return ConversionRequired::kNeedAVCC;
--- a/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.cpp
+++ b/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.cpp
@@ -3,23 +3,28 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/CDMProxy.h"
#include "mozilla/CDMCaps.h"
#include "mozilla/TaskQueue.h"
#include "MediaData.h"
+#include "MediaEventSource.h"
#include "SamplesWaitingForKey.h"
namespace mozilla {
-SamplesWaitingForKey::SamplesWaitingForKey(CDMProxy* aProxy)
+SamplesWaitingForKey::SamplesWaitingForKey(
+ CDMProxy* aProxy, TrackInfo::TrackType aType,
+ MediaEventProducer<TrackInfo::TrackType>* aOnWaitingForKey)
: mMutex("SamplesWaitingForKey")
, mProxy(aProxy)
+ , mType(aType)
+ , mOnWaitingForKeyEvent(aOnWaitingForKey)
{
}
SamplesWaitingForKey::~SamplesWaitingForKey()
{
Flush();
}
@@ -36,16 +41,19 @@ SamplesWaitingForKey::WaitIfKeyNotUsable
}
SampleEntry entry;
entry.mSample = aSample;
RefPtr<WaitForKeyPromise> p = entry.mPromise.Ensure(__func__);
{
MutexAutoLock lock(mMutex);
mSamples.AppendElement(Move(entry));
}
+ if (mOnWaitingForKeyEvent) {
+ mOnWaitingForKeyEvent->Notify(mType);
+ }
caps.NotifyWhenKeyIdUsable(aSample->mCrypto.mKeyId, this);
return p;
}
void
SamplesWaitingForKey::NotifyUsable(const CencKeyId& aKeyId)
{
MutexAutoLock lock(mMutex);
--- a/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.h
+++ b/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.h
@@ -5,35 +5,38 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef SamplesWaitingForKey_h_
#define SamplesWaitingForKey_h_
#include "mozilla/MozPromise.h"
#include "mozilla/Mutex.h"
#include "mozilla/RefPtr.h"
+#include "MediaInfo.h"
namespace mozilla {
typedef nsTArray<uint8_t> CencKeyId;
class CDMProxy;
+template <typename... Es> class MediaEventProducer;
class MediaRawData;
// Encapsulates the task of waiting for the CDMProxy to have the necessary
// keys to decrypt a given sample.
class SamplesWaitingForKey
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SamplesWaitingForKey)
typedef MozPromise<RefPtr<MediaRawData>, bool, /* IsExclusive = */ true>
WaitForKeyPromise;
- explicit SamplesWaitingForKey(CDMProxy* aProxy);
+ SamplesWaitingForKey(CDMProxy* aProxy, TrackInfo::TrackType aType,
+ MediaEventProducer<TrackInfo::TrackType>* aOnWaitingForKey);
// Returns a promise that will be resolved if or when a key for decoding the
// sample becomes usable.
RefPtr<WaitForKeyPromise> WaitIfKeyNotUsable(MediaRawData* aSample);
void NotifyUsable(const CencKeyId& aKeyId);
void Flush();
@@ -45,13 +48,15 @@ private:
Mutex mMutex;
RefPtr<CDMProxy> mProxy;
struct SampleEntry
{
RefPtr<MediaRawData> mSample;
MozPromiseHolder<WaitForKeyPromise> mPromise;
};
nsTArray<SampleEntry> mSamples;
+ const TrackInfo::TrackType mType;
+ MediaEventProducer<TrackInfo::TrackType>* const mOnWaitingForKeyEvent;
};
} // namespace mozilla
#endif // SamplesWaitingForKey_h_
--- a/dom/media/platforms/wrappers/H264Converter.cpp
+++ b/dom/media/platforms/wrappers/H264Converter.cpp
@@ -23,16 +23,18 @@ H264Converter::H264Converter(PlatformDec
, mKnowsCompositor(aParams.mKnowsCompositor)
, mImageContainer(aParams.mImageContainer)
, mTaskQueue(aParams.mTaskQueue)
, mDecoder(nullptr)
, mGMPCrashHelper(aParams.mCrashHelper)
, mNeedAVCC(aPDM->DecoderNeedsConversion(aParams.mConfig)
== PlatformDecoderModule::ConversionRequired::kNeedAVCC)
, mLastError(NS_OK)
+ , mType(aParams.mType)
+ , mOnWaitingForKeyEvent(aParams.mOnWaitingForKeyEvent)
{
CreateDecoder(aParams.mDiagnostics);
}
H264Converter::~H264Converter()
{
}
@@ -189,17 +191,19 @@ H264Converter::CreateDecoder(DecoderDoct
}
mDecoder = mPDM->CreateVideoDecoder({
mCurrentConfig,
mTaskQueue,
aDiagnostics,
mImageContainer,
mKnowsCompositor,
- mGMPCrashHelper
+ mGMPCrashHelper,
+ mType,
+ mOnWaitingForKeyEvent
});
if (!mDecoder) {
mLastError = NS_ERROR_FAILURE;
return NS_ERROR_FAILURE;
}
mNeedKeyframe = true;
--- a/dom/media/platforms/wrappers/H264Converter.h
+++ b/dom/media/platforms/wrappers/H264Converter.h
@@ -71,13 +71,15 @@ private:
RefPtr<MediaDataDecoder> mDecoder;
MozPromiseRequestHolder<InitPromise> mInitPromiseRequest;
MozPromiseRequestHolder<DecodePromise> mDecodePromiseRequest;
MozPromiseHolder<DecodePromise> mDecodePromise;
RefPtr<GMPCrashHelper> mGMPCrashHelper;
bool mNeedAVCC;
nsresult mLastError;
bool mNeedKeyframe = true;
+ const TrackInfo::TrackType mType;
+ MediaEventProducer<TrackInfo::TrackType>* const mOnWaitingForKeyEvent;
};
} // namespace mozilla
#endif // mozilla_H264Converter_h