Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: e77ffd167967c24232e8dcbac584ac1809524c90
      
https://github.com/WebKit/WebKit/commit/e77ffd167967c24232e8dcbac584ac1809524c90
  Author: Jean-Yves Avenard <j...@apple.com>
  Date:   2024-03-27 (Wed, 27 Mar 2024)

  Changed paths:
    M 
LayoutTests/media/media-source/media-managedmse-noresumeafterpause-expected.txt
    M LayoutTests/media/media-source/media-managedmse-noresumeafterpause.html
    A 
LayoutTests/media/media-source/media-managedmse-resume-after-remove-expected.txt
    A LayoutTests/media/media-source/media-managedmse-resume-after-remove.html
    M 
LayoutTests/media/media-source/media-managedmse-resume-after-stall-expected.txt
    M LayoutTests/media/media-source/media-managedmse-resume-after-stall.html
    A 
LayoutTests/media/media-source/media-managedmse-stall-endofstream-expected.txt
    A LayoutTests/media/media-source/media-managedmse-stall-endofstream.html
    M LayoutTests/media/media-source/media-source-fudge-factor-expected.txt
    M LayoutTests/media/media-source/media-source-fudge-factor.html
    M LayoutTests/platform/glib/TestExpectations
    M LayoutTests/platform/mac-wk1/TestExpectations
    M LayoutTests/platform/mac/TestExpectations
    M Source/WebCore/Modules/mediasource/ManagedMediaSource.cpp
    M Source/WebCore/Modules/mediasource/MediaSource.cpp
    M Source/WebCore/Modules/mediasource/MediaSource.h
    M Source/WebCore/platform/graphics/MediaSourcePrivate.cpp
    M Source/WebCore/platform/graphics/MediaSourcePrivate.h
    M Source/WebCore/platform/graphics/SourceBufferPrivate.cpp
    M 
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h
    M 
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm
    M 
Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.h
    M 
Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.mm
    M Source/WebKit/WebProcess/GPU/media/MediaPlayerPrivateRemote.cpp
    M Source/WebKit/WebProcess/GPU/media/MediaPlayerPrivateRemote.h
    M Source/WebKit/WebProcess/GPU/media/MediaSourcePrivateRemote.cpp

  Log Message:
  -----------
  [MSE] video's currentTime can be further than the gap's start time
https://bugs.webkit.org/show_bug.cgi?id=270618
rdar://124186726

Reviewed by Jer Noble.

The AVFObjC MSE player relies on using AVSampleBufferRenderSynchronizer
which provides the base routines to handle A/V sync, seeking and determining
the playback current time.
The code used notification listeners such as 
AVSampleBufferRenderSynchronizerRateDidChangeNotification
to determine when the actual playback rate changed to 0.
But this notification will be received only if playback was paused through
external means such as on iOS "by a phone call or another non-mixable app 
starting playback".
But actually AVSampleBufferRenderSynchronizer never stops otherwise, even
when it has run out of data to decode and play such as when there's a gap
in the buffered range or even if the currentTime has gone past the media's 
duration.
The MediaSource's monitorSourceBuffer would monitor the current time and
the buffered range and would pause the media element if it detected that
we no longer had anything to play. However this occurs in the content process
while decoding and playback occurs in the GPU process. The inherent latency
between the two processes means that the CP would set the readyState to
be HaveCurrentData which would make the MediaPlayerPrivateMediaSourceAVFObjC
pause playback, but by the time this was received the 
AVSampleBufferRenderSynchronizer's
timebase/clock would have already progressed further than it should have.
Worse, in combination with the time clock used by the MediaPlayerPrivateRemote
you would end up with nonsensical currentTime, positioned in the middle
of a media data gap, causing the readyState to move back to HaveMetadataData.
Similarly, you could end up with currentTime being significantly past
the media's duration. (When using a debugger, and blocking the GPU process
I saw currentTime being further than 90s past where it should have been).

