dom/media: more eme fixes

This commit is contained in:
roytam1 2023-09-14 16:57:56 +08:00
commit 58a39ca8cb
9 changed files with 72 additions and 10 deletions

View file

@ -388,7 +388,9 @@ MediaDecoder::MediaDecoder(MediaDecoderOwner* aOwner)
, mLogicalPosition(0.0) , mLogicalPosition(0.0)
, mDuration(std::numeric_limits<double>::quiet_NaN()) , mDuration(std::numeric_limits<double>::quiet_NaN())
, mResourceCallback(new ResourceCallback()) , mResourceCallback(new ResourceCallback())
#ifdef MOZ_EME
, mCDMProxyPromise(mCDMProxyPromiseHolder.Ensure(__func__)) , mCDMProxyPromise(mCDMProxyPromiseHolder.Ensure(__func__))
#endif
, mIgnoreProgressData(false) , mIgnoreProgressData(false)
, mInfiniteStream(false) , mInfiniteStream(false)
, mOwner(aOwner) , mOwner(aOwner)
@ -473,7 +475,9 @@ MediaDecoder::Shutdown()
mResourceCallback->Disconnect(); mResourceCallback->Disconnect();
#ifdef MOZ_EME
mCDMProxyPromiseHolder.RejectIfExists(true, __func__); mCDMProxyPromiseHolder.RejectIfExists(true, __func__);
#endif
DiscardOngoingSeekIfExists(); DiscardOngoingSeekIfExists();
@ -1547,6 +1551,7 @@ MediaDecoder::CanPlayThrough()
return GetStatistics().CanPlayThrough(); return GetStatistics().CanPlayThrough();
} }
#ifdef MOZ_EME
RefPtr<MediaDecoder::CDMProxyPromise> RefPtr<MediaDecoder::CDMProxyPromise>
MediaDecoder::RequestCDMProxy() const MediaDecoder::RequestCDMProxy() const
{ {
@ -1561,6 +1566,7 @@ MediaDecoder::SetCDMProxy(CDMProxy* aProxy)
mCDMProxyPromiseHolder.ResolveIfExists(aProxy, __func__); mCDMProxyPromiseHolder.ResolveIfExists(aProxy, __func__);
} }
#endif
bool bool
MediaDecoder::IsOpusEnabled() MediaDecoder::IsOpusEnabled()

View file

@ -7,7 +7,9 @@
#define MediaDecoder_h_ #define MediaDecoder_h_
#include "mozilla/Atomics.h" #include "mozilla/Atomics.h"
#ifdef MOZ_EME
#include "mozilla/CDMProxy.h" #include "mozilla/CDMProxy.h"
#endif
#include "mozilla/MozPromise.h" #include "mozilla/MozPromise.h"
#include "mozilla/ReentrantMonitor.h" #include "mozilla/ReentrantMonitor.h"
#include "mozilla/StateMirroring.h" #include "mozilla/StateMirroring.h"
@ -433,6 +435,7 @@ private:
MediaDecoderOwner* GetOwner() const override; MediaDecoderOwner* GetOwner() const override;
#ifdef MOZ_EME
typedef MozPromise<RefPtr<CDMProxy>, bool /* aIgnored */, /* IsExclusive = */ true> CDMProxyPromise; typedef MozPromise<RefPtr<CDMProxy>, bool /* aIgnored */, /* IsExclusive = */ true> CDMProxyPromise;
// Resolved when a CDMProxy is available and the capabilities are known or // Resolved when a CDMProxy is available and the capabilities are known or
@ -440,6 +443,7 @@ private:
RefPtr<CDMProxyPromise> RequestCDMProxy() const; RefPtr<CDMProxyPromise> RequestCDMProxy() const;
void SetCDMProxy(CDMProxy* aProxy); void SetCDMProxy(CDMProxy* aProxy);
#endif
static bool IsOggEnabled(); static bool IsOggEnabled();
static bool IsOpusEnabled(); static bool IsOpusEnabled();
@ -590,8 +594,10 @@ private:
RefPtr<ResourceCallback> mResourceCallback; RefPtr<ResourceCallback> mResourceCallback;
#ifdef MOZ_EME
MozPromiseHolder<CDMProxyPromise> mCDMProxyPromiseHolder; MozPromiseHolder<CDMProxyPromise> mCDMProxyPromiseHolder;
RefPtr<CDMProxyPromise> mCDMProxyPromise; RefPtr<CDMProxyPromise> mCDMProxyPromise;
#endif
protected: protected:
// The promise resolving/rejection is queued as a "micro-task" which will be // The promise resolving/rejection is queued as a "micro-task" which will be

View file

