From fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:14:29 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- dom/media/mediasource/MediaSourceDecoder.cpp | 33 +++++++++++++--- dom/media/mediasource/MediaSourceDecoder.h | 5 +++ dom/media/mediasource/test/mochitest.toml | 2 + .../test/test_BufferedSeekCanPlayThrough.html | 46 ++++++++++++++++++++++ dom/media/mediasource/test/test_EndOfStream.html | 2 +- .../mediasource/test/test_EndOfStream_mp4.html | 2 +- .../mediasource/test/test_ExperimentalAsync.html | 4 +- dom/media/mediasource/test/test_SetModeThrows.html | 2 +- 8 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 dom/media/mediasource/test/test_BufferedSeekCanPlayThrough.html (limited to 'dom/media/mediasource') diff --git a/dom/media/mediasource/MediaSourceDecoder.cpp b/dom/media/mediasource/MediaSourceDecoder.cpp index 24a74e261b..3a1308a9ca 100644 --- a/dom/media/mediasource/MediaSourceDecoder.cpp +++ b/dom/media/mediasource/MediaSourceDecoder.cpp @@ -57,8 +57,13 @@ MediaDecoderStateMachineBase* MediaSourceDecoder::CreateStateMachine( TrackingId::TrackAcrossProcesses::Yes); mReader = new MediaFormatReader(init, mDemuxer); #ifdef MOZ_WMF_MEDIA_ENGINE - // TODO : Only for testing development for now. In the future this should be - // used for encrypted content only. + // Our main purpose is to only using this state machine for encrypted playback + // (unless explicitly set the pref to allow non-encrypted playback), but we + // can't determine if playback is encrypted or not at the moment. Therefore, + // we will handle that in ExternalEngineStateMachine, and report special + // errors, such as NS_ERROR_DOM_MEDIA_EXTERNAL_ENGINE_NOT_SUPPORTED_ERR or + // NS_ERROR_DOM_MEDIA_CDM_PROXY_NOT_SUPPORTED_ERR, to switch the state + // machine if necessary. if (StaticPrefs::media_wmf_media_engine_enabled() && !aDisableExternalEngine) { return new ExternalEngineStateMachine(this, mReader); @@ -319,12 +324,13 @@ bool MediaSourceDecoder::CanPlayThroughImpl() { } // If we have data up to the mediasource's duration or 3s ahead, we can // assume that we can play without interruption. - dom::SourceBufferList* sourceBuffers = mMediaSource->ActiveSourceBuffers(); - TimeUnit bufferedEnd = sourceBuffers->GetHighestBufferedEndTime(); + TimeIntervals buffered = GetBuffered(); + buffered.SetFuzz(MediaSourceDemuxer::EOS_FUZZ / 2); TimeUnit timeAhead = std::min(duration, currentPosition + TimeUnit::FromSeconds(3)); TimeInterval interval(currentPosition, timeAhead); - return bufferedEnd >= timeAhead; + return buffered.ToMicrosecondResolution().ContainsWithStrictEnd( + ClampIntervalToEnd(interval)); } TimeInterval MediaSourceDecoder::ClampIntervalToEnd( @@ -366,6 +372,23 @@ bool MediaSourceDecoder::HadCrossOriginRedirects() { return false; } +#ifdef MOZ_WMF_MEDIA_ENGINE +void MediaSourceDecoder::MetadataLoaded( + UniquePtr aInfo, UniquePtr aTags, + MediaDecoderEventVisibility aEventVisibility) { + // If the previous state machine has loaded the metadata, then we don't need + // to load it again. This can happen when the media format or key system is + // not supported by previous state machine. + if (mFiredMetadataLoaded && mStateMachineRecreated) { + MSE_DEBUG( + "Metadata already loaded and being informed by previous state machine"); + return; + } + MediaDecoder::MetadataLoaded(std::move(aInfo), std::move(aTags), + aEventVisibility); +} +#endif + #undef MSE_DEBUG #undef MSE_DEBUGV diff --git a/dom/media/mediasource/MediaSourceDecoder.h b/dom/media/mediasource/MediaSourceDecoder.h index ff312cb6cf..2ebba67a17 100644 --- a/dom/media/mediasource/MediaSourceDecoder.h +++ b/dom/media/mediasource/MediaSourceDecoder.h @@ -85,6 +85,11 @@ class MediaSourceDecoder : public MediaDecoder, media::TimeInterval ClampIntervalToEnd(const media::TimeInterval& aInterval); bool CanPlayThroughImpl() override; +#ifdef MOZ_WMF_MEDIA_ENGINE + void MetadataLoaded(UniquePtr aInfo, UniquePtr aTags, + MediaDecoderEventVisibility aEventVisibility) override; +#endif + RefPtr mPrincipal; // The owning MediaSource holds a strong reference to this decoder, and diff --git a/dom/media/mediasource/test/mochitest.toml b/dom/media/mediasource/test/mochitest.toml index b9ed95b2bb..7e60af8929 100644 --- a/dom/media/mediasource/test/mochitest.toml +++ b/dom/media/mediasource/test/mochitest.toml @@ -270,3 +270,5 @@ skip-if = [ ["test_WaitingOnMissingData_mp4.html"] ["test_WaitingToEndedTransition_mp4.html"] + +["test_BufferedSeekCanPlayThrough.html"] diff --git a/dom/media/mediasource/test/test_BufferedSeekCanPlayThrough.html b/dom/media/mediasource/test/test_BufferedSeekCanPlayThrough.html new file mode 100644 index 0000000000..5c789a7b6e --- /dev/null +++ b/dom/media/mediasource/test/test_BufferedSeekCanPlayThrough.html @@ -0,0 +1,46 @@ + + + + MSE: Don't get stuck buffering for too long when we have frames to show + + + + + +