To fix this issue, we adds two steps:
1- In the MediaPlayerPrivateRemote, when using MSE we ensure that the 
currentTime never
goes past the start of a gap greater than 2/24th of a second (the 
SourceBuffer's timeFuzzingFactor),
nor past the media's duration.
2- Add stall detections in the MediaPlayerPrivateMediaSourceAVFObjC by
using time observers with AVSampleBufferRenderSynchronizer that will
immediately pause playback once we reached the start of a gap.

To reduce the latency between data being added to the source buffer and the
GPU's MediaPlayer being notified that new data got added, we make the 
SourceBufferPrivate
immediately notifies its MediaSourcePrivate's parent that the buffered data
has changed.

Add tests to ensure that we always stall and fire the waiting event where
a gap starts.

* 
LayoutTests/media/media-source/media-managedmse-noresumeafterpause-expected.txt:
* LayoutTests/media/media-source/media-managedmse-noresumeafterpause.html:
* 
LayoutTests/media/media-source/media-managedmse-resume-after-remove-expected.txt:
 Added.
* LayoutTests/media/media-source/media-managedmse-resume-after-remove.html: 
Copied from 
LayoutTests/media/media-source/media-managedmse-resume-after-stall.html.
* 
LayoutTests/media/media-source/media-managedmse-resume-after-stall-expected.txt:
* LayoutTests/media/media-source/media-managedmse-resume-after-stall.html:
* 
LayoutTests/media/media-source/media-managedmse-stall-endofstream-expected.txt: 
Added.
* LayoutTests/media/media-source/media-managedmse-stall-endofstream.html: 
Copied from 
LayoutTests/media/media-source/media-managedmse-resume-after-stall.html.
* LayoutTests/media/media-source/media-source-fudge-factor-expected.txt:
* LayoutTests/media/media-source/media-source-fudge-factor.html: The test 
relied on timers to check
value which would cause intermittent failures. Test had been marked as expected 
to fail
on mac. Re-write the test using events instead of timers.
* LayoutTests/platform/glib/TestExpectations:
* LayoutTests/platform/mac-wk1/TestExpectations:
* LayoutTests/platform/mac/TestExpectations:
* Source/WebCore/Modules/mediasource/ManagedMediaSource.cpp:
(WebCore::ManagedMediaSource::monitorSourceBuffers):
* Source/WebCore/Modules/mediasource/MediaSource.cpp:
(WebCore::MediaSource::hasFutureTime):
* Source/WebCore/Modules/mediasource/MediaSource.h:
* Source/WebCore/platform/graphics/MediaSourcePrivate.cpp:
(WebCore::MediaSourcePrivate::hasFutureTime const):
(WebCore::MediaSourcePrivate::trackBufferedChanged):
(WebCore::MediaSourcePrivate::hasBufferedData const):
(WebCore::MediaSourcePrivate::timeIsProgressing const):
* Source/WebCore/platform/graphics/MediaSourcePrivate.h:
* Source/WebCore/platform/graphics/SourceBufferPrivate.cpp:
(WebCore::SourceBufferPrivate::updateBuffered):
* 
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
* 
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::MediaPlayerPrivateMediaSourceAVFObjC):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::~MediaPlayerPrivateMediaSourceAVFObjC):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::currentTime const):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::clampTimeToSensicalValue const):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setCurrentTimeDidChangeCallback):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::bufferedChanged):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::durationChanged): we no longer 
needs to
specifically add an observer for when currentTime reaches the end of the media. 
This is taken
care by the more generic gap detection.
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setReadyState):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::clampTimeToLastSeekTime const): 
Deleted.
* 
Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.h:
* 
Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.mm:
(WebCore::MediaSourcePrivateAVFObjC::removeSourceBuffer):
(WebCore::MediaSourcePrivateAVFObjC::player const):
(WebCore::MediaSourcePrivateAVFObjC::bufferedChanged):
(WebCore::MediaSourcePrivateAVFObjC::trackBufferedChanged):
* Source/WebKit/WebProcess/GPU/media/MediaPlayerPrivateRemote.cpp:
(WebKit::MediaPlayerPrivateRemote::TimeProgressEstimator::cachedTimeWithLockHeld
 const):
(WebKit::MediaPlayerPrivateRemote::TimeProgressEstimator::timeIsProgressing 
const):
(WebKit::MediaPlayerPrivateRemote::currentTime const):
(WebKit::MediaPlayerPrivateRemote::currentTimeWithLockHeld const):
(WebKit::MediaPlayerPrivateRemote::currentOrPendingSeekTime const):
(WebKit::MediaPlayerPrivateRemote::setReadyState):
* Source/WebKit/WebProcess/GPU/media/MediaPlayerPrivateRemote.h:
* Source/WebKit/WebProcess/GPU/media/MediaSourcePrivateRemote.cpp:
(WebKit::MediaSourcePrivateRemote::setMediaPlayerReadyState):

Canonical link: https://commits.webkit.org/276761@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to