@ -192,7 +192,9 @@ public:
virtual State GetState() const = 0; virtual State GetState() const = 0;
// Event handlers for various events. // Event handlers for various events.
#ifdef MOZ_EME
virtual void HandleCDMProxyReady() {} virtual void HandleCDMProxyReady() {}
#endif
virtual void HandleAudioDecoded(MediaData* aAudio) {} virtual void HandleAudioDecoded(MediaData* aAudio) {}
virtual void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) {} virtual void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) {}
virtual void HandleEndOfStream() {} virtual void HandleEndOfStream() {}
@ -370,7 +372,9 @@ public:
return DECODER_STATE_WAIT_FOR_CDM; return DECODER_STATE_WAIT_FOR_CDM;
} }
#ifdef MOZ_EME
void HandleCDMProxyReady() override; void HandleCDMProxyReady() override;
#endif
RefPtr<MediaDecoder::SeekPromise> HandleSeek(SeekTarget aTarget) override RefPtr<MediaDecoder::SeekPromise> HandleSeek(SeekTarget aTarget) override
{ {
@ -1237,22 +1241,32 @@ DecodeMetadataState::OnMetadataRead(MetadataHolder* aMetadata)
// feeding in the CDM, which we need to decode the first frame (and // feeding in the CDM, which we need to decode the first frame (and
// thus get the metadata). We could fix this if we could compute the start // thus get the metadata). We could fix this if we could compute the start
// time by demuxing without necessaring decoding. // time by demuxing without necessaring decoding.
#ifdef MOZ_EME
bool waitingForCDM = Info().IsEncrypted() && !mMaster->mCDMProxy; bool waitingForCDM = Info().IsEncrypted() && !mMaster->mCDMProxy;
#endif
mMaster->mNotifyMetadataBeforeFirstFrame = mMaster->mNotifyMetadataBeforeFirstFrame =
mMaster->mDuration.Ref().isSome() || waitingForCDM; mMaster->mDuration.Ref().isSome()
#ifdef MOZ_EME
|| waitingForCDM
#endif
;
if (mMaster->mNotifyMetadataBeforeFirstFrame) { if (mMaster->mNotifyMetadataBeforeFirstFrame) {
mMaster->EnqueueLoadedMetadataEvent(); mMaster->EnqueueLoadedMetadataEvent();
} }
#ifdef MOZ_EME
if (waitingForCDM) { if (waitingForCDM) {
// Metadata parsing was successful but we're still waiting for CDM caps // Metadata parsing was successful but we're still waiting for CDM caps
// to become available so that we can build the correct decryptor/decoder. // to become available so that we can build the correct decryptor/decoder.
SetState<WaitForCDMState>(); SetState<WaitForCDMState>();
} else { } else {
#endif
SetState<DecodingFirstFrameState>(SeekJob{}); SetState<DecodingFirstFrameState>(SeekJob{});
#ifdef MOZ_EME
} }
#endif
} }
void void
@ -1261,18 +1275,24 @@ DormantState::HandlePlayStateChanged(MediaDecoder::PlayState aPlayState)
{ {
if (aPlayState == MediaDecoder::PLAY_STATE_PLAYING) { if (aPlayState == MediaDecoder::PLAY_STATE_PLAYING) {
// Exit dormant when the user wants to play. // Exit dormant when the user wants to play.
MOZ_ASSERT(!Info().IsEncrypted() || mMaster->mCDMProxy); MOZ_ASSERT(!Info().IsEncrypted()
#ifdef MOZ_EME
|| mMaster->mCDMProxy
#endif
);
MOZ_ASSERT(mMaster->mSentFirstFrameLoadedEvent); MOZ_ASSERT(mMaster->mSentFirstFrameLoadedEvent);
SetState<SeekingState>(Move(mPendingSeek), EventVisibility::Suppressed); SetState<SeekingState>(Move(mPendingSeek), EventVisibility::Suppressed);
} }
} }
#ifdef MOZ_EME
void void
MediaDecoderStateMachine:: MediaDecoderStateMachine::
WaitForCDMState::HandleCDMProxyReady() WaitForCDMState::HandleCDMProxyReady()
{ {
SetState<DecodingFirstFrameState>(Move(mPendingSeek)); SetState<DecodingFirstFrameState>(Move(mPendingSeek));
} }
#endif
void void
MediaDecoderStateMachine:: MediaDecoderStateMachine::
@ -1574,7 +1594,9 @@ ShutdownState::Enter()
// dispose of the timer. // dispose of the timer.
master->mVideoDecodeSuspendTimer.Reset(); master->mVideoDecodeSuspendTimer.Reset();
#ifdef MOZ_EME
master->mCDMProxyPromise.DisconnectIfExists(); master->mCDMProxyPromise.DisconnectIfExists();
#endif
if (master->IsPlaying()) { if (master->IsPlaying()) {
master->StopPlayback(); master->StopPlayback();
@ -2128,10 +2150,12 @@ nsresult MediaDecoderStateMachine::Init(MediaDecoder* aDecoder)
mMediaSink = CreateMediaSink(mAudioCaptured); mMediaSink = CreateMediaSink(mAudioCaptured);
#ifdef MOZ_EME
mCDMProxyPromise.Begin(aDecoder->RequestCDMProxy()->Then( mCDMProxyPromise.Begin(aDecoder->RequestCDMProxy()->Then(
OwnerThread(), __func__, this, OwnerThread(), __func__, this,
&MediaDecoderStateMachine::OnCDMProxyReady, &MediaDecoderStateMachine::OnCDMProxyReady,
&MediaDecoderStateMachine::OnCDMProxyNotReady)); &MediaDecoderStateMachine::OnCDMProxyNotReady));
#endif
nsresult rv = mReader->Init(); nsresult rv = mReader->Init();
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -3107,6 +3131,7 @@ void MediaDecoderStateMachine::OnMediaSinkAudioError(nsresult aResult)
DecodeError(MediaResult(NS_ERROR_DOM_MEDIA_MEDIASINK_ERR, __func__)); DecodeError(MediaResult(NS_ERROR_DOM_MEDIA_MEDIASINK_ERR, __func__));
} }
#ifdef MOZ_EME
void void
MediaDecoderStateMachine::OnCDMProxyReady(RefPtr<CDMProxy> aProxy) MediaDecoderStateMachine::OnCDMProxyReady(RefPtr<CDMProxy> aProxy)
{ {
@ -3123,6 +3148,7 @@ MediaDecoderStateMachine::OnCDMProxyNotReady()
MOZ_ASSERT(OnTaskQueue()); MOZ_ASSERT(OnTaskQueue());
mCDMProxyPromise.Complete(); mCDMProxyPromise.Complete();
} }
#endif
void void
MediaDecoderStateMachine::SetAudioCaptured(bool aCaptured) MediaDecoderStateMachine::SetAudioCaptured(bool aCaptured)

