mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
Bug 1823541 - part2 : recreate the state machine if DRM playback is not allowed for the media engine playback. r=jolin
As we can't determine if the external state machine is going to be used for DRM playback at the time we create it, we need to check that later when the CDM proxy is assigned to the decoder. So when detecting DRM playback on the media engine playback and the pref is disabled, we would destroy the external state machine and then create our normal state machine in order to run Gecko's media pipeline. There is a race between shutting down the old format reader and the new format reader. For the media source playback, we would reuse the demuxer [1]. If the demuxer init hasn't finished when the new format reader starts initializing the demuxer, we would end up chaining the same init promise twice, which hit the assertion of exclusive promise. Therefore, we change the init promise to non-exlusive, which won't hurt, because in our case that means we don't need to re-init the demuxer again. For other cases, it won't change any behavior because the media format reader won't change its demuxer at the middle of playback, and that promise actually isn't necessary to be an exclusive promise. [1] https://searchfox.org/mozilla-central/rev/137075514eddc08c68ff652e9899da82e8043574/dom/media/mediasource/MediaSourceDecoder.cpp#42-44 [2] https://searchfox.org/mozilla-central/rev/137075514eddc08c68ff652e9899da82e8043574/dom/media/MediaFormatReader.cpp#782-788 Depends on D173205 Differential Revision: https://phabricator.services.mozilla.com/D173206
This commit is contained in:
parent
79a84f1d8d
commit
fd3d570d36
@ -35,7 +35,7 @@ class MediaDataDemuxer : public DecoderDoctorLifeLogger<MediaDataDemuxer> {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDataDemuxer)
|
||||
|
||||
typedef MozPromise<MediaResult, MediaResult, /* IsExclusive = */ true>
|
||||
typedef MozPromise<MediaResult, MediaResult, /* IsExclusive = */ false>
|
||||
InitPromise;
|
||||
|
||||
// Initializes the demuxer. Other methods cannot be called unless
|
||||
|
@ -436,12 +436,13 @@ void MediaDecoder::OnPlaybackErrorEvent(const MediaResult& aError) {
|
||||
return;
|
||||
}
|
||||
|
||||
// External engine can't play the resource, try to use our own state machine
|
||||
// again. Here we will create a new state machine immediately and asynchrously
|
||||
// shutdown the old one because we don't want to dispatch any task to the old
|
||||
// state machine. Therefore, we will disconnect anything related with the old
|
||||
// state machine, create a new state machine and setup events/mirror/etc, then
|
||||
// shutdown the old one and release its reference once it finishes shutdown.
|
||||
// External engine can't play the resource or we intentionally disable it, try
|
||||
// to use our own state machine again. Here we will create a new state machine
|
||||
// immediately and asynchrously shutdown the old one because we don't want to
|
||||
// dispatch any task to the old state machine. Therefore, we will disconnect
|
||||
// anything related with the old state machine, create a new state machine and
|
||||
// setup events/mirror/etc, then shutdown the old one and release its
|
||||
// reference once it finishes shutdown.
|
||||
MOZ_ASSERT(aError == NS_ERROR_DOM_MEDIA_EXTERNAL_ENGINE_NOT_SUPPORTED_ERR);
|
||||
RefPtr<MediaDecoderStateMachineBase> discardStateMachine =
|
||||
mDecoderStateMachine;
|
||||
@ -1369,6 +1370,16 @@ bool MediaDecoder::CanPlayThrough() {
|
||||
|
||||
RefPtr<SetCDMPromise> MediaDecoder::SetCDMProxy(CDMProxy* aProxy) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
#ifdef MOZ_WMF_MEDIA_ENGINE
|
||||
// DRM playback via the media engine is disabled, switch back to the state
|
||||
// machine using Gecko's media pipeline.
|
||||
if (GetStateMachine()->IsExternalStateMachine() &&
|
||||
!StaticPrefs::media_wmf_media_engine_drm_playback()) {
|
||||
LOG("Disable external state machine due to DRM playback not allowed");
|
||||
OnPlaybackErrorEvent(
|
||||
MediaResult{NS_ERROR_DOM_MEDIA_EXTERNAL_ENGINE_NOT_SUPPORTED_ERR});
|
||||
}
|
||||
#endif
|
||||
return GetStateMachine()->SetCDMProxy(aProxy);
|
||||
}
|
||||
|
||||
|
@ -10212,6 +10212,12 @@
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
# This allows playing DRM video via the media engine pipeline.
|
||||
- name: media.wmf.media-engine.drm-playback
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
# The amount of video raw data the engine stream will queue
|
||||
- name: media.wmf.media-engine.raw-data-threshold.video
|
||||
type: RelaxedAtomicInt32
|
||||
|
Loading…
Reference in New Issue
Block a user