+
+ + diff --git a/dom/media/mediasource/test/test_EndOfStream.html b/dom/media/mediasource/test/test_EndOfStream.html index b926869f1f..bcaf2ee54d 100644 --- a/dom/media/mediasource/test/test_EndOfStream.html +++ b/dom/media/mediasource/test/test_EndOfStream.html @@ -12,7 +12,7 @@ SimpleTest.waitForExplicitFinish(); -runWithMSE(async (ms, v) => { +runWithMSE(async (ms) => { await once(ms, "sourceopen"); const sb = ms.addSourceBuffer("video/webm"); diff --git a/dom/media/mediasource/test/test_EndOfStream_mp4.html b/dom/media/mediasource/test/test_EndOfStream_mp4.html index 9319b80390..140641565d 100644 --- a/dom/media/mediasource/test/test_EndOfStream_mp4.html +++ b/dom/media/mediasource/test/test_EndOfStream_mp4.html @@ -12,7 +12,7 @@ SimpleTest.waitForExplicitFinish(); -runWithMSE(async (ms, v) => { +runWithMSE(async (ms) => { await once(ms, "sourceopen"); const sb = ms.addSourceBuffer("video/mp4"); diff --git a/dom/media/mediasource/test/test_ExperimentalAsync.html b/dom/media/mediasource/test/test_ExperimentalAsync.html index 6617716f26..e64a9befeb 100644 --- a/dom/media/mediasource/test/test_ExperimentalAsync.html +++ b/dom/media/mediasource/test/test_ExperimentalAsync.html @@ -61,7 +61,7 @@ runWithMSE(async function(ms, el) { await once(el, "seeked"); dump("dump: seeked to " + seekTime); is(el.currentTime, seekTime, "correctly seeked to " + seekTime); - await audiosb.appendBufferAsync(audioBuffer).catch(async function(ex2) { + await audiosb.appendBufferAsync(audioBuffer).catch(async function() { ok(false, "Shouldn't throw another time when data can be evicted"); dump(JSON.stringify(await SpecialPowers.wrap(el).mozRequestDebugInfo())); SimpleTest.finish(); @@ -73,7 +73,7 @@ runWithMSE(async function(ms, el) { await audiosb.removeAsync(ms.duration + 1, Infinity).catch(async function(ex4) { ok(true, "remove promise got rejected with start > duration"); is(ex4.name, "TypeError"); - await audiosb.removeAsync(0, Infinity).catch(function(ex5) { + await audiosb.removeAsync(0, Infinity).catch(function() { ok(false, "shouldn't throw"); }); ok(true, "remove succeeded"); diff --git a/dom/media/mediasource/test/test_SetModeThrows.html b/dom/media/mediasource/test/test_SetModeThrows.html index c715854b41..c81cb1b70f 100644 --- a/dom/media/mediasource/test/test_SetModeThrows.html +++ b/dom/media/mediasource/test/test_SetModeThrows.html @@ -13,7 +13,7 @@ SimpleTest.waitForExplicitFinish(); // MSE supports setting mode now. make sure it does not throw. -runWithMSE(function(ms, v) { +runWithMSE(function(ms) { ms.addEventListener("sourceopen", () => { const sb = ms.addSourceBuffer("video/webm"); -- cgit v1.2.3