View file

@ -767,10 +767,12 @@ private:
// Playback will not start when audio is offloading. // Playback will not start when audio is offloading.
bool mAudioOffloading; bool mAudioOffloading;
#ifdef MOZ_EME
void OnCDMProxyReady(RefPtr<CDMProxy> aProxy); void OnCDMProxyReady(RefPtr<CDMProxy> aProxy);
void OnCDMProxyNotReady(); void OnCDMProxyNotReady();
RefPtr<CDMProxy> mCDMProxy; RefPtr<CDMProxy> mCDMProxy;
MozPromiseRequestHolder<MediaDecoder::CDMProxyPromise> mCDMProxyPromise; MozPromiseRequestHolder<MediaDecoder::CDMProxyPromise> mCDMProxyPromise;
#endif
private: private:
// The buffered range. Mirrored from the decoder thread. // The buffered range. Mirrored from the decoder thread.

View file

@ -3,7 +3,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef MOZ_EME
#include "mozilla/CDMProxy.h" #include "mozilla/CDMProxy.h"
#endif
#include "mozilla/ClearOnShutdown.h" #include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/HTMLMediaElement.h" #include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
@ -617,6 +619,7 @@ private:
}; };
#endif #endif
#ifdef MOZ_EME
void void
MediaFormatReader::SetCDMProxy(CDMProxy* aProxy) MediaFormatReader::SetCDMProxy(CDMProxy* aProxy)
{ {
@ -628,6 +631,7 @@ MediaFormatReader::SetCDMProxy(CDMProxy* aProxy)
}); });
OwnerThread()->Dispatch(r.forget()); OwnerThread()->Dispatch(r.forget());
} }
#endif
bool bool
MediaFormatReader::IsWaitingOnCDMResource() { MediaFormatReader::IsWaitingOnCDMResource() {

View file

@ -19,7 +19,9 @@
namespace mozilla { namespace mozilla {
#ifdef MOZ_EME
class CDMProxy; class CDMProxy;
#endif
class MediaFormatReader final : public MediaDecoderReader class MediaFormatReader final : public MediaDecoderReader
{ {
@ -90,7 +92,9 @@ public:
return mTrackDemuxersMayBlock; return mTrackDemuxersMayBlock;
} }
#ifdef MOZ_EME
void SetCDMProxy(CDMProxy* aProxy) override; void SetCDMProxy(CDMProxy* aProxy) override;
#endif
// Returns a string describing the state of the decoder data. // Returns a string describing the state of the decoder data.
// Used for debugging purposes. // Used for debugging purposes.
@ -583,7 +587,9 @@ private:
RefPtr<VideoFrameContainer> mVideoFrameContainer; RefPtr<VideoFrameContainer> mVideoFrameContainer;
layers::ImageContainer* GetImageContainer(); layers::ImageContainer* GetImageContainer();
#ifdef MOZ_EME
RefPtr<CDMProxy> mCDMProxy; RefPtr<CDMProxy> mCDMProxy;
#endif
#ifdef MOZ_GMP #ifdef MOZ_GMP
RefPtr<GMPCrashHelper> mCrashHelper; RefPtr<GMPCrashHelper> mCrashHelper;

View file

@ -9,7 +9,9 @@
#include "MP4Demuxer.h" #include "MP4Demuxer.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "nsCharSeparatedTokenizer.h" #include "nsCharSeparatedTokenizer.h"
#ifdef MOZ_EME
#include "mozilla/CDMProxy.h" #include "mozilla/CDMProxy.h"
#endif
#include "mozilla/Logging.h" #include "mozilla/Logging.h"
#include "mozilla/SharedThreadPool.h" #include "mozilla/SharedThreadPool.h"
#include "nsMimeTypes.h" #include "nsMimeTypes.h"

View file

@ -22,7 +22,9 @@
#include "GMPDecoderModule.h" #include "GMPDecoderModule.h"
#endif #endif
#ifdef MOZ_EME
#include "mozilla/CDMProxy.h" #include "mozilla/CDMProxy.h"
#endif
#include "mozilla/ClearOnShutdown.h" #include "mozilla/ClearOnShutdown.h"
#include "mozilla/SharedThreadPool.h" #include "mozilla/SharedThreadPool.h"
#include "mozilla/StaticPtr.h" #include "mozilla/StaticPtr.h"
@ -35,7 +37,9 @@
#include "H264Converter.h" #include "H264Converter.h"
#include "AgnosticDecoderModule.h" #include "AgnosticDecoderModule.h"
#ifdef MOZ_EME
#include "EMEDecoderModule.h" #include "EMEDecoderModule.h"
#endif
#include "DecoderDoctorDiagnostics.h" #include "DecoderDoctorDiagnostics.h"
@ -454,11 +458,13 @@ PDMFactory::GetDecoder(const TrackInfo& aTrackInfo,
return pdm.forget(); return pdm.forget();
} }
#ifdef MOZ_EME
void void
PDMFactory::SetCDMProxy(CDMProxy* aProxy) PDMFactory::SetCDMProxy(CDMProxy* aProxy)
{ {
RefPtr<PDMFactory> m = new PDMFactory(); RefPtr<PDMFactory> m = new PDMFactory();
mEMEPDM = new EMEDecoderModule(aProxy, m); mEMEPDM = new EMEDecoderModule(aProxy, m);
} }
#endif
} // namespace mozilla } // namespace mozilla

View file

@ -283,15 +283,7 @@ WEBIDL_FILES = [
'MediaDeviceInfo.webidl', 'MediaDeviceInfo.webidl',
'MediaDevices.webidl', 'MediaDevices.webidl',
'MediaElementAudioSourceNode.webidl', 'MediaElementAudioSourceNode.webidl',
'MediaEncryptedEvent.webidl',
'MediaError.webidl', 'MediaError.webidl',
'MediaKeyError.webidl',
'MediaKeyMessageEvent.webidl',
'MediaKeys.webidl',
'MediaKeySession.webidl',
'MediaKeysRequestStatus.webidl',
'MediaKeyStatusMap.webidl',
'MediaKeySystemAccess.webidl',
'MediaList.webidl', 'MediaList.webidl',
'MediaQueryList.webidl', 'MediaQueryList.webidl',
'MediaRecorder.webidl', 'MediaRecorder.webidl',
@ -583,6 +575,18 @@ WEBIDL_FILES = [
'XULElement.webidl', 'XULElement.webidl',
] ]
if CONFIG['MOZ_EME']:
WEBIDL_FILES += [
'MediaEncryptedEvent.webidl',
'MediaKeyError.webidl',
'MediaKeyMessageEvent.webidl',
'MediaKeys.webidl',
'MediaKeySession.webidl',
'MediaKeysRequestStatus.webidl',
'MediaKeyStatusMap.webidl',
'MediaKeySystemAccess.webidl',
]
if CONFIG['MOZ_WEBEXTENSIONS']: if CONFIG['MOZ_WEBEXTENSIONS']:
WEBIDL_FILES += ['AddonManager.webidl'] WEBIDL_FILES += ['AddonManager.webidl']